先看一下头文件中的申明和一些定义:
/*******************************************************************/
/* UART模块头文件 */
/*******************************************************************/
#if defined(__PIC24H__)
#include
#endif
#ifndef __UART_H
#define __UART_H
//UART寄存器默认值,可以根据需要进行修改,PIC24HJ128GP506带两个UART模块
#define UxMODE_VALUE 0x0000 //uart模块控制寄存器
#define UxSTA_VALUE 0x0110 //
^
#define UART_EN 0xFFFF /* Module enable */
#define UART_DIS 0x7FFF /* Module disable */
#define UART_IDLE_CON 0xDFFF /* Work in IDLE mode */
#define UART_IDLE_STOP 0xFFFF /* 在处理器IDLE模式下继续工作去使能*/
#define UART_IrDA_ENABLE 0xFFFF /* IrDA encoder and decoder enabled*/
#define UART_IrDA_DISABLE 0xEFFF /* UART支持LIN2.0和irDA协议 */
#define UART_MODE_SIMPLEX 0xFFFF /* UxRTS pin in Simplex mode */
#define UART_MODE_FLOW 0xF7FF /* 两种模式*/
//UXCTS和UXRTS用于基于irDA的硬件流控制。
#define UART_UEN_11 0xFFFF /*UxTX,UxRX and BCLK pins are enabled and used; UxCTS pin controlled by port latches*/
#define UART_UEN_10 0xFEFF /*UxTX,UxRX, UxCTS and UxRTS pins are enabled and used*/
#define UART_UEN_01 0xFDFF /*UxTX,UxRX and UxRTS pins are enabled and used; UxCTS pin controlled by port latches*/
#define UART_UEN_00 0xFCFF /*UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/BCLK pins controlled by port latches*/
//wake up使能
#define UART_EN_WAKE 0xFFFF /*Enable Wake-up on START bit Detect during SLEEP Mode bit*/
#define UART_DIS_WAKE 0xFF7F /*Disable Wake-up on START bit Detect during SLEEP Mode bit*/
//LOOPBACK模式,就是发送出去的数据,同时又收回来,引脚继续作IO功能
#define UART_EN_LOOPBACK 0xFFFF /*Loop back enabled*/
#define UART_DIS_LOOPBACK 0xFFBF /*Loop back disabled*/
//先发送一个0X55,芯片自动计算波特率
#define UART_EN_ABAUD 0xFFFF /*Enable baud rate measurement on the next character*/
#define UART_DIS_ABAUD 0xFFDF /*Baud rate measurement disabled or completed*/
//闲置时UXRX的状态
#define UART_UXRX_IDLE_ZERO 0xFFFF /* UxRX Idle state is zero */
#define UART_UXRX_IDLE_ONE 0xFFEF /* UxRx Idle state is one */
//波特率速度设置
#define UART_BRGH_FOUR 0xFFFF /* BRG generates 4 clocks per bit period */
#define UART_BRGH_SIXTEEN 0xFFF7 /* BRG generates 16 clocks per bit period */
//数据位,奇偶校验
#define UART_NO_PAR_9BIT 0xFFFF /*No parity 9 bit*/
#define UART_ODD_PAR_8BIT 0xFFFD /*odd parity 8 bit*/
#define UART_EVEN_PAR_8BIT 0xFFFB /*even parity 8 bit*/
#define UART_NO_PAR_8BIT 0xFFF9 /*no parity 8 bit*/
//几位停止位
#define UART_2STOPBITS 0xFFFF /*2 stop bits*/
#define UART_1STOPBIT 0xFFFE /*1 stop bit*/
//下面是状态和控制寄存器
//下面是发生中断时,发送缓冲器的状态
#define UART_INT_TX_BUF_EMPTY 0xDFFF /* Interrupt on TXBUF becoming empty */
#define UART_INT_TX_LAST_CH 0x7FFF /* Interrupt when last character shifted out*/
#define UART_INT_TX 0x5FFF /* Interrupt on transfer of every character to TSR */
//UXTX在闲置时候的状态
#define UART_IrDA_POL_INV_ONE 0xFFFF /*IrDA encoded, UxTX Idle state is '1' */
#define UART_IrDA_POL_INV_ZERO 0xBFFF /* IrDA encoded, UxTX Idel state is '0' */
//发送同步终止信号
#define UART_SYNC_BREAK_ENABLED 0xFFFF /* Send sync break on next transmission */
#define UART_SYNC_BREAK_DISABLED 0xF7FF /* Sync break transmission disabled or completed */
//TX使能
#define UART_TX_ENABLE 0xFFFF /* Transmit enable */
#define UART_TX_DISABLE 0xFBFF /* Transmit disable */
//发送缓冲器的满状态
#define UART_TX_BUF_FUL 0xFFFF /* Transmit buffer is full */
#define UART_TX_BUF_NOT_FUL 0xFDFF /* Transmit buffer is not full */
//接收中断发生的时候缓冲器的状态
#define UART_INT_RX_BUF_FUL 0xFFFF /* Interrupt on RXBUF full */
#define UART_INT_RX_3_4_FUL 0xFFBF /* Interrupt on RXBUF 3/4 full */
#define UART_INT_RX_CHAR 0xFF7F /* Interrupt on every char received */
//地址检测,如果确实是8位,为1
#define UART_ADR_DETECT_EN 0xFFFF /* address detect enable */
#define UART_ADR_DETECT_DIS 0xFFDF /* address detect disable */
//RX发生溢出
#define UART_RX_OVERRUN_CLEAR 0xFFFD /* Rx buffer Over run status bit clear */
//部分位在这里没有定义,可以根据需要添加。
//未定义的部分在头文件的结构体里面有申明,也可以直接调用结构体
//RX和TX使能,以及中断优先级
……
//宏定义RX和TX使能,以及中断优先级
//下面申明编译器中定义的函数
……
这里注意到方框图中多了两个模块,一个是硬件流控制模块,一个是IRDA模块。
其中控制寄存器和状态寄存器已经在上面有描述,另外还有收发数据寄存器,以及一个波特率寄存器。
波特率的产生:
波特率的计算公式如下:
UXBRG=FCY/16*BAND-1,比如需要设置为9600的波特率,FCY为40M则:UXBRG=259,0X103.这里有一个要注意的,259不是整数,实际上他是有误差的。
如果设置为BGRH为4的话,这里的FCY/4.
这里还有一个波特率的输出引脚,这里可以在控制寄存器中设置为BCLK输出,用于做同步信号或者测试。
UART的配置:
使能UART,和UTXEN,则IO被配置为被UART模块控制,其优先级要高于普通的IO端口。
去使能将复位所有的寄存器状态等。
UART发送的步骤如下:
-
设置波特率
-
设置数据位,停止位,和校验位
-
如果需要用到中断,则开中断使能
-
设置中断优先级以及配置中断的模式
-
使能UART模块
-
使能发送
-
发送中断后,清零标志
-
开始加载数据到发送寄存器
UART的发送:
方框图如下,其中通过模式寄存器和状态寄存器来控制发送,UXTXREG四级缓冲和一个UXTSR一共五级来做FIFO数据发送寄存器。
发送缓存:如果四级缓存全部满,则UTXBF为1:
此时不能继续写入。
发送中断:
发送中断可以在如下的三种情况的其中一种发生的时候,触发中断,标志位同样需要在中断程序中清零。
发送BREAK字符:
就是一位开始,12位0,一位结束.
下面描述了BREAK字符发送的典型应用:
数据位检测:
这里有以为BRGH位可以设置采样的时钟,下面是16X的情况,显然,4X的情况的稳定性要比16X差一些:
缓存部分和发送没有多大区别,这里注意一点:
如果没有及时读走FIFO中的数据,则RSR中的15位满了以后,将产生一个错误位。
如果15位还需要,则先读15位再清零错误位,否组直接清零就行。
还有一个错误位,也就是帧错误,正常停止位应该是高电平,如果为低电平,则FERR置高。
还有一位校验错误位
三种错误都会触发中断。
接收中断:
同样,和发送中断一样,有三种模式的来指示在缓冲器何种状态下触发中断:
另外有两位来只是缓冲器中是否有数据,以及是否闲置,这里不会触发中断,需要在使用的时候根据要求来查询该位。
接收的步骤如下:
-
波特率
-
数据位,校验位,停止位设置
-
设置中断使能和优先级
-
使能UART模式
-
设置缓冲器何种状态时触发中断
-
如果不用中断程序处理数据,则用URXDA位来设置数据接收
-
从缓冲中读数据
不使用中断来实现读数据的程序例程如下:
使用UART的9位通信:
多处理器环境中会用到9位的通信,如果第9为为0则忽略后面的数据。
多机通信的协议如下:
主机发送9位带地址的数据
从机链检查是否叫到自己
叫到自己的从机接收数据
其他UART的性能:
LOOP功能:通过设置LPBACK位可以设置LOOP模式,LOOP一共有四种模式,如下:
波特率自适应功能:
通过设置ABAUD位。
DMA操作UART
这里体现PIC24HJ强大的地方来了,DMA!!!
如果设置为DMA模式,则通信完全不需要由CPU来控制,而是自动的进行保存,CPU只需要处理DMA的中断即可。
具体DMA的内容,在相关的章节里面再看。
节能模式下的操作:
工作在睡眠模式下:如果工作在睡眠模式下,或者在发送和接收的时候切入到睡眠模式,则通信丢失,此时不能工作。
如果设置了一位WAKE,则外部发送开始位将唤醒通信,这里还有一个优先级与当前CPU的优先级比较问题,决定程序是从头开始,还是从睡眠的地方开始。
工作在闲置模式下:如果设置在闲置模式下,继续工作,在支持左右的通信操作,如果闲置模式不工作,则只能支持睡眠状态时候的接收中断功能。
把UXCTS和UXRTS利用起来:
FLOW CONTROL MODE
SIMPLEX MODE
另外,UART模块支持irDA和LIN功能,在使用的时候再相信看这块的资料。
文章评论(0条评论)
登录后参与讨论