UART0串口编程(五):串口编程(UART0)之UC/OS(一)UC/OS下的串口发送任务编程

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  删除自己

程序:void      UART0_Init(uint32 bps)

4.按键任务流程:

l  等待开始信号量

l  制造模拟数据

l  按键按下发送信号量,否则延迟等待

 

程序:void Task1     (void *pdata)

5.发送任务流程:

l  等待按键信号量

l  打开串口中断

l  发送10次

l  等待发送信号量

l  发送8字节

l  关发送串口中断

l  发送开始信号量

 

程序:void Task2     (void *pdata)

6.串口发送中断流程:

l  关中断

l  清除中断控制标志位

l  清除串口中断标志位

l  开中断

l  发送发送信号量

程序:void  UART0_Exception(void)

7.总程序:

 

/**--------------File Info-------------------------------------------------------------------------------
** File name:			UART0_while
** Last modified Date:  2011-01-20
** Last Version:		1.0
** Descriptions:		当按键按下后,串口发送中断给上位机发送80字节数据
**-----------------------------------------------------------------------------------------------------
#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);           //发送开始信号量
	}		
	 	 
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

魏波.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值