UART0串口编程系列 串口(UART0)之UC/OS(一)

一.在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初始化 通讯波特率115200,8位数据位,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

* 时间:2011年1月21

* 名称: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.总的程序如下:

 

 


view plaincopy to clipboardprint?
/****************************************Copyright (c)**************************************************  
**                                       西安邮电学院  
**                                      graduate school  
**                                       XNMS实验室  
**                                      Author:冀博  
**                                      Time:2011年1月21日  
**                                 http://blog.csdn.net/tigerjb  
**  
**--------------File Info-------------------------------------------------------------------------------  
** File name:           UART0_while  
** Last modified Date:  2011-01-20  
** Last Version:        1.0  
** Descriptions:        当按键按下后,串口发送中断给上位机发送80字节数据  
**-----------------------------------------------------------------------------------------------------  
 
 
/******************************************************************************  
** Modified by:         TIGER0-JOHN  
** Modified date:       2011-1-21  
** Version:             1.1    
** Descriptions:        测试成功  
****************************************************************************/ 
#include "config.h"  
#include "stdlib.h"  
 
#define KEY             1<<20        //设置为触发按键  
#define TaskStkLengh    64          //Define the Task0(启动任务) 堆栈长度  
#define TaskStkLengh    64          //Define the Task1(按键任务)  堆栈长度   
#define TaskStkLengh    64          //Define the Task2((发送任务) 堆栈长度   
  
  
OS_STK  TaskStk0[TaskStkLengh];     //Define the Task0 stack  定义启动任务堆栈    
OS_STK  TaskStk1[TaskStkLengh];     //Define the Task1 stack  定义按键任务堆栈   
OS_STK  TaskStk2[TaskStkLengh];     //Define the Task2 stack  定义发送任务堆栈   
  
  
void    Task0(void *pdata);         //Task0 启动任务   
void    Task1(void *pdata);         //Task1 按键任务   
void    Task2(void *pdata);         //Task2 发送任务   
  
uint8   send_buf[80];   
OS_EVENT        *Sem_ButtonFlag;    //定义按键信号量   
OS_EVENT        *Sem_SendFlag;      //定义发送信号量   
OS_EVENT        *Sem_StartFlag;      //定义开始信号量   
  
  
/****************************************************************************  
* 名称:           UART0_Init  
* 功能:           UART0初始化 通讯波特率115200,8位数据位,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中断   
      
}   
/****************************************************************************  
* 名    称:       UART0_Exception  
* 功    能:       串口发送中断  
* 入口参数:     无  
* 出口参数:     data        发送的数据  
****************************************************************************/  
void  UART0_Exception(void)   
{   
       
    uint32 data;   
    OS_ENTER_CRITICAL();                            //关中断   
    VICVectAddr = 0;                                //清除中断   
    data = U0IIR;                                   //清除中断表示寄存器标志   
    OS_EXIT_CRITICAL();                             //开中断   
    OSSemPost(Sem_SendFlag);                        //发出发送信号量   
 }   
/*********************************************************************************************************  
**                              main()函数  
********************************************************************************************************/  
  
int main (void)   
{   
    OSInit ();                                                          //初始化操作系统                                                  
    OSTaskCreate (Task0,(void *)0, &TaskStk0[TaskStkLengh - 1], 2);     //创建启动任务   
    OSStart ();                                                         //启动操作系统,开始对任务进行调度管理   
    return 0;                                                              
}   
/*********************************************************************************************************  
**                            Task0(启动任务)  
********************************************************************************************************/  
  
void Task0  (void *pdata)   
{   
    pdata = pdata;                  
    TargetInit ();                                                     //硬件初始化                                                   
    UART0_Init(115200);                                                //初始化串口   
    Sem_ButtonFlag =  OSSemCreate(0);                                  //创建按键信号量   
    Sem_SendFlag   =  OSSemCreate(0);                                     //创建发送信号量   
    Sem_StartFlag  =  OSSemCreate(1);    
    OSTaskCreate(Task1,(void *)0, &TaskStk1[TaskStkLengh - 1],5);      //创建按键任务   
    OSTaskCreate(Task2,(void *)0, &TaskStk2[TaskStkLengh - 1],4);               //创建发送任务   
    OSTaskDel(OS_PRIO_SELF);                                           //删除自己   
           
}   
/*********************************************************************************************************  
**                            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);          //发送按键信号量   
               
        }   
}   
/*********************************************************************************************************  
**                            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);           //发送开始信号量   
    }          
            
}   
     
/*********************************************************************************************************  
**                            End Of File  
********************************************************************************************************/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怀想天空2011

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值