UART0串口編程系列(四)

串口編程(UART0)UC/OS(一) 編程

---------------------------------------------------------------------數據結構

Author   :tiger-john
WebSite  :blog.csdn.net/tigerjb
app

Email    jibo.tiger@gmail.com函數

Tiger聲明:本人鄙視直接複製本人文章而不加出處的我的或團體,但不排斥別人轉載tiger-john的文章,只是請您註明出處並和本人聯繫或留言給我3Q工具

--------------------------------------------------------------------測試

 

一.UC/OS中設計串口程序所要考慮的問題ui

1.     串口通訊數據以幀爲單位進行處理,若是須要接收大量數據,則幀緩衝區規模必然很大;若是須要發送大量數據,則可將原始數據快看做緩衝區,不須要另外再建立幀緩衝區。spa

2.     幀緩衝區是全局數據結構,一般爲共享資源,須要考慮互斥訪問問題(如在任務中關中斷)。可是此時系統的效率就會降低。咱們能夠經過合理設計通訊任務,將對幀緩衝區進行讀/寫操做的雙方封裝到一個任務裏,是幀緩衝區稱爲這個任務的私有數據結構,再也不是共享資源, 次時就不須要互斥信號量了操作系統

3.     UC/OS操做系統中串口發送和串口接收函數都被設計成了任務。.net

Tiger-john說明:

UC/OS上編寫串口編程時,主要是考慮以上問題。其它的方面就是UART0的配置以及如何編寫中斷程序這些方面在前面已經提過,再此再也不涉及。

若是你還不是很明白的話請看我《UART0串口編程系列》文章的前半部分。

二.UC/OS串口編程

經過一個程序來分析UC/OS串口編程設計和實現:

程序實現的目標:

經過按鍵來控制串口發送任務80字節的幀,每次發送8字節,分25次發送完。

1.UC/OS串口編程中由那幾個任務組成

1>啓動任務

2>按鍵任務(此任務能夠根據不一樣的程序設計內容來改變)

3>發送任務

4>串口發送中斷

2.各個任務之間的關係

3.啓動任務流程:

l  定義各類通訊工具(例如:信號量)

l  系統硬件初始化

l  初始化UART0

l  建立各個任務

l  建立各類通訊工具

l  刪除本身

 

3啓動任務流程圖

 

程序:

/**********************************************************

* 名稱:                    UART0_Init

* 功能:                    UART0初始化 通信波特率1152008位數據位,1位中止位,無奇偶校驗,使能TxFIFO,THRE中斷

* 入口參數:            bps        串口波特率

* 出口參數:           

**********************************************************/

void      UART0_Init(uint32 bps)

{

 

    uint16  Fdiv;

    PINSEL0 = (PINSEL0 & ~(0xf) | 0x05) ;      //設置UART0的引腳

    U0LCR = 0x83;            

    Fdiv = (Fpclk>>4)/bps;

    U0DLM = Fdiv>>8;

    U0DLL = Fdiv%256;

    U0LCR = 0x03;  

    U0FCR = 0x05;                             // 使能TxFIFO

    U0IER = 0x02;                            //使能THRE中斷

  

}

 

/**********************************************************

* 做者:tiger-john

* 時間:2011121

* 名稱:Task0 啓動任務

* 功能:初始化硬件,建立其餘任務,

* 入口參數:pdata

**********************************************************/

void Task0     (void *pdata)

{

pdata = pdata;              

//硬件初始化

TargetInit ();

//初始化串口

UART0_Init(115200);

//建立按鍵信號量                                              

Sem_ButtonFlag =  OSSemCreate(0);  

//建立發送信號量                               

Sem_SendFlg =  OSSemCreate(0);

//建立按鍵任務                                    

OSTaskCreate(Task1,(void *)0, &TaskStk1[TaskStkLengh - 1],10);     

OSTaskCreate(Task2,(void *)0, &TaskStk2[1000 - 1],6);               //建立發送任務

OSTaskDel(OS_PRIO_SELF);                                            //刪除本身

       

}

4.按鍵任務流程:

l  等待開始信號量

l  製造模擬數據

l  按鍵按下發送信號量,不然延遲等待

程序:

/**********************************************************

**                            Task1(按鍵任務)

**********************************************************/

void Task1     (void *pdata)

{

uint8 i;

uint8 err;

pdata = pdata;

while(1)

        {

               OSSemPend(Sem_StartFlag,0,&err); //等帶開始信號量

               for(i = 0;i < 80;i++)

                      {

                             send_buf[i] = i ;             //製造模擬數據。

                      }     

            while((IO0PIN & KEY ) != 0);     //等帶按鍵

            OSSemPost(Sem_ButtonFlag);   //發送按鍵信號量

           

        }

}

5.發送任務流程:

l  等待按鍵信號量

l  打開串口中斷

l  發送10

l  等待發送信號量

l  發送8字節

l  關發送串口中斷

l  發送開始信號量

程序:

/************************************************************                            Task2(發送任務)

**********************************************************/

void Task2     (void *pdata)

{

uint8 i,j,err;

pdata = pdata;

while(1)

{

        OSSemPend(Sem_ButtonFlag,0,&err);  //等待按鍵信號量

        U0IER = U0IER | 0x02;               //打開串口發送中斷

        for(i = 0;i < 10;i++)                     //發送10

               {

                    for(j = 0;j < 8;j++)                //每次8字節

                      {

                             U0THR = send_buf[i*8+j];

                      }     

               OSSemPend(Sem_SendFlag,0,&err); //等待發送信號量

                     

         }

               U0IER = U0IER & ~0x02;              //關掉串口中斷

               OSSemPost(Sem_StartFlag);           //發送開始信號量

}            

       

}

6.串口發送中斷流程:

l  關中斷

l  清除中斷控制標誌位

l  清除串口中斷標誌位

l  開中斷

l  發送發送信號量

 

/**********************************************************

*     稱:            UART0_Exception

*     能:            串口發送中斷

* 入口參數:           

* 出口參數:            data              發送的數據

**********************************************************/

void  UART0_Exception(void)

{

uint32 data;

OS_ENTER_CRITICAL();             //關中斷

VICVectAddr = 0;                  //清除中斷

data = U0IIR;                            //清除中斷表示寄存器標誌

OS_EXIT_CRITICAL();               //開中斷

OSSemPost(Sem_SendFlag);        //發出發送信號量

 }
7.總的程序以下:

 

 

  

 

  1. /****************************************Copyright (c)************************************************** 
  2. **                                       西安郵電學院 
  3. **                                      graduate school 
  4. **                                       XNMS實驗室 
  5. **                                      Author:冀博 
  6. **                                      Time:2011年1月21日 
  7. **                                 http://blog.csdn.net/tigerjb 
  8. ** 
  9. **--------------File Info------------------------------------------------------------------------------- 
  10. ** File name:           UART0_while 
  11. ** Last modified Date:  2011-01-20 
  12. ** Last Version:        1.0 
  13. ** Descriptions:        當按鍵按下後,串口發送中斷給上位機發送80字節數據 
  14. **----------------------------------------------------------------------------------------------------- 
  15.  
  16.  
  17. /****************************************************************************** 
  18. ** Modified by:         TIGER0-JOHN 
  19. ** Modified date:       2011-1-21 
  20. ** Version:             1.1   
  21. ** Descriptions:        測試成功 
  22. ****************************************************************************/  
  23. #include "config.h"  
  24. #include "stdlib.h"  
  25.  
  26. #define KEY             1<<20        //設置爲觸發按鍵  
  27. #define TaskStkLengh    64          //Define the Task0(啓動任務) 堆棧長度  
  28. #define TaskStkLengh    64          //Define the Task1(按鍵任務)  堆棧長度   
  29. #define TaskStkLengh    64          //Define the Task2((發送任務) 堆棧長度  
  30.   
  31.   
  32. OS_STK  TaskStk0[TaskStkLengh];     //Define the Task0 stack  定義啓動任務堆棧   
  33. OS_STK  TaskStk1[TaskStkLengh];     //Define the Task1 stack  定義按鍵任務堆棧  
  34. OS_STK  TaskStk2[TaskStkLengh];     //Define the Task2 stack  定義發送任務堆棧  
  35.   
  36.   
  37. void    Task0(void *pdata);         //Task0 啓動任務  
  38. void    Task1(void *pdata);         //Task1 按鍵任務  
  39. void    Task2(void *pdata);         //Task2 發送任務  
  40.   
  41. uint8   send_buf[80];  
  42. OS_EVENT        *Sem_ButtonFlag;    //定義按鍵信號量  
  43. OS_EVENT        *Sem_SendFlag;      //定義發送信號量  
  44. OS_EVENT        *Sem_StartFlag;      //定義開始信號量  
  45.   
  46.   
  47. /**************************************************************************** 
  48. * 名稱:           UART0_Init 
  49. * 功能:           UART0初始化 通信波特率115200,8位數據位,1位中止位,無奇偶校驗 
  50. *                   使能TxFIFO,和THRE中斷 
  51. * 入口參數:     bps     串口波特率 
  52. * 出口參數:     無 
  53. ****************************************************************************/  
  54. void    UART0_Init(uint32 bps)  
  55. {  
  56.    
  57.     uint16  Fdiv;  
  58.     PINSEL0 = (PINSEL0 & ~(0xf) | 0x05) ;       //設置UART0的引腳  
  59.     U0LCR = 0x83;               
  60.     Fdiv = (Fpclk>>4)/bps;  
  61.     U0DLM = Fdiv>>8;  
  62.     U0DLL = Fdiv%256;  
  63.     U0LCR = 0x03;     
  64.     U0FCR = 0x05;                               // 使能TxFIFO  
  65.     U0IER = 0x02;                               // 使能THRE中斷  
  66.      
  67. }  
  68. /**************************************************************************** 
  69. * 名    稱:       UART0_Exception 
  70. * 功    能:       串口發送中斷 
  71. * 入口參數:     無 
  72. * 出口參數:     data        發送的數據 
  73. ****************************************************************************/  
  74. void  UART0_Exception(void)  
  75. {  
  76.       
  77.     uint32 data;  
  78.     OS_ENTER_CRITICAL();                            //關中斷  
  79.     VICVectAddr = 0;                                //清除中斷  
  80.     data = U0IIR;                                   //清除中斷表示寄存器標誌  
  81.     OS_EXIT_CRITICAL();                             //開中斷  
  82.     OSSemPost(Sem_SendFlag);                        //發出發送信號量  
  83.  }  
  84. /********************************************************************************************************* 
  85. **                              main()函數 
  86. ********************************************************************************************************/  
  87.   
  88. int main (void)  
  89. {  
  90.     OSInit ();                                                          //初始化操做系統                                                 
  91.     OSTaskCreate (Task0,(void *)0, &TaskStk0[TaskStkLengh - 1], 2);     //建立啓動任務  
  92.     OSStart ();                                                         //啓動操做系統,開始對任務進行調度管理  
  93.     return 0;                                                             
  94. }  
  95. /********************************************************************************************************* 
  96. **                            Task0(啓動任務) 
  97. ********************************************************************************************************/  
  98.   
  99. void Task0  (void *pdata)  
  100. {  
  101.     pdata = pdata;                 
  102.     TargetInit ();                                                     //硬件初始化                                                  
  103.     UART0_Init(115200);                                                //初始化串口  
  104.     Sem_ButtonFlag =  OSSemCreate(0);                                  //建立按鍵信號量  
  105.     Sem_SendFlag   =  OSSemCreate(0);                                     //建立發送信號量  
  106.     Sem_StartFlag  =  OSSemCreate(1);   
  107.     OSTaskCreate(Task1,(void *)0, &TaskStk1[TaskStkLengh - 1],5);      //建立按鍵任務  
  108.     OSTaskCreate(Task2,(void *)0, &TaskStk2[TaskStkLengh - 1],4);               //建立發送任務  
  109.     OSTaskDel(OS_PRIO_SELF);                                           //刪除本身  
  110.           
  111. }  
  112. /********************************************************************************************************* 
  113. **                            Task1(按鍵任務) 
  114. ********************************************************************************************************/  
  115. void Task1  (void *pdata)  
  116. {  
  117.     uint8 i;  
  118.     uint8 err;  
  119.     pdata = pdata;   
  120.     while(1)  
  121.         {  
  122.             OSSemPend(Sem_StartFlag,0,&err);           //等帶開始信號量  
  123.             for(i = 0;i < 80;i++)  
  124.                 {  
  125.                     send_buf[i] = i ;           //製造模擬數據。  
  126.                 }     
  127.             while((IO0PIN & KEY ) != 0);        //等帶按鍵  
  128.             OSSemPost(Sem_ButtonFlag);          //發送按鍵信號量  
  129.               
  130.         }  
  131. }  
  132. /********************************************************************************************************* 
  133. **                            Task2(發送任務) 
  134. ********************************************************************************************************/  
  135. void Task2  (void *pdata)  
  136. {  
  137.     uint8 i,j,err;  
  138.     pdata = pdata;  
  139.       
  140.     while(1)  
  141.     {  
  142.         OSSemPend(Sem_ButtonFlag,0,&err);       //等待按鍵信號量  
  143.         U0IER = U0IER | 0x02;                   //打開串口發送中斷  
  144.         for(i = 0;i < 10;i++)                    //發送10次  
  145.             {  
  146.                 for(j = 0;j < 8;j++)             //每次8字節  
  147.                     {  
  148.                         U0THR = send_buf[i*8+j];  
  149.                     }     
  150.                 OSSemPend(Sem_SendFlag,0,&err);    //等待發送信號量  
  151.                       
  152.             }  
  153.             U0IER = U0IER & ~0x02;              //關掉串口中斷  
  154.             OSSemPost(Sem_StartFlag);           //發送開始信號量  
  155.     }         
  156.            
  157. }  
  158.     
  159. /********************************************************************************************************* 
  160. **                            End Of File 
  161. ******************************************************************************************
相關文章
相關標籤/搜索