历史上的今天
今天是:2025年04月10日(星期四)
2019年04月10日 | 关于STM32F4的串口注意的坑
2019-04-10 来源:eefocus
最近在研究STM32F4的串口通信的时候,发现一些有意思的现象,在这里做一个记录
这里就不再说明串口配置的具体步骤了,重点不在这边。
先贴上我的串口接收中断的程序
void USART_IRQHandler(void)
{
OS_ERR err;
char * p_mem_blk;
OSIntEnter(); //进入中断
p_mem_blk =(char*) OSMemGet(&uC_mem,&err);
//确保是否产生了USART_IT_RXNE中断
if(USART_GetITStatus(USART,USART_IT_Flag) != RESET)
{
* p_mem_blk = USART_ReceiveData ( USART ); //获取接收到的数据
OSTaskQPost(&USART1_Get_TCB,p_mem_blk,1,OS_OPT_POST_FIFO,&err);
//将信息发送给USART1_Get_TCB 任务
USART_SendData(USART1, *p_mem_blk);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
LED_TOGGLE;
}
USART_ClearITPendingBit(USART,USART_IT_Flag);
OSIntExit(); //退出中断
}
这是一个串口接收到什么就回传什么的程序,而且每进入一次中断就会改变一次LED的电平。先忽略一些uCOS-III的内存管理的函数。
开始试验
我先发送了一个1,结果是灯亮了,串口助手也会显了一个1
一切都很按预想进行。
再次发送12,结果是灯还是亮着,串口也是回显了12,那么说明进入了中断2次,所以LED的电平不变
那么可以得出一个结论:串口中断是由接受到1个字节触发中断
试试发送123,结果灯灭了,那么说明我们之前的猜想是有一定正确性的
现在中断函数换为
void USART_IRQHandler(void)
{
OS_ERR err;
char * p_mem_blk;
OSIntEnter(); //进入中断
p_mem_blk =(char*) OSMemGet(&uC_mem,&err);
//确保是否产生了USART_IT_RXNE中断
if(USART_GetITStatus(USART,USART_IT_Flag) != RESET)
{
* p_mem_blk = USART_ReceiveData ( USART ); //获取接收到的数据
OSTaskQPost(&USART1_Get_TCB,p_mem_blk,1,OS_OPT_POST_FIFO,&err);
//将信息发送给 USART1_Get_TCB 任务
USART_SendData(USART1, *p_mem_blk);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, 'n');
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
LED_TOGGLE;
}
USART_ClearITPendingBit(USART,USART_IT_Flag);
OSIntExit(); //退出中断
}
其实就是发送完后面再加一个‘n’
重新我们上面的实验:
我们发送一个1,结果是 回显了一个1和换行,灯也亮了,和上面的一样,perfect!
继续发送12,结果还是回显了一个1和换行,灯灭了,奇怪了,为什么和预想的不一样,
进入中断1次,还是发送了一个1和换行,
正常应该是:进入中断2次,所以灯还是亮着的,回显 1rn2rn 才对啊
emmmmm,再试试发送123
结果是灯还是灭的,回显了13和换行,等等,有点小慌。这是为什么?
难道我们之前的推理的是错误的:即接收到1个字节就进入中断
其实不然。
// USART_ClearITPendingBit(USART,USART_IT_Flag);
其实把这个中断标志注释了就知道了,

连续发送3次123,最后灯是亮着的,可以说明我们的推论是没有错误的,只是说中断标志被人为消除了,其中接收到的第2个数据被冲掉了,再次接收时已经是第三个字节触发的中断了。
如果在中断函数中发送多个值且又接收多个值,因为发送和接收的寄存器是同一个,你接收到数据后又发送该数据,之后又发送一个数据完成后,这时候第二个接收数据已经装入了寄存器了,但是你人为清除了标志位,所以不进入中断,第二个字节就被吃了,紧接着第三个字节重复第一个字节。。。。。。
而如果是不人为消除中断位的话,第二个字节的标志位是中断函数结束后再置位的,所以可以进入中断的。
这里的后面出现的E8是由于uCOS-III内存管理API管理函数造成的,每次进入中断都申请内存,一直产生中断,处理中断函数,所以没有归还内存导致的内存数据错误,注释相关的函数即可,或者扩大申请的内存块数量都可以。
下一篇:STM32F4跑马灯实验
史海拾趣
|
我这有一个stm32f10xx的开发板,但是使用IAR5.40.7的开发软件,可是编译通过了,可无论如很都写不进flash,也无法 ...… 查看全部问答> |
|
我的EK-LM3S811-ND Rev2 无法download 和debug 按照LM3S811 TI Evaluation kit光盘资料中的LM3S811EVALUATION KIT README FIRST安装驱动,安装后和资料里显示是驱动名称不一样. 资料讲的是LM3S811 Virtual COM Port(com6).”而我安装后显示\"stellaris ICDI Debug port(COM15)\",\"\"stellaris IC ...… 查看全部问答> |
|
请教一下大家,我想在沈阳开一个制作电路板的小店,主要是针对零散小批量的客户,利用雕刻机做,不知道有没有市场,需求量怎么样?有了解的朋友能不能给点建议。先谢谢大家了!… 查看全部问答> |
|
【跟TI学电源】系列----- TI工程师编写的的WEBENCH设计教程资料,不会的童鞋有福了! TI工程师编写的的WEBENCH设计教程资料,不会的童鞋有福了! 不知道怎么使用WEBENCH的同学可以下载看看,很详细的中文教程.本文档图文并茂,一步一步带你畅游WEBENCH设计,,, 这些日子,eeworld论坛的【三重礼】活动,正在如火如荼的进行,正确使 ...… 查看全部问答> |




