可控跑馬燈仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include<regx51.h> //加入頭文件
- #define uchar unsigned char //宏定義用uchar來代替unsigned char
- #define uint unsigned int //宏定義用uint來代替unsined int
- uint code unm[]={0,1,3,5,7,9,15,60,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500};
- //用于調速的數組
- uchar unm1[]={0xff,0xef,0xc7,0xab,0xef,0xef,0xef,0xff};
- //用于顯示箭頭的數組
- uchar m,n,j,y; //定義全局變量
- uint l,g;
- //==========延時子程序============
- void delay(uint i)
- {
- uchar j; //定義局部變量
- while(i--) //循環執行空指令用于延時
- for(j=0;j<120;j++);
- }
- //===========定時器初始化子程序===================
- void init()
- {
- TMOD = 0x11; //設置定時器0、1都工作在方式1
- TH0 = 0x00; //設置定時器0初值
- TL0 = 0x00;
- TH1 = 0xaa; //設置定時器1初值
- TL1 = 0xbb;
- EA = 1; //打開總中斷
- ET0 = 1; //打開定時器0中斷
- ET1 = 1; //打開定時器1中斷
- TR0 = 1; //啟動定時器0
- TR1 = 1; //啟動定時器1
- }
- //=================================================
- //函數名:ce_anjian ( )
- //功能:檢測是否有按鍵按下,并返回是否有按鍵按下
- //輸出參數:key
- //說明:有按鍵按下,key=1;無鍵按下,key=0;
- //=================================================
- bit ce_anjian ( )
- {
- bit key=0; //定義局部變量
- P1=0xf3; //輸出掃描信號,將行置高電平,將列置低電平
- if(P1!=0xf3) //讀入P1口數據,與掃描信號比較判斷是否有鍵按下
- key=1; //如果有鍵按下,key賦值為1
- else
- key=0; //如果沒有鍵按下,key賦值為0
- return(key); //返回key值
- }
- //=================================================
- //函數名:ce_jianzhi ( )
- //功能:測按鍵值并去除按鍵按下和按鍵松開時的抖動
- //調用函數:doudong_ys();ce_anjian();
- //說明:鍵值y=i*2+j+1;
- //=================================================
- void ce_jianzhi ( )
- {
- uchar i,j,p; //定義局部變量
- do
- {
- while(ce_anjian()==0); //是否有按鍵按下?若按鍵沒有按下,原地等待
- //若按鍵按下,則返回值為1,則繼續往下執行
- delay(50); //調用去抖延時子程序
- }while(ce_anjian()==0); //再次判斷是否有鍵按下?若沒有按下,返回0
- for(i=0;i<2;i++)
- {
- P1=(0xfe<<i)|i; //循環掃描輸出行掃描信號
- for(j=0;j<2;j++)
- {
- p=P1&0x0c; //讀取并保留鍵盤的列數據,其余清0
- if(p==0x08>>j) //是否有1或2列按鍵按下?
- {
- y=i*2+j+1; //計算鍵值
- goto D1; //跳出循環,使程序跳轉至D1
- }
- }
- }
- D1: delay(50); //調用去抖延時子程序
- do
- {
- while(ce_anjian()==1); //判斷按鍵是否釋放,若按鍵沒有釋放,繼續判斷
- //若按鍵有釋放,返回值為0,則繼續往下執行
- delay(50); //調用去抖延時子程序
- }while(ce_anjian()==1); //再次判斷是否釋放,若按鍵沒有釋放,繼續判斷
- }
- //=======蜂鳴器鳴叫子程序==========
- void mingjiao()
- {
- uchar t; //定義局部變量
- for(t=0;t<50;t++)
- {
- P1_7=0;
- }
- P1_7=1; //停止鳴叫
- }
- //============主程序===============
- void main()
- {
- init(); //調用定時器初始化子程序
- n=5; //單片機一上電,速度設置在第5擋
- while(1) //主程序無限循環執行
- {
- l=unm[n]; //設置定時器的設定值
- if(ce_anjian()==1) //快速判斷是否有按鍵按下
- {
- ce_jianzhi(); //若有按鍵按下,則側鍵值
- switch(y)
- {
- case 1: {m=1;j=0x7f;mingjiao();}break; //鍵值為1,則P2口賦值0xfe,點亮P2.0LED
- case 2: {m=2;j=0xfe;mingjiao();}break; //鍵值為2,則P2口賦值0xfd,點亮P2.1LED
- case 3: {n=n+1;if(n==24)n=23;mingjiao();}break;//鍵值為3,則P2口賦值0xfb,點亮P2.2LED
- case 4: {n=n-1;if(n==0)n=1;mingjiao();}break; //鍵值為4,則P2口賦值0xf7,點亮P2.3LED
- default: break;
- }
- }
- }
- }
- //=========定時器1中斷子程序=======
- void t_1()interrupt 3
- {
- uchar a,k; //定義局部變量
- TH1 = 0xaa; //設置定時器初值
- TL1 = 0xbb;
- switch(m) //判斷模式
- {
- case 1: //模式1
- {
- a=0x01; //顯示左移箭頭
- for(k=0;k<8;k++)
- {
- P2=a;
- P3=unm1[k];
- delay(2);
- a=a<<1;
- if(a==0)a=0x01;
- P0=j;
- }
- }break;
- case 2: //模式2
- {
- a=0x80; //顯示右移箭頭
- for(k=0;k<8;k++)
- {
- P2=a;
- P3=unm1[k];
- delay(2);
- a=a>>1;
- if(a==0)a=0x80;
- P0=j; //跑馬燈右移
- }
- }
- }
- }
- //=======定時器0中斷子程序=========
- void t_0()interrupt 1
- {
- uchar b1,b2,b3,b4,b5,b6,b7,b8; //定義局部變量
- if(++g<l) return; //如果g+1小于設定值l那么跳出中斷
- g=0; //如果g+1大于設定值l則g清零
- switch(m)
- {
- case 1:{ j=(j>>1)|0x80;
- if(j==0xff)j=0x7f;}break;
- case 2:{ j=(j<<1)|0x01;
- if(j==0xff)j=0xfe;}break;
- }
- b1=unm1[0]; //箭頭移動
- b2=unm1[1];
- b3=unm1[2];
- b4=unm1[3];
- b5=unm1[4];
- b6=unm1[5];
- b7=unm1[6];
- b8=unm1[7];
- unm1[0]=b2;
- unm1[1]=b3;
- unm1[2]=b4;
- unm1[3]=b5;
- unm1[4]=b6;
- unm1[5]=b7;
- unm1[6]=b8;
- unm1[7]=b1;
- }
復制代碼
所有資料51hei提供下載:
項目1.zip
(76.45 KB, 下載次數: 25)
2020-3-8 00:01 上傳
點擊文件名下載附件
|