|
|
/********************************************************************** * 文件名称: main.c * 程序作者: kidcao1987 * 程序版本: V1.0 * 功能描述: 按动16个按键,在数码管上显示“0~e” 这16个16进制的数字。 * 编译器:WinAVR-20090313 * 芯片:ATmega16,外部11.0592MHZ晶振 * 技术支持:http://bbs.cepark.com **********************************************************************/ #i nclude<avr/io.h> #i nclude<util/delay.h>
#define uint unsigned int #define uchar unsigned char
unsigned char const LedData[]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xF8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; unsigned char const LedPos[]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; uchar n,x,key;
void HC595send(uchar x); void init(void); void HC595shift(void); void HC595store(void); void display(uchar pos,uchar dat); uchar keyscan(void); void init(void);
int main(void) { init(); while(1) { display(n,keyscan()); } } void init(void) { DDRB=0xff; PORTB=0xff; } uchar keyscan(void) { uchar temp=0;
PORTA=0xef; DDRA=0xf0; //设置行线电平,注意先PORTx再DDRx temp=PINA; //读取列线电平 temp&=0x0f; //屏蔽行线电平 if(temp!=0x0f) //判断是否有按键按下 { _delay_ms(20); //有按键按下,延时消抖 temp=PINA; //消抖后再读列线电平 temp&=0x0f; //屏蔽行线电平 if(temp!=0x0f) //判断是否抖动 { temp=PINA; //确定不是抖动,读取列线 switch(temp) //根据列线电平给按键赋值 { case 0xee:key=0;break; case 0xed:key=1;break; case 0xeb:key=2;break; case 0xe7:key=3;break; } } while(temp!=0x0f) //松手检测 { temp=PINA; temp&=0x0f; } } //以下为第二到第四行扫描,只需要更改行线电平 PORTA=0xdf; DDRA=0xf0; temp=PINA; temp&=0x0f; if(temp!=0x0f) { _delay_ms(20); temp=PINA; temp&=0x0f; if(temp!=0x0f) { temp=PINA; switch(temp) { case 0xde:key=4;break; case 0xdd:key=5;break; case 0xdb:key=6;break; case 0xd7:key=7;break; } } while(temp!=0x0f) { temp=PINA; temp&=0x0f; } }
PORTA=0xbf; DDRA=0xf0; temp=PINA; temp&=0x0f; if(temp!=0x0f) { _delay_ms(20); temp=PINA; temp&=0x0f; if(temp!=0x0f) { temp=PINA; switch(temp) { case 0xbe:key=8;break; case 0xbd:key=9;break; case 0xbb:key=10;break; case 0xb7:key=11;break; } } while(temp!=0x0f) { temp=PINA; temp&=0x0f; } }
PORTA=0x7f; DDRA=0xf0; temp=PINA; temp&=0x0f; if(temp!=0x0f) { _delay_ms(20); temp=PINA; temp&=0x0f; if(temp!=0x0f) { temp=PINA; switch(temp) { case 0x7e:key=12;break; case 0x7d:key=13;break; case 0x7b:key--;break; case 0x77:key++;break; } } while(temp!=0x0f) { temp=PINA; temp&=0x0f; } } return key; } void HC595send(uchar x) { uchar n,temp; for(n=0;n<8;n++) { temp=x&0x80; if(temp!=0) { PORTB|=(1<<PB5); HC595shift(); } else { PORTB&=~(1<<PB5); HC595shift(); } x<<=1; } } void HC595store(void) { PORTB|=(1<<PB4); PORTB&=~(1<<PB4); } void HC595shift(void) { PORTB|=(1<<PB7); PORTB&=~(1<<PB7); } void display(uchar pos,uchar dat) { HC595send(LedPos[pos]); HC595send( LedData[dat]); HC595store(); }
视频地址:
|
|
| |
|