程序和硬件都嚴格按照手冊來做的,特別是加了二極管了,數(shù)碼管倒是點亮了(使用4位),但是使用4*4矩陣鍵盤的時候沒有無法識別,測試DOUT有數(shù)據(jù)讀過單片機,但是一按鍵,某個數(shù)碼管就滅一下,就沒有什么反應了.還有一個比較嚴重的問題是CH452工作一段時間之后就自己罷工了,要重新工作的話只有把程序燒進單片機才能夠重新開始,上電沒有辦法復位.我使用的是MEGA8+452的4線接線方式,RST獨自接了高電平,上電沒有任何反應!!有沒有遇到過這樣的問題的啊?很郁悶啊啊!!誰能幫幫我啊啊啊.謝謝啊. 程序如下: #include #include #include "CH452CMD.H" //CH452命令碼
#define CONTROL_PORT_452 PORTB #define CONTROL_DIR_452 DDRB #define CONTROL_DIR_452_OUT {CONTROL_DIR_452|=0X0E;} #define DCLK BIT(1) #define DIN BIT(2) #define LOAD BIT(3) #define DCLK_H() CONTROL_PORT_452|=BIT(1) //時鐘高電平 #define DCLK_L() CONTROL_PORT_452&=~BIT(1) //時鐘低電平 #define DIN_H() CONTROL_PORT_452|=BIT(2) //數(shù)據(jù)輸入高電平 #define DIN_L() CONTROL_PORT_452&=~BIT(2) //數(shù)據(jù)輸入低電平 #define LOAD_H() CONTROL_PORT_452|=BIT(3) //數(shù)據(jù)加載高電平 #define LOAD_L() CONTROL_PORT_452&=~BIT(3) //數(shù)據(jù)加載低電平 #define DOUT_DIR_IN() DDRD&=~BIT(2) #define DOUT_DIR_OUT() DDRD|=BIT(2) #define DOUT_state (PIND&0X04) #define DISABLE_KEY_INT() {GICR=0x00;} //屏蔽外中斷 #define ENABLE_KEY_INT() {MCUCR=0x02; GICR=0x40;} //允許外中斷
unsigned char keynum=0; //按鍵代碼值 unsigned char table1[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};//0-9對應BCD碼 unsigned char table2[]={0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89};//0.-9.帶小數(shù)點BCD unsigned char sleep_flag=1; //休眠標志位 unsigned int count=0;
/*********函數(shù)聲明*************/ void delay_1us(void); void delay_nus(unsigned int n); void delay_1ms(void); void delay_nms(unsigned int n); void clock_falling(void); void clock_rising(void); void Load_rising(void); void write_ch452(unsigned int data); unsigned char read_ch452(void); void ch452_init (void); void display_process(void); //void display_process(unsigned int count1); void LED_display (unsigned char dig,unsigned char data); /*******************************/
/************各延時函數(shù),晶振頻率:8MHZ****/ void delay_1us(void) //1us延時函數(shù) { asm("nop"); }
void delay_nus(unsigned int n) //N us延時函數(shù) { unsigned int i=0; for (i=0;i delay_1us(); } void delay_1ms(void) //1ms延時函數(shù) { unsigned int i; for (i=0;i<1140;i++); } void delay_nms(unsigned int n) //N ms延時函數(shù) { unsigned int i=0; for (i=0;i delay_1ms(); } /********************************************/ //*******DCLK可高達10MHZ*********************/
/*****************************************//* (1)CH452內(nèi)部為12位寄存器,存儲滿之后LOAD上升沿加載 (2)DCLK的一次上升沿送出1位數(shù)據(jù) /*******************************************/ void write_ch452(unsigned int data) {unsigned char m=0; // DISABLE_KEY_INT(); //禁止鍵盤中斷,防止傳輸過程中被CH452中斷 //而進入中斷服務程序中再次傳輸 LOAD_L(); //命令開始,LOAD置低 CONTROL_DIR_452_OUT; //端口設(shè)置為輸出 DOUT_DIR_IN(); // 數(shù)據(jù)輸入口設(shè)置為輸入 for(m=0;m<12;m++) //寫命令,命令都是12位 { DCLK_L(); if(data&(1< { DIN_H() ; delay_nus(1); } else {DIN_L(); delay_nus(1); } DCLK_H(); //一個時鐘上升沿寫一位數(shù)據(jù) } LOAD_H() ; //寫完之后LOAD的上升沿把移位寄存器中的數(shù)據(jù)送出 delay_nus(8); //ENABLE_KEY_INT(); //允許外中斷服務 }
/*****************************************//* (1)DOUT先輸出下降沿中斷 (2)然后LOAD的上升沿輸出7位按鍵代碼的最高位 (3)DCLK的下降沿DOUT依次輸出按鍵代碼的剩余6位 (4)7位輸出完畢后,無論DCLK如何變化,DOUT變?yōu)楦? /*******************************************/ //輸入按鍵代碼子程序,從CH452讀取按鍵代碼
unsigned char read_ch452(void) {unsigned char i=0,cmd=0,keycode=0; DISABLE_KEY_INT(); //禁止外中斷 DOUT_DIR_IN(); cmd=0x07; //讀取按鍵代碼的指令 LOAD_L(); for(i=0;i<4;i++) //發(fā)送讀取按鍵指令,低4位 {DCLK_L(); if(cmd&(1< else {DIN_L(); delay_nus(1);} DCLK_H(); //DCLK一個上升沿傳送一位數(shù)據(jù) } LOAD_H(); //寫完之后LOAD的上升沿把移位寄存器中的數(shù)據(jù)送出 keycode=0; for(i=0;i!=7;i++) {DCLK_H(); if(DOUT_state) {keycode|=(1< else {keycode&=~(1< delay_nus(2); DCLK_L(); //產(chǎn)生時鐘下升沿通知CH451輸出下一位 } ENABLE_KEY_INT(); //重新打開中斷 return(keycode); } #pragma interrupt_handler int0_read_ch452:2 void int0_read_ch452 (void) { CLI(); keynum=read_ch452(); if(keynum) {if(count<9999) {count++;} else {count=0;} keynum=0; } SEI(); } void LED_display (unsigned char dig,unsigned char data) { unsigned int dis_data=0; dis_data=dig; dis_data=(dis_data<<8); //12位命令,11-8位是DIG選擇(0x08-0x0f),bit7-bit0這八位是顯示的數(shù)據(jù)位 dis_data|=data; write_ch452(dis_data); //寫命令和數(shù)據(jù) } void display_process(void) {unsigned char temp1=0,temp2=0; // temp1=count/1000; LED_display (CH452_DIG0 ,table1[count]); //temp2=count%1000; //temp1=temp2/100; LED_display (CH452_DIG1 ,table1[count]); //temp2=((count%1000)%100)/10; LED_display (CH452_DIG2 ,table1[count]); // temp1=(((count%1000)%100)/10)%10; LED_display (CH452_DIG3 ,table1[count]); } void ch452_init(void) { CLI(); CONTROL_DIR_452_OUT; //PB1,PB2,PB3設(shè)置為輸出 CONTROL_PORT_452|=0X0E; //初始值設(shè)置為高 DOUT_DIR_IN(); PORTD|=0X04; //PD2(INT0)初始值設(shè)置為高 write_ch452(CH452_RESET); //CH452復位操作 write_ch452( CH452_SYSON2W); //開啟顯示 ,鍵盤,下降沿觸發(fā) write_ch452( CH452_4BCD ); //設(shè)置為BCD譯碼方式,4位掃描極限 MCUCR = 0x02; //下降沿觸發(fā) GICR = 0x40; //INT0中斷使能 SEI(); } void main(void) {ch452_init(); while(1) { display_process(); delay_nms(5); } }