分享

关于HAL库串口中断接收哪些路子 第二弹

 圆锥的布袋 2017-09-13
                                     一个大端午就这么没了,没吃到粽子的有木有?
言归正转,上次说道要耍“码子”,奈何篇幅限制,只传了一小部分上去,今天陆续把接下来的也都发上去,记得第一弹的结尾说道了串口处理结构体,`UART_HandleTypeDef huart1;`这里暂且不用,往下看,声明三个函数,内容不解释(你懂得),有两个带static修饰的要注意,封装好的接口,对外部透明,别想着在main.c外面调用。嘿嘿!这里全是废话,直接跳过吧!
现在进去主函数,HAL库初始化略过,时钟初始化略过,引脚初始化略过,都是在MX里配置好的,不管它们,现在到了串口初始化,这个本该也略过的,但是里面涉及了一些参数,后期封装时如果想修改例如波特率之类的,可以借鉴一下,也一笔带过。
现在,高潮来了,在一系列初始化完成后,我们需要自己操作串口了,调这个东东`while(HAL_UART_Receive_IT(&huart1,&RxByte,1)==HAL_OK);`
这个函数的作用为打开串口接收中断,我们之前在MX里设置的global interrupt 是UART的总中断开关,这里单独打开接收中断(本人亲测,不打开是进不去中断IRQ函数滴),第一个参数指明UART控制器,第二个参数是一个地址,用来存储接收到的数据,第三个是接收个数,这三参数我一个一个说:
1.先说这里为何要 while();经我了解,HAL_UART_Receive_IT()函数只会返回3种结果:错误,正常,忙碌。体现到代码里,分别是HAL_ERROR、HAL_OK、HAL_BUSY。如果参数错误,直接返回HAL_ERROR(用屁股想都知道)如果参数正确,第一次会返回HAL_OK,第二次会返回HAL_BUSY,原因在这里

1.png


2.png


跟踪这两枚举常量,值不去管他,看它的解释

3.png


意思是这样的:HAL_UART_STATE_READY外设已被初始化并且备用,HAL_UART_STATE_BUSY_TX数据发送进程正在进行中,看到这里,应该就差不多明白了while();的意义。在我们打开串口接收中断的初次,系统标志位没有被置位,返回了HAL_OK,当第二次进入的时候,由于外设已被初始化,直接跳出判断语句,返回HAL_BUSY。这样做的好处是:我表达了一个主观意愿,我要打开UART接收中断,你只有打开了或者打开出错了,才能从while()里出来,你要是尝试去打开了,结果又没出错又打不开,你就死到while()里去吧!(你就去死吧!。。。。。。。。)这种状况很少见,除非寄存器坏了或初始化错误!理论通了,你也可以表达你的主观意愿,例如:你出错了,就死到里边吧`while(HAL_UART_Receive_IT(&huart1,&RxByte,1)==HAL_ERROR);`
例如:你没打开或出错,你就死到里边吧


do{
if(huart.State== HAL_UART_STATE_BUSY_TX)
{
continue;
}
}while(HAL_UART_Receive_IT(&huart1,&RxByte,1)!=HAL_BUSY);

各位自由发挥吧!

这里啰嗦一下,继续。
打开接收中断后,理论上已经可以收到数据了,用串口助手发送一个字符或数字,可以看到程序进到USART1串口中断处理函数`void USART1_IRQHandler(void)`,类似这样的中断处理函数是有限的,根据芯片资源固定死了的,声明在启动代码文件里(俺觉得是声明)它在内部自己调用了`HAL_UART_IRQHandler(&huart1);`MX生成的中断处理函数,看他传参的形式,可以了解到看来串口的中断处理九成九是共用的这个函数,再次给ST的可移植性点个赞!
继续跟进,HAL_UART_IRQHandler内部是一大堆的标志位检验,什么中断奇偶校验错误、中断帧错误巴拉巴拉之类的不去管它,主要看看被控UART到底发生的是神马中断类型和中断源,这时,来波小高潮,如果按照上面所说,串口助手发送的是一个字符,那么恭喜你,你将跳过所有错误,进入`UART_Receive_IT`球洞,并成功的接收到数据而不报错。这个 一个字符,主要由`HAL_UART_Receive_IT`最后一个参数决定。那如果发的不是一个字节呢?呵呵,你的第一个数据会放到指定地址的内存空间,之后程序会报这个错Over-Run,然后清掉你的UART ORE标志位,意味着你再也收不到了。那我只能收一个数据吗?我的回答是:第一弹里说过,我们平时用到的数据位,也就8位,每次发过来的数据,必定是一帧一帧的,所以我们以往的中断接收,都是发来一帧,立刻中断关闭,拿出数据,打开中断,处理数据。你发10个字符,他要关中断10次,开中断10次。而ST新的HAL库,是这么做滴:开中断等数据,数据来了之后,关闭中断,如果数据个数不够我传给它的接收个数,继续接收,什么时候收够了,再打开中断,处理数据这样,接收了10个数据,只中断了一次,避免了频繁产生中断的一系列问题,你问我依据在哪里?这样搞有木有不好的地方?咱第三弹再聊!

发现打字真的好累,不过台湾尚未回归,美国依旧横行,忍了!当你看到这行字的的时候,请出门左转论坛找 《关于HAL库串口中断接收哪些路子 第三弹》谢谢!                                                                                                                                                                   

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多