1. 程式人生 > >uC/OS 的訊息郵箱——uC/OS學習筆記(五)

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微控制器的核心為了減少空間而裁剪了訊息郵箱,所以在使用之前需要配置訊息郵箱的程式碼

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