使用SPI的三大步骤
一、创建和注册SPI总线设备
创建SPI总线
创建 SPI 总线设备 主要实现 SPI 总线设备 struct rt_spi_bus 的数据结构定义,并实现操作方法 struct rt_spi_ops ,也就是实例化SPI总线设备
注册SPI总线
SPI 总线设备被注册后,使用如下接口注册到 SPI 设备驱动框架中:
rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus,
const char *name,
const struct rt_spi_ops *ops);
具体操作如下:
1、在软件包中心 —>组件中,勾选SPI总线设备,如下图所示:
2、打开 board.h 文件,并按照 文件中 的 SPI CONFIG BEGIN 至 SPI CONFIG END 的内容进行相关配置即可。
二、创建和挂载从设备
创建 SPI 从设备主要是实现 SPI 从设备 struct rt_spi_device 的数据结构体定义,然后使用 rt_spi_bus_attach_device() 接口将从设备挂载在总线设备上。(此方法源自 官方撰写的一本书)
本示例使用另外一种方法,使用这个接口: rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef* cs_gpiox, uint16_t cs_gpio_pin);
具体代码如下所示:
#include
#include
#include
#include
static int rt_hw_spi_flash_init(void)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
/*spi10表示挂载在 SPI1 总线上的设备,PB14是片选,这一步就可以将设备挂载到总线上 */
rt_hw_spi_device_attach("spi1", "spi10", GPIOB, GPIO_PIN_14);
/* 注册设备,这一步可以将外部flash抽象为系统的块设备 */
if (RT_NULL==rt_sfud_flash_probe("w25q128","spi10"))
{
return -RT_ERROR;
}
return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);
三、访问SPI从设备
1、查找设备 rt_device_find()
2、配置 SPI 模式、频率参数等,配置参数的结构体 struct rt_spi_configuration 原型如下:
struct rt_spi_configuration
{
rt_uint8_t mode; /* SPI模式 */
rt_uint8_t data_width; /* 数据宽度 */
rt_uint16_t reserved; /* 保留 */
rt_uint8_t max_hz; /* 最大频率 */
};
3、发送接收数据
该部分具体代码如下:
//SPI1配置例程
void SPI1_INIT(void)
{
struct rt_spi_device *spi_dev_w25q;
char name[RT_NAME_MAX]="spi10";
rt_uint8_t w25x_read_id = 0x90;//命令码
rt_uint8_t id[5] = {0};
/* 查找 spi 设备获取设备句柄 */
spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
if (!spi_dev_w25q)
{
rt_kprintf("spi sample run failed! can't find %s device!
", name);
}
else
{
/*配置SPI通讯相关参数 */
struct rt_spi_configuration cfg;
cfg.data_width = 8; /* 数据宽度 */
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; /* 主从模式、时钟极性和时钟相位、数据传输顺序是MSB位在前还是LSB位在前 */
cfg.max_hz = 20 * 1000 *1000; /* 20M */
rt_spi_configure(spi_dev_w25q, &cfg);
/* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x
", id[3], id[4]);
/* 方式2:使用 rt_spi_transfer_message()发送命令读取ID */
struct rt_spi_message msg1, msg2;
msg1.send_buf = &w25x_read_id;
msg1.recv_buf = RT_NULL;
msg1.length = 1;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = RT_NULL;
msg2.recv_buf = id;
msg2.length = 5;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(spi_dev_w25q, &msg1);
rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x
", id[3], id[4]);
}
}
原作者:The Subtly