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();
}