网上并没有找到相关的资料或者例子,只看到TI的在Zigbee下如何使用2538的介绍(大致是按照2538的UART使用说明,逐个配置),2538里使用UART口需要一系列配置,虽然很多但是不一定要弄得很清楚,可以参照UART0的使用方法配置UART1,注意的一点是:UART1有CTS和RTS用于流控,UART0没有,由于我并不需要这个功能,所以直接忽略就行。
由于没有资料,所以就从源码跟踪,看看UART0到底是如何设置并且被初始化的。
platform.c
contiki-main.c是Contiki-NG的入口代码,C语言里那个不可或缺的main函数就在这里。第一行就是一个平台初始化函数platform_init_stage_one(),这个函数在arch/platform/cc2538dk/platform.c文件中实现,顺着这看下去,会看到这个文件中的另一个函数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根据配置好的引脚信息对UART口进行初始化,传入的参数就是UART口编号。为了使用UART1,需要设置UART1的TX和RX引脚,这个在arch/platform/cc2538dk/dev/board.h配置。 -
uart_set_input设置输入信息处理函数,默认情况下只设置UART0,SERIAL_LINE_CONF_UART默认是0,serial_line_input_byte是接收输入的处理函数。为了让UART1也能接收数据,因此需要增加处理UART1的输入处理函数。 -
serial_line_init函数用于启动处理UART口输入信息处理进程,也需要在这个函数里增加UART1的输入处理进程。
综上所述,修改如下:
#if UART_CONF_ENABLE
uart_init(0);
uart_init(1);
uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte);
// 如果只是为了发信息,下面这行代码可以不用
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
经过上述设置后,UART1能发信息了,为了让UART1能收信息,还需要设置这个文件。在platform.c中的sensor_serial_line_input_byte和serial_line_init函数都来自这个文件。
默认情况下,这个文件代码处理了UART0的输入,包括:定义接收缓冲区
(用ringbuf实现)、接收处理事件信号、接收处理函数和处理进程。为了能够将独立处理UART1的输入,只需要把处理UART0的代码仿写一下就好。如下:
/*******
* UART1
* */
// 定义不同名称的接收缓冲区
static struct ringbuf srxbuf;
static uint8_t srxbuf_data[BUFSIZE];
// 定义处理进程
PROCESS(sensor_serial_line_process, "Sensor Serial driver");
// 定义接收处理事件信号
process_event_t sensor_serial_line_event_message;
/*---------------------------------------------------------------------------*/
// 接收处理函数
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;
}
/*---------------------------------------------------------------------------*/
// 接收处理进程
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的相关代码:
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);
}
如何使用
- 首先在需要使用地方,包含相关头文件:
#include "dev/serial-line.h"
#include "dev/uart.h"
- 发送字符。如果要发送字符串的话,使用循环发送字符即可。
uart_write_byte(1, 0x41);
- 接收信息。进程中处理
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++);
}
}











网友评论