51單片機 初學入門 24小時必答區(qū) STM32/8 ARM M3 AVR PIC MSP430 DSP Proteus仿真 Arduino 綜合區(qū)
單片機DIY制作 智能小車/機器人 智能家居 飛行器diy/多軸/航模 程序設(shè)計 資料共享
模擬數(shù)字 電子制作DIY 拆機樂園 PCB 電源 音響/功放 無線/紅外 儀器儀表 PLC Labview 業(yè)界動態(tài)
Protel Altium Designer Allegro orcad Pads/PowerPCB FPGA/CPLD Multisim仿真
Windows/CE 安卓 uCOS uCLinux
硬件制作資料從http://m.zg4o1577.cn/bbs/dpj-19358-1.html 下載 //課題:無線遙控自行車風火輪 //程序編寫:潘觀學 //單片機:STC89C54RD //晶振:12MHZ //單片機時鐘模式:6T #include<stc89.h> #include "fenghuolun.h" //定義在這里 /********************************* 延時函數(shù) ***********************************/ void delay_ms(unsigned int i)//1ms基準延時 { unsigned char j; while(i--) { for(j=0;j<246;j++) { ; } } } void delay_us(unsigned int n) //10us延時 { uchar i; uchar j; for(i=0;i<n;i++) //延時程序 for(j=0;j<2;j++); } /******************************* 呼吸燈 ********************************/ void huxi() { uint k=0,t,i,j; for(i=0;i<=350;i++) { if((i%4)==0) k++; for(t=0;t<=16;t++) { led=0; for(j=0;j<=52;j++) if(j==k) led=1; } if(enable==1)break; } for(i=0;i<=350;i++) { if((i%4)==0) k--; for(t=0;t<=16;t++) { led=0; for(j=0;j<=90;j++) //j越大速度越慢 if(j==k) led=1; } if(enable==1)break; } led=0xff; delay_ms(200); } /****************************** 閃爍函數(shù) *****************************/ void shan() { led=0; delay_ms(100); led=1; delay_ms(400); } void shan1() { led=0; delay_ms(100); led=1; delay_ms(100); led=0; delay_ms(100); led=1; delay_ms(300); } /********************************** 蜂鳴器函數(shù) ************************************/ void beep() { fmq=0; delay_ms(100); fmq=1; } /******************************* 畫面切換函數(shù) ********************************/ void huan() { uchar i; P1=0xff;//P1口設(shè)置為輸入狀態(tài) 先全部寫1 i=P1;//賦值給臨時存貯變量
i=i&0x0f;//和0x0f相與 屏蔽高四位,讀取無線遙控碼
if (i==0x04)//如果是0x04,則代表無線遙控器的按鍵A按下 { if(moshi==0) { modle0++;//下一個靜態(tài)畫面 if(modle0>9) modle0=0; } if(moshi==1) { modle1++;//下一個動態(tài)畫面 if(modle1>2) modle1=0; } beep(); //提示音 } if (i==0x01)//如果是0x01,則代表無線遙控器的按鍵B按下 { if(moshi==0) { modle0--;//上一個靜態(tài)畫面 if(modle0<0) modle0=9; } if(moshi==1) { modle1--;//上一個動態(tài)畫面 if(modle1<0) modle1=2; } beep(); //提示音 } if (i==0x08)//如果是0x08,則代表無線遙控器的按鍵C按下 { moshi=~moshi; beep(); //提示音 } if (i==0x02)//如果是0x02,則代表無線遙控器的按鍵D按下 { enable=~enable; beep(); } }
/******************* 靜態(tài)畫面顯示函數(shù) *******************/ void display(uchar n) { uint i;//0-255形成整個圓 uchar a=8;//發(fā)送循環(huán)次數(shù) uchar h1,h2,h3,h4;
for(i=0;i<256;i++) { h4=tab[n][i*4+3]; st_cp4=0; while(a--)//發(fā)送第4個8位 { ds4=h4&0x01; sh_cp4=0; h4=h4>>1; sh_cp4=1; } a=8;
h3=tab[n][i*4+2]; st_cp3=0; while(a--)//發(fā)送第3個8位 { ds3=h3&0x01; sh_cp3=0; h3=h3>>1; sh_cp3=1; } a=8;
h1=tab[n][i*4]; st_cp1=0; while(a--)//發(fā)送第1個8位 { ds1=h1&0x01; sh_cp1=0; h1=h1>>1; sh_cp1=1; } a=8; h2=tab[n][i*4+1]; st_cp2=0; while(a--)//發(fā)送第2個8位 { ds2=h2&0x01; sh_cp2=0; h2=h2>>1; sh_cp2=1; } a=8; st_cp1=1; st_cp2=1; st_cp3=1; st_cp4=1;
delay_us(time1); //每顯示一組產(chǎn)生一個延時 } }
/******************************** 動態(tài)畫面顯示函數(shù) *********************************/ /*******自動切換畫面*********/ void zidong() { if(z0>=20) //每顯示20次切換 { z0=0; z1++; } if(z1>9) z1=0; } /***********速度顯示函數(shù)*************/ void sudu() //速度越快,亮燈越多 { uint i;//0-255形成整個圓 uchar a=8;//發(fā)送循環(huán)次數(shù) uchar h1,h2,h3,h4; // l=30-((time/4)-1); //l等于0~31 if(time<=64) { if(time<=15) time=0; if(time>15&&time<=20) time=10; if(time>20&&time<=24) time=16; if(time>24&&time<=27) time=20; if(time>27&&time<=29) time=24; l=32-time/2; for(i=0;i<256;i++) { h4=tabd[l*4+3]; st_cp4=0; while(a--)//發(fā)送第4個8位 { ds4=h4&0x80; sh_cp4=0; h4=h4<<1; sh_cp4=1; } a=8; h3=tabd[l*4+2]; st_cp3=0; while(a--)//發(fā)送第3個8位 { ds3=h3&0x80; sh_cp3=0; h3=h3<<1; sh_cp3=1; } a=8; h1=tabd[l*4]; st_cp1=0; while(a--)//發(fā)送第1個8位 { ds1=h1&0x80; sh_cp1=0; h1=h1<<1; sh_cp1=1; } a=8; h2=tabd[l*4+1]; st_cp2=0; while(a--)//發(fā)送第2個8位 { ds2=h2&0x80; sh_cp2=0; h2=h2<<1; sh_cp2=1; } a=8; st_cp1=1; st_cp2=1; st_cp3=1; st_cp4=1; delay_us(time1+30); //每顯示一組產(chǎn)生一個延時 } } } /************開傘燈函數(shù)***************/ void kaisan() { uint i; uchar a=8;//發(fā)送循環(huán)次數(shù) uchar h1,h2,h3,h4; if((s-b)>0) { for(i=0;i<256;i++) { h4=tabd[s*4+3]; st_cp4=0; while(a--)//發(fā)送第4個8位 { ds4=h4&0x80; sh_cp4=0; h4=h4<<1; sh_cp4=1; } a=8; h3=tabd[s*4+2]; st_cp3=0; while(a--)//發(fā)送第3個8位 { ds3=h3&0x80; sh_cp3=0; h3=h3<<1; sh_cp3=1; } a=8; h1=tabd[s*4]; st_cp1=0; while(a--)//發(fā)送第1個8位 { ds1=h1&0x80; sh_cp1=0; h1=h1<<1; sh_cp1=1; } a=8; h2=tabd[s*4+1]; st_cp2=0; while(a--)//發(fā)送第2個8位 { ds2=h2&0x80; sh_cp2=0; h2=h2<<1; sh_cp2=1; } a=8; st_cp1=1; st_cp2=1; st_cp3=1; st_cp4=1; delay_us(time1+37); //每顯示一組產(chǎn)生一個延時 } }
b=s; }
/**************************** 初始化函數(shù) *****************************/ void init() { uchar a=8;//發(fā)送循環(huán)次數(shù) uchar h1,h2,h3,h4;
delay_ms(50); beep(); delay_ms(50); //測試蜂鳴器
led=0; delay_ms(100); led=1; delay_ms(100); //測試led
//測試排燈,亮 oe1=0; oe2=0; oe3=0; oe4=0; h4=0xFF; st_cp4=0; while(a--)//發(fā)送第4個8位 { ds4=h4&0x80; sh_cp4=0; h4=h4<<1; sh_cp4=1; } a=8; h3=0xFF; st_cp3=0; while(a--)//發(fā)送第3個8位 { ds3=h3&0x80; sh_cp3=0; h3=h3<<1; sh_cp3=1; } a=8; h1=0xFF; st_cp1=0; while(a--)//發(fā)送第1個8位 { ds1=h1&0x80; sh_cp1=0; h1=h1<<1; sh_cp1=1; } a=8; h2=0xFF; st_cp2=0; while(a--)//發(fā)送第2個8位 { ds2=h2&0x80; sh_cp2=0; h2=h2<<1; sh_cp2=1; } a=8; st_cp1=1; st_cp2=1; st_cp3=1; st_cp4=1;
delay_ms(100);
//測試排燈,滅 oe1=0; oe2=0; oe3=0; oe4=0; h4=0x00; st_cp4=0; while(a--)//發(fā)送第4個8位 { ds4=h4&0x80; sh_cp4=0; h4=h4<<1; sh_cp4=1; } a=8; h3=0x00; st_cp3=0; while(a--)//發(fā)送第3個8位 { ds3=h3&0x80; sh_cp3=0; h3=h3<<1; sh_cp3=1; } a=8; h1=0x00; st_cp1=0; while(a--)//發(fā)送第1個8位 { ds1=h1&0x80; sh_cp1=0; h1=h1<<1; sh_cp1=1; } a=8; h2=0x00; st_cp2=0; while(a--)//發(fā)送第2個8位 { ds2=h2&0x80; sh_cp2=0; h2=h2<<1; sh_cp2=1; } a=8; st_cp1=1; st_cp2=1; st_cp3=1; st_cp4=1;
delay_ms(50); }
/***************************** 主函數(shù) *****************************/ void main() { IP=0x05;//設(shè)定兩個外部中斷為你高優(yōu)先級 TMOD=0x01; //定時器T0工作在方式1 ET0=1; //允許定時器T0中斷 TH0=(65536-10000)/256; //定時器T0高八位賦初值 10ms TL0=(65536-10000)%256; //定時器T0低八位賦初
IT0=1;//P3.2下降沿觸發(fā) EX0=1;//開外部中斷0
IT1=1;//P3.3下降沿觸發(fā) EX1=1;//外部1
EA=1;//開總中斷
modle0=0; modle1=0;
t=0; time=0; man=1;//上電時為慢狀態(tài)
enable=1;//上電使能 moshi=1;//
s=0; b=0;
fmq=1;//等于1的時候關(guān)蜂鳴器 led=1;//等于1關(guān)閉led
init();//初始化
while(1) { if(enable==1)//使能有效 { /*********模式0*************/ if(moshi==0)//模式0下顯示靜態(tài)畫面 { if(time>=10&&time<=70&&t<=70) { //判斷速度如果小于10,則程序反應不過來 if(man==1) { man=0; beep(); } } if(time>70||t>70) { if(man==0) { man=1; beep(); } } if(man==0) { led=1; oe1=0; oe2=0; oe3=0; oe4=0; display(modle0);//速度正常則根據(jù)modle顯示靜態(tài)畫面 } if(man==1) { oe1=1; oe2=1; oe3=1; oe4=1; shan();//當速度太慢,關(guān)閉595,開LED閃爍 } } /*******模式1*************/ if(moshi==1)//模式1下顯示動態(tài)畫面 { /*判斷速度 如果小于10,則程序反應不過來*/ /*這個t小于等于70,可以避免突然剎車的時候,蜂鳴器響不停*/ if(time>=10&&time<=70&&t<=70) { if(man==1) { man=0; beep(); } } if(time>70||t>70||t==0) { oe1=1; oe2=1; oe3=1; oe4=1; shan1();//當速度太慢,關(guān)閉595,開LED閃爍1 if(man==0) { man=1; beep(); } } if(modle1==0&&man==0) { led=1; oe1=0; oe2=0; oe3=0; oe4=0; zidong();//自動切換畫面 display(z1); } if(modle1==1) { led=1; oe1=0; oe2=0; oe3=0; oe4=0; kaisan();//開傘效果 } if(modle1==2&&man==0) { led=1; oe1=0; oe2=0; oe3=0; oe4=0; sudu();//速度越快,亮燈越多 } } } if(enable==0) { oe1=1; oe2=1; oe3=1; oe4=1; huxi();//使能無效,關(guān)595,開LED呼吸 } } }
/********************************* 外部中斷O *********************************/ void intersvr0() interrupt 0 { huan();//畫面切換 TR0=0;//每切換畫面都從新開始運行 t=0; time=0; }
/********************************** 外部中斷1 **********************************/ void intersvr1() interrupt 2 { TR0=1;//開啟定時器T0中斷 time=t; if(t>=10) time1=(t*1000-9500)/256; /*轉(zhuǎn)換成10us,減掉程序執(zhí)行的95ms 再265等份*/ /*因為us延時函數(shù)最小單位是10us,所以轉(zhuǎn)換成10us為單位*/ t=1; s=s+y; if(s>=31||s==0) { y=y*(-1); } if(moshi==1&&modle1==0) z0++; }
/********************************* 定時器T0的中斷 **********************************/ void T0int() interrupt 1 { t++; if(t>127)//1.28s每圈,25寸輪子周長2.14m,速度是每小時6公里 t=127; TH0=(65536-20000)/256;//定時器T0高八位賦初值 10ms TL0=(65536-20000)%256;//定時器T0低八位賦初 }