程序和硬件都严格按照手册来做的,特别是加了二极管了,数码管倒是点亮了(使用4位),但是使用4*4矩阵键盘的时候没有无法识别,测试DOUT有数据读过单片机,但是一按键,某个数码管就灭一下,就没有什么反应了.还有一个比较严重的问题是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) //数据输入高电平 #define DIN_L() CONTROL_PORT_452&=~BIT(2) //数据输入低电平 #define LOAD_H() CONTROL_PORT_452|=BIT(3) //数据加载高电平 #define LOAD_L() CONTROL_PORT_452&=~BIT(3) //数据加载低电平 #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.带小数点BCD unsigned char sleep_flag=1; //休眠标志位 unsigned int count=0;
/*********函数声明*************/ 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); /*******************************/
/************各延时函数,晶振频率:8MHZ****/ void delay_1us(void) //1us延时函数 { asm("nop"); }
void delay_nus(unsigned int n) //N us延时函数 { unsigned int i=0; for (i=0;i delay_1us(); } void delay_1ms(void) //1ms延时函数 { unsigned int i; for (i=0;i<1140;i++); } void delay_nms(unsigned int n) //N ms延时函数 { unsigned int i=0; for (i=0;i delay_1ms(); } /********************************************/ //*******DCLK可高达10MHZ*********************/
/*****************************************//* (1)CH452内部为12位寄存器,存储满之后LOAD上升沿加载 (2)DCLK的一次上升沿送出1位数据 /*******************************************/ void write_ch452(unsigned int data) {unsigned char m=0; // DISABLE_KEY_INT(); //禁止键盘中断,防止传输过程中被CH452中断 //而进入中断服务程序中再次传输 LOAD_L(); //命令开始,LOAD置低 CONTROL_DIR_452_OUT; //端口设置为输出 DOUT_DIR_IN(); // 数据输入口设置为输入 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(); //一个时钟上升沿写一位数据 } LOAD_H() ; //写完之后LOAD的上升沿把移位寄存器中的数据送出 delay_nus(8); //ENABLE_KEY_INT(); //允许外中断服务 }
/*****************************************//* (1)DOUT先输出下降沿中断 (2)然后LOAD的上升沿输出7位按键代码的最高位 (3)DCLK的下降沿DOUT依次输出按键代码的剩余6位 (4)7位输出完毕后,无论DCLK如何变化,DOUT变为高 /*******************************************/ //输入按键代码子程序,从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++) //发送读取按键指令,低4位 {DCLK_L(); if(cmd&(1< else {DIN_L(); delay_nus(1);} DCLK_H(); //DCLK一个上升沿传送一位数据 } LOAD_H(); //写完之后LOAD的上升沿把移位寄存器中的数据送出 keycode=0; for(i=0;i!=7;i++) {DCLK_H(); if(DOUT_state) {keycode|=(1< else {keycode&=~(1< delay_nus(2); DCLK_L(); //产生时钟下升沿通知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这八位是显示的数据位 dis_data|=data; write_ch452(dis_data); //写命令和数据 } 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设置为输出 CONTROL_PORT_452|=0X0E; //初始值设置为高 DOUT_DIR_IN(); PORTD|=0X04; //PD2(INT0)初始值设置为高 write_ch452(CH452_RESET); //CH452复位操作 write_ch452( CH452_SYSON2W); //开启显示 ,键盘,下降沿触发 write_ch452( CH452_4BCD ); //设置为BCD译码方式,4位扫描极限 MCUCR = 0x02; //下降沿触发 GICR = 0x40; //INT0中断使能 SEI(); } void main(void) {ch452_init(); while(1) { display_process(); delay_nms(5); } }