網(wǎng)上并沒有找到相關(guān)的資料或者例子,只看到TI的在Zigbee下如何使用2538的介紹(大致是按照2538的UART使用說明,逐個配置),2538里使用UART口需要一系列配置,雖然很多但是不一定要弄得很清楚,可以參照UART0的使用方法配置UART1,注意的一點是:UART1有CTS和RTS用于流控,UART0沒有,由于我并不需要這個功能,所以直接忽略就行。
由于沒有資料,所以就從源碼跟蹤,看看UART0到底是如何設(shè)置并且被初始化的。
platform.c
contiki-main.c是Contiki-NG的入口代碼,C語言里那個不可或缺的main函數(shù)就在這里。第一行就是一個平臺初始化函數(shù)platform_init_stage_one(),這個函數(shù)在arch/platform/cc2538dk/platform.c文件中實現(xiàn),順著這看下去,會看到這個文件中的另一個函數(shù)platform_inti_stage_two()中有UART的初始化代碼。
#if UART_CONF_ENABLE
uart_init(0);
uart_init(1);
uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
#endif
...
serial_line_init();
-
uart_init根據(jù)配置好的引腳信息對UART口進(jìn)行初始化,傳入的參數(shù)就是UART口編號。為了使用UART1,需要設(shè)置UART1的TX和RX引腳,這個在arch/platform/cc2538dk/dev/board.h配置。 -
uart_set_input設(shè)置輸入信息處理函數(shù),默認(rèn)情況下只設(shè)置UART0,SERIAL_LINE_CONF_UART默認(rèn)是0,serial_line_input_byte是接收輸入的處理函數(shù)。為了讓UART1也能接收數(shù)據(jù),因此需要增加處理UART1的輸入處理函數(shù)。 -
serial_line_init函數(shù)用于啟動處理UART口輸入信息處理進(jìn)程,也需要在這個函數(shù)里增加UART1的輸入處理進(jìn)程。
綜上所述,修改如下:
#if UART_CONF_ENABLE
uart_init(0);
uart_init(1);
uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
// 如果只是為了發(fā)信息,下面這行代碼可以不用
uart_set_input(1, sensor_serial_line_input_byte);
#endif
...
serial_line_init();
board.h
位置:arch/platform/cc2538dk/dev/board.h
配置UART1的引腳(可參照UART0的配置,引腳不能和其他沖突),修改如下:
// UART1
#define UART1_RX_PORT GPIO_A_NUM
#define UART1_RX_PIN 4
#define UART1_TX_PORT GPIO_A_NUM
#define UART1_TX_PIN 5
#define UART1_CTS_PORT (-1) //GPIO_B_NUM
#define UART1_CTS_PIN (-1) //0
#define UART1_RTS_PORT (-1) //GPIO_D_NUM
#define UART1_RTS_PIN (-1) //3
serial-line.c
經(jīng)過上述設(shè)置后,UART1能發(fā)信息了,為了讓UART1能收信息,還需要設(shè)置這個文件。在platform.c中的sensor_serial_line_input_byte和serial_line_init函數(shù)都來自這個文件。
默認(rèn)情況下,這個文件代碼處理了UART0的輸入,包括:定義接收緩沖區(qū)
(用ringbuf實現(xiàn))、接收處理事件信號、接收處理函數(shù)和處理進(jìn)程。為了能夠?qū)ⅹ毩⑻幚鞺ART1的輸入,只需要把處理UART0的代碼仿寫一下就好。如下:
/*******
* UART1
* */
// 定義不同名稱的接收緩沖區(qū)
static struct ringbuf srxbuf;
static uint8_t srxbuf_data[BUFSIZE];
// 定義處理進(jìn)程
PROCESS(sensor_serial_line_process, "Sensor Serial driver");
// 定義接收處理事件信號
process_event_t sensor_serial_line_event_message;
/*---------------------------------------------------------------------------*/
// 接收處理函數(shù)
int
sensor_serial_line_input_byte(unsigned char c)
{
static uint8_t overflow = 0; /* Buffer overflow: ignore until END */
if(!overflow) {
/* Add character */
if(ringbuf_put(&srxbuf, c) == 0) {
/* Buffer overflow: ignore the rest of the line */
overflow = 1;
}
} else {
/* Buffer overflowed:
* Only (try to) add terminator characters, otherwise skip */
if((c == END || c == END2) && ringbuf_put(&srxbuf, c) != 0) {
overflow = 0;
}
}
/* Wake up consumer process */
process_poll(&sensor_serial_line_process);
return 1;
}
/*---------------------------------------------------------------------------*/
// 接收處理進(jìn)程
PROCESS_THREAD(sensor_serial_line_process, ev, data)
{
static char buf[BUFSIZE];
static int ptr;
PROCESS_BEGIN();
sensor_serial_line_event_message = process_alloc_event();
ptr = 0;
while(1) {
/* Fill application buffer until newline or empty */
int c = ringbuf_get(&srxbuf);
if(c == -1) {
/* Buffer empty, wait for poll */
PROCESS_YIELD();
} else {
if((c != END && c != END2)) {
if(ptr < BUFSIZE-1) {
buf[ptr++] = (uint8_t)c;
} else {
/* Ignore character (wait for EOL) */
}
} else {
/* Terminate */
buf[ptr++] = (uint8_t)'\0';
/* Broadcast event */
process_post(PROCESS_BROADCAST, sensor_serial_line_event_message, buf);
/* Wait until all processes have handled the serial line event */
if(PROCESS_ERR_OK ==
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL)) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE);
}
ptr = 0;
}
}
}
PROCESS_END();
}
接下來還需要在serial_line_init增加UART1的相關(guān)代碼:
void
serial_line_init(void)
{
// UART0
ringbuf_init(&rxbuf, rxbuf_data, sizeof(rxbuf_data));
process_start(&serial_line_process, NULL);
// UART1
ringbuf_init(&srxbuf, srxbuf_data, sizeof(srxbuf_data));
process_start(&sensor_serial_line_process, NULL);
}
如何使用
- 首先在需要使用地方,包含相關(guān)頭文件:
#include "dev/serial-line.h"
#include "dev/uart.h"
- 發(fā)送字符。如果要發(fā)送字符串的話,使用循環(huán)發(fā)送字符即可。
uart_write_byte(1, 0x41);
- 接收信息。進(jìn)程中處理
sensor_serial_line_event_message事件即可。
if(ev == sensor_serial_line_event_message) {
uint8_t dLen = strlen((char*)data);
for (size_t i = 0; i < dLen; i++)
{
uart_write_byte(1, *(char*)data++);
}
}