准备
材料:STM32F407ZGT6最小系统板,串口1通过跳线帽连接到了CH340上。
需求:从电脑向板子的串口1发送一个字符串(以回车和换行结尾,字符串末尾两个字符为0x0d和0x0a),板子接收到之后原样返回给电脑。
思路:用串口的接收中断实现。
代码实现
后台执行内容: 当判断接收完毕后,将存放在字符数组里的字符用循环的方式发送出去。
后台时刻检查变量STA的bit15的状态决定要不要发送数据。
大部分时候后台仅仅运行闪灯的那一部分。
int main()
{
u8 i=0;
u16 t=0;
u16 len=0;
uint8_t s[10];
SysTick_Init(168);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
USART1_Init(115200);
LED_Init();
LED2=0;
printf("初始化配置完成\r\n");
while(1)
{
if(USART1_RX_STA&0x8000)
{
len=USART1_RX_STA&0x3fff;
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART1_RX_BUF[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
USART1_RX_STA=0;
}
LED1=!LED1;
delay_ms(500);
}
}
前台执行内容: 用一个16位的变量来计数,同时由于字符串长度不可能达到16383个字符,故变量STA的bit15、bit14永远都是用不到的。
STA计数的作用一是发送数据是一次发送一个字符,要知道发送多少次;二是储存时要按下标存到数组的对应位置。
那么对STA的前两位进行操作时必然会影响到STA整体的值,是否存在问题呢? 不会!发送数据与储存数据均是只提取STA的低14位,在16383之内STA的自增只影响这14位数据。
u16 USART1_RX_STA=0;
串口每接收一个字符就进入中断一次,对于每一字符来讲都可能有3种情况:有效数据、0x0d、0x0a。先检查15位的状态是0还是1,再检查14位的状态是0还是1,最后对这一次接收的数据进行比对并对相应位进行置1标记或者写入数组操作。
每次接收到字符前台也会检查STA的bit15的状态。
前台的程序执行由硬件层面引发,当串口接收到数据就触发中断,执行中断服务程序里面的内容。这里面会对外界的输入进行检查判断,在合适的时机对一个全局变量USART1_RX_STA进行操作。而后台会时刻检测这个变量。这样就建立起前后台的联系。
void USART1_IRQHandler(void)
{
u8 r;
u16 i=0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
r =USART_ReceiveData(USART1);
if((USART1_RX_STA&0x8000)==0)
{
if(USART1_RX_STA&0x4000)
{
if(r!=0x0a)
USART1_RX_STA=0;
else USART1_RX_STA|=0x8000;
}
else
{
if(r==0x0d)
USART1_RX_STA|=0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=r;
USART1_RX_STA++;
if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;
}
}
}
}
}
总结
从下午看到晚上才搞懂,花了我这么多时间,算是正式开始单片机之旅了。还是太菜了,万里长征第一步,迈出去就好了。写个博客纪念一下。
|