一、明确spi通信中的片选场景
软cs ,即自己定义片选引脚(任意引脚)
硬cs,则使用芯片定义的引脚。
主机的cs 会在通信时拉低已选中通信设备进行通信,通信完成拉高的规则。
二、双机通信的逻辑设计
配置
spi通信参数默认参数。
gpio配置
代码调整
#define CS_L HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET);
#define CS_H HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);
主机中断回调处理
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
CS_H;
printf("\r\n recv slave date:\r\n");
for(int i=0;i<sizeof(rxbuf);i++)
{
printf("0x%0x ",rrxbuf[i]);
}
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
CS_H;
printf("\r\n masert send date pass \r\n");
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
CS_L;
//填充0xff,提供时钟信号
memset(txbuf3,0xff,sizeof(rxbuf));
memset(rrxbuf,0,sizeof(rxbuf));
HAL_SPI_TransmitReceive_IT(&hspi2,txbuf3,rrxbuf,sizeof(txbuf2));
}
从机中断处理
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
printf("\r\n recv masert dates pass:\r\n ");
for(int i=0;i<sizeof(rxbuf);i++)
{
if(rxbuf[i]==0xff){}
else
{
printf("0x%0x ",rxbuf[i]);
}
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
//从机发送数据
if(i%2==1)
{
HAL_SPI_TransmitReceive_IT(&hspi2,ttxbuf,rxbuf,sizeof(txbuf));
}
else
{
HAL_SPI_TransmitReceive_IT(&hspi2,txbuf,rxbuf,sizeof(txbuf));
}
i++;
}
主机的while中调用
if(getchar()=='q')
{
CS_L;
if(i%2==1)
{
printf("spi date1\n");
HAL_SPI_Transmit_IT(&hspi2,txbuf2,sizeof(txbuf2));
}
else
{
printf("spi date2\n");
HAL_SPI_Transmit_IT(&hspi2,txbuf,sizeof(txbuf2));
}
i++;
}
从机的while中调用
if(getchar()=='q')
{
//从机发送信号启动
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_Delay(5);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_SET);
}
通信测试结果
缺陷:能实现固定长度的数据通信,要实现变长需要主机提供的时钟的数据长度提前获知从机要传输的数据长度,可以自定义协议帧,类似flash读取数据的方式。