/********************************************************************* MCU: ATmega16 外部晶振: 8MHz 程序功能: 4*4鍵盤識別,LED七段數碼管顯示,密碼功能模塊,直流電機正反轉控制 AD轉換模塊, 模擬比較器,外部中斷應用,12864液晶,C/T0 硬件設計: 參考PROTUES硬件仿真電路 調試: 所有程序主要功能都軟硬件仿真通過,實際使用時要根據需要加入可靠性。 編譯環境: ICC AVR Design by: wdw ********************************************************************/#include#include #include #define uchar unsigned char#define uint unsigned int#define SET_1(a,b) a|=bit(b) //將寄存器a的第b位置1#define CLR_0(a,b) a&=~bit(b) //將寄存器a的第b位清0#program date code: const date[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,//共陽數據; 0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};#program duan code: const duan[]={0x20,0x10,0x08,0x04,0x02,0x01}; //段選;char adchannel; int dispbuf[]={0,0,0,0,0,0,}; //顯示緩存;uchar securbuf[]={0,0,0,0,0,}; //5位密碼緩存;/********************************************************************名稱:ms延時子函數功能:延時指定的ms*********************************************************************/void delayms(int ms) { int i,j; for(i=ms;i>0;i--) { for(j=1722;j>0;j--); //8M时改为1141; } //12M时为1722; }/*******************************************************************名稱:us延時子程序功能:延時指定的us********************************************************************/void delayus(uchar us) { for(us;us<0;us--); { } //12M时单位T为1.45US } /********************************************************************单参数LED 显示硬件连接:数据PORTC-----D7~D0 段选PORTD-----D7~D4*********************************************************************/ void LEDShow(long int shownum){ uchar i,tmp,curnum; long int tmpnum; tmp = 0xfb; tmpnum = shownum; for(i=0;i<6;i++) //显示的位数为5 { curnum = tmpnum % 10; tmpnum = tmpnum / 10; PORTD = tmp; PORTC = date[curnum]; delayus(1); tmp = (tmp << 1) + 0x01; //补上移位造成的最右位为0; }}/*******************************************************名稱:七段LED共陽數碼管,在指定数位上显示指定的数,双参数功能:在指定的位置上顯示制定的數;硬件連接:PC口複用控制段選和位選,有2片573進行數據鎖存;*******************************************************/ void show(uchar dat,uchar num) //六位七段數碼管顯示程序OK; { PORTC=date[dat]; PORTD|=BIT(0); PORTD&=~BIT(0); //送數據; delayus(2); PORTC=0X00; delayus(1); PORTC=duan[num]; PORTD|=BIT(1); delayus(2); PORTD&=~BIT(1); delayus(2); } //送選通信號;/************************************************************名稱:MCU端口初始化功能:設置MCU端口初始方向為輸出初始狀態為低*************************************************************/void Gpioinit0() { DDRA=0XFF; PORTA=0X00; DDRB=0XFF; PORTB=0X00; DDRC=0XFF; PORTC=0X00; DDRD=0XFF; PORTD=0X00; }/***********************************************************名稱:MCU端口初始化功能:設置MCU端口初始為輸出初始狀態為高 ************************************************************/void Gpioinit1() { DDRA=0Xff; PORTA=0XFF; DDRB=0xff; PORTB=0XFF; DDRC=0xff; PORTC=0XFF; DDRD=0xff; PORTD=0XFF; } /**************************************************名稱:單端口測試輸入:測試PC的任意端口號0~7功能:週期改變一個端口的電平**************************************************/ void IOtest(uchar num) { DDRC|=BIT(num); // while(1) // { PORTC|=BIT(num); delayms(50); PORTC&=~BIT(num); delayms(50); // } }/*************************************************名稱:按鍵動作檢測子程序。功能:檢測4*4鍵盤是否有鍵按下;硬件連接:PB0~PB3為行;PB4~pb7為列;*************************************************/ uchar key_press() { uchar key; DDRB=0XFF; PORTB=0X0F; DDRB=0XF0; delayms(2); //此處要加上適當延時否則讀不到端口信息; key=PINB; key&=0x0f; //按下返回1,否則為0; if(key==0x0f) { return 0; } else return 1; }/*************************************************** 名稱:4*4矩陣按鍵掃描子程序 功能:掃描一個4*4矩陣案件,比返回相應按鍵值; 硬件連接:PB0~PB3為行;PB4~pb7為列;***************************************************/ uchar keyscan() //4*4鍵盤掃面程序,調試0K; { uchar keycode,keynum; do{ }while(key_press()==0); //按鍵是否按下? asm("nop"); asm("nop"); while(key_press()==1) { DDRB=0XFF; //PB0~PB3為列,PB4~PB7為行; PORTB=0X0F; //列輸出高電平,行輸出低電平; DDRB=0XF0; delayus(10); //延時2毫秒,讀列狀態; keycode=PINB; keycode&=0x0f; //讀列狀態,屏蔽行狀態; DDRB=0XFF; PORTB=0XF0; DDRB=0X0F; delayus(10); PINB&=0Xf0; //讀行狀態,屏蔽列狀態; keycode|=PINB; delayus(10); do{ }while(key_press()==1); //按鍵是否釋放; switch(keycode) { case 0xee: keynum=0; break; case 0xde: keynum=1; break; case 0xbe: keynum=2; break; case 0x7e: keynum=3; break; case 0xed: keynum=4; break; case 0xdd: keynum=5; break; case 0xbd: keynum=6; break; case 0x7d: keynum=7; break; case 0xeb: keynum=8; break; case 0xdb: keynum=9; break; case 0xbb: keynum=10; break; case 0x7b: keynum=11; break; case 0xe7: keynum=12; break; case 0xd7: keynum=13; break; case 0xb7: keynum=14; break; case 0x77: keynum=15; break; default : keynum=16; break; } } return keynum; } /************************************************************ 名稱:六位密碼輸入比對程序 功能:輸入六位數並與存儲密碼比對,0K返回1,按錯或者順序錯返回0; 原始密碼654321**************************************************************/ uchar securtcom() //6位密碼輸入比對程序0K; { uchar keycount=0; while(key_press()==1); delayms(3); do{ while(key_press()==1); delayms(1); while(key_press()==0); show(8,keycount); securbuf[keycount++]=keyscan(); }while(keycount<6); if(securbuf[0]==6) //初始比對,密碼654321; { if(securbuf[1]==5) { if(securbuf[2]==4) { if(securbuf[3]==3) { if(securbuf[4]==2) { if(securbuf[5]==1); } } } } return 1; //密碼正確,返回1; } else return 0; //密碼錯誤,返回0; } uchar serset() //密碼設定子程序; { }uchar speci_keypress(uchar presstimes) //特殊按鍵F按下某一設定次數OK; { } uchar key_longpress(uchar prst) //按鍵長按子程序 { } /**************************************************名稱: 直流蜂鳴器控制 功能: 控制蜂鳴器鳴響時間硬件連接:PD5輸出控制信號**************************************************/ void dcbeep(uchar beeptime) //直流蜂鳴器,調試OK; {uchar beep; DDRD|=BIT(5); PORTD&=~BIT(5); PORTD|=BIT(5); delayus(beeptime); PORTD&=~BIT(5); delayus(100-beeptime); }/**********************************************************名稱:直流電機全橋控制功能:fbw=1.正轉;fbw=0,反轉;硬件連接:PD6與PD7口組合輸出控制信號;**********************************************************/ void moto(uchar fbw) //直流電機正反轉程序,驅動全橋; { DDRD|=BIT(6); DDRD|=BIT(7); PORTD&=~BIT(6); PORTD&=~BIT(7); delayms(5); if(fbw==1) { PORTD|=BIT(6); delayms(500); PORTD&=~BIT(6); delayms(20); } else { } if(fbw==0) { PORTD|=BIT(7); delayms(500); PORTD&=~BIT(7); delayms(20); } }/********************************************************* 名稱: AD單次轉換子程序;
Atmega16单片机实用程序
时间:2024-05-12 06:07:10