STM32 HAL库学习(四) SPI查询发送与接收

又是花了两天时间调SPI......细心细心还是需要细心啊,还是用的上次的SPI Flash芯片mx25l04600E,主要是测试芯片的初始化和读取芯片ID是否成功。

STM32F070芯片只有一个SPI,但可用作SPI信号管脚的引脚却不只一组,建议通信前先连接MOSI和MISO测试自发自收是否成功,如果不成功要考虑换一组引脚(我的就是有一组SPI引脚不能用。。。。)

首先采用CubeMX配置SPI,模式为Full-Duplex Master,即全双工主机模式;

接下来是选择NSS 的模式,NSS模式共有三种:NSS_Soft、Hardware Input和Hardware Output

  • NSS_Soft —— 即软件控制CS片选信号拉高或者拉低,选择该模式时,如果需要输出CS,要配置选择的引脚为输出模式,如我这里将PA4引脚做CS信号输出脚,则应该在CubeMX中配置其为GPIO_Output模式,之后在程序中通过设置引脚SET或RESET进行拉高或者拉低。
  • Hardware Output —— 即硬件输出模式,选择该模式时,硬件SPI要发送数据时会自动将片选信号拉低并且通过PA4引脚输出,主要用于一主一从的SPI通信控制
  • Hardware Input —— 即硬件输入模式,该模式只有在设备作为从机通信时可选择,输入的片选信号控制设备的通信与否

    这里选择NSS_Soft(后面解释为什么不能选Hardware Output模式)

    因为MX25L04006E芯片还有一个需要控制的WP信号,因此再选择一个引脚配置为输出模式用于控制WP信号的拉高或拉低

紧接着配置SPI通信数据的格式,采样模式只能选择“CPOL = 0,CPHA = 0”或者“CPOL = 1,CPHA = 1”两种模式(配合MX25L04006E芯片)

 配置完成后就可以写MX25L04006E的驱动函数了,例如MX25L4006E读取芯片ID的操作时发送0x9F指令,则代码如下

/*
 * Read identification
 * MID -- Manufacture Identification
 * DID -- Device Identification
 */
void mx25_RDID(uint8_t *MID,uint16_t *DID)
{
	uint8_t cmd;
	uint8_t ID[2];
	cmd=0x9f;
	clr_cs();
	HAL_SPI_Transmit(&hspi1, &cmd, 1, 10);
	HAL_SPI_Receive(&hspi1,MID,1,10);
	HAL_SPI_Receive(&hspi1,ID,2,10);
	set_cs();
	DID[0]=ID[0];
	DID[0]=DID[0]<<8;
	DID[0]+=ID[1];
}

测试返回的MID和DID与芯片手册提供的相同,则SPI通信成功。

接下来说下在调试过程中遇到的问题:

1、首先就是硬件......一定要先自发自收测试下管脚功能是否正常,不然后面一直调试不正确又找不到软件问题......

2、其次是NSS信号的模式,一开始我设置的是Hardware Output模式,对应的mx25l04006e芯片的驱动函数中就直接调用HAL_SPI_Transmit函数就可以 ,但在实际的测试中发现并不能正常返回芯片的ID,用逻辑分析抓取信号发现MISO返回的都是0.之后查看芯片手册,看了每个读写操作的时序图,每次发送指令前需要把NSS信号拉低,等指令发送完后再拉高,我猜想只有NSS信号拉高后数据才能正确地送入到芯片当中。而我设置的Hardware Output模式中,只要有调用SPI Transmit或者Receive,NSS信号就会一直处于低电平,这不符合芯片手册中的读写操作时序图。因此要实现芯片的读写,应设置为NSS_Soft模式,然后每次软件控制NSS拉低再拉高,从而实现指令的成功发送。

猜你喜欢

转载自blog.csdn.net/yhl_sophia/article/details/83825600