“所有模式功能都有啦,快快把它們聯繫起來,好激動哦!!”
3.7 模式選擇
關於模式選擇,就是一個switch函數。通過紅外遙控來更改mode的值,之後==switch(mode)==來進行對應的模式切換,不過有些模式需要初始化,所以設置了一個mode_pre來存放上一次模式的值,當mode!=mode_pre時,說明模式切換了,之後進入新模式的初始化,進行mode_pre=mode賦值操作,這樣初始化就只進行了一次,之後在進入switch(mode)就會正常的模式運行了。
定義了一些變量
u8 mode=0xff; //當前模式
u8 mode_pre=0xff; //上次模式
正常的模式是從mode=0開始的,單片機上電時先不進行任何模式,所以先設置成0xff。
代碼很簡單,在這裏就不畫流程圖了,直接上代碼圖片(完整代碼太長,就放最後代碼附錄裏了,下面是模式選擇的框架)
3.8 其餘的一些小模式
3.8.1 短動畫
如果放較長的動畫,單片機的存儲器不夠用,需要用SD卡,但是。。時間不夠,一切從簡,從網上找了一個短一點的動畫,更確切的是表情包,分出來的圖片只有6張。
放動畫的原理也很簡單,也就是很快的刷新圖片,根據人眼的視覺暫留效應。只要能成功顯示一張圖片,那麼動畫也就是瞬間的事了。
拍的不是很清楚,見諒撒,嘻嘻嘻!
3.8.2 顯示正弦,餘弦,中心水平垂直線、圓
這個模式純粹的就是調用LCD12864裏的函數,沒有什麼新奇的東西,具體代碼請看鏈接: LCD12864——基於STC15W5K32S4
“到這裏基本就結束啦,最後附上主函數的代碼”
3.9 主函數
#include "STC15Fxxxx.h"
#include "delay.h"
#include "LCD12864.h"
#include "picture.h"
#include "HC595.h"
#include "timer.h"
#include "remotecontrol.h"
#include "adc.h"
#include "jisuan.h"
#include "PS2.h"
#include "Tetris.h"
void main(void)
{
u8 i=0;
P0M1 = 0; P0M0 = 0; //設置爲準雙向口
P1M1 = 0; P1M0 = 0; //設置爲準雙向口
P2M1 = 0; P2M0 = 0; //設置爲準雙向口
P3M1 = 0; P3M0 = 0; //設置爲準雙向口
P4M1 = 0; P4M0 = 0; //設置爲準雙向口
P5M1 = 0; P5M0 = 0; //設置爲準雙向口
P6M1 = 0; P6M0 = 0; //設置爲準雙向口
P7M1 = 0; P7M0 = 0; //設置爲準雙向口
jisuaninit();
HC595_Init(); //595初始化
//DisableHC595(); //595關閉
Timer_Init(); //定時器初始化
ADCinit(); //ADC初始化
delay_ms(100); //啓動等待,等LCD講入工作狀態
LCD12864_Init(); //LCD初始化
delay_ms(5); //延時片刻(可不要)
PS2_Init(); //PS2初始化
EA = 1; //開啓總中斷
LCD12864_Clear(); //LCD清屏
DisplayListChar(0,1,uctech); //顯示字庫中的中文數字
DisplayListChar(0,2,net); //顯示字庫中的中文數字
DisplayListChar(0,3,mcu); //顯示字庫中的中文
DisplayListChar(0,4,qq); //顯示字庫中的中文數字
delay_ms(5000); //延時
delay_ms(5000);
LCD12864_Clear(); //LCD清屏
ShowList(); //顯示列表目錄
while(1)
{
if(B_1ms) //1ms到
{
B_1ms = 0;
if(B_IR_Press) //檢測到收到紅外鍵碼
{
B_IR_Press = 0;
RemotecontrolSwitch();
/*****顯示接收到的紅外編碼*******/
//要顯示紅外編碼的話要把搖桿的顯示部分註釋/
// LED8[0] = (u8)((UserCode >> 12) & 0x0f); //用戶碼高字節的高半字節
// LED8[1] = (u8)((UserCode >> 8) & 0x0f); //用戶碼高字節的低半字節
// LED8[2] = (u8)((UserCode >> 4) & 0x0f); //用戶碼低字節的高半字節
// LED8[3] = (u8)(UserCode & 0x0f); //用戶碼低字節的低半字節
// LED8[6] = IR_code >> 4;
// LED8[7] = IR_code & 0x0f;
/*******************************/
}
Mode_Switch();//模式選擇函數
Read_PS2(); //讀取PS2函數
delay_ms(150);
if(!PS2_RedLight())
{
LED8[0] = (u8)((out[7] >> 4) & 0x0f); //左搖桿左右模擬值高半字節
LED8[1] = (u8)(out[7]& 0x0f); //左搖桿左右模擬值低半字節
LED8[2] = (u8)((out[8] >> 4) & 0x0f); //左搖桿上下模擬值高半字節
LED8[3] = (u8)(out[8]& 0x0f); //左搖桿上下模擬值高半字節
LED8[4] = DIS_;
LED8[5] = (u8)(Point_L_ShowLine & 0x0f);
LED8[6] = DIS_; //按鍵高半字節(右按鍵的上下左右,L1,L2,L3,R1,R2,R3)
LED8[7] = (u8)(Point_R_ShowLine & 0x0f); //按鍵低半字節(右按鍵的上下左右,L1,L2,L3,R1,R2,R3)
}
else
{
LED8[0] = (u8)((out[3] >> 4) & 0x0f); //按鍵高半字節(左按鍵的上下左右)
LED8[1] = (u8)(out[3]& 0x0f); //按鍵低半字節(左按鍵的上下左右)
LED8[2] = DIS_;
LED8[3] = DIS_;
LED8[4] = DIS_;
LED8[5] = DIS_;
LED8[6] = (u8)((out[4] >> 4) & 0x0f); //按鍵高半字節(右按鍵的上下左右,L1,L2,R1,R2)
LED8[7] = (u8)(out[4]& 0x0f); //按鍵低半字節(右按鍵的上下左右,L1,L2,R1,R2)
}
}
}
}
附錄代碼
模式選擇的代碼
/********************************
功能:模式選擇
*********************************/
void Mode_Switch(void)
{
u8 i;
switch(mode)
{
case 0://計算器
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
lie=2;
LCD12864_Clear();
}
else
{
jisuan();//計算器函數
break;
}
case 1://遙控畫線
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
lie=3;
LCD12864_fill_GDRAM(0x00);
LCD12864_Clear();
LCD12864_Circle(Tantan_x,Tantan_y,Tantan_r,0);
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//左搖桿座標起始點顯示
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//右搖桿座標起始點顯示
}
else
{
if(out[4]==0xFB)//L1
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);
Point_L_r++;
if(Point_L_r>=6)Point_L_r=6;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);
}
if(out[4]==0xFE)//L2
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);
Point_L_r--;
if(Point_L_r<=1)Point_L_r=1;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);
}
if(out[4]==0xF7)//R1
{
Point_R_ShowLine=!Point_R_ShowLine;
if(!Point_R_ShowLine)Jiahao(Point_R_x,Point_R_y,Point_R_r,1);
else
{
Jiahao(Point_R_x,Point_R_y,Point_R_r,0);
LCD12864_Fill_Point(Point_R_x,Point_R_y,1);
}
}
if(out[4]==0xFD)//R2
{
LCD12864_fill_GDRAM(0x00);//設置GDRAM
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//左搖桿座標起始點顯示
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//左搖桿左右
i=PS2_AnologData(7);//讀取一次左搖桿左右的模擬值(out[7]中)0~255
//(模擬值小於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
if((i<=0x40)||(out[3]==Left_L))
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);//上次的點滅掉
Point_L_x--;
if(Point_L_x<Point_L_r)Point_L_x=Point_L_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//(模擬值大於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
else if((i>=0xBF)||(out[3]==Right_L))
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);//上次的點滅掉
Point_L_x++;
if(Point_L_x>(127-Point_L_r))Point_L_x=127-Point_L_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//右搖桿左右
i=PS2_AnologData(5);//讀取一次右搖桿左右的模擬值(out[5]中)0~255
//(模擬值小於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
if((i<=0x40)||(out[4]==Left_R))
{
if(!Point_R_ShowLine) Jiahao(Point_R_x,Point_R_y,Point_R_r,0);//上次的點滅掉
Point_R_x--;
if(Point_R_x<Point_R_r)Point_R_x=Point_R_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//(模擬值大於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
else if((i>=0xBF)||(out[4]==Right_R))
{
if(!Point_R_ShowLine) Jiahao(Point_R_x,Point_R_y,Point_R_r,0);//上次的點滅掉
Point_R_x++;
if(Point_R_x>(127-Point_R_r))Point_R_x=127-Point_R_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//左搖桿上下
i=PS2_AnologData(8);//讀取一次左搖桿上下的模擬值(out[7]中)0~255
//(模擬值小於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
if((i<=0x40)||(out[3]==Up_L))
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);//上次的點滅掉
Point_L_y--;
if(Point_L_y<Point_L_r)Point_L_y=Point_L_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//(模擬值大於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
else if((i>=0xBF)||(out[3]==Down_L))
{
Fangxing(Point_L_x,Point_L_y,Point_L_r,0);//上次的點滅掉
Point_L_y++;
if(Point_L_y>(63-Point_L_r))Point_L_y=63-Point_L_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//右搖桿上下
i=PS2_AnologData(6);//讀取一次右搖桿上下的模擬值(out[6]中)0~255
//(模擬值小於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
if((i<=0x40)||(out[4]==Up_R))
{
if(!Point_R_ShowLine) Jiahao(Point_R_x,Point_R_y,Point_R_r,0);//上次的點滅掉
Point_R_y--;
if(Point_R_y<Point_R_r)Point_R_y=Point_R_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
//(模擬值大於自己定的值)|| (左按鍵(out[3]中)的值==PS2中規定的值)
//關於out,模擬值的定義在PS2.c中
else if((i>=0xBF)||(out[4]==Down_R))
{
if(!Point_R_ShowLine) Jiahao(Point_R_x,Point_R_y,Point_R_r,0);//上次的點滅掉
Point_R_y++;
if(Point_R_y>(63-Point_R_r)) Point_R_y=63-Point_R_r;
Fangxing(Point_L_x,Point_L_y,Point_L_r,1);//刷新點
if(Point_R_ShowLine)
Jiahao(Point_R_x,Point_R_y,0,1);//刷新點
else
Jiahao(Point_R_x,Point_R_y,Point_R_r,1);//刷新點
}
break;
}
case 2://彈一彈
if((B_list==1)||(mode!=mode_pre))//第一次進入當前模式
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
lie=4;//列表箭頭指向當前模式
i=TL0;//獲取當前定時器的值,作爲僞隨機數
Tantan_x=(u8)( i & 0x7f);//獲取定時器的後7位作爲圓的起始橫座標x
Tantan_y=(u8)( i & 0x3f);//獲取定時器的後6位作爲圓的起始縱座標y
Tantan_r=(u8)( i & 0x07);//獲取定時器的後3位作爲圓的半徑r
Tantan_dx=(u8)( i & 0x01);//獲得起始橫座標移動方向dx
Tantan_dy=(u8)( (i>>1) & 0x01);//獲得起始縱座標移動方向dy
if(!Tantan_dx)Tantan_dx=-1;//左方向-1
if(!Tantan_dy)Tantan_dy=-1;//上方向-1
if(Tantan_r==0) Tantan_r=1;//確保半徑最小爲1
if(Tantan_x<=Tantan_r) Tantan_x=Tantan_r+1;//防止初始圓被邊界錯位
else if(Tantan_x>=127-Tantan_r)Tantan_x=127-Tantan_r-1;//防止初始圓被邊界錯位
if(Tantan_y<=Tantan_r) Tantan_y=Tantan_r+1;//防止初始圓被邊界錯位
else if(Tantan_y>=63-Tantan_r)Tantan_y=63-Tantan_r-1;//防止初始圓被邊界錯位
LCD12864_Clear();//清屏
LCD12864_fill_GDRAM(0x00);//清除GDRAM
LCD12864_Circle(Tantan_x,Tantan_y,Tantan_r,1);//顯示初始圓
break;
}
else//第二次以及以後進入模式
{
LCD12864_Circle(Tantan_x,Tantan_y,Tantan_r,0);//清除上次的圓
if(Tantan_x<=Tantan_r) Tantan_dx=1;//碰到邊界座標移動方向變爲相反
else if(Tantan_x>=127-Tantan_r)Tantan_dx=-1;
if(Tantan_y<=Tantan_r) Tantan_dy=1;
else if(Tantan_y>=63-Tantan_r)Tantan_dy=-1;
Tantan_x+=Tantan_dx;//更新座標
Tantan_y+=Tantan_dy;
LCD12864_Circle(Tantan_x,Tantan_y,Tantan_r,1);//顯示當前圓
break;
}
case 3://俄羅斯方塊
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
lie=5;//列表箭頭指向當前模式
LCD12864_Clear();//清屏
LCD12864_fill_GDRAM(0x00);//清除GDRAM
LCD12864_Clear();//清屏
SysFlag=0;
KeyCode=0;
Score=0;
SysFlag^=1<<PAUSEFLAG;//開啓時暫停
Game_Init();//遊戲初始化
DrawBoard();//畫界面
break;
}
else
{
GamePlay();//遊戲進行
break;
}
case 4://動畫
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
picture_num=0;//第0張圖片
LCD12864_Clear();//清屏
DisplayImage(gImage1[picture_num]);//顯示第picture_num張圖片
break;
}
else
{
picture_num++;//更新當前圖片數
if(picture_num>=6)picture_num=0;//圖片數復位
DisplayImage(gImage1[picture_num]);//顯示第picture_num張圖片
break;
}
case 5://正弦,餘弦,中心水平垂直線、圓
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
LCD12864_Clear();//清屏
LCD12864_fill_GDRAM(0x00);//清除GDRAM
LCD12864_Circle(64,32,30,1);//畫圓
LCD12864_Verticalline(63,0,63,1);//畫垂線
LCD12864_Horizontalline(0,127,31,1);//畫水平線
LCD12864_fsin();//畫正弦波
LCD12864_fcos();//畫餘弦波
break;
}
else break;
case 6:
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
break;
}
else break;
case 7:
if((B_list==1)||(mode!=mode_pre))
{
B_list=0;//清除列表標誌位
mode_pre=mode;
cmode=mode;
break;
}
else break;
case 8: break;
case 9: break;
default:break;
}
}
短動畫和波形顯示代碼
這些代碼分別在上面Mode_Switch中的case 4,case 5中。
“完成啦!慶賀吧!!”
“其餘部分在這裏哦”