本文主要介绍stm32的spi接口、cubemx软件配置spi接口和分析spi相关代码。
stm32之spi简介:
spi协议【serial peripheral interface】
串行外围设备接口,是一种高速全双工的通信总线。主要用在mcu与flashadclcd等模块之间的通信。
spi信号线
spi 共包含 4 条总线。
ss(slave select):片选信号线,当有多个spi 设备与 mcu 相连时,每个设备的这个片选信号线是与 mcu 单独的引脚相连的,而其他的 sck、mosi、miso 线则为多个设备并联到相同的 spi 总线上,低电平有效。
sck (serial clock):时钟信号线,由主通信设备产生,不同的设备支持的时钟频率不一样,如 stm32 的 spi 时钟频率最大为 f pclk /2。
mosi (master output slave input):主设备输出 / 从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入数据,即这条线上数据的方向为主机到从机。
miso(master input slave output):主设备输入 / 从设备输出引脚。主机从这条信号线读入数据,从机的数据则由这条信号线输出,即在这条线上数据的方向为从机到主机。
其中sck,mosi,miso是接在一起的,nss分别接到不同的io管脚控制。主器件要和从器件通信就先拉低对应从器件的nss管脚使能。默认状态io1,io2,io3全为高电平,当主器件和从器件1通信时,拉低io1管脚使能从器件1。而从器件2,3不使能,不作响应。下图是主器件与多个从器件通信图。
spi特性
单次传输可选择为 8 或 16 位。波特率预分频系数(最大为 fpclk/2) 。时钟极性(cpol)和相位(cpha)可编程设置。数据顺序的传输顺序可进行编程选择,msb 在前或 lsb 在前。
注:msb(most significant bit)是“最高有效位”,lsb(least significant bit)是“最低有效位”。
可触发中断的专用发送和接收标志。可以使用 dma 进行数据传输操作。下图是stm32的spi框架图。
如上图,miso数据线接收到的信号经移位寄存器处理后把数据转移到接收缓冲区,然后这个数据就可以由我们的软件从接收缓冲区读出了。当要发送数据时,我们把数据写入发送缓冲区,硬件将会把它用移位寄存器处理后输出到 mosi数据线。sck 的时钟信号则由波特率发生器产生,我们可以通过波特率控制位(br)来控制它输出的波特率。
控制寄存器 cr1掌管着主控制电路,stm32的 spi模块的协议设置(时钟极性、相位等)就是由它来制定的。而控制寄存器 cr2则用于设置各种中断使能。
最后为 nss引脚,这个引脚扮演着 spi协议中的ss片选信号线的角色,如果我们把 nss引脚配置为硬件自动控制,spi模块能够自动判别它能否成为 spi的主机,或自动进入 spi从机模式。但实际上我们用得更多的是由软件控制某些 gpio引脚单独作为ss信号,这个 gpio引脚可以随便选择。
spi时钟时序
根据时钟极性(cpol)及相位(cpha)不同,spi有四种工作模式。
时钟极性(cpol)定义了时钟空闲状态电平:
cpol=0为时钟空闲时为低电平
cpol=1为时钟空闲时为高电平
时钟相位(cpha)定义数据的采集时间。
cpha=0:在时钟的第一个跳变沿(上升沿或下降沿)进行数据采样。
cpha=1:在时钟的第二个跳变沿(上升沿或下降沿)进行数据采样。
cubemx软件配置spi:
下面继续介绍cubemx软件配置stm32l152的spi接口方法。
(1)打开软件,选择对应芯片后,配置好时钟源;
(2)勾选spi1为全双工,硬件nss关闭,如下图:
(3)勾选好后,pa5、pa6、pa7如下图,在配置pa4为普通io口,gpio_output
(4)spi1的参数配置选择默认,如下图所示
(5)生成代码,保存即可。
hal库的spi函数分析:
下面具体分析下生成的spi函数和函数调用。
spi_handletypedef hspi1; //spi结构体类定义,下面看其结构体内部的声明。
下面分析spi的初始化函数:
void hal_spi_mspinit(spi_handletypedef* hspi){gpio_inittypedef gpio_initstruct;if(hspi->instance==spi1){/* user code begin spi1_mspinit 0 *//* user code end spi1_mspinit 0 *//* peripheral clock enable */__hal_rcc_spi1_clk_enable();//使能spi1时钟/**spi1 gpio configurationpa5 ------> spi1_sckpa6 ------> spi1_misopa7 ------> spi1_mosi*/gpio_initstruct.pin = gpio_pin_5|gpio_pin_6|gpio_pin_7;gpio_initstruct.mode = gpio_mode_af_pp;gpio_initstruct.pull = gpio_nopull;gpio_initstruct.speed = gpio_speed_freq_very_high;gpio_initstruct.alternate = gpio_af5_spi1;hal_gpio_init(gpioa, &gpio_initstruct);//配置spi的数据线和时钟线/* user code begin spi1_mspinit 1 *//* user code end spi1_mspinit 1 */} static void mx_spi1_init(void){hspi1.instance = spi1;hspi1.init.mode = spi_mode_master;//主模式hspi1.init.direction = spi_direction_2lines;//全双工hspi1.init.datasize = spi_datasize_8bit;//数据位为8位hspi1.init.clkpolarity = spi_polarity_low;//cpol=0,lowhspi1.init.clkphase = spi_phase_1edge;//cpha为数据线的第一个变化沿hspi1.init.nss = spi_nss_soft;//软件控制nsshspi1.init.baudrateprescaler = spi_baudrateprescaler_2;//2分频,32m/2=16mhzhspi1.init.firstbit = spi_firstbit_msb;//最高位先发送hspi1.init.timode = spi_timode_disable;//timode模式关闭hspi1.init.crccalculation = spi_crccalculation_disable;//crc关闭hspi1.init.crcpolynomial = 10;//默认值,无效if (hal_spi_init(&hspi1) != hal_ok)//初始化{_error_handler(__file__, __line__);}}
利用spi接口发送和接收数据主要调用以下两个函数:
hal_statustypedef hal_spi_transmit(spi_handletypedef *hspi, uint8_t *pdata, uint16_t size, uint32_t timeout);//发送数据hal_statustypedefhal_spi_receive(spi_handletypedef*hspi,uint8_t*pdata,uint16_tsize,uint32_ttimeout);//接收数据
原文标题:stm32cubemx-hal库的spi接口使用
文章出处:【微信公众号:stm32嵌入式开发】欢迎添加关注!文章转载请注明出处。
燃料电池汽车将逐步由政策驱动转向市场驱动
IFIX实现与S7-200的OPC通讯的详细步骤
手臂代替触摸面板用声波传感器检测位置
英伟达和华为/海思主流GPU型号性能参考
11月大陆显卡品牌SellIn出货排行榜公布 七彩虹稳居第一其次分别为影驰和微星
STM32的SPI接口、cubeMX软件配置SPI接口和分析SPI相关代码
图形气象站的制作教程
中科曙光医疗数字化平台方案推动新郑市县域医共体的建设工作
基于DSP和CPLD的液晶模块的设计
头部电视厂商芯片和显示屏供应不足,库存下降明显
卡轨式DTU,方便快捷的远程监控利器!
“定制检测”成为智慧产业奇葩 适用于玻璃瓶综合检测
英特尔、高通、AMD等美芯片企业致信拜登:要求提供“激励资金”
小米6被曝有双曲屏版 但没有双摄像头
施耐德电气上线开发者社区 打造能源与自动化领域开放交流平台
AirPods Pro 2C54固件更新会恶化降噪功能
每日一课 | 智慧灯杆感知技术之无线传感网的节点与特点介绍
瑞萨电子RE产品家族可实现超低电流消耗
汉威城市生命线感知与安全运营平台构筑安全城市地下“生命线”
紫光拟投资300亿美元做中国首个芯片巨头