if(flag) OSMboxPost(mbox,&key); } }
(2)如果希望实验效果为:键盘扫描任务检测到按键后,如果需要将按键信息发送给多个任务(如串口发送任务、数码管显示任务),请问如何改造程序达到以上要求的实验效果,请写出三个任务的任务函数框架,说明三个任务的数据通信的实现。
void TaskSendByUart(void *pdata) {
while(1) {
pkey = (_key *)OSMboxPend(mbox,0,&err);
sprintf(s,\ UART0SendStr(s); } }
void TaskLed(void *pdata) { while(1) {
pkey = (_key *)OSMboxPend(mbox,0,&err); i = pkey->row*4 + pkey->col;
HC595_SendDat(DISP_TAB[i]); //输出LED显示数据 DelayNS(100); //延时 } }
void TaskKeyScan(void *pdata) { while(1) {
while((IO1PIN&(0xf0<<16)) != (0xf0<<16)); //等待按键释放
if(flag) OSMboxPostOpt(mbox,&key,OS_POST_OPT_BROADCAST); } }
实验六:
编写两个任务,一个任务获取汉字区位码,并将汉字区位码发送到消息邮箱,另外一个任务从消息邮箱接收汉字区位码,并从汉字字库中获取汉字点阵信息并显示。请写出根据汉字内码获取汉字点阵信息并显示的基本步骤。
1.根据汉子机内码求出区位码:qh=*p++ - 160;wh = *p - 160 2.求出汉子在字库中的位置:loc=(94*(qh - 1) + (wh - 1)*hzsize); 3.读入汉字字库点阵信息:fseek(fp, loc, 0);fread(&hz, sizeof(hz), 1, fp); 4.显示汉字:Load_HZ(hz, 24, 24, x, 100);
void MyTask(void * pdata) {
char s[]=\电子科技大学中山学院\ p = s;
while(*p) { //根据汉字机内码求出区位码 qw.qh=*p++-160; qw.wh=*p++-160; OSMboxPost(mbox,&qw); }
while(1) { } }
void YourTask(void * pdata)
{
fp = fopen(\楷\ while(1) { qw = (_qwh *)OSMboxPend(mbox,0,&err); GUI_DispDecAt(qw->qh,x+3,60,2); GUI_DispDecAt(qw->wh,x+3,80,2); loc=(94*(qw->qh-1)+(qw->wh-1))*HZSize; //求出汉字在字库中的位置 //读入汉字字库点阵信息 fseek(fp,loc,0); fread(&hz,sizeof(hz),1,fp); Load_HZ(hz,24,24,x,100); x += 30; }
fclose(fp);
while(1) { } }
//汉字显示完整代码 : #include
#define TaskStkLengh 2048 //定义用户任务的堆栈长度 OS_STK TaskSendStk[TaskStkLengh]; //定义发送汉字点阵任务堆栈 OS_STK TaskDispStk[TaskStkLengh]; //定义显示汉字点阵任务堆栈 void TaskSend(void * pdata) ; void TaskDisp(void * pdata) ; OS_EVENT * mbox; typedef struct QWM { INT8U qh; INT8U wh; }QWCode;
//显示汉字点阵函数
void Load_HZ( const INT8U *hz,INT16U Len,INT16U Height,INT16U xPos,INT16U yPos) {
INT16U x,y,i; INT8U temp;
for(y=yPos;y<=(yPos+Height-1);y++) { for(x=xPos;x<=(xPos+Len-1);) { temp = *hz++;
for(i=128; i>=1; i=i/2) { GUI_SetColor(GUI_RED);
if(temp&i) GUI_DrawPixel(x,y); x++; } } } }
int main() {
GUI_Init(); OSInit();
OSTaskCreate(TaskSend, 0, &TaskSendStk[TaskStkLengh-1], 5); OSTaskCreate(TaskDisp, 0, &TaskDispStk[TaskStkLengh-1], 4); mbox = OSMboxCreate((void *)0); OSStart(); return 0; }
void TaskSend(void * pdata) { QWCode qw;
char s[]=\电子科大计算机学院\
//实际应用中可能是通过通信链路获得要显示的字符串 p = s;
while(*p) { //根据汉字机内码求出区位码 qw.qh=*p++-160; qw.wh=*p++-160; OSMboxPost(mbox,&qw); } while(1) {} }
void TaskDisp(void * pdata) { FILE *fp; INT8U err; QWCode *p; INT8U hz[72]; INT32U loc; INT16U x = 10;
fp = fopen(\ //打开汉字库文件
if(!fp) { GUI_DispStringAt(\ exit(0); }
else GUI_DispStringAt(\ while(1) { p =(QWCode*)OSMboxPend(mbox,0,&err); loc=(94*(p->qh-1)+(p->wh-1))*72; //求出汉字在字库中的位置 //读入汉字字库点阵信息 fseek(fp,loc,0); fread(&hz,72,1,fp);
Load_HZ(hz,24,24,x,100); x += 30; } }
//BMP图片显示
//#include \#define TaskStkLengh 2048 //定义用户任务的堆栈长度 OS_STK TaskSendStk[TaskStkLengh]; //定义用户任务堆栈 OS_STK TaskDispStk[TaskStkLengh]; //定义用户任务堆栈 void TaskSend(void * pdata) ; void TaskDisp(void * pdata) ; OS_EVENT *mbox;
INT16U Width,Height,w; //定义BMP文件信息区 typedef struct BMP_file { INT16U bfType; //文件类型
INT32U bfSize; //bmp文件长度 INT16U Reserved1; INT16U Reserved2;
INT32U bfOffset; //文件描述区长度,16色为118,256色为1078 }bitmapfile;
//定义图象信息区
typedef struct BMP_info { INT32U biSize;
INT32U biWidth; INT32U biHeight; INT16U biPlanes;
INT16U biBitCount; //每个像素的颜色位 INT32U biCompression; INT32U biSizeImage;
INT32U biXplosPerMeter; INT32U biYplosPerMeter; INT32U biClrUsed;
INT32U biClrImportant; }bitmapinfo;
int main() {
GUI_Init(); OSInit();
OSTaskCreate(TaskSend, 0, &TaskSendStk[TaskStkLengh-1], 5); OSTaskCreate(TaskDisp, 0, &TaskDispStk[TaskStkLengh-1], 4); mbox = OSMboxCreate((void *)0); OSStart(); return 0; }
void TaskSend(void * pdata) { FILE *fp; bitmapfile file; bitmapinfo info;
INT8U mybuf[3*320]; int y; //打开文件
fp = fopen(\
if(!fp) GUI_DispStringAt(\ else GUI_DispStringAt(\
//读入文件信息内容
fread(&file,sizeof(bitmapfile),1,fp);
//读入图像有关信息内容 fseek(fp,14,0);
fread(&info,sizeof(bitmapinfo),1,fp); Width = info.biWidth; Height = info.biHeight;
GUI_DispDecAt(info.biWidth,100,120,6); GUI_DispDecAt(info.biHeight,100,140,6); GUI_DispDecAt(file.bfOffset,100,160,6);
GUI_Delay(5000);
for(y=Height-1;y>=0;y--) { //文件指针定位 w = 3*Width; if(w%4>0) w = (w/4+1)*4; fseek(fp,54+y*w,0); //读取一个行像素数据放入缓冲区 fread(mybuf,1,3*Width,fp); OSMboxPost(mbox,mybuf); }
fclose(fp);
while(1) { } }
void TaskDisp(void * pdata) { INT8U *p; INT8U err;
INT32U lcdColor; INT32U r,g,b; INT16U x,y=0; while(1) { p = (INT8U *)OSMboxPend(mbox,0,&err); for(x=0;x #define TaskStkLength 200 //定义用户任务的堆栈长度 OS_STK TaskLedStk[TaskStkLength]; // 定义按键任务的堆栈 void TaskLed(void *pdata); //声明 sem1 = OSSemCreate(0); OSTaskCreate (TaskLed,(void *)0, &TaskLedStk[TaskStkLength - 1],3); OSSemPend(sem1,0,&err);//等待一个信号量函数 OSSemPost(sem1);