- 作者:zzssdd2
- E-mail:zzssdd2@foxmail.com
一、需求描述
- MCU需要接收来自CPLD的升级固件数据
- CPLD对MCU只进行发送数据,不接收MCU的数据
- CPLD无法告知数据传输的开始和结束,需要MCU自行判断(CPLD只是数据透传,不做数据判断)
- 数据通信速率至少是UART通信的115200波特率
- PCB上MCU与CPLD之间通过3个普通IO引脚连接
二、功能分析
-
MCU与CPLD之间有3根线,那么可以选择UART通信或者SPI通信方式。
-
由于CPLD无法通知MCU数据传输的开始与结束,MCU需要自行判别,那么MCU可以通过中断方式来检测数据传输的开始,通过超时来检测数据传输的结束。
-
UART与SPI的区别在于前者是异步通信后者是同步通信方式,不论是SPI还是UART方式都需要MCU通过IO模拟方式软件实现。使用UART传输如果收发双方产生的波特率存在偏差则会导致数据传输出错,而同步传输方式有时钟信号的约束,相比异步传输方式数据准确率会更高。如果使用软件模拟UART,需要使用定时器作为波特率发生器。如果波特率比较高,那么定时器中断频率就需要更高,这样会影响整个MCU系统的实时性。综合考虑后选择SPI方式。
-
CPLD对MCU只发送数据,那么MCU只需要作为SPI的从机即可,三个IO分配为SPI的CS、CLK、DAT引脚。
-
由于CS是低电平有效,那么将CS引脚配置为中断输入方式,当CS中断触发后开始数据接收处理。因为CPLD也不知道数据传输什么时候结束,所以无法通过将CS置高电平来告诉数据传输的结束,那么CS置高电平只能表明一个字节传输结束。MCU可以通过超时方式来判断一包数据的结束,类似于串口的空闲中断方式。
-
SPI数据接收在外部中断中操作。将CLK引脚配置为外部中断的
上升沿触发,CS有效的情况下CLK中断触发后进行数据接收。 -
SPI空闲中断采用100us周期定时器判断。为了MCU系统的实时性,只有CS中断触发后才会开启定时器,超时判断完成后关闭定时器。
-
CPLD向MCU发送一字节的时序图如下(速率:200KBit/s):

三、软件实现
GPIO的配置:无数据CLK为低电平,CS低有效。CS上升沿、下降沿都会触发中断,判断1字节传输的起始与结束;CLK上升沿触发中断,数据在CLK上升沿采样
/*
***********************************************************************************************
* 函 数: BSP_CPLD_GPIO_Init
* 描 述: 配置CPLD的SPI通信引脚
* 输 入: 无
* 输 出: 无
***********************************************************************************************
*/
void BSP_CPLD_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {
0};
/* GPIO Ports Clock Enable */
CPLD_PIN_CLK_ENABLE();
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = CPLD_SPI_CSN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull


2926

被折叠的 条评论
为什么被折叠?



