Contiki-NG中使用2538的雙UART

網(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_byteserial_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++);
      }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容