UART0串口编程系列(四)(转)

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

---------------------------------------------------------------------

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

Email    jibo.tiger@gmail.com

Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我3Q

--------------------------------------------------------------------

一.UC/OS中设计串口程序所要考虑的问题

1.     串口通信数据以帧为单位进行处理,如果需要接收大量数据,则帧缓冲区规模必然很大;如果需要发送大量数据,则可将原始数据快看作缓冲区,不需要另外再创建帧缓冲区。

2.     帧缓冲区是全局数据结构,通常为共享资源,需要考虑互斥访问问题(如在任务中关中断)。但是此时系统的效率就会下降。我们可以通过合理设计通信任务,将对帧缓冲区进行读/写操作的双方封装到一个任务里,是帧缓冲区称为这个任务的私有数据结构,不再是共享资源, 次时就不需要互斥信号量了

3.     UC/OS操作系统中串口发送和串口接收函数都被设计成了任务。

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. ********************************************************************************************************/ 
posted @ 2011-01-28 09:26  董雨  阅读(267)  评论(0编辑  收藏  举报