关于STM32F4的串口注意的坑

最近在研究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次,所以灯还是亮着的,回显 1\r\n2\r\n 才对啊

emmmmm,再试试发送123

结果是灯还是灭的,回显了13和换行,等等,有点小慌。这是为什么?

难道我们之前的推理的是错误的:即接收到1个字节就进入中断

其实不然。

//  USART_ClearITPendingBit(USART,USART_IT_Flag);        

 

其实把这个中断标志注释了就知道了,

 

连续发送3次123,最后灯是亮着的,可以说明我们的推论是没有错误的,只是说中断标志被人为消除了,其中接收到的第2个数据被冲掉了,再次接收时已经是第三个字节触发的中断了。


如果在中断函数中发送多个值且又接收多个值,因为发送和接收的寄存器是同一个,你接收到数据后又发送该数据,之后又发送一个数据完成后,这时候第二个接收数据已经装入了寄存器了,但是你人为清除了标志位,所以不进入中断,第二个字节就被吃了,紧接着第三个字节重复第一个字节。。。。。。

而如果是不人为消除中断位的话,第二个字节的标志位是中断函数结束后再置位的,所以可以进入中断的。

这里的后面出现的E8是由于uCOS-III内存管理API管理函数造成的,每次进入中断都申请内存,一直产生中断,处理中断函数,所以没有归还内存导致的内存数据错误,注释相关的函数即可,或者扩大申请的内存块数量都可以。

 

 

 

 

 

 

 

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32F4系列的串口通信是通过USART模块实现的。USART模块包含了发送器(Transmitter)和接收器(Receiver),通过TX(发送线)和RX(接收线)进行通信。上位机和STM32之间的通信需要先建立物理连接,上位机通过USB转串口将数据发送给STM32,同时需要确保电平匹配。然后,在通信的过程中需要遵循特定的协议,这个协议就是串口协议。串口协议规定了数据包的格式,包括起始位、数据位、校验位和停止位等。起始位一般为0,停止位的电平为1。上位机一般使用串口助手这样的软件来与STM32进行通信,串口助手底层的程序实现了串口协议,并通过软件界面显示出来。当上位机发送数据时,实际上是将数据按照串口协议的要求进行封装,然后通过TX线发送给STM32STM32接收到数据后,会解析数据的起始位、数据位和校验位,并进行相应的处理。具体的通信过程可以通过调用USART_SendData()函数来实现数据的发送。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [STM32F4应用-串口通信](https://blog.csdn.net/dianji2015_/article/details/121911894)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [STM32F4_串口通信详解](https://blog.csdn.net/light_2025/article/details/128472781)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值