UART0串口编程(三):中断方式的串口编程;用中断编写发送

2019-09-17来源: eefocus关键字:UART0  串口编程  中断方式的  发送函数

一:中断方式的串口编程


1.用中断方式编写串口程序由那几部分组成


2.硬件上的支持


1>UART0 发送FIFO缓冲区


A.UART0含有1个16字节的发送FIFO缓冲区


B.U0THR是UART0发送FIFO的最高字节


C.UART的发送FIFO是一直使能的

2>UART0接收FIFO缓冲区


A. UART0含有一个16字节的接收FIFO缓冲区。


B. 软件设置接收FIFO缓冲区的触发字节。

3> 中断接口:UART0的中断接口包含中断使能寄存器(U0IER)和中断标识寄存器(U0IIR)。


第一:U0IIR:提供状态码用于指示一个挂起中断的中断源和优先级。


第二:U0IER可以控制UART0的4个中断源。


4> UART0有4个中断源:


A. RLS(接收线状态)中断:


(1) 优先级最高


(2) 它在以下条件发生时产生错误


第一:帧错误(FE)


第二:溢出错误(OE)


第三:奇偶错误(PE)


第四:间隔中断(BI)


注:可以通过查看U0LSR[4:1]中的值看到产生该中断的错误条件,读取U0LSR寄存器时清除该中断。


B. RDA(接收数据可用)中断:


(1)与CTI中断并列第二优先级。


(2)在以下情况触发中断:


第一:当接收的有效数据到达接收FIFO设置寄存器(U0FCR)中设置的触发点时,RDA被激活。当接收FIFO中的有效数据少于触发点时,RDA复位。


第二:中断过程:


1>  移位寄存器(U0RSR)从RxD引脚接收串行数据后,送入接收FIFO中


2>  当接收FIFO中的有效数据数量达到预定的触发点时,置位RDA中断。


3>  从U0RBR寄存器中读取FIFO中最早到达的数据,当FIFO中的有效数据小于触发点时,清零RDA中断。


C.  CTI(字符超时指示)中断


(1) 优先级为2.


(2) 在以下情况发生中断:


当接收FIFO中的有效数据少于预定的触发点数量时,如果在一定时间内仍没有接收到新的数据,那将触发该中断。


(3) 上面的时间指的是:3.5~4.5个字节所需要的时间。


(4)  对接收FIFO的任何操作都会清零该中断标志。


(5) 中断过程:


第一:移位寄存器(U0RSR)从RxD0引脚接收串行数据后,送入接收FIFO中。


第二:当接收FIFO中的有效数据少于触发个数,但如果长时间没有数据到达,则触发CTI中断。


第三:从U0RBR中读取接收FIFO中的数据,或者有新的数据送入接收FIFO,都将清零CTI中断。


注:3.5~4.5个字节的时间:指在串口当前的波特率下,发送3.5~4.5个字节所需要的时间。


当接收FIFO中存放多个数据,从U0RBR读取数据,但是没有读完所有数据,那么在经过3.5~4.5个字节的时间后触发CTI中断。


D.  THRE(发送)中断


(1) 优先级为第三级优先级。


(2) 当FIFO为空并且在以下情况触发中断:


第一:系统启动时,虽然发送FIFO为空,但不会产生THRE中断。


第二:在上一次发生THRE中断后,向发送FIFO中写入1个字节数据,将在一个字节加上一个停止位后发生THRE中断


(because:如果发送移位寄存器为空,那么写入发送FIFO的数据将直接进入发送移位寄存器。此时发送FIFO仍然为空,如果立即产生THRE中断,就会影响紧接着写入发送FIFO的数据。所以在发送完该一个字节以及一个停止位后,才产生THRE中断。)


如果在发送FIFO中有过两个字节以上的数据,但是现在发送FIFO为空时,将立即触发THRE中断。当THRE中断为当前有效的最高优先级中断时,往U0THR写数或者对U0IIR的读操作,将使THRE中断复位


我们来看看这些中断源与存储器之间的关系:


注:由上图可知:UART0有4个中断源:分别是RLS(线状态)中断,RDA(接收数据)中断,CTI(字符超时)中断,THRE(发送数据)中断。4个中断源的优先级如下图所示:

3.串口中断接收初始化


1>串口中断接收初始化流程


l  设置I/O引脚连接到UART0


l  置位除数锁存位,配置UART0帧数据格式


l  根据波特率计算分频值


l  设置波特率


l  清除除数锁存位,并设置工作模式


l  使能FIFO,并设置触发点


l  允许RBR中断


注:我们可以发现与轮训方式相比,中断方式只是增加了使能FIFO,并设置中断触发点和允许RBR中断两步。


2>中断串口初始化需要配置的寄存器


     (与轮循方式配置方法相同的寄存器在此处不在涉及)


l  U0FCR(FIFO控制寄存器):U0FCR控制UART0 Rx和Tx FIFO的操作。


l  U0IER(中断使能寄存器):U0IER用于使能4个UART0中断源。


3>具体寄存器的配置


(1) U0FCR


A作用:控制UART0 Rx和Tx的操作。


B长度:8位寄存器。


C:每一位的含义:


l  第0位:表示FIFO使能


置1:表示使能对UART0 Rx和Tx的FIFO以及U0FCR[7:1]的访问。


置0:表示不能使用Rx和Tx的FIFO以及步能对U0FCR[7:1]的访问。


注:该位的任何变化都将使UART0 FIFO清空。


l  第1位:表示Rx FIFO的复位。


置1:会清零UART0 RxFIFO中的所有字节并复位指针逻辑。该位自动清零。


l  第2位:表示Tx FIFO的复位。


置1:会清零UART0 TxFIFO中的所有字节并复位指针逻辑。改位自动清零。


l  第[5:3]位:保留位,用户不能对其进行操作。从保留位读出的值未被定义。


l  第[7:6]位:表示Rx触发选择


00:触发点为0(默认为1字节)


01:触发点为1(默认为4字节)


10:触发点为2(默认为8字节)


11: 触发点为3(默认为14字节)


注:这两个位决定在激活中断之前,接收UART0 FIFO必须写入个字符。


(2) U0IER(中断使能寄存器)


A 作用:U0IER用于使能4个UART0中断源


B 长度:8位寄存器


C每一位的含义:


l  第0位:表示RBR中断使能


置1:使能RDA中断


置0:禁止RDA中断


注:U0IEER 第零位使能UART0接收数据可用中断。它还控制(CTI)字符接收超时中断。


l  第1位:表示THRE中断使能


置1:使能THRE中断


置0:禁止THRE中断


l  第2位:表示Rx线状态中断使能


置1:使能Rx线状态中断


置0:禁止RX线状态中断


注:U0IER第二位使能UART0 Rx线状态中断。该中断的状态可从U0LSR[4:1]读出


l  第[7:3]位:是保留位


注:用户不能向其写入1.


4>串口初始化程序:void   UART0_Init(uint32 bps)


 

4.  中断初始化


先来看一下UART0和VIC之间的关系:




1>中断初始化流程:


l  选择中断为向量中断或快速中断


l  分配中断通道


l  设置UART0向量地址


l  使能UART0中断


2>关于ARM中断编程方法和寄存器的使用在此不做涉及(如果想知道的话,可以看这篇文章http://blog.csdn.net/tigerjb/archive/2010/11/30/6045409.aspx


3>中断初始化程序:void Interrupt_Init (void)


5.用中断编写接收函数


1>  中断服务函数流程


l  清除串口中断标识寄存器(U0IIR)


l  清除中断标志


l  读取接收FIFO中的数据


2>  中断函数服务函数中需要配置的寄存器


(1) U0IIR中断标识寄存器。


l  第0位:表示中断挂起


置1:表示没有挂起的中断


置0:表示至少有一个中断挂起


l  第[3:1]位:中断标识,这三位表示了对应UART0 Rx FIFO的中断。


001:表示发送中断(THRE)


010:  表示接收数据可用中断(RDA)


011:  表示接收线状态中断(RLS)


110:  表示字符超时中断(CTI)


l  第[7:4]:是保留位


注:


1.    U0IIR提供的状态码可用于指示一个挂起中断的中断源和优先级。


2.    在访问U0IIR过程中,中断被冻结


3.    如果在访问U0IIR时,产生了中断,该中断被记录。在下次访问U0IIR时可以读出,避免中断的丢失。


3>  中断服务函数程序:void   __irq IRQ_UART0(void)


6.总程序:通过上位机给串口发送8字节数据,ARM2200接收到串口数据后,把数据又发送回上位机。


(在用中断的时候在Startup.S文件中的InitStack子程序中,修改设置系统模式堆栈处的代码为"MSR CPSR_c,#0x5f",

测试成功 ,在上面上发送16进制数时,每个之间用空格隔开不加前缀。)



#include "config.h"

uint8 recver_buffer[8];    

uint8 rcv_new;     

/**********************************************************

* 名称: UART0_Init()

* 功能: UART0初始化(通讯波特率115200,8位数据位,

1位停止位,无奇偶校验)

* 入口参数: bps     串口波特率

* 出口参数: 无

**********************************************************/

void  UART0_Init(uint32 bps)

{  

    uint16 Fdiv;

    PINSEL0 = 0x00000005;               //设置串口引脚

    U0LCR = 0x83; //置为除数锁存位,进行配置

    Fdiv = (Fpclk >> 4) / bps;     // 设置波特率

    U0DLM = Fdiv >> 8;

    U0DLL = Fdiv & 0xff;

    U0LCR = 0x03;                      //清除除数锁存位,并设置工作模式模式

    U0FCR = 0x81;                     // 使能FIFO,并设置触发点为8字节

    U0IER = 0x01;                     // 允许RBR中断,即接收中断

 

}

/*********************************************************  

* 名    称:    IRQ_UART0

* 功    能: 串口UART0中断接收8个字节的数据

* 入口参数: 无

* 出口参数: 无

**********************************************************/ 

void   __irq IRQ_UART0(void)

{   uint8  i;

    if( 0x04 == (U0IIR&0x0F) ) 

    {

     rcv_new = 1; // 设置接收到新的数据标志,并清除中断标志位

fo

[1] [2] [3]
关键字:UART0  串口编程  中断方式的  发送函数 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic474717.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM8S UART串口使用中断收发数据
下一篇:STM8学习笔记-----uart1串口中断

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

UART0串口编程(四):UART0串口编程之在UC/OS—II中遭遇的危机
一.潜在的危机1.在uc/os操作系统中设计串口编程时,由于ISR和多个任务并发执行,情况比较复杂。尤其是接收状态为被动状态时,只能靠串行口中断来接收数据。2.在进行串行通信时,双方遵循相同的通信协议。由于波特率不变,因此相邻两次串口中断的间隔时间基本固定。3.在以下两种情况时会使接收过程出现错误:(1)第一种情况是系统关中断的最长时间大于相邻两次串行接收中断的间隔时间,这时将可能导致遗漏一次中断,造成数据丢失。(2)实时操作系统内核的关中断的最长时间是已知的,通常很短,它不是问题关键。(3)系统关中断的最长时间往往是由用户软件造成的,例如:我们编写的中断服务函数过于复杂,导致系统为了处理中断服务函数而导致关中断时间过长
发表于 2019-09-23
UART0串口编程(一):通信协议设计;RS232标准
嵌入式系统之间采用通信方式交换数据,串行通信是一种最基本的通信手段。现在由于各类CPU均集成了UART部件。本节对串口编程时如何设计串口通信协议,以及对RS232接口进行了说明。1.    通信协议设计在进行通信时,每次需要传送的信息一般超过1字节。为此,通信双方必须约定通信数据的排列格式,即通信协议。通常把一次通信过程的全部内容称为一个“通信帧”。通信协议设计就是帧结构设计。在一帧内容中,通常包括以下部分。(1)起始码:由一个或若干个包含特定内容的字节,表示一个通信帧的开始。起始码的内容必须与通信数据内容有明显区别(不能在通信数据里出现与起始码相同的内容)。当通信帧的总长度比较短,信道质量比较高时,为了提高
发表于 2019-09-23
UART0<font color='red'>串口编程</font>(一):通信协议设计;RS232标准
UART0串口编程(二):硬件原理;轮训方式的串口编程
本节针对的是ARM2200环境下编写串口程序,其中设计轮循方式,中断方式,以及在UC/OS-II操作系统下的串口编程。使用轮循和中断两种方式来实现串口编程。用中断实现串口编程,系统的效率较高,但是难度也较大 ;轮循方式效率较低,但是编程比较简单。一.串口编程的硬件原理1.     串口特性:1>16字节接收FIFO和16字节发送FIFO2>接收FIFO触发点可设置为1,4,8或14字节。3>内置波特率发生器。2.     UART0引脚:1>RxD0 引脚用于UART0接受数据,接受方式为串行输入。2>TxD0引脚用于UART0发送数据,发送
发表于 2019-09-23
UART0<font color='red'>串口编程</font>(二):硬件原理;轮训方式的<font color='red'>串口编程</font>
UART0串口编程(三):中断方式;用中断编写发送函数
标志l  读取接收FIFO中的数据2>  中断函数服务函数中需要配置的寄存器(1) U0IIR中断标识寄存器。l  第0位:表示中断挂起置1:表示没有挂起的中断置0:表示至少有一个中断挂起l  第[3:1]位:中断标识,这三位表示了对应UART0 Rx FIFO的中断。001:表示发送中断(THRE)010:  表示接收数据可用中断(RDA)011:  表示接收线状态中断(RLS)110:  表示字符超时中断(CTI)l  第[7:4]:是保留位注:1.    U0IIR提供的状态码可用于指示一个挂起中断的中断源和优先级
发表于 2019-09-23
UART0串口编程(三):中断方式;用中断编写<font color='red'>发送</font><font color='red'>函数</font>
LPC17xx Uart0,Uart1,Uart2,Uart3的区别
LPC1700系列ARM具有4个异步串口(Uart0,1,2,3),具有以下特性- 16字节收发FIFO- 内置小数分频器- 支持DMA发送 区别是:UART1增加Modem和RS-485/EIA485模式Uart0,2,3增加IrDA接口,可用于扩展红外功能
发表于 2018-06-01
stm32l01系列单片机通过串口编程(ISP)
官方给出的ISP软件(串口烧录软件)FlashLoader Demonstrator不支持stm32l01系列的单片机那么我们怎么使用串口给这个型号的单片机通过串口烧录程序呢? 最近做了一个项目有这方面的需求,所以研究了一下这个方法,在此分享出来给有需要的人。准备工具只需mcuisp(也称flymcu)软件,串口助手 给懒人提供mcuisp软件mcuisp 经过我的试验mcuisp可以给这个单片机编程但是不能擦除这个芯片,后来我发现这个芯片的擦除指令不一样有兴趣的同学可以读一读这个文档AN3155 (USART protocol used in the STM32 bootloader)去度娘搜
发表于 2018-08-22
小广播
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved