我所使用的Contiki系统是contiki-sensinode。理解该文需要有cc2530里uart的相关知识,具体寄存器的用法不做介绍。
先放上所有代码,然后再仔细分析。
1 #include <stdlib.h> 2 #include <string.h> 3 4 #include "cc253x.h" 5 #include "sfr-bits.h" 6 #include "dev/uart0.h" 7 8 #if UART0_ENABLE 9 /*---------------------------------------------------------------------------*/ 10 void 11 uart0_init() 12 { 13 #if UART0_CONF_HIGH_SPEED 14 UART_SET_SPEED(0, UART_460_M, UART_460_E); 15 #else 16 UART_SET_SPEED(0, UART_115_M, UART_115_E); 17 #endif 18 19 #ifdef UART0_ALTERNATIVE_2 20 PERCFG |= PERCFG_U0CFG; / *alternative port 2 = P1.5-2 */ 21 #ifdef UART0_RTSCTS 22 P1SEL |= 0x3C; /* peripheral select for TX and RX, RTS, CTS */ 23 #else 24 P1SEL |= 0x30; /* peripheral select for TX and RX */ 25 P1 &= ~0x08; /* RTS down */ 26 #endif 27 P1DIR |= 0x28; /* RTS, TX out */ 28 P1DIR &= ~0x14; /* CTS & RX in */ 29 #else 30 PERCFG &= ~PERCFG_U0CFG; /* alternative port 1 = P0.5-2 */ 31 #ifdef UART0_RTSCTS 32 P0SEL |= 0x20 | 0x10; /* peripheral select for TX and RX */ 33 #else 34 P0SEL |= 0x0C; /* peripheral select for TX and RX */ 35 P0 &= ~0x20; /* RTS down */ 36 #endif 37 P0DIR |= 0x28; /* RTS, TX out */ 38 P0DIR &= ~0x14; /* CTS, RX in */ 39 #endif 40 41 42 #ifdef UART0_RTSCTS 43 U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/ 44 #else 45 U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/ 46 #endif 47 48 U0CSR = UCSR_MODE; /* UART mode */ 49 U0UCR |= 0x80; /* Flush */ 50 UART0_RX_EN(); 51 52 UART0_RX_INT(1); 53 } 54 /*---------------------------------------------------------------------------*/ 55 /* Write one byte over the UART. */ 56 void 57 uart0_writeb(uint8_t byte) 58 { 59 UTX0IF = 0; 60 U0DBUF = byte; 61 while(!UTX0IF); /* Wait until byte has been transmitted. */ 62 UTX0IF = 0; 63 } 64 #endif
- 首先是包含的头文件,就不多说了。
- 然后是一个宏定义,#if UART0_ENABLE,若该宏未被定义,则uart0_init()不会被编译,节省内存空间。查看头文件:
1 /* UART0 Enable - Disable */ 2 #ifdef UART0_CONF_ENABLE 3 #define UART0_ENABLE UART0_CONF_ENABLE 4 #else 5 #define UART0_ENABLE 0 6 #endif
发现UART0_CONF_ENABLE为真时,UART0_ENABLE也为真;否则UART0_ENABLE为0。再往上就没有找到UART0_CONF_ENABLE的定义了,可能需要自己定义。
- 之后就是uart0_init()函数了,
1 #if UART0_CONF_HIGH_SPEED 2 UART_SET_SPEED(0, UART_460_M, UART_460_E); 3 #else 4 UART_SET_SPEED(0, UART_115_M, UART_115_E); 5 #endif
这是为了设置波特率,若定义的UART0_CONF_HIGH_SPEED为真,则设置的波特率大一些。查看宏定义:
#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0)
以上面第二行为例:变换结果为(“##”为连接符,把两边的字符相连)
1 do{ 2 U0BUAD = UART_460_M; 3 U0GCR = UART_460_E; 4 }while(0);
继续跟踪宏定义:
1 /* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */ 2 #define UART_2K_M 0 3 #define UART_2K_E 16 4 /* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */ 5 #define UART_1K_M 0 6 #define UART_1K_E 15 7 /* 921600 */ 8 #define UART_921_M 216 9 #define UART_921_E 14 10 /* 460800 Higher values lead to problems when the node needs to RX */ 11 #define UART_460_M 216 12 #define UART_460_E 13 13 /* 115200 */ 14 #define UART_115_M 216 15 #define UART_115_E 11 16 /* 38400 */ 17 #define UART_38_M 59 18 #define UART_38_E 10 19 /* 9600 */ 20 #define UART_9_M 59 21 #define UART_9_E 8
最终的替换结果为,波特率查表为460800。
1 do{ 2 U0BUAD = 216; 3 U0GCR = 13; 4 }while(0);
- 继续往下看:
1 #ifdef UART0_A