zoukankan      html  css  js  c++  java
  • RT Thread SPI设备 使用

    后记:

    之前,我把SPI的片选在Cubemx中配置成了SPI_NSS。
    现在我给它改为了GPIO_OUTPUT.  同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的系统API的调用流程)。
    年初第一天上班,有空回过头来看这个问题,就成功解决了。

    ------Sx1278.h-----------------------------------------------------------------------------------------------------

    #ifndef __SX1278_H__
    #define __SX1278_H__


    #include "drv_gpio.h"


    struct spi_sx1278_device
    {
    struct rt_device sx1278_device;
    struct rt_spi_device * rt_spi_device;
    struct rt_mutex lock;
    void * user_data;
    };


    typedef struct spi_sx1278_device * rt_spi_sx1278_device_t;


    // 引脚定义
    #define Sx1278_IRQ_PIN GET_PIN(C, 8)
    #define Sx1278_nCS_PIN GET_PIN(B, 12)
    #define Sx1278_RST_PIN GET_PIN(C, 9)

    // 引脚状态
    #define ST_SX1278_IRQ() rt_pin_read(Sx1278_IRQ_PIN)

    // 引脚输出
    #define SX1278_SPI_NCS_H() rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
    #define SX1278_SPI_NCS_L() rt_pin_write(Sx1278_nCS_PIN, PIN_LOW);

    #define SX1278_SPI_RST_H() rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);
    #define SX1278_SPI_RST_L() rt_pin_write(Sx1278_RST_PIN, PIN_LOW);

    typedef rt_uint8_t u8;
    typedef rt_uint16_t u16;
    typedef rt_uint32_t u32;

    void test(void);

    #endif

    ------Sx1278.c-----------------------------------------------------------------------------------------------------
    #include "board.h"
    #include "drv_spi.h"
    #include "Sx1278.h"

    #define SPI_BUS_NAME         "spi2"
    #define SPI_SX1278_DEVICE_NAME   "spi20"


    void hdr_callback(void *args)// 回调函数
    {
    char *a = args; // 获取参数
    rt_kprintf("KEY_PIN down! %s ",a);
    }

    //struct stm32_hw_spi_cs
    //{
    // rt_uint32_t pin;
    //}; 不自己定义了,新的STM32 BSP 的drv_spi.h 有如下定义

    // drv_spi.h 内定义:
    //struct stm32_hw_spi_cs
    //{
    // GPIO_TypeDef* GPIOx;
    // uint16_t GPIO_Pin;
    //};
    static struct stm32_hw_spi_cs spi_cs; /* SPI设备CS片选引脚 */

    static struct spi_sx1278_device spi_sx1278_device;

    #define CS_PIN 28 // Sx1278_nCS_PIN

    static u8 SX1278_spiReadWriteByte(const u8 Sdata)
    {
    u8 Rdata[13] = {0};

    // rt_pin_write(CS_PIN, PIN_LOW); /* 先 低电平 */

    // rt_spi_send_then_recv第一个形参:struct rt_spi_device *device;
    rt_spi_send_then_recv( spi_sx1278_device.rt_spi_device, &Sdata, (rt_size_t)1, Rdata, (rt_size_t)1);

    // rt_spi_send(spi_sx1278_device.rt_spi_device, &Sdata, 1);

    return Rdata[0];
    }


    int rt_hw_spi2_config(const char * spi_device_name)  // 这里填的就是"spi20"为参数。这里应该直接直接命名参数为const char * device name
    {                                                                                     // spi_device_name是spi总线设备的意思, 对应的是"spi2"总线。
    rt_err_t res;

    struct rt_spi_device * rt_spi_device;

    rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT);

    // 这个不用根据SPI设备名字 来 查找 设备
    //res = rt_spi_bus_attach_device(spi_sx1278_device.rt_spi_device, SPI_SX1278_DEVICE_NAME, SPI_BUS_NAME, (void*)&spi_cs);

    spi_cs.GPIOx = GPIOB;
    spi_cs.GPIO_Pin = GPIO_PIN_12;

    // 这个要根据SPI设备名字 来 查找 设备 功能1: 把spi20挂到spi2上
    res = rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_SX1278_DEVICE_NAME, spi_cs.GPIOx, spi_cs.GPIO_Pin);
    if( res == RT_EOK )
    {
    rt_kprintf(" rt_hw_spi_device_attach(), OK! ");
    }

    rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);

    spi_sx1278_device.rt_spi_device = rt_spi_device;

    if(spi_sx1278_device.rt_spi_device == RT_NULL)
      rt_kprintf(" Wrong ! ");

    /* config spi */
    {
    struct rt_spi_configuration cfg;
    cfg.data_width = 8;
    cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
    cfg.max_hz = 1 * 1000 *1000; /* 20M,SPI max 42MHz,ssd1351 4-wire spi */

    res = rt_spi_configure(spi_sx1278_device.rt_spi_device, &cfg);

    if( res == RT_EOK )
    {
      rt_kprintf(" rt_spi_configure(), OK! ");
    }

    }

    return RT_EOK;
    }


    rt_err_t rt_hw_SX1278_config(const char * sx1278_device_name, const char * spi_device_name)
    {
    rt_hw_spi2_config(sx1278_device_name);

    return RT_EOK;
    }

    static int rt_hw_SX1278_init(void)
    {
    // rt_hw_SX1278_config( "spi2", "spi20");         参数填写错误
       rt_hw_SX1278_config( "spi20", "spi2");      // 参数填写正确

    // SX1278 部分
    // IO 方向
    rt_pin_mode(Sx1278_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(Sx1278_RST_PIN, PIN_MODE_OUTPUT);

    // SX1278中断
    rt_pin_attach_irq(Sx1278_IRQ_PIN, PIN_IRQ_MODE_FALLING, hdr_callback, (void*)"CallBack args"); // 绑定中断,下降沿模式,回调函数
    rt_pin_irq_enable(Sx1278_IRQ_PIN, PIN_IRQ_DISABLE); // PIN_IRQ_DISABLE、PIN_IRQ_ENABLE

    // IO初值设置
    rt_pin_write(Sx1278_nCS_PIN, PIN_HIGH);
    rt_pin_write(Sx1278_RST_PIN, PIN_HIGH);

    return 0;
    }
    INIT_PREV_EXPORT(rt_hw_SX1278_init); /* 使用RT-Thread的组件自动初始化机制 */

    u8 WirelessInit(u8 channel, u8 pa)
    {
    u8 result=0;

    // SX1278_DisableInt();

    // SX1278_SetLoRaPA(pa);
    // SX1278_Init(channel); // 初始化
    //
    // sG_RfState = ST_RF_RECE; // 接收状态
    //
    // SX1278_EnableInt();

    return result;
    }


    void Delay_1ms(u8 x)
    {
    //rt_thread_mdelay(x);
    rt_thread_delay(x);
    }


    void SX1278_Reset(void)
    {
    static int sPowerUpFlag=1;

    SX1278_SPI_RST_H();
    Delay_1ms(2);

    SX1278_SPI_RST_L(); // 至少100us
    Delay_1ms(2);

    SX1278_SPI_RST_H(); // 至少5ms
    if(sPowerUpFlag)
    {
    sPowerUpFlag = 0;
    Delay_1ms(12); // 第一次上电,延时时间长一点
    }
    else
    {
    Delay_1ms(7);
    }
    }

    static u8 SX1278Read(u8 adr)
    {
    u8 tmp;

    SX1278_SPI_NCS_L();

    SX1278_spiReadWriteByte(adr); // Send address first
    tmp = SX1278_spiReadWriteByte(0xFF);

    SX1278_SPI_NCS_H();

    return tmp;
    }

    void test(void)
    {
    u8 TempReg;

    u8 timeOutCnt=0;

    SX1278_Reset(); rt_thread_mdelay(500);


    while(1)
    {
    TempReg = SX1278Read(0x06);

    //rt_kprintf("Hard SPI TempReg = %d ", TempReg);

    rt_thread_delay(50);
    }
    }

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    net异步编程
    二维码的生成细节和原理
    4605 Magic Ball Game
    (Java实现) 子集和问题
    (Java实现) 组合的输出
    (Java实现) 自然数的拆分
    (Java实现) 装载问题
    (Java实现) 整数区间
    (Java实现) 最佳调度问题
    (Java实现) 最佳调度问题
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/10427795.html
Copyright © 2011-2022 走看看