1. 程式人生 > >ZigBee開發(13)--組網實驗協議棧串列埠

ZigBee開發(13)--組網實驗協議棧串列埠

實驗現象: 模組通過串列埠傳送“HELLO WEBEE給電腦串列埠除錯助手打印出來。整個實驗在協議棧(TI z-stack 2.5.1a)中進行。用上一節的連結即可下載

整個例程很簡單,分三步走,實際上就是三個語句,不過我們可以瞭解一下具體原理:程式碼不好啃,想長命一點的還是看教程吧。步驟如下:
  1、串列埠初始化
  2、登記任務號
  3、串列埠傳送 

我們開啟 Z-stack 目錄 Projects\zstack\Samples\ SamplesAPP\CC2530DB裡面的 SampleApp.eww 工程。這次試驗我們直接基於協議棧的SampleApp 來進行。

開啟工程後,可以看到上一節說到 workspace 目錄下比較重要的兩個資料夾, Zmain App。這裡我們主要用到 App,這也是使用者自己新增自己程式碼的地方。

主要在 SampleApp.c SampleApp.h 中就可以了,

第一步:串列埠初始化
  串列埠初始化很熟悉了,就是配置串列埠號、波特率、流控、校驗位等等。以 前都 是 配 置 好 寄存 器 然 後 使 用 。

  現 在 我 們 在 workspace 下 找 到HAL\Target\CC2530EB\drivers hal_uart.c 檔案,我們可以看到裡面已經包括了串列埠初始化、傳送、接收等函式, 很是方便
瀏覽一下關於串列埠的操作函式還是挺全的,但是好的東西還在後面!!!workspace 上的 MT 層,發覺有很多基本函式,前面帶 MT。包括 MT_UART.C,我們開啟這個檔案。

看到 MT_UartInit()函式,這裡也有一個串列埠初始化函式的,Z-stack 上有一個 MT 層,使用者可以選用 MT 層配置和呼叫其他驅動。進一步簡化了操作流程。然後SampleApp 的檔案下面加入初始化函式。

開啟 APP目錄下的 OSAL_SampleApp.C 檔案,找到上節提到的 osalInitTasks()任務初始化函式中的 SampleApp_Init ()函式,

進入這個函式,發現原來在 SampleApp.c檔案中。在這裡加入串列埠初始化代 碼

/**********串列埠初始化***************/
  MT_UartInit ();

進入 MT_UartInit();,修改自己想要的初始化配置,程式碼如下。

/***************************************************************************************************
 * @fn      MT_UartInit
 *
 * @brief   Initialize MT with UART support
 *
 * @param   None
 *
 * @return  None
***************************************************************************************************/
void MT_UartInit ()
{
  halUARTCfg_t uartConfig;

  /* Initialize APP ID */
  App_TaskID = 0;

  /* UART Configuration */
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = MT_UART_DEFAULT_BAUDRATE;
  uartConfig.flowControl          = MT_UART_DEFAULT_OVERFLOW;
  uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;
  uartConfig.rx.maxBufSize        = MT_UART_DEFAULT_MAX_RX_BUFF;
  uartConfig.tx.maxBufSize        = MT_UART_DEFAULT_MAX_TX_BUFF;
  uartConfig.idleTimeout          = MT_UART_DEFAULT_IDLE_TIMEOUT;
  uartConfig.intEnable            = TRUE;
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
  uartConfig.callBackFunc         = MT_UartProcessZToolData;
#elif defined (ZAPP_P1) || defined (ZAPP_P2)
  uartConfig.callBackFunc         = MT_UartProcessZAppData;
#else
  uartConfig.callBackFunc         = NULL;
#endif

  /* Start UART */
#if defined (MT_UART_DEFAULT_PORT)
  HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig);
#else
  /* Silence IAR compiler warning */
  (void)uartConfig;
#endif

  /* Initialize for ZApp */
#if defined (ZAPP_P1) || defined (ZAPP_P2)
  /* Default max bytes that ZAPP can take */
  MT_UartMaxZAppBufLen  = 1;
  MT_UartZAppRxStatus   = MT_UART_ZAPP_RX_READY;
#endif

}

uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE;   是配置波特率,我們 go to definition of MT_UART_DEFAULT_BAUDRATE,可以看到:
    #define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_38400
  預設的波特率是 38400bps,現在我們修改成 115200bps,修改如下:
    #define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_115200
uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;    語句是配置流控的,我們進入定義可以看到:
  #define MT_UART_DEFAULT_OVERFLOW TRUE
  預設是開啟串列埠流控的,如果你是隻連了 TX/RX 2 根線的方式務必關流控,像功能底板一樣。
  #define MT_UART_DEFAULT_OVERFLOW FALSE
注意: 2 根線的通訊連線務必關流控,不然是永遠收發不了資訊的。 

根據預先定義的 ZTOOL 或者 ZAPP 選擇不同的資料處理函式。後面的 P1 P2 則是串列埠 0 和串列埠 1。我用ZTOOL,串列埠 0

可以在 option——C/C++ CompilerPreprocessor 裡面看到,已經預設新增 ZTOOL_P1 預編譯。

 

第二步:登記任務號
  在 SampleApp_Init();剛新增的串列埠初始化語句下面加入語句:
  

MT_UartRegisterTaskID(task_id);//登記任務號

意思就是把串列埠事件通過 task_id 登記在 SampleApp_Init();

第三步:串列埠傳送

經過前面兩個步驟,現在串列埠已經可以傳送資訊了。我們在剛剛新增初始化程式碼後面加入一條上電提示 Hello World 的語句。

HalUARTWrite(0,”Hello World\n”,12); (串列埠 0, ‘字元’,字元個數。)

提示:需要在 SampleApp.c 這個檔案里加入標頭檔案語句: #include “MT_UART.h

連線模擬器和 USB 轉串列埠線,選擇 CoordinatorEB,點解下載並除錯。全速執行,可以看到串列埠助手收到資訊。

但是我們發現 Hello World 後面有一小段亂碼。這是 Z-stack MT 層定義的串列埠傳送格式,還有液晶提示資訊。解決辦法為:  
在預編譯地方把 MT LCD 相關內容註釋。如:
   ZTOOL_P1
  xMT_TASK
  xMT_SYS_FUNC
  xMT_ZDO_FUNC
  xLCD_SUPPORTED=DEBUG
xMT_TASK:表示沒有定義 MT_TASK,也就是不定義了。 其他幾項也用這種方法,我們把改好的重新編譯再下載,按復位鍵,觀察串列埠已經沒有亂碼了。

 

 

拓展:
我們在協議棧裡再做一個測試,在 osal_start_system()函式裡 for(;;)里加入:HalUARTWrite(0,”Hello,WeBee\n”,12);如圖 3.37,下載執行後發現串列埠不停地接收到 Hello WeBee。

這就證明了前一節的協議棧執行後會在這個函式裡不停地迴圈查詢任務、執行任務。注意這只是一個演示用的方法,實際應用中可千萬不能有把串列埠傳送函式弄到這個位置然後給 PC 發信息的想法,

因為這破壞了協議棧任務輪詢的工作原則,相當於我們普通微控制器不停用 Delay 延時函式一樣,是極其低效的。