本帖最后由 xlhtracy 于 2013-8-21 13:53 编辑
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>串口初始化程序: *********************************************************** * 作者: tiger-john * 时间: 2011年1月18日 * 名称: UART0_Init * 功能: UART0初始化 通讯波特率115200,8位数据位, 1位停止位,无奇偶校验 * 接收FIFO触发点为8字节,使能RDR(接收数据)中断 * 入口参数: bps 串口波特率 * 出口参数: 无 ****************************************************************************/ void UART0_Init(uint32 bps) { uint16 Fdiv; PINSEL0 = (PINSEL0 & ~(0xf) | 0x05) ; //设置UART0的引脚 U0LCR = 0x83; //置为除数锁存位,进行配置 Fdiv = (Fpclk>>4)/bps; U0DLM = Fdiv>>8; U0DLL = Fdiv%256; U0LCR = 0x03; //清除除数锁存位,并设置工作模式 U0FCR = 0x81; // 使能FIFO,并设置触发点为8字节 U0IER = 0x01; // 允许RBR中断,即接收中断 } 5. 中断初始化 先来看一下UART0和VIC之间的关系:
1>中断初始化流程: l 选择中断为向量中断或快速中断 l 分配中断通道 l 设置UART0向量地址 l 使能UART0中断 2>关于ARM中断编程方法和寄存器的使用在此不做涉及 3>中断初始化程序: /********************************************************** * 作者: tiger-john * 时间: 2011年1月18日 * 名称: Interrupt_Init * 功能: 初始化串口中断,给串口中断选择为向量中断, 分配向量通道号1给串口 * 入口参数: 无 * 出口参数: 无 **********************************************************/ void Interrupt_Init (void) { VICIntSelect = 0x00000000; // 设置所有通道为IRQ中断 VICVectCntl1 = (0x20 | 6); // UART0中断通道分配到IRQ slot 1 VICVectAddr1 = (uint32)UART0_Exception; // 设置UART0向量地址 VICIntEnable = 1 << 6; //使能串口中断 }
6. 用中断编写接收函数 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> 中断服务函数程序: /****************************************************** * * 名 称:IRQ_UART0() * 功 能:串口UART0中断接收8个字节的数据 * 入口参数:无 * 出口参数:无 **********************************************************/ uint8 rcv_buf[8]; // UART0数据接收缓冲区 void __irq IRQ_UART0(void) { uint8 i; uint32 data; data = U0IIR; //清除中断表示寄存器标志 VICVectAddr = 0; //清除中断 for(i=0; i<8; i++) { rcv_buf = U0RBR; // 读取FIFO的数据 } } |