基于uCOSII的LCD驱动实验
- 實驗目的
- 實驗內容
- 實驗設備
- ?實驗步驟
???????實驗題目1:
???????實驗代碼:
???????????代碼說明:
????????????Main:此函數創建并啟動了任務一,利用“郵箱”來進行多任務間的通信。
???????????Task1:創建并啟動了任務2,3,4,也是利用“郵箱” 來進行多任務間的通信。通過設置任務的優先級來控制任務的調度。
???????????Task2:主要是控制LED燈的交替閃爍效果
???????????Task3:主要是向超級終端中輸出鍵盤上的按鍵值,代碼只變動了輸出內容。 ??
? ? ? ? ? ?Task4:是進行GUI任務,代碼變動主要是改寫此函數,函數編寫代碼已經進行了相關的注釋。
void Task_4(void *pdata) { I32 number;INT8U Loop;for(;;) { number = GUI_WaitKey();Loop = TRUE;do{switch (number){case GUI_KEY_START: // 得到開始命令 Set_Color(GUI_BLUE);Fill_Rect(0,0,639,479); //畫窗口的邊框Set_Color(GUI_WHITE);Set_BkColor (GUI_BLUE); //設置窗口的背景顏色Fill_Rect(0,0,639,2); Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479); Set_Color(GUI_YELLOW);Set_Font (&CHINESE_FONT16);Disp_String (CN_start"這是一個多任務顯示的例程"CN_end,50,30); Set_Color(GUI_RED); //畫紅色的圓,Fill_Circle (320, 240, 20); //圓心坐標、半徑為20Loop = FALSE;number = 0;break;default: // 等待主任務發送的鍵值命令number = GUI_WaitKey(); Loop = TRUE;break;}}while(Loop==TRUE);do{switch (number) {case GUI_KEY_UP: //選擇上移Set_Color(GUI_BLUE); //將原先的圓消失掉Fill_Rect(0,0,639,479); //重新繪制窗口Set_Color(GUI_WHITE);Set_BkColor (GUI_BLUE);Fill_Rect(0,0,639,2); //窗口的四條邊框的繪制Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479);Set_Color(GUI_RED);if(y-20<=1){y=240; //如果圓要超過上邊界,將圓設置到中心}else{y=y-6;}Fill_Circle(x, y, 20);Loop = TRUE;number = 0;break; case GUI_KEY_DOWN: //選擇下移Set_Color(GUI_BLUE); //將原先的圓消失掉Fill_Rect(0,0,639,479); //重新繪制窗口Set_Color(GUI_WHITE);Set_BkColor (GUI_BLUE); Fill_Rect(0,0,639,2); //窗口的四條邊框的繪制Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479);Set_Color(GUI_RED);if(y+20>=479){ //如果圓要超過下邊界,將圓設置到中心y=240;}else{y=y+6;}Fill_Circle(x, y, 20); Loop = TRUE;number = 0;break;case GUI_KEY_RIGHT: //選擇右移Set_Color(GUI_BLUE); //將原先的圓消失掉Fill_Rect(0,0,639,479); //重新繪制窗口Set_Color(GUI_WHITE); Set_BkColor (GUI_BLUE);Fill_Rect(0,0,639,2); //窗口的四條邊框的繪制Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479);Set_Color(GUI_RED); //x為全局變量if(x+20>=639){ //如果圓要超過右邊界x=320; //將圓心重新設置到中間}else{ x=x+6; //每一次右移,x值加6}Fill_Circle(x, y, 20); Loop = TRUE;number = 0; break; case GUI_KEY_LEFT: //選擇左移 Set_Color(GUI_BLUE); //將原先的圓消失掉Fill_Rect(0,0,639,479); //重新繪制窗口Set_Color(GUI_WHITE);Set_BkColor (GUI_BLUE);Fill_Rect(0,0,639,2); //窗口的四條邊框的繪制Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479); Fill_Rect(637,0,639,479);Set_Color(GUI_RED);if(x-20<=1){ //如果圓要超過左邊界x=320; //將圓心重新設置到中間}else{ x=x-6;}Fill_Circle(x, y, 20);Loop = TRUE;number = 0;break;case GUI_KEY_ESCAPE: // 得到退出命令Set_Color(GUI_BLUE);Fill_Rect(0,0,639,479);Set_Color(GUI_WHITE);Fill_Rect(0,0,639,2);Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479);Loop = FALSE;number = 0;break; default: // 等待主任務發送的鍵值命令number = GUI_WaitKey();Loop = TRUE;break;}}while(Loop == TRUE);} } void Task_3(void *pdata) {for(;;){if(key_number!=0xff){ Uart_Printf("key_number=%x Button Pressed!\n",key_number); //任務的干得活兒就是向超級終端發送內容key_number=0xff;OSTimeDly(30); //延時100個節拍}} }實驗題目2:
??在編寫一個任務5,此任務中完成,設置其優先級為60,繪制一個圓,此圓的初始半徑為2,然后擴大到50之后縮小為半徑為2的圓。擴大的頻率為LED燈閃爍的頻率的1/2.
??代碼的實現:
?在task1中創建并啟動任務task5,在task2中設置讓task2閃爍完一回,線程睡眠OSTimeDly(30); ,讓低優先級的task5得到執行,task2中創建一個信號量,讓task2運行兩次,往信號量中扔一把鑰匙,達到燈閃爍頻率的1/2是圓擴大的頻率,task5負責接受取出鑰匙得到運行。
void Task_5(void *pdata) { I32 number;INT8U Loop;for(;;) { Key_P = OSMboxPend(Key_Mbox1, 0, &err); //取鑰匙獲取執行機會number = GUI_WaitKey();// 得到開始命令 Set_Color(GUI_BLUE);Fill_Rect(0,0,639,479); //畫窗口的邊框Set_Color(GUI_WHITE);Set_BkColor (GUI_BLUE); //設置窗口的背景顏色Fill_Rect(0,0,639,2); Fill_Rect(0,0,2,479);Fill_Rect(0,477,639,479);Fill_Rect(637,0,639,479); Set_Color(GUI_YELLOW);Set_Font (&CHINESE_FONT16);Disp_String (CN_start"這是一個多任務顯示的例程"CN_end,50,30); R+=2; //此處R是全局變量If(R>50){R=2; //當圓半徑到達了50時,圓半徑回到2}Set_Color(GUI_RED); //畫紅色的圓,Fill_Circle (320, 240, R); //圓心坐標、半徑為20Loop = FALSE;number = 0; Loop = TRUE;number = GUI_WaitKey(); Loop = TRUE;}} void Task_2(void *pdata) {INT32U i,flag=0;K=1; //k是全局變量,控制代碼執行兩次往信號量里//面扔一把鑰匙Key_Mbox1 = OSMboxCreate((void *)0);//創建信號量Key_Mbox1for(;;){k++; If(k%2==0) OSMboxPost(Key_Mbox1,&key_number);//往信號量Key_Mbox1仍鑰匙OSTimeDly(30); if(flag==0){for(i=0;i<100000;i++);rGPGDAT = rGPGDAT&~(0x3<<8)|(0x1<<8);for(i=0;i<100000;i++);flag = 1;}else{for(i=0;i<100000;i++);rGPGDAT = rGPGDAT&~(0x3<<8)|(0x2<<8);for(i=0;i<100000;i++);flag = 0;}OSTimeDly(30); //延時30個節拍} }實驗結果截圖:
問題以及總結:
? ? ? ? ?本次實驗過程中繪制紅心圓的時候往上移,左移、右移發現之前的圓不會消失,于是就造成了圓移動的過程中繪畫成一條線,于是我就想到每次點擊上下移動之前把原先這個圓給刪除掉,但是GUI中又沒有提供相關的函數,于是借鑒了一下別人的做法,每一移動觸發之前,先把面板上的組件清空,把原先的窗口設置成白色,然后重新繪制窗口,這樣之前的圓就消失了。
????????在任務二中,task5老是得不到機會運行,因為task5的優先級太低,而task2中總是在運行,導致低優先級的task5得不到機會運行,后來在老師的幫助下,將task任務線程睡眠,也就是延遲30個節拍,讓task5得到機會能夠運行。
總結
以上是生活随笔為你收集整理的基于uCOSII的LCD驱动实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: R语言第十一讲 决策树与随机森林
- 下一篇: java数组显示最大值,java 如何用