第一部分 設計內容和要求1.1設計內容 利用keil、Proteus和C51單片機設計出快棋賽電子計時器 1.2 設計要求 1. 八個數碼管分為兩組,每組四個數碼管動態顯示對應方的定時時間,以及倒計過程,包括分鐘(2位,00~99)、秒(2位,00~59) 2. 相互控制啟停開關(2個) 3. 總暫停開關(用于雙方選手同時休息) 4. 各自初始時間設置(選手同意情況下可以設置不同的初始時間),即可以對相應的分鐘及秒分別進行初始設置 5. 任何一方的選手如果時間倒計為零,則報警并在其四個數碼管上閃爍顯示“LOSE” 1.3系統運行流程 程序首先進行初始化,在主程序的循環中,首先調用數據處理函數,將分和秒數值拆開儲存在顯示緩沖區中(即一個數組中),然后按鍵掃描函數,判斷是否有按鍵按下;若有,則執行相應程序,若沒有;則往下功能指示燈led函數。若功能按鍵按下,則亮相應的led;若無,則繼續往下執警告函數。若有時間快耗完了,則執行相應程序;若無,則繼續往下結束函數,若時間耗完了,則執行相應程序;若無,執行循環。這里,我用了定時器0和定時器1,定時器0用來計時間,定時器1用做動態顯示。 第二部分 設計方案

程序流程
主程序流程圖 按鍵掃描子程序 檢測是否有按鍵按下,若無返回主程序; 若K1按下,若計時開始且功能按鍵記錄次數為0,則是控制時間作用:紅色時間暫停,藍色時間開始;若計時暫停且功能按鍵記錄次數不為0,則是調節時間作用:根據功能按鍵次數,增加對應數值 若K2按下,若計時開始且功能按鍵記錄次數為0,則是控制時間作用:藍色時間暫停,紅色時間開始;若計時暫停且功能按鍵記錄次數不為0,則是調節時間作用:根據功能按鍵次數,減少對應數值 若K3按下,全部時間暫停或者開啟;(一開始時,時間都是暫停的,只有當K3按下時,紅色方先開始計時) 若K4按下,記錄按下次數;(作為功能按鍵,讓K1和K2調整紅色分和秒數值以及藍色分秒數值) (注:當程序開始計時時或比賽結束時,K4按鍵無效)
功能指示燈程序(附加功能) 共有4個led作為指示燈,根據功能按鍵按下次數,亮不同的led,作為指示燈,告知使用者,你正在調整的是哪個數值。
警告子程序(附加功能) 若有一方的時間少于十秒了,則代表他的兩個led就會閃爍,作為提示。
結束子程序 當一方的時間耗完了,則他的數碼管會閃爍“lose”,另一方閃爍顯示“win”(附加功能),并且4個led也會一起閃爍(附加功能)。
定時器0 我用做秒計時,每當秒計時到了,根據判斷,減少紅色時間或減少藍色時間。
定時器1 我用做數碼管的動態顯示;這樣能消除按鍵帶來的顯示影響。 第三部分 Proteus電路圖
第四部分 keil編譯結果和Proteus仿真結果Keil編譯結果 Proteus仿真結果 編譯和仿真都能通過沒有問題。 第五部分 單片機仿真第六部分 附加功能在第二部分設計方案中,我已用紅色字體標注出,這里不再贅述了。
第八部分設計心得及體會
本次課程設計中,特別是在程序編寫過程中,遇到了很多的問題。但這是對我的考驗一定要充滿耐心,遇到問題,就去尋找解決問題的辦法。我設計過程中還不斷提出自己的疑點以及新的想法,聯系實際應用,將課本上學習的東西運用到實際中,這些都令我受益匪淺。最終得以完成這次單片機課程設計,非常感謝老師教導。
第七部分 代碼及注釋- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar DispBuf[8]; //顯示緩沖區
- uchar DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,
- 0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF}; //LED字形碼
- uchar BitTab[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; //LED位驅動碼
- uchar redlose[]={0xC1,0xC1, 0xF9,0xC8,0xC7,0xC0,0x92,0x84};//紅色時間到LED字形碼
- uchar bluelose[]={0xC7,0xC0,0x92,0x84,0xC1,0xC1,0xF9,0xC8};//藍色時間到LED字形碼
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit L1=P3^0;
- sbit L2=P3^1;
- sbit L3=P3^2;
- sbit L4=P3^3;
- uint num,flag1=1,flag2,flag3=1;,k4num;
- uchar miao1=00,fen1=30,miao2=00,fen2=30;
- void Timer1(void) interrupt 1{
- TH0=(65536-50000)/256;//重裝數值
- TL0=(65536-50000)%256;
- num++;
- if(num==20)//如果到了20次,說明一秒時間到
- {
- num=0;//清零,重新計數20次
- if(flag1==1)//紅方時間減少
- {
- miao1--;//秒時間減少
- if(miao1==-1){//說明一分鐘到了,重新減少一分鐘,并且分鐘減一
- miao1=59;
- fen1--;
- }
- }
- if(flag1==0)//藍方時間減少
- {
- miao2--;
- if(miao2==-1){
- miao2=59;
- fen2--;
- }
-
- }
- }
- }
- void Timer2(void) interrupt 3{
- uchar tmp;
- uchar Count;
- TH1=(65536-3000)/256;//重裝數值
- TL1=(65536-3000)%256;
-
- P2=BitTab[Count]; //取位值
- tmp=DispBuf[Count]; //取出待顯示的數
- tmp=DispTab[tmp]; //取字形碼
- P0=tmp;
- Count++;
- if(Count==8)
- Count=0;
-
-
- }
- void delay(uint xms)//延時函數
- {
- uint i,j;
- for(i=xms;i>0;i--)
-
- for(j=110;j>0;j--);
- }
-
- void keyscan(void)//按鍵函數
- {
- if(k1==0)//按鍵按下
- {
- delay(5);
- if(k1==0)//確認按鍵按下
- {
-
- while(!k1);//等待按鍵釋放
- if(k4num==0&&TR0==1)//當計時開始,并且功能鍵記錄次數為零時,作用為控制時間
- {
- if(flag1==1)//紅色時間暫停,藍色時間開始
- flag1=0;
- }
- if(k4num!=0&&TR0==0)//當計時暫停,并且功能鍵記錄次數不為零,作用為調節時間
- {
- switch(k4num)//根據功能鍵次數,增加相應數值
- {
- case 1: miao1++;
- if(miao1==60)
- miao1=0;
- break;
- case 2: fen1++;
- if(fen1==100)
- fen1=0;
- break;
- case 3: miao2++;
- if(miao2==60)
- miao2=0;
- break;
- case 4: fen2++;
- if(fen2==100)
- fen2=0;
- break;
- }
- }
- }
- }
- if(k2==0){
- delay(5);
- if(k2==0){
-
- while(!k2);
- if(k4num==0&&TR0==1)//
- {
- if(flag1==0)//藍色時間暫停,紅色時間開始
- flag1=1;
- }
- if(k4num!=0&&TR0==0)//根據功能鍵次數,增加相應數值
- {
- switch(k4num)
- {
- case 1: miao1--;
- if(miao1==-1)
- miao1=59;
- break;
- case 2: fen1--;
- if(fen1==-1)
- fen1=99;
- break;
- case 3: miao2--;
- if(miao2==-1)
- miao2=59;
- break;
- case 4: fen2--;
- if(fen2==-1)
- fen2=99;
- break;
- }
- }
- }
-
- }
- if(k3==0)//總暫停開關
- {
- delay(5);
- if(k3==1){
- while(!k3);
- TR0=~TR0;//控制時間暫停或是開始
- k4num=0;//功能按鍵記錄次數清零
- flag3=0;//清零標志
- }
- }
- if(k4==0)//功能按鍵
- {
- delay(5);
- if(k4==0){
- if(TR0==0)//當計時暫停時,這個按鍵才有效
- {
- flag3=1;//做標志,防止在調節時間時,調到零的時候,就進入子程序last()
- k4num++;//記錄功能按鍵按下次數
- }
- if(k4num==5||TR0==1||flag2==1)//當帶五次按下或開始計時或某一方時間耗完,清零記錄次數
- {
- k4num=0;
-
- }
- while(!k4);
- }
- }
-
-
- }
- void last()//某一方時間耗完,分別顯示lose和win
- {
- uint i,j;
- if(miao1==0&&fen1==0&&flag3==0)//紅方時間先耗完
- {
- TR0=0;//關閉計時
- TR1=0;//關閉時間顯示
- flag2=1;//標志比賽結束
- for(i=80;i>0;i--)//動態顯示 lose和win 80次
- {
- for(j=0;j<8;j++){
- P2=BitTab[j];//送入位選
- P0=redlose[j];//送入lose和win的字形碼
- delay(2);
- P0=0xFF;
- }
- L1=~L1;//led不斷閃爍
- L2=~L2;
- L3=~L3;
- L4=~L4;
- }
- P0=0XFF;//關閉顯示300ms
- P2=0X00;
- delay(300);
- }
- if(miao2==0&&fen2==0&&flag3==0)//藍色方時間耗完
- {
- TR0=0;
- TR1=0;
- flag2=1;
- for(i=70;i>0;i--){
- for(j=0;j<8;j++){
- P2=BitTab[j];
- P0=bluelose[j];
- delay(3);
- P0=0xFF;
- }
- L1=~L1;
- L2=~L2;
- L3=~L3;
- L4=~L4;
- }
- P0=0XFF;
- P2=0X00;
- delay(100);
- }
- }
- void led()//功能按鍵對應的指示led燈亮或滅
- {
- switch(k4num){
- case 0: P3=0xFF;
- break;
- case 1: P3=0xF7;
- break;
- case 2: P3=0xFB;
- break;
- case 3: P3=0xFD;
- break;
- case 4: P3=0xFE;
- break;
- }
-
-
- }
- void warn(){
- if(fen1==0&&miao1<10&&TR0==1&&flag1==1)//當紅色時間少于十秒的時候,閃爍led燈提示
- {
- L3=~L3;
- L4=~L4;
- }
- if(fen2==0&&miao2<10&&TR0==1&&flag1==0)//當紅色時間少于十秒的時候,閃爍led燈提示
- {
- L1=~L1;
- L2=~L2;
- }
-
- }
-
- void zixing(){
- DispBuf[0]=fen2/10;
- DispBuf[1]=fen2%10;
- DispBuf[2]=miao2/10;
- DispBuf[3]=miao2%10;
- DispBuf[4]=fen1/10;
- DispBuf[5]=fen1%10;
- DispBuf[6]=miao1/10;
- DispBuf[7]=miao1%10;
-
- }
- void main(){
- TMOD=0X11;//設置T0定時方式一和T1定時方式一
- TH0=(65536-50000)/256;//裝入初值,計時一秒
- TL0=(65536-50000)%256;
- TH1=(65536-3000)/256; //裝入初值,計時30us
- TL1=(65536-3000)%256;
- EA=1;//打開總中斷
- ET0=1;//打開定時器0中斷
- ET1=1;//打開定時器1中斷
- TR0=0;//暫停定時器0
- TR1=1;//開啟定時器1
- while(1){
- zixing();//將分和秒數值拆開,存入顯示緩沖區,等待顯示
- keyscan();//按鍵函數
- led();//功能指示led
- warn();//當時間少于十秒時,警告函數
- last();//比賽結束,顯示lose和win 函數
- }
- }
復制代碼 完整的Word格式文檔51黑下載地址:
龐智仁2016160111.doc
(695 KB, 下載次數: 23)
2018-7-10 15:12 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|