/********************************************************************* MCU: ATmega16 外部晶振: 8MHz 程序功能: 4*4鍵盤(pán)識(shí)別,LED七段數(shù)碼管顯示,密碼功能模塊,直流電機(jī)正反轉(zhuǎn)控制 AD轉(zhuǎn)換模塊, 模擬比較器,外部中斷應(yīng)用,12864液晶,C/T0 硬件設(shè)計(jì): 參考PROTUES硬件仿真電路 調(diào)試: 所有程序主要功能都軟硬件仿真通過(guò),實(shí)際使用時(shí)要根據(jù)需要加入可靠性。 編譯環(huán)境: ICC AVR Design by: wdw ********************************************************************/ #include<iom16v.h> #include<macros.h> #include<math.h> #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,//共陽(yáng)數(shù)據(jù); 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位密碼緩存; /******************************************************************** 名稱(chēng):ms延時(shí)子函數(shù) 功能:延時(shí)指定的ms *********************************************************************/ void delayms(int ms) { int i,j; for(i=ms;i>0;i--) { for(j=1722;j>0;j--); //8M時(shí)改為1141; } //12M時(shí)為1722; } /******************************************************************* 名稱(chēng):us延時(shí)子程序 功能:延時(shí)指定的us ********************************************************************/ void delayus(uchar us) { for(us;us<0;us--); { } //12M時(shí)單位T為1.45US } /******************************************************************** 單參數(shù)LED 顯示 硬件連接:數(shù)據(jù)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++) //顯示的位數(shù)為5 { curnum = tmpnum % 10; tmpnum = tmpnum / 10; PORTD = tmp; PORTC = date[curnum]; delayus(1); tmp = (tmp << 1) + 0x01; //補(bǔ)上移位造成的最右位為0; } } /******************************************************* 名稱(chēng):七段LED共陽(yáng)數(shù)碼管,在指定數(shù)位上顯示指定的數(shù),雙參數(shù) 功能:在指定的位置上顯示制定的數(shù); 硬件連接:PC口複用控制段選和位選,有2片573進(jìn)行數(shù)據(jù)鎖存; *******************************************************/ void show(uchar dat,uchar num) //六位七段數(shù)碼管顯示程序OK; { PORTC=date[dat]; PORTD|=BIT(0); PORTD&=~BIT(0); //送數(shù)據(jù); delayus(2); PORTC=0X00; delayus(1); PORTC=duan[num]; PORTD|=BIT(1); delayus(2); PORTD&=~BIT(1); delayus(2); } //送選通信號(hào); /************************************************************ 名稱(chēng):MCU端口初始化 功能:設(shè)置MCU端口初始方向?yàn)檩敵龀跏紶顟B(tài)為低 *************************************************************/ void Gpioinit0() { DDRA=0XFF; PORTA=0X00; DDRB=0XFF; PORTB=0X00; DDRC=0XFF; PORTC=0X00; DDRD=0XFF; PORTD=0X00; } /*********************************************************** 名稱(chēng):MCU端口初始化 功能:設(shè)置MCU端口初始為輸出初始狀態(tài)為高 ************************************************************/ void Gpioinit1() { DDRA=0Xff; PORTA=0XFF; DDRB=0xff; PORTB=0XFF; DDRC=0xff; PORTC=0XFF; DDRD=0xff; PORTD=0XFF; } /************************************************** 名稱(chēng):?jiǎn)味丝跍y(cè)試 輸入:測(cè)試PC的任意端口號(hào)0~7 功能:週期改變一個(gè)端口的電平 **************************************************/ void IOtest(uchar num) { DDRC|=BIT(num); // while(1) // { PORTC|=BIT(num); delayms(50); PORTC&=~BIT(num); delayms(50); // } } /************************************************* 名稱(chēng):按鍵動(dòng)作檢測(cè)子程序。 功能:檢測(cè)4*4鍵盤(pán)是否有鍵按下; 硬件連接:PB0~PB3為行;PB4~pb7為列; *************************************************/ uchar key_press() { uchar key; DDRB=0XFF; PORTB=0X0F; DDRB=0XF0; delayms(2); //此處要加上適當(dāng)延時(shí)否則讀不到端口信息; key=PINB; key&=0x0f; //按下返回1,否則為0; if(key==0x0f) { return 0; } else return 1; } /*************************************************** 名稱(chēng):4*4矩陣按鍵掃描子程序 功能:掃描一個(gè)4*4矩陣案件,比返回相應(yīng)按鍵值; 硬件連接:PB0~PB3為行;PB4~pb7為列; ***************************************************/ uchar keyscan() //4*4鍵盤(pán)掃面程序,調(diào)試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); //延時(shí)2毫秒,讀列狀態(tài); keycode=PINB; keycode&=0x0f; //讀列狀態(tài),屏蔽行狀態(tài); DDRB=0XFF; PORTB=0XF0; DDRB=0X0F; delayus(10); PINB&=0Xf0; //讀行狀態(tài),屏蔽列狀態(tài); 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; } /************************************************************ 名稱(chēng):六位密碼輸入比對(duì)程序 功能:輸入六位數(shù)並與存儲(chǔ)密碼比對(duì),0K返回1,按錯(cuò)或者順序錯(cuò)返回0; 原始密碼654321 **************************************************************/ uchar securtcom() //6位密碼輸入比對(duì)程序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) //初始比對(duì),密碼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; //密碼錯(cuò)誤,返回0; } uchar serset() //密碼設(shè)定子程序; { } uchar speci_keypress(uchar presstimes) //特殊按鍵F按下某一設(shè)定次數(shù)OK; { } uchar key_longpress(uchar prst) //按鍵長(zhǎng)按子程序 { } /************************************************** 名稱(chēng): 直流蜂鳴器控制 功能: 控制蜂鳴器鳴響時(shí)間 硬件連接:PD5輸出控制信號(hào) **************************************************/ void dcbeep(uchar beeptime) //直流蜂鳴器,調(diào)試OK; {uchar beep; DDRD|=BIT(5); PORTD&=~BIT(5); PORTD|=BIT(5); delayus(beeptime); PORTD&=~BIT(5); delayus(100-beeptime); } /********************************************************** 名稱(chēng):直流電機(jī)全橋控制 功能:fbw=1.正轉(zhuǎn);fbw=0,反轉(zhuǎn); 硬件連接:PD6與PD7口組合輸出控制信號(hào); **********************************************************/ void moto(uchar fbw) //直流電機(jī)正反轉(zhuǎn)程序,驅(qū)動(dòng)全橋; { 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); } } /********************************************************* 名稱(chēng): AD單次轉(zhuǎn)換子程序; 功能: 採(cǎi)樣AD通路0的電壓,該函數(shù)輸出為AD 轉(zhuǎn)換後的數(shù)據(jù), 查詢(xún)工作方式 *********************************************************/ void ad_init() { ADMUX=0XC0; //設(shè)置AD輸入通道為0通道,內(nèi)部2.56V參考電壓; ADCSRA=0X80; //使能ADC,清中斷標(biāo)誌ADIF,查詢(xún)方式; DDRA&=~BIT(0); //設(shè)置PA0口為輸入; PORTA&=~BIT(0); //PA0口清零; } int ad_conv() //單次轉(zhuǎn)換子程序,OK; { int addata; ADCSRA|=BIT(ADSC); //啟動(dòng)一次轉(zhuǎn)換; while(!(ADCSRA&(BIT(ADIF)))); //查詢(xún)等待轉(zhuǎn)換結(jié)束標(biāo)誌置位; ADCSRA&=~BIT(ADIF); addata=ADCL; addata=addata+ADCH*256; return addata; } int ad_aver() //轉(zhuǎn)換8次,做平均值濾波 { int adaver,count; for(count=7;count>0;count--) { adaver=ad_conv(); adaver+=adaver; delayms(1); } adaver=adaver/8; delayms(1); return adaver; } /********************************************************* 名稱(chēng):AD採(cǎi)樣 功能:採(cǎi)樣AD0的電壓,內(nèi)部2.56V參考電壓,中斷工作方式 **********************************************************/ void ad0_init() { ADMUX=0xc0; adchannel=0; ADCSRA=0x98; DDRA&=~BIT(0); PORTA&=~BIT(0); SEI(); } #pragma interrupt_handler process:15 //interrupt process program void process() { int adcode=0; ADCSRA&=~BIT(ADIE); adcode=ADCL; adcode=(ADCH<<8)+adcode; //get adc value /************************ 中斷處理函數(shù) *************************/ ADCSRA|=BIT(ADIE); } /******************************************************** 名稱(chēng):DAC0832 DA轉(zhuǎn)換 輸入:有效分度0~255 輸出:無(wú) 功能:對(duì)8為數(shù)字信號(hào)進(jìn)行DA轉(zhuǎn)換,實(shí)際應(yīng)用需調(diào)試 ********************************************************/ #define cs_low PORTD&=~BIT(0) #define cs_high PORTD|=BIT(0) #define wr1_low PORTD&=~BIT(1) #define wr1_high PORTD|=BIT(1) #define ile_high PORTD|=BIT(2) #define ile_low PORTD&=~BIT(2) #define wr2_low PORTD&=~BIT(3) #define wr2_high PORTD|=BIT(3) #define xfer_low PORTD&=~BIT(5) #define xfer_high PORTD|=BIT(5) void dac(int dadata) { Gpioinit1(); DDRD=0xff; DDRC=0xff; ile_high; //delayus(1); cs_low; wr1_low; //delayus(1); PORTC=dadata; //delayus(1); wr1_high; cs_high; // delayus(1); wr2_low; xfer_low; // delayus(1); xfer_high; } /***************************************************** 名稱(chēng): 數(shù)據(jù)拆分顯示函數(shù) 功能: 將四位數(shù)據(jù)分別顯示到對(duì)應(yīng)的數(shù)碼管。 *****************************************************/ void addisplay(int addat) //轉(zhuǎn)換數(shù)據(jù)顯示,運(yùn)算OK; { int a; a=addat; show(a/1000,3); delayms(2); show((a/100)%10,2); delayms(2); show(((a/10)%10)/10,1); delayms(2); show(a%10,0); delayms(2); } /********************************************************** 名稱(chēng):SPI通信 功能:應(yīng)用mega16自身SPI通信模塊與外設(shè)進(jìn)行通信.查詢(xún)方式; ***********************************************************/ void SPI_masterinit() { DDRB|=BIT(5)|BIT(7); //設(shè)置MOSI與SCK為輸出 DDRB&=~(BIT(4)&BIT(6)); //設(shè)置MISO與SS為輸入 SPCR|=BIT(4)|BIT(3)|BIT(1)|BIT(0); //數(shù)據(jù)高位先發(fā)送,主機(jī)模式,空閒時(shí)鐘極性 //為高,SCK起始沿採(cǎi)樣數(shù)據(jù),128分頻 SPCR|=BIT(6); //使能SPI delayms(1); } void SPI_mastertransdata(uchar data) { SPDR=data; while(!(SPSR&BIT(7))); } void SPI_slaveinit() { } void SPI_slaverecive() { } /********************************************************* 名稱(chēng):比較匹配模式,,中斷方式,調(diào)試OK 功能:AVR比較匹配模式應(yīng)用,當(dāng)AIN大於AIN1時(shí),上升沿產(chǎn)生中斷 **********************************************************/ void com_inti() { SEI(); //開(kāi)總中斷; DDRB&=((~BIT(2))&(~BIT(3))); //設(shè)置PB2/3口為輸入; SFIOR&=~BIT(3); //設(shè)置AIN1為模擬比較器反向輸入端; ACSR&=~BIT(7); //使能模擬比較器,注意此處為低電平有效; ACSR&=~BIT(6); //設(shè)置AIN0為正極輸入端; ACSR|=BIT(3); //使能模擬比較器中斷; ACSR|=(BIT(1)|BIT(0)); //比較器上升沿觸發(fā)中斷; } #pragma interrupt_handler comp:17 //注意函數(shù)名後不加(); void comp() //模擬比較器中斷服務(wù)程序; { ACSR&=~BIT(3); /************* 此處加中斷處理函數(shù) **************/ ACSR|=BIT(3); } /********************************************************** 名稱(chēng):外部中斷INT0 調(diào)試OK 功能:低電平觸發(fā)INT0端口引起中斷,並響應(yīng)相關(guān)中斷服務(wù)程序 **********************************************************/ void int0_init() { DDRD&=~BIT(2); //PD2/INT0端口配置為輸入; MCUCR&=((~BIT(0))&(~BIT(0))); //INT0觸發(fā)方式為低電平; GICR|=BIT(6); //使能外部中斷0; SEI(); //開(kāi)總中斷; } #pragma interrupt_handler int0:2 void int0() //INT0中斷服務(wù)函數(shù); { GICR&=~BIT(6); //關(guān)閉外部INT0; /************************ 此處加INT0中斷處理函數(shù) ************************/ GICR|=BIT(6); //開(kāi)啟外部INT0; } /********************************************************* 名稱(chēng):外部中斷INT1, 功能:邊沿觸發(fā)INT0端口引起中斷,並響應(yīng)相關(guān)中斷服務(wù)程序 **********************************************************/ void int1_init() { DDRD&=~BIT(3); //將PD3口配置為輸入; PORTD&=~BIT(3); //pd3口初始值為0; MCUCR|=(BIT(3)|BIT(2)); //INT1上升沿觸發(fā)中斷; GICR|=BIT(7); //使能INT1中斷; SEI(); //開(kāi)總中斷; } #pragma interrupt_handler int1:3 void int1() { GICR&=~BIT(7); //關(guān)閉INT1中斷; /******************************* 此處加INT1中斷服務(wù)函數(shù); *******************************/ GICR|=BIT(7); //開(kāi)啟INT1中斷; } /********************************************************** /********************************************************** 名稱(chēng):12864(ks0108)顯示應(yīng)用 功能:圖形液晶使用 **********************************************************/ #define EN_CLR PORTD&=~BIT(0) //使能12864 #define EN_SET PORTD|=BIT(0) //關(guān)閉12864 #define RW_READ PORTD|=BIT(1) //讀操作 #define RW_WRITE PORTD&=~BIT(1) //寫(xiě)操作 #define RS_COMM PORTD&=~BIT(2) //命令操作 #define RS_DATA PORTD|=BIT(2) //數(shù)據(jù)操作 #define RESET PORTD&=~BIT(3) //12864液晶複位 #define RESET_OVER PORTD|=BIT(3) //12864液晶結(jié)束複位; #define CS1_EN PORTD&=~BIT(4) //使能CS1,選擇左半屏幕; #define CS1_DIS PORTD|=BIT(4) //禁止CS1 #define CS2_EN PORTD&=~BIT(5) //使能CS2,選擇右半屏幕; #define CS2_DIS PORTD|=BIT(5) //禁止CS2 #define basic_com 0x30 //一次送8BIT數(shù)據(jù),基本指令集; #define explo_com 0xc4 //擴(kuò)展指令集 #define show_stitude 0x0f //顯示狀態(tài),整體顯示,游標(biāo)開(kāi),游標(biāo)位置開(kāi) #define cleanscreen 0x01 //顯示清零,AC歸零 #define cursor 0x07 //寫(xiě)入/讀取時(shí),游標(biāo)右移,畫(huà)面左移 #define AC_0 0x03 //AC歸0,不改變DDRAM內(nèi)容 const int char_0816[]={ 0xe0,0x18,0x04,0x04,0x04,0x18,0xe0,0x00, 0x07,0x18,0x20,0x20,0x20,0x18,0x07,0x00 }; /************************************************************ 名稱(chēng):MCU端口初始化 功能:設(shè)置MCU端口初始方向以及狀態(tài) *************************************************************/ void GPIO_INIT() { DDRA=0XFF; PORTA=0X00; DDRB=0XFF; PORTA=0X00; DDRC=0XFF; PORTA=0X00; DDRD=0XFF; PORTA=0X00; } /**************************************************************** 名稱(chēng):輸入數(shù)據(jù) 功能:MCU將數(shù)據(jù)送到總線 *****************************************************************/ void SET_DATA(uchar data) { delayus(3); PORTC=data; delayus(3); } /**************************************************************** 名稱(chēng):開(kāi)關(guān)顯示控制 功能:開(kāi)啟與關(guān)閉顯示操作,1為開(kāi)顯示,0為關(guān)閉顯示 *****************************************************************/ void LCD_Command_Displayonoff(uchar onoff) { RW_WRITE; RS_COMM; EN_CLR; SET_DATA(0x3e + onoff); //onoff為1開(kāi)顯示,為0關(guān)顯示; EN_SET; delayus(2); EN_CLR; } /*************************************************************** 名稱(chēng): LCD顯示起始行設(shè)定 功能:設(shè)置LCD顯示起始行位置,startline範(fàn)圍0~63 ***************************************************************/ void LCD_Command_setstartline(uchar startline) { RW_WRITE; RS_COMM; EN_CLR; SET_DATA(0Xc0 + startline); //12864行地址為0~63之間設(shè)定; EN_SET; delayus(2); EN_CLR; } /*************************************************************** 名稱(chēng):設(shè)置顯示行頁(yè)地址 功能:設(shè)置顯示行頁(yè)地址,12864為0~7 ****************************************************************/ void LCD_Command_set_x(uchar x) { RW_WRITE; RS_COMM; EN_CLR; SET_DATA(0xB8+x); //設(shè)置12864行頁(yè)地址 x範(fàn)圍0~7; EN_SET; delayus(2); EN_CLR; } /**************************************************************** 名稱(chēng):設(shè)置顯示列地址 功能:設(shè)置顯示列地址y,範(fàn)圍0~63; *****************************************************************/ void LCD_Command_set_y(uchar column) { RW_WRITE; RS_COMM; EN_CLR; SET_DATA(0x40+column); //設(shè)置顯示列地址y,範(fàn)圍0~63; EN_SET; delayus(2); EN_CLR; } /******************************************************************** 名稱(chēng):LCD顯示數(shù)據(jù)寫(xiě)入 功能:將顯示數(shù)據(jù)寫(xiě)入12864液晶 *********************************************************************/ void LCD_Command_writebyte(uchar data) { RW_WRITE; RS_DATA; EN_CLR; SET_DATA(data); EN_SET; delayus(2); EN_CLR; } /********************************************************************* 名稱(chēng):LCD複位操作 功能:複位LCD **********************************************************************/ void LCD_RESET() { RESET; NOP(); NOP(); NOP(); RESET_OVER; } /************************************************************ 名稱(chēng):清除指定範(fàn)圍函數(shù) 功能:清除LCD屏幕指定範(fàn)圍起始行~結(jié)束行的顯示內(nèi)容 ************************************************************/ void LCD_CLEAR_LINE(uchar startline,uchar endline) { uchar i,j; for(i-startline;i<=endline;i++) { CS1_EN; CS2_EN; LCD_Command_set_x(i); LCD_Command_set_y(0); //y地址每次操作後自動(dòng)加1; for(j=0;j<64;j++) { LCD_Command_writebyte(0x00); } } } /************************************************************* 名稱(chēng):顯示初始化 功能:初始化LCD *************************************************************/ void LCD_init() { LCD_RESET(); LCD_CLEAR_LINE(0,7); NOP(); LCD_Command_Displayonoff(1); NOP(); LCD_Command_setstartline(0); } /************************************************************** 名稱(chēng):LCD_WRITE_DATA 輸入:x in [0,7] and y in [0,127] 輸出:無(wú) 功能:在LCD指定行列寫(xiě)一個(gè)數(shù)據(jù) **************************************************************/ void LCD_write_data(uchar x,uchar y,uchar data) { if(y<64) { CS1_EN; CS2_DIS; LCD_Command_set_x(x); LCD_Command_set_y(y); } else { CS1_DIS; CS2_EN; LCD_Command_set_x(x); LCD_Command_set_y(y-64); } LCD_Command_writebyte(data); delayus(1); } /********************************************************* 名稱(chēng):LCD_WRITE_DOT 輸入:x in [0,63] and y in [0,127] 輸出:無(wú) 功能:在指定像素位置描點(diǎn),此函數(shù)為覆蓋式描點(diǎn),原位置一個(gè) 字節(jié)數(shù)據(jù)被覆蓋 *********************************************************/ void LCD_write_dot(uchar x,uchar y) { uchar x_address,y_address; uchar data=0; if((x<64)&&(y<128)) { x_address=x>>3; y_address=y; LCD_write_data(x_address,y_address,data|(1<<(x%8))); } } /********************************************************** 名稱(chēng):LCD_WRITE_CHAR 輸入:x in [0,3],y in [0,15], disp-顯示字符自模數(shù)組首地址 輸出:無(wú) 功能:在LCD指定顯示單元顯示一個(gè)字符,每個(gè)顯示單元默認(rèn)為8*16 點(diǎn)陣字體,對(duì)12864點(diǎn)陣LCD,x最多顯示4行,y最多顯示16個(gè)字 符。 ***********************************************************/ void LCD_write_char(uchar x,uchar y,const uchar *disp) { uchar i; uchar x_address; uchar y_address; if((x<4)&&(y<16)) { for(i=0;i<8;i++) { x_address=x<<1; y_address=(y<<3)+i; LCD_write_data(x_address,y_address,*disp++); } for(i=0;i<8;i++) { x_address=(x<<1)+1; y_address=(y<<3)+i; LCD_write_data(x_address,y_address,*disp++); } } } /*********************************************************** 名稱(chēng):LCD_write_word 輸入:x in [1,3],y in [1,14] disp-顯示字符字模組首地址 輸出:無(wú) 功能:在LCD指定顯示單元顯示一個(gè)中文字符,每個(gè)顯示單元默認(rèn)為 16*16點(diǎn)陣字體,對(duì)128*64點(diǎn)陣LCD,x最多顯示4行,y最多顯 示16個(gè)字符,不允許顯示半個(gè)漢字 ***********************************************************/ void LCD_write_word(int x,int y,const uchar *disp) { int i; int x_address; int y_address; if((x<4)&&(y<15)) { for(i=0;i<16;i++) { x_address=x<<1; y_address=(y<<3)+i; LCD_write_data(x_address,y_address,*disp++); } } for(i=0;i<16;i++) { x_address=(x<<1)+1; y_address=(y<<3)+i; LCD_write_data(x_address,y_address,*disp++); } } /************************************************************ 名稱(chēng):LCD_write_picture 輸入:x in [1,7] and y in [0,127],x1_length-縱向像素(8的整數(shù)倍), y1_length-橫向像素(不一定為8的整數(shù)倍) 輸出:無(wú) 功能:在指定區(qū)域顯示指定像素大小的圖片 ************************************************************/ void LCD_write_picture(int x1,int y1,int x_length,int y_length,const int *pdata) { int x_address; int y_address; for(x_address=x1;x_address<=x1+(x_length>>3)-1;x_address++) { for(y_address=y1;y_address<y1+y_length;y_address++) { LCD_write_data(x_address,y_address,*pdata); } } } /********************************************************** 名稱(chēng): busy 輸入:無(wú) 輸出:忙狀態(tài)返回1,空閒狀態(tài)返回0; 功能:判別LCD控制器內(nèi)部狀態(tài),忙時(shí)返回1,閑時(shí)返回0 **********************************************************/ uchar busy(void) { RS_COMM; RW_READ; if(BIT(7)==0) { return 0; } else return 1; } /*************************************************************** 名稱(chēng):12864測(cè)試 功能:逐點(diǎn)掃描 ****************************************************************/ void LCD_test() { uchar i,j; for(i=0;i<63;i++) { for(j=0;j<127;j++) { delayms(20); LCD_write_dot(i,j); delayms(100); } } } /************************************************************** 名稱(chēng):axis() 輸入:無(wú) 輸出:無(wú) 功能:標(biāo)定界面坐標(biāo) ***************************************************************/ void axis() { uchar a,b,y,x; for(a=0;a<63;a++) //y軸坐標(biāo)及分位點(diǎn); { LCD_write_data(a,29,0x01); } for(b=0;b<127;b+=5) //x軸坐標(biāo)及分位點(diǎn); { LCD_write_data(30,b,0x04); } } /********************************************************** /******************************************************** 名稱(chēng):定時(shí)器0初始化 輸入: 輸出: 描述:普通方式,中斷工作方式,注意中斷響應(yīng)程序中要重裝初值 *********************************************************/ void timer0_init() { SFIOR|=BIT(0); //復(fù)位預(yù)定比例分頻器; TCCR0|=(BIT(2)|BIT(0)); //設(shè)定分頻器為1024分頻; //TCCR0|=BIT(0); //設(shè)定分頻器為無(wú)分頻; TCNT0=255; //裝訂計(jì)數(shù)初值 TIMSK|=BIT(0); //開(kāi)啟T/C0中斷; SEI(); //開(kāi)總中斷; DDRC|=BIT(0); PORTC|=BIT(0); } /************************************************************ 中斷處理函數(shù) ************************************************************/ #pragma interrupt_handler time0_proc:10 void time0_proc() { TIMSK&=~BIT(0); //關(guān)閉中斷; TCNT0=255; //重新裝訂計(jì)數(shù)初值; PORTC^=BIT(0); TIMSK|=BIT(0); //開(kāi)啟T0中斷 } /************************************************************* 名稱(chēng):6位數(shù)碼管按鍵位移顯示 輸入:無(wú) 輸出:無(wú) 描述:按鍵輸入時(shí)在LED上移位顯示按鍵值,當(dāng)按下f時(shí),全部清零。 **************************************************************/ void keymovedis() { uchar keyval1,keyval2,presstimes; while(1) { if(keyscan()==15) //F的鍵值為15; { for(presstimes=0;presstimes<5;presstimes++) { dispbuf[presstimes]=date[0]; show(0,presstimes); } } else { for(presstimes=0;presstimes<5;presstimes++) { dispbuf[5-presstimes]=dispbuf[4-presstimes]; dispbuf[0]=keyscan(); show(dispbuf[presstimes],presstimes); } } } } /********************************************************* 主函數(shù)main().c,地球人都知道,不必廢話 **********************************************************/ void main() { while(1) { } }