嵌入式成长轨迹50 【Zigbee项目】【CC2430基础实验】【单片机串口发数】
USART0 和USART1. 是串行通信接口,它们能够分别运行于异步UART 模式或者同步SPI模式。两个USART具有同样的功能,可以设置在分隔开的I/O 引脚。
1. UART 模式
UART 模式提供异步串行接口。在UART 模式中,接口使用2 线或者含有 RXD、TXD、RTS和CTS 的4 线。UART 模式的操作具有下列特点:8 位或者 9 位数据;奇校验、偶校验或者无奇偶校验;配置起始位和停止位电平;配置LSB 或者MSB首先传送;独立收发中断;独立收发DMA触发;奇偶校验和帧校验出错状态。UART 模式提供全双工传送,接收器中的位同步不影响发送功能。传送一个UART 字节包含1 个起始位、8 个数据位、1 个作为可选项的第 9位数据或者奇偶校验位再加上1 个(或2 个)停止位。注意,虽然真实的数据包含 8 位或者9 位,但是,数据传送只涉及一个字节。
UART 操作由USART控制和状态寄存器UxCSR以及UART 控制寄存器来控制。这里的 x是USART的编号,其数值为 0 或者1。当 UxCSR。MODE 设置为1 时,就选择了 UART 模式。
(1) UART 发送
当USART收/ 发数据缓冲器、寄存器 UxBUF(这里的x 是USART的编号,其数值为 0 或者
1,寄存器UxBUF双缓冲)写入数据时,该字节发送到输出引脚TXDx。
当字节传送开始时,UxCSR。ACTIVE 位设置为1,而当字节传送结束时UxCSR。AC-TIVE位清0。当传送结束时,TX-BYTE位设置为1。当 USART收/ 发数据缓冲寄存器就绪,准备接收新的发送数据时,就产生了一个中断请求。该中断在传送开始之后立刻发生,因此,当字节正在发送时,新的字节能够装入数据缓冲器。
(2) UART 接收
当1 写入 UxCSR。RE位时,在UART 上数据接收就开始了。然后UTART会在输入引脚RXDx 中寻找有效起始位,并且设置UxCSR;ACTIVE 位为1。当检测出有效起始位时,收到的字节就传人接收寄存器,UxCSR;RX-B g Tn 位设置为1. 。该操作完成时,产生接收中断。通过寄存器UxBUF提供收到的数据字节。当UxBUF读出时,UxCSR。RX-BYTE位由硬件清0。
(3) UART硬件流控制
当UxUCR。FLOW 设置为1,硬件流控制使能。然后,当接收寄存器空而且接收使能时,RTS输出变低。在CTS 输入变低之前;不会发生字节传送。
(4) UART特征格式
如果寄存器 UxUCR中的BIT9和奇偶校验位设置为 1,那么奇偶校验产生而且检测使能。奇偶校验计算出来,作为第9 位来传送。在接收期间,奇偶校验位计算出来而且与收到的第 9位进行比较。如果奇偶校验出错,则UxCSR;ERR 位设置为 1。当UxCSR读取时,UxC-SR。ERR 位清0。
要传送的停止位的数量设置为 1 或者2,这取决于寄存器位 UxUCR STOP。接收器总是要核对一个停止位。如果在接收期间收到的第一个停止位不是期望的停止位电平,就通过设置寄存器位UxCSR。FE为1,发出帧出错信号。当 UxCSR读取时,UxCSR;FE位清0,当 UxCSR。SPB 设置为1 时,接收器将核对两个停止位。
2.SPI 模式
在SPI 模式中,USART通过3 线接口或者 4 线接口与外部系统通信。接口包含引脚 MOSI 、MISO、SCK 和SSN 。参见1.5.1 小节中有关如何将 USART引脚指派到I/O 引脚的描述。
SPI 模式包含下列特征:3 线或者4 线SPI 接口;主/ 从模式;可配置的SCK 极性和相位;可配置的LSB 或MSB传送。
当UxCSR。MODE 设置为0 时,选中 SPI 模式。在SPI 模式中,USART可以通过写UxCSR。SLAVE位来配置SPI 为主模式或者从模式。
1)SPI 主模式操作
当寄存器UxBUF写入字节后,SPI 主模式字节传送就开始了。USAR'I、使用波特率发生器生成SCK 串行时钟,而且传送发送寄存器提供的字节到输出引脚 MOSI。与此同时,接收寄存器从输入引脚MISO获取收到的字节。
当传送开始时 UxCSR。.ACTIVE 位变高,而当传送结束后,UxCSR。.ACTIVE 位变低。当传送结束时,UxCSR。RX_BYTE 位和UxCSR。FX_BYTE 位设置为1。当收到的新数据在USART收/ 发数据寄存器UxBUF中就绪时,接收中断产生。
串行时钟 SCK 的极性由UxGCR。CPOtl。位选择,其相位由UxCSR。CPHA 位选择。字节传送的顺序由UxCSR。ORDER.位选择。
传送结束时,收到的数据字节由 UxBUF提供,供读取。当SPI 就绪接收另一个字节用来发送时,发送中断产生。由于UxBUF是双缓冲,这个操作刚好在发送开始时就发生了。
2)SPI 从模式操作
SPI 从模式字节传送由外部系统控制。输入引脚MISO上的数据传送到接收寄存器,该寄存器由串行时钟SCK.控制。SCK 为从模式输入。与此同时,发送寄存器中的字节传送到输出引脚MOSI。
当传送开始时 UxCSR.。ACTIVE 位变高,而当传送结束后,UxCSR-ACTIVE位变低。当传送结束时,UxCSR。RX_BYTE 位和 UxCSR。TX-BYTE位设置为1。接收中断产生。
串行时钟 SCK 的极性由UxCSR。CPOI位选择,其相位由UxCSR。CP H A位选择。字节传送的顺序由UxCSR。ORDER位选择。
传送结束时,收到的数据字节由 UxBUF提供,供读取。当 SPI 从模式操作开始时,发送中断产生。
3) 波特率发生器
当运行在UART 模式时,内部的波特率发生器设置UART、波特率。当运行在SPI 模式时,内部的波特率发生器设置SPI 主时钟频率。
由寄存器 UxBAUD。BAUD_M[7:O]和UxCSR,BAUD_E[4 :O]定义波特率。该波特率用于UART 传送,也用于SPI 传送的串行时钟速率。波特率由下式给出:
Baudrate=(256+BAUD_M)*2^BAUD_E*F/2^28式中:F 是系统时钟频率,等于16 MHz 或者32 MHz。
标准波特率所需的寄存器值如表 1-l 9 所列。该表适用于典型的 32 MHz 系统时钟。真实波特率与标准波特率之间的误差,用百分数表示。 .
当BAUD_E 等于16 且BAUD M 等于0 时,UART 模式的最大波特率是F/16(F 是系统时钟频率)。当BAUD_E 等于1 9且BAUD_M等于O 时,SPI 模式的最大波特率(即SCK 频率)是F/2。如果设置比这个更高的波特率就会出错。
4) 清除USART
通过设置寄存器位 UxUCR。FLUSH可以取消当前的操作。这一事件会立即停止当前操作并且清除全部数据缓冲器。
5) USART中断
每个USART都有两个中断:RX完成中断(URXx)和TX完成中断(UTXx)。USART的中断使能位在寄存器IEN0 和寄存器IEN2 中,中断标志位在寄存器TCON 和寄存器IRCON2 中。
中断使能:
●USART0 RX:IENO 。URXOIE
● USARTl RX :IENO 。URXlIE
●USART0 TX:IEN2。UTXOIE
● USARTl TX :至EN2 。UTXlIE
中断标志:
●USART0 RX:TCON 。URXOIF
●USARTl RX:TCON 。URXlIF
●USART0 TX:至RCON2。UTXOIF
● USARTl TX :iRCON2 。UTXIIF
6)USART DMA 触发
有两个DMA触发与每个USART相关。DMA触发由事件RX或者TX完成激活,也就是,该事件作为DMA中断请求。可以配置DMA信道使用USART收/ 发缓冲器(即UxBUF)作为它的源地址或者匿标地址。
7) USART寄存器 。
对于每个USART,有5 个寄存器(x 是USART的编号,为0 或者1) :
●UxCSR;USARTx 控制和状态;
●UxUCR:USARTx UART 控制; 。
●UxGCR:USARTx 通用控制;
●UxBUF:USARTx 收/ 发数据缓冲器
●UxBAUD USARTx 波特率控制
void initUARTtest(void) ;
函数原型:
1 void initUARTtest(void) 2 { 3 4 CLKCON &= ~0x40; //晶振 5 while(!(SLEEP & 0x40)); // 等待晶振稳定 6 CLKCON &= ~0x47; //TICHSPD128 分频,CLKSPD 不分频 7 SLEEP |= 0x04; // 关闭不用的RC振荡器 8 9 PERCFG = 0x00; // 位置1 P0 口 10 P0SEL = 0x3c; //P0 用作串口 11 P2DIR &= ~0XC0; //P0 优先作为串口0 12 13 U0CSR |= 0x80; //UART 方式 14 U0GCR |= 10; //baud_e 15 U0BAUD |= 216; // 波特率设为57600 16 UTX0IF = 0; 17 }
函数功能:初始化串口 0,将 I/O 映射到P0口,P0优先作为串口0 使用,UART 工作方式,波特率为57600。使用晶振作为系统时钟源。
void UartTX_Send_String(char *Data,int len);
函数原型:
1 void UartTX_Send_String(char *Data,int len) 2 { 3 int j; 4 for(j=0;j<len;j++) 5 { 6 U0DBUF = *Data++; 7 while(UTX0IF == 0); 8 UTX0IF = 0; 9 } 10 }
函数功能:串口发字串,*Data 为发送缓存指针,len 为发送字串的长度,只能是在初始化函数void initUARTtest(void) 之后调用才有效。发送完毕后返回,无返回值。
1 //main.c 串口0发数据 2 #include <ioCC2430.h> 3 #include <string.h> 4 5 #define uint unsigned int 6 #define uchar unsigned char 7 8 //定义控制灯的端口 9 #define led1 P1_0 10 #define led2 P1_1 11 12 //函数声明 13 void Delay(uint); 14 void initUARTtest(void); 15 void UartTX_Send_String(char *Data,int len); 16 17 char Txdata[30]=" ChenDu WuXianLong TongXun "; 18 19 /**************************************************************** 20 *函数功能 :延时 21 *入口参数 :定性延时 22 *返 回 值 :无 23 *说 明 : 24 ****************************************************************/ 25 void Delay(uint n) 26 { 27 uint i; 28 for(i=0;i<n;i++); 29 for(i=0;i<n;i++); 30 for(i=0;i<n;i++); 31 for(i=0;i<n;i++); 32 for(i=0;i<n;i++); 33 } 34 35 /**************************************************************** 36 *函数功能 :初始化串口1 37 *入口参数 :无 38 *返 回 值 :无 39 *说 明 :57600-8-n-1 40 ****************************************************************/ 41 void initUARTtest(void) 42 { 43 44 CLKCON &= ~0x40; //晶振 45 while(!(SLEEP & 0x40)); //等待晶振稳定 46 CLKCON &= ~0x47; //TICHSPD128分频,CLKSPD不分频 47 SLEEP |= 0x04; //关闭不用的RC振荡器 48 49 PERCFG = 0x00; //位置1 P0口 50 P0SEL = 0x3c; //P0用作串口 51 P0DIR &= ~0X80; //P0优先作为串口0 52 //p1dir 53 U0CSR |= 0x80; //UART方式 54 U0GCR |= 10; //baud_e 55 U0BAUD |= 216; //波特率设为57600 56 UTX0IF = 0; 57 } 58 59 /**************************************************************** 60 *函数功能 :串口发送字符串函数 61 *入口参数 : data:数据 62 * len :数据长度 63 *返 回 值 :无 64 *说 明 : 65 ****************************************************************/ 66 void UartTX_Send_String(char *Data,int len) 67 { 68 int j; 69 for(j=0;j<len;j++) 70 { 71 U0DBUF = *Data++; 72 while(UTX0IF == 0); 73 UTX0IF = 0; 74 } 75 } 76 77 78 /**************************************************************** 79 *函数功能 :主函数 80 *入口参数 :无 81 *返 回 值 :无 82 *说 明 :无 83 ****************************************************************/ 84 void main(void) 85 { 86 uchar i; 87 //P1 out 88 P1DIR = 0x03; //P1控制LED 89 led1 = 0; 90 led2 = 1; //关LED 91 92 initUARTtest(); 93 UartTX_Send_String(Txdata,29); //如:wu xian long tong xun 94 95 for(i=0;i<30;i++)Txdata[i]=' '; 96 97 strcpy(Txdata,"UART0 TX test "); //将UART0 TX test赋给Txdata; 98 99 while(1) 100 { 101 UartTX_Send_String("12345",sizeof("12345")); //串口发送数据 102 Delay(50000); //延时 103 Delay(50000); 104 Delay(50000); 105 led1=~led1; 106 led2=~led2; 107 } 108 }