USART1_IRQHandler 函数的理解

发布者:心灵飞翔最新更新时间:2024-08-12 来源: cnblogs关键字:函数 手机看文章 扫描二维码
随时随地手机看文章

 1 void USART1_IRQHandler(void) //串口 1 中断服务程序

 2 {

 3   u8 Res;

 4   #if SYSTEM_SUPPORT_OS //如果 SYSTEM_SUPPORT_OS 为真,则需要支持 OS

 5   OSIntEnter();

 6   #endif

 7   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

 8   //接收中断(接收到的数据必须是 0x0d 0x0a 结尾)

 9   {

10     Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据

11     if((USART_RX_STA&0x8000)==0)//接收未完成15     {

16       if(USART_RX_STA&0x4000)//接收到了 0x0d

17       {

18         if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始

19         else USART_RX_STA|=0x8000; //接收完成了

20       }

21       else //还没收到 0X0D

22       { 

23         if(Res==0x0d)USART_RX_STA|=0x4000;

24         else

25         {

26           USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;

27           USART_RX_STA++;

28           if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;

29           //接收数据错误,重新开始接收

30         } 

31       }

32     }

33   }

34 #if SYSTEM_SUPPORT_OS //如果 SYSTEM_SUPPORT_OS 为真,则需要支持 OS

35 OSIntExit();

36 #endif

37 }


下面这段话来自原子的stm32开发指南-库函数版本V1.3 129页。

当接收到从电脑发过来的数据,把接收到的数据保存在 USART_RX_BUF 中,同时在接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(回车的表示由 2 个字节组成:0X0D 和 0X0A)的第一个字节 0X0D 时,计数器将不再增加,等待0X0A 的到来,而如果 0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如果顺利接收到 0X0A,则标记 USART_RX_STA 的第 15 位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到 0X0D,那么在接收数据超过 USART_REC_LEN 的时候,则会丢弃前面的数据,重新接收。

 

 计算机向串口发送一串字符,一般不止一个,例如发送”abcdefg回车“。那么串口中断函数会执行9次,回车要执行两次串口中断。当串口中断函数第一次执行时,USART1->DR里面装的是字符a,下面以串口第一次执行来分析这个串口中断函数。

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)这是判断读数据寄存器是否空,因为接受到了a,所以不是空的,这个判断成立。

Res =USART_ReceiveData(USART1);//(USART1->DR); 既然接受到了字符a,那么就要把他读取出来

  if((USART_RX_STA&0x8000)==0) 因为现在接受的是第一个字符,所以接收肯定没有完成,USART_RX_STA还是它的初始化值,于是第15位还是0,这个判断语句成立。于是要执行下面这句话  

if(USART_RX_STA&0x4000)   USART_RX_STA的第14位仍然是0,所以这个判断不成立,所以会执行下面这句话   

 if(Res==0x0d) 当然这个判断也不成立,所以要执行下面这句话

USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;计算出接收的是第几个字符,然后装到缓存里面

USART_RX_STA++;加1表明已经接收好了几个数据原文链接:https://blog.csdn.net/qq_36226810/article/details/82787905


 


个人理解:相当于数组存储数值,当作缓冲


关键字:函数 引用地址:USART1_IRQHandler 函数的理解

上一篇:串口程序的理解
下一篇:STM32串口的理解

推荐阅读最新更新时间:2024-11-11 13:21

STVD中断函数写法
一、寄存器开发方式 1)以定时器TIM4为例,首先对TIM4的相关寄存器进行初始化,打开TIM4的中断,注意在STVD+COSMIC的开发环境下,开总中断使用语句_asm( rim ); void TIM4_init(void) //TIM4 init { TIM4_CR1=0x80; TIM4_PSCR=0x07; //clock div : 128 (T=8us) TIM4_ARR=125; //interrupt per 1ms TIM4_IER=0x01; //enable update interrupt _asm( rim ); //enable EA TI
[单片机]
ARM基础:为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
之前看了很多关于uboot的分析,其中就有说要为C语言的运行,准备好堆栈。 而自己在Uboot的start.S汇编代码中,关于系统初始化,也看到有堆栈指针初始化这个动作。但是,从来只是看到有人说系统初始化要初始化堆栈,即正确给堆栈指针sp赋值,但是却从来没有看到有人解释,为何要初始化堆栈。所以,接下来的内容,就是经过一定的探究,试图来解释一下,为何要初始化堆栈,即: 为何C语言的函数调用要用到堆栈,而汇编却不需要初始化堆栈。 要明白这个问题,首先要了解堆栈的作用。 关于堆栈的作用,要详细讲解的话,要很长的篇幅,所以此处只是做简略介绍。 总的来说,堆栈的作用就是:保存现场/上下文,传递参数。 1.保存现场/上下文 现场
[单片机]
最高效率使用单片机,放弃程序中的延时函数
我是PC机底层编程转过来的,以前从来没接触过单片机,五个月前学习AVR,在这里学到很多东西。但也意识到电子工程师们的硬件编程思想与PC机底层编程思想上的很多不同,引发了一些思考。我说一说,供大家参考,只为学习,无意争论。 我第一次看到教程里Delay()函数的代码时我吓了一跳,竟然让单片机空转以实现和外界同步,这怎么可能? 试想,如果PC机CPU空转一秒,那么音乐会断一秒、画面会停顿一秒、下载文件会断一秒,这怎么可行? 我看到很多单片机程序,它们的单片机99.9%的工作时间都在打空转,99.9%大家可能感到有些危言耸听,那就让我们算一算: 已内部8M频的AVR单片机来说,单指令周期仅为1/8 = 0.125us,那一毫秒
[单片机]
STM32 LED跑马灯-库函数
一,GPIO知识回顾 1,四种输入模式: 输入浮空 输入上拉 输入下拉 模拟输入 2,四种输出模式: 开漏输出 开漏复用输出 推挽输出 推挽复用输出 3,三种最大输出速度 2MHz 10MHz 50MHz 每组GPIO共16个IO口,含下7个寄存器 GPIOx_CRL : 端口配置低寄存器 GPIOx_CRH : 端口配置高寄存器 GPIOx_IDR : 端口输入寄存器 GPIOx_ODR : 端口输出寄存器 GPIOx_BSRR : 端口位设置/清除寄存器 GPIOx_BRR : 端口位清除寄存器 GPIOx_LCKR : 端口配置锁存寄存器 二,LED硬件连接
[单片机]
STM32 LED跑马灯-库<font color='red'>函数</font>
USART1_IRQHandler 函数的理解
1 void USART1_IRQHandler(void) //串口 1 中断服务程序 2 { 3   u8 Res; 4   #if SYSTEM_SUPPORT_OS //如果 SYSTEM_SUPPORT_OS 为真,则需要支持 OS 5   OSIntEnter(); 6   #endif 7   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 8   //接收中断(接收到的数据必须是 0x0d 0x0a 结尾) 9   { 10     Res =USART_ReceiveData(USART1);//(USART1- DR); //读取接收到
[单片机]
typedef define C复杂函数声明
概述   在很多情况下,尤其是读别人所写代码的时候,对C语言声明的理解能力变得非常重要,而C语言本身的凝练简约也使得C语言的声明常常会令人感到非常困惑,因此,在这里我用一篇的内容来集中阐述一下这个问题。   问题:声明与函数   有一段程序存储在起始地址为0的一段内存上,如果我们想要调用这段程序,请问该如何去做?   答案   答案是(*(void (*)( ) )0)( )。看起来确实令人头大,那好,让我们知难而上,从两个不同的途径来详细分析这个问题。   答案分析:从尾到头   首先,最基本的函数声明:void function (paramList);   最基本的函
[单片机]
解决ST-LINK进行硬件调试时,进不了main()函数的问题
前段时间想用ST-LINK对板子进行硬件调试,发现出不了现象(而代码是没有问题的)。打开设置后,设置从启动文件开始运行,经调试后,发现进不了Main()函数。 后来通过查阅尝试,发现问题解决的方法如下: 在初始时,点击“魔术棒”,选择“Debug”,可以看见最初的参数是这样的配置: 在选定“ST-Link Debugger”后,直接调试,会发现如下图所示,黄色箭头所指示的语句位置会一直卡在启动文件下,无论如何都进不了主函数,即便已经勾选了“Run to main()”选项。 按下图设置,即可顺利的完成调试: 其实勾选箭头的指向的栏目,则在打开调试界面时会直接进入主函数。否则,则会往启动文件开
[单片机]
解决ST-LINK进行硬件调试时,进不了main()<font color='red'>函数</font>的问题
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved