uC/OS 的消息邮箱——uC/OS学习笔记(五)

1.简介

   在多任务操作系统中,常常需要在任务与任务之间通过传递一个数据(也叫做“消息”)的方式进行通信。为了实现这个目的,可以在内存中创建一个存储空间作为该数据的缓冲区

   如果把这个缓冲区叫做消息缓冲区,那么在任务间传递数据的一个简单方法就是传递消息缓冲区的指针。因此,用来传递消息缓冲区指针的数据结构叫做消息邮箱


2.消息邮箱的操作

   a)声明消息邮箱

         OS_EVENT *box;   

         跟信号量一样,声明一个消息邮箱也是OS_EVENT 类型

   b)创建消息邮箱

         调用函数:OSMboxCreate()

   c)向消息邮箱发送消息

         调用函数:OSMboxPost()

   d)请求消息邮箱

         阻塞方式:调用函数:OSMboxPend()

         非阻塞方式:调用函数:OSMboxAccept()

   e)查询邮箱的状态

         调用函数:OSMboxQuery()

    f)删除邮箱

         调用函数:OSMboxDel()


3.51单片机上测试例程

   芯片:STC90C516

   开发板:广工无线电开发板

   实验程序:矩阵键盘输入-数码管显示。

   程序原理:矩阵键盘扫描独立成一个任务。数码管显示独立成一个任务。矩阵键盘得到按键输入后,通过消息邮箱发送给数码管任务。

   有些51单片机的内核为了减少空间而裁剪了消息邮箱,所以在使用之前需要配置消息邮箱的代码

    完整程序下载地址:http://download.csdn.net/detail/jk050802/6450365

    配置os_cfg.h文件:

#define OS_MBOX_EN                1    /* Enable (1) or Disable (0) code generation for MAILBOXES      */
#define OS_MBOX_ACCEPT_EN         1    /*     Include code for OSMboxAccept()                          */
#define OS_MBOX_DEL_EN            0    /*     Include code for OSMboxDel()                             */
#define OS_MBOX_POST_EN           1    /*     Include code for OSMboxPost()                            */
#define OS_MBOX_POST_OPT_EN       0    /*     Include code for OSMboxPostOpt()                         */
#define OS_MBOX_QUERY_EN          0    /*     Include code for OSMboxQuery()                           */

下面是main.c文件

/* 本例程uCOS-II 版本为2.51*/  

#include "includes.h"

#define uchar unsigned char
#define uint unsigned int


/* 共阴数码管编码 */
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
#define DATA_OUT P2	    //宏定义 数码管段选
#define BIT_CHOOSE P0	//宏定义 数码管位选

uchar num,temp;
uchar key_number;

OS_STK Task1Stk[MaxStkSize+1];
OS_STK Task2Stk[MaxStkSize+1];



OS_EVENT* my_box;	 		//定义消息邮箱

INT8U err;

uchar key_scan() //键盘扫描
{
	
	P1=0xfe; //扫描第一行
	temp=P1;
	temp&=0xf0;
	if(temp!=0xf0)	//检测有按键按下
	{
		OSTimeDlyHMSM(0,0,0,5);
		temp=P1;
		temp&=0xf0;
		if(temp!=0xf0)
		{
			temp=P1;
			switch(temp)	  //判断按下是哪一个按键
			{
				case 0xee:num=0;
					break;
				case 0xde:num=1;
					break;
				case 0xbe:num=2;
					break;
				case 0x7e:num=3;
					break;
			}
			while(temp!=0xf0)
			{
				temp=P1;
				temp&=0xf0;	
			}
		}
	}

	P1=0xfd;	//扫描第二行
	temp=P1;
	temp&=0xf0;
	if(temp!=0xf0)
	{
		OSTimeDlyHMSM(0,0,0,5);
		temp=P1;
		temp&=0xf0;
		if(temp!=0xf0)
		{
			temp=P1;
			switch(temp)
			{
				case 0xed:num=4;
					break;
				case 0xdd:num=5;
					break;
				case 0xbd:num=6;
					break;
				case 0x7d:num=7;
					break;
			}
		 	while(temp!=0xf0)
			{
				temp=P1;
				temp&=0xf0;	
			}	
		}
	}

	P1=0xfb;         //扫描第三行
	temp=P1;
	temp&=0xf0;
	if(temp!=0xf0)
	{
		OSTimeDlyHMSM(0,0,0,5);
		temp=P1;
		temp&=0xf0;
		if(temp!=0xf0)
		{
			temp=P1;
			switch(temp)
			{
				case 0xeb:num=8;
					break;
				case 0xdb:num=9;
					break;
				case 0xbb:num=10;
					break;	 
				case 0x7b:num=11;
					break;
			}
		 	while(temp!=0xf0)
			{
				temp=P1;
				temp&=0xf0;	
			}	
		}
	}

	P1=0xf7;	  //扫描第四行
	temp=P1;
	temp&=0xf0;
	if(temp!=0xf0)
	{
		OSTimeDlyHMSM(0,0,0,5);
		temp=P1;
		temp&=0xf0;
		if(temp!=0xf0)
		{
			temp=P1;
			switch(temp)
			{
				case 0xe7:num=12;
					break;
				case 0xd7:num=13;
					break;
				case 0xb7:num=14;
					break;
				case 0x77:num=15;
					break;
			}
		 	while(temp!=0xf0)
			{
				temp=P1;
				temp&=0xf0;	
			}	
		}
	}
	return num;	   //返回按键对应编号
}	



/*	数码管任务		*/
void Task1(void *ppdata) reentrant
{
	uchar i=0;
	uchar *number;
	
	ppdata=ppdata;

	DATA_OUT=0X00;
	BIT_CHOOSE=0XFF;

	for(;;)
	{
		number = OSMboxPend(my_box,10,&err);	//阻塞式请求信号量
	    //number = OSMboxAccept(my_box);	//非阻塞式请求信号量,测试不成功

		DATA_OUT=tab[*number];
		BIT_CHOOSE = ~1;
		OSTimeDlyHMSM(0,0,0,2); 		
	}   
}




void Task2(void *ppdata) reentrant
{
	ppdata=ppdata;
	for(;;)
    {		
		key_number = key_scan();
		OSMboxPost(my_box,&key_number);	//发送信号量

		OSTimeDlyHMSM(0,0,0,10);  
    }    
}

void main(void)
{
	OSInit();
	InitHardware();

	my_box=OSMboxCreate((void* )0);//定义一个信号量

	OSTaskCreate(Task1,(void*)0,&Task1Stk[0],0);
	OSTaskCreate(Task2,(void*)0,&Task2Stk[0],1);


	OSStart();
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值