1,前言
单片机型号:STM32F407
编程环境 :STM32CubeMX + Keil v5
硬件连接 :SPI1,CS/SS--->PB14
注:本工程在1,STM32CubeMX工程基础(配置Debug、时钟树)基础上完成。
本工程在4,STM32CubeMX配置UART串口工程基础上完成。
2,STM32CubeMX配置SPI工程
首先开启STM32的SPI接口,STM32F407一共有三个SPI接口,本文使用接口SPI1。
在Connectivity(1)下方点击SPI1(2)启用SPI接口1。点击设置部分Mode(3)将SPI模式设置为Full-Duplex Master全双工主机模式,可以在Paramater Setting(4)设置分频系数64,让SPI的速度低一些。设置完成后可以看到Pinout view(5)以及显示出信息。这里本文用的是复用功能的SPI1和原SPI1效果相同。
其次,配置SPI1的CS/SS片选引脚,可以在cubeMX上使用硬件CS/SS片选功能,本文使用软件的方式实现。配置方式如下,首先在PB14(1)引脚处左击选择模式未GPIO_Output,在System Core(2)下选择GPIO(3)进行设置。在PB14 Configuration(4)配置界面,将输出默认电平改为High、上拉输出、输出速度为高(由于SPI传输速度较高)。
3,STM32HAL库常用SPI函数
1,SPI发送函数HAL_SPI_Transmit。输入量hspi为句柄, 输入量pData为传输的数据, 输入量 Timeout为超时时间。
/**
* @brief 在阻塞模式下传输一定数量的数据。
* SPI_HandleTypeDef@param指向包含
* SPI 模块的配置信息。
* @param指向数据缓冲区的 pData 指针
* @param 大小 要发送的数据量
* @param 超时超时持续时间
* @retval HAL 状态
*/
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2.SPI接收函数HAL_SPI_Receive。输入量hspi为句柄, 输入量pData为接收的数据, 输入量Size为要接收的数据大小(多少字节),输入量 Timeout为超时时间。
/**
* @brief 在阻塞模式下接收一定数量的数据。
* SPI_HandleTypeDef@param指向包含
* SPI 模块的配置信息。
* @param指向数据缓冲区的 pData 指针
* @param 要接收的数据量大小
* @param 超时超时持续时间
* @retval HAL 状态
*/
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2.SPI发送接收函数HAL_SPI_TransmitReceive。输入量hspi为句柄,输入量pTxData为发送的数据, 输入量pRxData为接收的数据, 输入量Size为要接收的数据大小(多少字节),输入量 Timeout为超时时间。(注:为什么会有发送接收函数,SPI通信作为单主多从模式,其协议必须有发送才会有接收。如果只想接收数据,则需要发送一个空数据来实现。)
/**
* @brief 在阻塞模式下发送和接收一定量的数据。
* SPI_HandleTypeDef@param指向包含
* SPI 模块的配置信息。
* @param pTxData 指针指向传输数据缓冲区
* @param pRxData 指针指向接收数据缓冲区
* @param 大小 要发送和接收的数据量
* @param 超时超时持续时间
* @retval HAL 状态
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout)
4,编程实战(SPI读取norflash的ID)
首先添加两个.c/.h文件。然后设置norflash的spi的发送接收函数。
uint8_t spi1_read_write_byte(uint8_t Txdata)
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&hspi1 ,&Txdata, &Rxdata, 1, 1000);
return Rxdata;
}
下面是读取norflash的ID时序函数。
/**
* @brief 读取芯片ID
* @param 无
* @retval FLASH芯片ID
* @note 芯片ID列表见: norflash.h, 芯片列表部分
*/
uint16_t norflash_read_id(void)
{
uint16_t deviceid;
NORFLASH_CS(0);
spi1_read_write_byte(FLASH_ManufactDeviceID); /* 发送读 ID 命令 */
spi1_read_write_byte(0); /* 写入一个字节 */
spi1_read_write_byte(0);
spi1_read_write_byte(0);
deviceid = spi1_read_write_byte(0xFF) << 8; /* 读取高8位字节 */
deviceid |= spi1_read_write_byte(0xFF); /* 读取低8位字节 */
NORFLASH_CS(1);
return deviceid;
}
编译成功,烧录后打开串口调试助手,实验完成。