rtthread工业使用_RT Thread SPI设备 使用

本文详细介绍了如何在RT Thread操作系统中配置和使用SPI设备,特别是针对SX1278模块的驱动实现。通过修改Cubemx配置,将SPI的片选改为GPIO_OUTPUT,并展示了SPI设备的初始化、读写操作以及中断处理。代码中包含关键函数如rt_hw_spi2_config和rt_hw_SX1278_config,用于设备的配置和挂载。
AI助手已提取文章相关产品:

后记:

之前,我把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\n",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("\n rt_hw_spi_device_attach(), OK! \r\n");

}

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("\n Wrong ! \r\n");

/* 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("\n rt_spi_configure(), OK! \r\n");

}

}

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 \r\n", TempReg);

rt_thread_delay(50);

}

}

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值