历史上的今天
返回首页

历史上的今天

今天是:2025年03月25日(星期二)

正在发生

2019年03月25日 | STM32的CubeMX关于串口中断

2019-03-25 来源:eefocus

1、关于串口的初始化函数:


    MX_USART2_UART_Init()---波特率、奇偶校验等配置


            HAL_UART_Init()---会将 huart->RxState = HAL_UART_STATE_READY;


    HAL_UART_MspInit()---GPIO,中断优先级等配置


2、当需要使用中断接收时需要调用


    HAL_UART_Receive_IT()---配置接收的缓冲区指针,数量,huart->RxState = HAL_UART_STATE_BUSY_RX;,最后使能相应中断


3、当中断发生时,执行


    HAL_UART_IRQHandler()--判断中断的类型,在此处我用到的是非空中断,那么会继续调用UART_Receive_IT(huart);


    这个函数会首先判断串口的接收状态huart->RxState == HAL_UART_STATE_BUSY_RX,若果为真就进行数据的保存,进 如     果达到规定的传输数量就会关闭中断,改变huart->RxState = HAL_UART_STATE_READY;然后执行HAL_UART_RxCpltCallback();如果不为真,就清除接收中断标志。


4、HAL_UART_RxCpltCallback()这个函数里尽可能的少些代码否则影响效率,如果想再次开启中断,可以在这里调用       HAL_UART_Receive_IT(),进行再次接收


下面说说我遇到的问题:


初始化串口完毕后,调用一次HAL_UART_Receive_IT(&huart2,uxComDMA.ucRxBuf,ONE_BYTE),进行一个字节的中断接收,然后在HAL_UART_RxCpltCallback()函数里,进行帧头的校验和传输数量的计算,然后继续开启。代码如下


           //如果计算的数量大于规定的数量,说明传输出错。丢弃,判定上位机发送是否错误

            if(usRecLength > DMA_BUF_MAX)

            {

                uxComDMA.ucRxBuf[eMsg_DTH] = APP_NULL;

                uxComDMA.ucRxBuf[eMsg_DTL] = APP_NULL;

                uxComDMA.usRxLen = APP_NULL;

                PTCL_Dbg("计算数量大于规定数量");

            }

            //接收的数量大于等于计算的数量

            if(uxComDMA.usRxLen >= usRecLength)

            {

                uxComDMA.uxReceiveFlag = eAppTrue;//标记接收完成。---此时不再调用HAL_UART_Receive_IT()

            }

            else//继续接受下一个数据

            {

                HAL_UART_Receive_IT(&huart2, uxComDMA.ucRxBuf+uxComDMA.usRxLen,ONE_BYTE);


            }


当正确接收一帧数据后,便不再开启,直到这一阵数据处理完,主程序再次调用HAL_UART_Receive_IT()进行下一轮的接收。


那么问题来了:规定的协议是8个字节,在正确接收到8个字节后便不再开启中断接收,主函数执行数据帧的处理完毕后才会开启。但是如果上位机一次一共发送了10个字节,前8个字节是正确的一帧,后面2个无用。当下位机接收到8个字节便关闭了中断,处理完后再次开启。然后上位机再发来数据,发现下位机再也不能执行HAL_UART_RxCpltCallback(),协议就报废了。


调试后发现,后来接收数据时虽然可以进入中断并且执行了UART_Receive_IT();但是huart->RxState 的值不是HAL_UART_STATE_BUSY_RX导致不能继续执行传输完成回调。疑问是,最后一次开启中断接收时调用HAL_UART_Receive_IT()函数确实将 huart->RxState = HAL_UART_STATE_BUSY_RX;


 


PTCL_Dbg("初始化接收的状态%d",HAL_UART_Receive_IT(&huart2,uxComDMA.ucRxBuf,ONE_BYTE));//串口2的接收中断


函数返回值为HAL_OK


PTCL_Dbg("串口的接收状态%#x\r\n",huart2.RxState);----确实不等于HAL_UART_STATE_BUSY_RX,而是等于                                                                                                                                                   HAL_UART_STATE_READY


//    huart2.RxState = HAL_UART_STATE_BUSY_RX; ----加上这句话,可以解决问题


这是为什呢?


解决上述问题:


关于上述问题的总结:后两个字节传输时,已经关闭了中断,但是硬件将ORE位(溢出标志,看数据手册)置一和RXNE位置一。当调用HAL_UART_Receive_IT()函数时,会同时使能EIE、PEIE、RXNEIE三个中断。第一次我手动将RXNE位清除,但是没有清除ORE位,造成调用就会立即产生中断(溢出中断)。当执行HAL_UART_IRQHandler()函数时:      


 

    

关于HAL库,更多的是考虑到安全性和兼容性所以代码量比较大,一开始使用不会像我们使用寄存器那么随意,所以必须深入看源码,才能更好的使用。


推荐阅读

史海拾趣

FCT Electronics公司的发展小趣事

在国内市场取得成功后,FCT Electronics开始将目光投向国际市场。公司积极参加国际电子展会,与多家国际知名企业建立了合作关系。凭借出色的产品性能和专业的客户服务,FCT Electronics的测试设备逐渐在海外市场上占据了一席之地,为公司的国际化发展奠定了坚实基础。

Dynawave Incorporated公司的发展小趣事

随着技术的成熟,Dynawave开始寻求市场拓展。公司高层决定,将目标市场锁定在智能家居和物联网领域。他们与多家知名厂商合作,将自己的无线传输技术应用到各类智能设备中。通过不断的技术优化和市场推广,Dynawave的产品逐渐得到了市场的认可,销售额稳步增长。

Enable Semiconductor Corp公司的发展小趣事

品质是Enable Semiconductor Corp公司的生命线。公司从原材料采购到产品生产、从质量检测到售后服务,都严格执行质量管理体系的要求。这种对品质的执着追求使得公司的产品在市场上享有良好的口碑。同时,公司还积极参与国际标准的制定和认证工作,不断提升产品的国际竞争力。

Corstat Containers公司的发展小趣事

在环保意识日益增强的背景下,Corstat Containers公司积极响应,推出了可回收、可降解的环保电子元件包装盒。这一产品不仅满足了市场对环保产品的需求,还为公司赢得了良好的社会声誉。同时,公司还加大了对环保技术的研发投入,不断推出更加环保、高效的电子产品包装解决方案,进一步巩固了其在电子行业的领先地位。

APM Hexseal公司的发展小趣事

APM Hexseal的产品很快在军事领域获得了广泛应用。公司的密封靴子通过了严格的军事检查和独立的QPL等效项,证明了其卓越的性能和可靠性。此外,APM Hexseal还协助开发了MIL-B-5423规范(现为MIL-DTL-5423),为军方的新设备保护要求设定了初始标准。这一合作不仅提升了APM Hexseal在军事领域的影响力,也为其在电子行业中的发展打开了新的大门。

AF International公司的发展小趣事

随着公司业务规模的不断扩大,AF International意识到建立完善的质量管理体系至关重要。公司引进了先进的质量管理理念和方法,建立了严格的质量控制流程,确保从原材料采购到产品生产的每一个环节都符合质量标准。同时,AF International还加强了对员工的培训和教育,提高员工的质量意识和操作技能。这些措施使得公司的产品质量得到了有效保障,赢得了客户的广泛赞誉。

问答坊 | AI 解惑

求助一个支持snmp的modem的制作问题

用一个嵌入式设备把一个usb的拨号上网设备 用ppp拨号上网,然后通过以太网口提供ppp oe服务,要能够使这个设备能够支持snmp管理,可是拨号上网设备的ip又要能够传给以太网口接着的路由器或者机器。其实就是一个支持snmp的modem。不过那位大侠能帮个 ...…

查看全部问答>

妙用LM317的闪烁灯

LM317常用作电压稳压器中的调整元件,这里给大家介绍一个不寻常的应用,只要配上不多的外部元件,可以使一个12V的小灯泡闪烁发光。   如图,采用所给的元件参数值和信号,当电路接通以后,小灯泡将以4Hz的频率闪烁,当然,若改变元件参数(R2 ...…

查看全部问答>

【藏书阁】实用的温度量测教程

雜訊排除(Noise Rejection) 樹狀切換 是一種將掃描器的通道分成數組,每一組都有自己的主要開關的方法。 如果沒有使用樹狀切換法的話,每個通道都會直接透過其雜散電容貢獻一些雜訊,但若透過樹狀切換方式的話,群組內並聯通道的電容值會與單 ...…

查看全部问答>

如何实现交换机的web管理机制?

可以通过浏览器访问交换机的web界面对交换机进行各种参数的设置,请问这种是如何实现的?是不是首先在本地建立好相关函数,然后通过web界面经由web服务器调用这些函数?能详细一些最好,谢谢! …

查看全部问答>

建立XILINX FPGA开发中的ModelSim仿真环境方法

FPGA的开发中,仿真环节是必不可少的,而ISE自带的仿真工具只能仿真一些简单的HDL代码,无法仿真使用Coregen生成的IP,这个时候最简单的方式就是使用ModelSim。本文介绍如何在Xilinx FPGA开发环境中,建立ModelSim仿真环境。其实方法有多种,这里使 ...…

查看全部问答>

急!如何将cadence原理图,PCB转换成protel格式

拿到一套评估板,代理商给的资料是用cadence设计的,我一般画图用Altium Designer,各位高手给指点一下,怎样才能将cadence原理图,PCB转换成protel格式…

查看全部问答>

tms320f2812的CAn问题?

使用tms320f2812芯片,在线仿真时CAn运行正常,可烧写到flash后,其他部分运行正常,只有CAN不能通信,这是怎么回事啊?请教大家!…

查看全部问答>

关于单片机的定时器大家最多的是用作什么呢?

几乎所有的MCU都会带有一个或者多个定时器,大家一般拿它来做什么呢?咱们做个小调查看看,定时器那些方面使用的最多。…

查看全部问答>