ATmega16计算器
单片机源程序如下:
- /**********************************************************************/
- /**计数器按键**
-
- (1) (2) (3) (4)
- (5) (6) (7) (8)
- (9) (0) (C) (=)
- (+) (-) (*) (/)
-
- 10:清零 11:确认 12:加 13:减 14:乘 15:除
-
- **********************************************************************/
- //头文件
- #include <iom16v.h> //包含型号头文件
- #include <macros.h> //包含"位"操作头文件
- //宏定义
- #define uchar unsigned char
- #define uint unsigned int
- //定义按键返回值
- unsigned char keyvalue;
- //定义数码管段码(共阳)
- uchar LED[]=
- {
- 0xC0,0xF9,0xA4,0xB0,
- 0x99,0x92,0x82,0xF8,
- 0x80,0x90
- };
- //定义数码管位的控制端
- uchar tab[]={0,0,0,0};
- //IO端口初始化
- void IO_init(void)
- {
- DDRA = 0XFF;
- DDRB = 0XFF;
- DDRC = 0XFF;
- DDRD = 0XF0;
- PORTA = 0X00;
- PORTB = 0X00;
- PORTC = 0X08;
- //PORTD = 0XFF;
- }
- //8M晶振下,延时1ms
- void delayms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=1333;y>0;y--);
- }
- //数码管显示
- void display(uint num)
- {
- tab[0]=num%10; //取个位数
- tab[1]=num/10%10; //取十位数
- tab[2]=num/100%10; //取百位数
- tab[3]=num/1000%10; //取千位数
-
- if(num<=9)//检测为小于等于9的在个位数显示
- {
- PORTA=LED[tab[0]];
- PORTC=0x08;
- delayms(1);
- }
- if(num>9&&num<=99)//检测为大于9与小于等于99在个十位显示
- {
- PORTA=LED[tab[0]];
- PORTC=0x08;
- delayms(1);
- PORTA=LED[tab[1]];
- PORTC=0x04;
- delayms(1);
- }
- if(num>99&&num<=999)//检测为大于99与小于等于999在个十百位显示
- {
- PORTA=LED[tab[0]];
- PORTC=0x08;
- delayms(1);
- PORTA=LED[tab[1]];
- PORTC=0x04;
- delayms(1);
- PORTA=LED[tab[2]];
- PORTC=0x02;
- delayms(1);
- }
- if(num>999&&num<=9999)//检测为大于999与小于等于9999在个十百千位显示
- {
- PORTA=LED[tab[0]];
- PORTC=0x08;
- delayms(1);
- PORTA=LED[tab[1]];
- PORTC=0x04;
- delayms(1);
- PORTA=LED[tab[2]];
- PORTC=0x02;
- delayms(1);
- PORTA=LED[tab[3]];
- PORTC=0x01;
- delayms(1);
- }
- }
- //按键扫描
- int key_scan(void)
- {
- uint j;//按键循环次数变量定义
- PORTD=0xEF;// PD端口输出 1111 1110
- for(j=0;j<5;j++)//按键检测4次
- if((PIND&0x0F)!=0x0F)//按键检测
- {
- delayms(20);//延时消抖
- if((PIND&0x0F)!=0x0F)//再次检测
- {
- if((PIND&0x01)==0) //第一个按键按下
- keyvalue=1; //返回按键值 1
- if((PIND&0x02)==0) //第二个按键按下
- keyvalue=2; //返回按键值 2
- if((PIND&0x04)==0) //第三个按键按下
- keyvalue=3; //返回按键值 3
- if((PIND&0x08)==0) //第四个按键按下
- keyvalue=4; //返回按键值 4
- while((PIND&0x0F)!=0x0F);//等待按键释放
- }
- }
- PORTD=0xDF;
- for(j=0;j<5;j++)
- if((PIND&0x0F)!=0x0F)
- {
- delayms(20);
- if((PIND&0x0F)!=0x0F)
- {
- if((PIND&0x01)==0)
- keyvalue=5;
- if((PIND&0x02)==0)
- keyvalue=6;
- if((PIND&0x04)==0)
- keyvalue=7;
- if((PIND&0x08)==0)
- keyvalue=8;
- while((PIND&0x0F)!=0x0F);
- }
- }
- PORTD=0xBF;
- for(j=0;j<5;j++)
- if((PIND&0x0F)!=0x0F)
- {
- delayms(20);
- if((PIND&0x0F)!=0x0F)
- {
- if((PIND&0x01)==0)
- keyvalue=9;
- if((PIND&0x02)==0)
- keyvalue=0;
- if((PIND&0x04)==0)
- keyvalue=10;
- if((PIND&0x08)==0)
- keyvalue=11;
- while((PIND&0x0F)!=0x0F);
- }
- }
- PORTD=0x7F;
- for(j=0;j<5;j++)
- if((PIND&0x0F)!=0x0F)
- {
- delayms(20);
- if((PIND&0x0F)!=0x0F)
- {
- if((PIND&0x01)==0)
- keyvalue=12;
- if((PIND&0x02)==0)
- keyvalue=13;
- if((PIND&0x04)==0)
- keyvalue=14;
- if((PIND&0x08)==0)
- keyvalue=15;
- while((PIND&0x0F)!=0x0F);
- }
- }
- }
- /*
- //两种按键扫描都可以选择
- //按键扫描
- uint key_scan(void)
- {
- unsigned char X,Y,Z;
- DDRD=0xF0;
- PORTD=0x0F;
- if(PIND!=0x0F) //判断是否有键按下
- {
- delayms(5); //延时,软件去干扰
- if(PIND!=0x0F) //确认按键按下
- {
- X=PIND|0xF0;
- delayms(5);
- DDRD=0x0F;
- PORTD=0xF0;
- if(PIND!=0xF0) //判断是否有键按下
- {
- delayms(5); //延时,软件去干扰
- if(PIND!=0xf0) //确认按键按下
- {
- Y=PIND|0x0F;
- Z=X&Y; //取出键值
- switch ( Z ) //判断键值(那一个键按下)
- {
- //对键值赋值
- case 0b11101110: keyvalue= 1; break;//数字1键
- case 0b11101101: keyvalue= 2; break;//数字2键
- case 0b11101011: keyvalue= 3; break;//数字3键
- case 0b11100111: keyvalue= 4; break;//数字4键
- case 0b11011110: keyvalue= 5; break;//数字5键
- case 0b11011101: keyvalue= 6; break;//数字6键
- case 0b11011011: keyvalue= 7; break;//数字7键
- case 0b11010111: keyvalue= 8; break;//数字8键
- case 0b10111110: keyvalue= 9; break;//数字9键
- case 0b10111101: keyvalue= 0; break;//数字0键
- case 0b10111011: keyvalue=10; break;//删除键
- case 0b10110111: keyvalue=11; break;//ok键
- case 0b01111110: keyvalue=12; break;//加键
- case 0b01111101: keyvalue=13; break;//减键
- case 0b01111011: keyvalue=14; break;//乘键
- case 0b01110111: keyvalue=15; break;//除键
- default:break;
- }
- while(PIND!=0xf0); //等待按键释放
- }
- }
- }
- }
- } */
- void main(void)
- {
- uint num=0;//按键值
- uint shu=0,shu1=0,shu2=0,flag=0,jieguo,fuhao;//数值定义
- IO_init();//IO端口初始化
- while(1)
- {
- /*键盘值赋给num,如果小于9,说明是数值,假如先按的数值键为2,
- 第一次用到shu1的值为0,则shu1=shu1*10+num(0*10+2=2),
- 如果再按下第二个数值键,假设按下的数值键为3,
- 则shu1=shu1*10+num(2*10+2=23),这样就能按下的数值显示出来。
- */
- keyvalue=20;//按键初值
- key_scan();//按键扫描
- num=keyvalue;//按键值赋给num
- if(num<=9&&flag==0)//按键0~9
- {
- shu1=shu1*10+num; //计算第一个数
- shu=shu1;
- }
- /*flag是标志位,作用就是第一次按下数值键赋值后,再按下功能键后,
- flag=1,当再按下数值键,就运行下面程序。
- */
- if(num>=0&&num<=9&&flag==1)//按键0~9
- {
- shu2=shu2*10+num;//计算第二个数
- shu=shu2;
- }
- /*使得数码管把第二次的数值shu2显示出来*/
- if(num>=12&&num<=15)//按键12~15 显示运算符号
- {
- fuhao=num;
- flag=1;
- }
- /*这程序表示按下功能键后,把功能键值赋给fuhao这个数,
- 同时把fuaho置1,为下次按下数值键作准备。
- */
- if(num==11)//计算数值确认
- {
- flag=0;
- switch(fuhao)
- {
- case 12:jieguo=shu1+shu2;break;
- case 13:jieguo=shu1-shu2;break;
- case 14:jieguo=shu1*shu2;break;
- case 15:jieguo=shu1/shu2;break;
- default:break;
- }
- shu=jieguo;//计算结果送到shu显示,把shu1和shu2数清零。
- shu1=0;
- shu2=0;
- }
- if(num==10)//计算结果清零
- {
- num=0;
- jieguo=0;
- shu=0;
- shu1=0;
- shu2=0;
- flag=0;
- fuhao=0;
- }
- display(shu);//计算结果显示
- }
- }
复制代码
所有资料51hei提供下载:
ATmega16计算器.zip
(36.21 KB, 下载次数: 94)
|