目錄
一、賽題展示
二、具體分析
1、任務(wù)
2、基本功能
3、發(fā)揮要求
一、賽題展示
二、具體分析
總思路:根據(jù)第一個(gè)按鍵先判斷方向(利用一個(gè)變量存儲(chǔ)),該方向所有樓層經(jīng)過后,反向運(yùn)動(dòng)。當(dāng)最后一個(gè)樓層到達(dá)后,判斷是否有新按鍵按下,判斷時(shí)間大于三秒,返回默認(rèn)樓層。
1、任務(wù)
????????開機(jī)后,屏幕第一行顯示“DCFZBJQ”,第二行顯示“抽簽號(hào)后4位”(如0207),并自下而上滾動(dòng),3秒后停止?jié)L動(dòng)。
? ? ? ??代碼分析:調(diào)用lcd屏顯示函數(shù),定義一個(gè)變量改變位置,調(diào)用函數(shù)清屏。實(shí)現(xiàn)動(dòng)態(tài)效果。
for(i=0;i<6;i++)//圖片動(dòng)態(tài)顯示
{
LCD_Clear(WHITE );//清屏
LCD_ShowString(180,(show-20),200,16,16,"DCFZBGQ");
LCD_ShowString(180,show,200,16,16,"0207");
show-=30;
delay_ms(500);
}
2、基本功能
? ? ? ? 1、使用4×4矩形鍵盤模擬電梯轎廂內(nèi)的樓層選擇按鈕。當(dāng)按鍵按下時(shí),電梯控制系統(tǒng)記錄對(duì)應(yīng)樓層(建筑共有9層樓高)。
????????代碼分析:按鍵掃描,顯示。因?yàn)橹挥芯艑訕撬源笥诰诺臒o效。(加個(gè)判斷)
key_value1 = keyhandle();//按鍵掃描
if((key_value1>9)&&(key_value1<16))
key_value1=0;
if(key_value1 > 0)//防止沒有按鍵按下時(shí),返回值干擾
{
key_value=key_value1;
}
LCD_ShowNum(200,170,key_value,4,16);
? ? ? ? 2、使用步進(jìn)電機(jī)驅(qū)動(dòng)模塊控制步進(jìn)電機(jī)的轉(zhuǎn)動(dòng),順時(shí)針轉(zhuǎn)動(dòng)表示電梯上升,逆時(shí)針表示電梯下降。電機(jī)每轉(zhuǎn)動(dòng)一圈表示電梯升降一個(gè)樓層。(查詢資料計(jì)算需要步進(jìn)電機(jī)轉(zhuǎn)一圈需要多少個(gè)脈沖)。
????????代碼分析:根據(jù)自己步進(jìn)電機(jī)調(diào)調(diào)參數(shù)。和按鍵組合起來。定義一個(gè)變量,讓它不斷和按鍵值比較。步進(jìn)電機(jī)轉(zhuǎn)一圈它增或減一,直到和按鍵值一樣。
if(((key_value-elevator)>0)&&(key_value!=16))//按下樓層大于電梯當(dāng)前樓層電機(jī)上升
{
RELAY=1;
LCD_Clear(WHITE );
elevator+=up;
LCD_ShowNum(200,170,key_value,4,16);
LCD_ShowNum(90,170,elevator-1,4,16);
LCD_ShowString(122,170,16,16,16,"up");
for( i = 0;i < 512;i++) //電機(jī)正轉(zhuǎn)
stepper(Pos,5);
LCD_ShowNum(90,170,elevator,4,16);
delay_ms(500);
z=1;
}
if(((key_value-elevator)<0)&&(key_value!=16))//按下樓層小于電梯當(dāng)前樓層電機(jī)下降
{
RELAY=1;
LCD_Clear(WHITE );
elevator+=down;
LCD_ShowNum(200,170,key_value,4,16);
LCD_ShowNum(90,170,elevator+1,4,16);
LCD_ShowString(122,170,32,16,16,"down");
for(i = 0;i < 500;i++) //電機(jī)反轉(zhuǎn)
stepper(Neg,6);
LCD_ShowNum(90,170,elevator,4,16);
delay_ms(500);
z=1;
}
? ? ? ?3、 使用 TFT 屏顯示電梯所在的樓層等信息
????????代碼分析:了解一下原理,看看野火之類的源碼學(xué)會(huì)調(diào)用即可。
LCD_ShowNum(90,170,elevator,4,16);//tft屏顯示函數(shù)
3、發(fā)揮要求
? ? ? ? 1、當(dāng)電梯空閑時(shí)(3秒內(nèi)矩陣鍵盤未有按鍵被按下),電梯停留到5樓。
? ? ? ? 代碼分析:判斷按鍵值,看是否達(dá)到三秒。如果達(dá)到直接賦值5即可。使用定時(shí)器記錄。可以用輸入捕獲,也可以簡單用一個(gè)定時(shí)器。設(shè)置重裝載值(根據(jù)所用單片機(jī)調(diào)整),查詢計(jì)數(shù)器。(簡單,但不精準(zhǔn))
if((key_value==elevator)&&(key_value-elevator!=16))
{
if(z==1) //打開計(jì)時(shí)器
{
TIM_Cmd(TIM2,ENABLE);
LED0=0;
delay_ms(500);
LED0=1;
delay_ms(1000);
z=0;
RELAY=0;
}
if(TIM_GetCounter(TIM2)>=30000)//判斷時(shí)間是否大于三秒,大于則返回默認(rèn)樓層
{
key_value=5;
TIM_Cmd(TIM2,DISABLE);
}
}
???????2、當(dāng)電梯啟動(dòng)前和電梯停止以后,使用LED燈和蜂鳴器實(shí)現(xiàn)Is聲光提示
????????代碼分析:電梯停止:前文三,我們定義了一個(gè)變量用來和按鍵對(duì)比,其實(shí)它如果和按鍵值一樣就代表電梯停止了。我們加個(gè)led燈,和蜂鳴器相關(guān)代碼即可。
if((key_value==elevator)&&(key_value-elevator!=16))//到達(dá)按下樓層報(bào)警
{
if(z==1)
{
TIM_Cmd(TIM2,ENABLE);
LED0=0;
delay_ms(500);
LED0=1;
delay_ms(1000);
z=0;
RELAY=0;
}
? ? ? ? 3、設(shè)置電梯具有互鎖功能(運(yùn)行時(shí),門開不了:門開狀態(tài),不能運(yùn)行)。使用繼電器模塊模擬電梯門狀態(tài)互鎖。門開時(shí),LED燈亮,電機(jī)停止;當(dāng)電梯門關(guān)閉,LED燈滅,電機(jī)運(yùn)行。
????????代碼分析:當(dāng)電梯停止時(shí)我們打開繼電器,當(dāng)電梯運(yùn)行時(shí)我們關(guān)閉繼電器。
? ? ? ?4、設(shè)置電梯按鍵具有記憶功能。電梯在運(yùn)行時(shí)能及時(shí)接受各樓層按鍵的呼叫信號(hào),以先方向后距離的優(yōu)先原則(例:電梯從5層上升至6層途中,此時(shí)按下4層和9層按鍵,電梯到達(dá)6層后電梯的運(yùn)行方向不變,繼續(xù)上行至9層后下降,直至4層)進(jìn)行判斷,自行優(yōu)化運(yùn)行路徑,運(yùn)行過程中具備不可逆響應(yīng)功能,任何反方向的呼叫均無效。應(yīng)符合實(shí)際電梯的運(yùn)行模式。
? ? ? ? 代碼分析:將按鍵存入數(shù)組,對(duì)數(shù)組掃描。當(dāng)數(shù)組對(duì)應(yīng)值不為0時(shí)輸出,和電梯變量比對(duì)。
? ? ? ? 我將前文大多數(shù)代碼封裝成了函數(shù)便于理清思路。
if(key_value1>0)
key[key_value1]=key_value1;
for(j=5;j<=9;j++)//將所有按鍵值放入對(duì)應(yīng)數(shù)組
{
if(key[j]!=0)
run(key[j]);
}
另一種思路:利用位存儲(chǔ)文章來源:http://www.zghlxwxcb.cn/news/detail-445243.html
代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-445243.html
int main(void)
{
u8 x=0;
u8 y,i,j,n; //tft顯示豎坐標(biāo)
u8 temp[]="0";
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
uart_init(115200); //串口初始化為115200
LED_Init(); //LED端口初始化
LCD_Init();
KEY_Init(); //矩陣按鍵初始化
MOTOR_Init(); //步進(jìn)電機(jī)IO初始化
RELAY_Init(); //繼電器初始化
BEEP_Init(); //蜂鳴器初始化
//TIM3_Int_Init(4999,7199);//10Khz的計(jì)數(shù)頻率,計(jì)數(shù)到5000為500ms
MotorStop(); //停止步進(jìn)電機(jī)轉(zhuǎn)動(dòng)
BEEP=1; // 關(guān)蜂鳴器
LED0=1; //關(guān)燈
RELAY=1; //關(guān)門
POINT_COLOR=RED;
//sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//將LCD ID打印到lcd_id數(shù)組。
for( y=30;y>0;y-- ) //第二行顯示信息,滾動(dòng)顯示總耗時(shí)30*0.1s
{
LCD_Clear(WHITE); //屏幕分辨率320*480
LCD_ShowString(30,y*10,210,24,24,"ZNDTKZQ");
LCD_ShowString(30,y*10+30,200,24,24,"0208");
delay_ms(100);
}
delay_ms(1000);
LCD_Clear(WHITE); //清屏
LCD_ShowString(30,90+10,240,24,24,"1x2x3x4x5x6x7x8x9x");//第三行 記錄按下的樓層信息
sprintf((char*)FloorNum,"Floor:%d",CurrentFloor);
LCD_ShowString(30,60+10,200,24,24,FloorNum); //第二行顯示當(dāng)前樓層號(hào)
while(1)
{
KeyCode = keyhandle(); //按鍵掃描
if(KeyCode > 0)
{
KeySetLiftUpDownValue();
}
if((GoTo5FloorFlag==1)&&(CurrentFloor!=5)&&((LiftDirection==0)) ) //當(dāng)電梯空閑時(shí)運(yùn)行到5樓
{
if(CurrentFloor>5)
{
LiftDirection=2; //電梯下行
}
else
{
LiftDirection=1; //電梯上行
}
GoTo5FloorFlag = 0;
DesFloor = 5 ; //目標(biāo)樓層賦值5
LCD_ShowNum(30,10,DesFloor,1,24);
GoToFloor(DesFloor); //電梯運(yùn)行到5樓
}
//-------------------電梯控制邏輯處理部分-----------------------
if((PressFloorValue>0)) //樓層按鍵有被按下 LiftDirection賦值策略
{
if((LiftDirection==0)&&(PressFloorValue<(0x00000001<<(CurrentFloor-1)))&&(PressFloorValue>0)) //當(dāng)前停止?fàn)顟B(tài) 當(dāng)前樓層數(shù)以下的樓層有被按下 優(yōu)先下行 0001 0000
{
LiftDirection = 2; //下行
//LCD_ShowString(30,22,240,24,24,"Goingdown");
}
else if((LiftDirection==0)&&(PressFloorValue>(0x00000001<<(CurrentFloor-1)))&&(PressFloorValue>0))
{
LiftDirection = 1; //上行
//LCD_ShowString(30,22,240,24,24,"GoingUp");
}
}
if((LiftDirection==2)&&(PressFloorValue>0) ) //當(dāng)前下行狀態(tài) DesFloor賦值策略
{
for(j=1;j<CurrentFloor;j++)
//for(j=CurrentFloor;j>0;j--)
{
if(((0x00000001<<(CurrentFloor-j-1))&PressFloorValue)> 0)
{
break;
}
}
if(j<CurrentFloor)
{
if(DesFloor>0) //如果此時(shí)DesFloor不為0 代表設(shè)備正在運(yùn)行中
{
if(DesFloor < CurrentFloor-j )//對(duì)于下行來說
{
DesFloor = CurrentFloor-j; //更新DesFloor
}
}
else DesFloor = CurrentFloor-j;
LCD_ShowNum(30,10,DesFloor,1,24);//第一行顯示 調(diào)試信息 目的樓層號(hào)
}
else //if j==CurrentFloor 的處理分支
{
LiftDirection=0; //電梯停止
DesFloor = 0 ; //目標(biāo)樓層賦值0
}
}
else if ((LiftDirection==1)&&(PressFloorValue>0)) //當(dāng)前上行狀態(tài) DesFloor賦值策略
{
for(j=0;j<(8-CurrentFloor+1);j++)
//for(j=CurrentFloor-1;j>0;j--)
{
if(((0x00000001<<(CurrentFloor+j-1))&PressFloorValue)> 0)
{
break;
}
}
if(j<(8-CurrentFloor+1))
{
if(DesFloor>0) //如果此時(shí)DesFloor不為0 代表設(shè)備正在運(yùn)行中
{
if(DesFloor > CurrentFloor+j )//對(duì)于下行來說
{
DesFloor = CurrentFloor+j; //更新DesFloor
}
}
else DesFloor = CurrentFloor+j;
LCD_ShowNum(30,10,DesFloor,1,24);//第一行顯示 調(diào)試信息 目的樓層號(hào)
}
else //if j==CurrentFloor 的處理分支
{
LiftDirection=0; //電梯停止
DesFloor = 0 ; //目標(biāo)樓層賦值0
}
}
//電梯運(yùn)行的控制
if(DesFloor>0)
{
if(DesFloor<CurrentFloor)
{
GoToFloor(CurrentFloor-1); //一層一層控制
}
else if(DesFloor>CurrentFloor)
{
GoToFloor(CurrentFloor+1); //一層一層控制
}
else //到達(dá)
{
LCD_ShowString(114,70,240,24,24,"="); //提示電梯停
//LiftDirection=0; //電梯停止
DesFloor = 0 ; //目標(biāo)樓層賦值0
BEEP=0; //聲光提示
LED0=0;
delay_ms(100);
BEEP=1; // 關(guān)蜂鳴器
LED0=1; //關(guān)燈
RELAY=0; //開門開燈
LED0=0;
delay_ms(1000); //開門維持1s時(shí)間
delay_ms(1000); //開門維持1s時(shí)間
RELAY=1; //關(guān)門關(guān)燈
LED0=1;
}
}
//---------------------------------------------
}
}
到了這里,關(guān)于2019年安徽省機(jī)器人大賽單片機(jī)與嵌入式系統(tǒng)應(yīng)用技能競賽試題(2)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!