基于atmega48的扫描按键例子

仿真图:其中左边的的温度传感器等AD转换与本例子无关
在这里插入图片描述

#include “iom48v.h”
#include “macros.h”
#define uchar unsigned char
#define uint unsigned int
#define KEY_Press keycode!=0x00

#pragma interrupt_handler T1_refresh: 12

void delay(uint a)
{
while(a–);
}

const uchar disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xA7,0xA1,0x86,0x8E};

uchar segcode[4]={0XFF,0XFF,0XFF,0XFF}; //段码 (存放译码值)
uchar data[4]; //显示数据
uchar keycode; //判断按键位置
uchar n=0; //显示刷新标志
uchar key=0; //键值 PINB!=0X0F
uchar digit=0;

/IO口初始化函数/
void IO_Init(void)
{
DDRB = 0xF0;
PORTB = 0x0F; //上拉
DDRC = 0xFF;
PORTC = 0xFF;
DDRD = 0xFF;
PORTD = 0xFF;
}

/定时器T1初始化/
void T1_Init(void)
{
TCCR1A = 0x00; //CTC
TCCR1B = 0x0B; // 64分频
OCR1A = 78; // 5ms
TIFR1 = 0x02;
TIMSK1 = 0X02; //开中断
}

/定时器T1中断服务—数据刷新/
void T1_refresh(void)
{
n=(++n)%4;
//PORTC |=0X0F; //关闭位选(必须)
PORTC =0X0F;
PORTD = segcode[n]; //传送数据位
switch(n)
{
case 0: PORTC = ~0x01; //显示千位
break;
case 1: PORTC = ~0x02;
break; //显示百位
case 2: PORTC = ~0x04;
break; //显示十位
case 3: PORTC = ~0x08;
break; //显示个位

default:  break;    

}
TIFR1 = 0X02; //清标志
}

/译码函数/
void decode(uchar *num)
{
if(digit1)
{
segcode[3]=disp[num[3]];
}
else if(digit
2)
{
segcode[3]=disp[num[3]];
segcode[2]=disp[num[2]];
}
else if(digit==3)
{
segcode[3]=disp[num[3]];
segcode[2]=disp[num[2]];
segcode[1]=disp[num[1]];
}
else if(digit>3)
{
segcode[3]=disp[num[3]]; //个位
segcode[2]=disp[num[2]]; //十位
segcode[1]=disp[num[1]]; //百位
segcode[0]=disp[num[0]]; //千位
}
else
;

// segcode[0] &= ~0x80; // 加小数点
}

/输入移位函数/
void Digit_Move(uchar *b)
{
uchar i,j;
for(i=0;i<3;i++)
{
b[i]=b[i+1];
}
b[3]=key;

}

/按键扫描及数据处理/
void KEY_Scan(void)
{
//keycode = (~PINB)&0X0F; //记录按键在第几行
PORTB = ~0X10; //扫描第一列
delay(10);
keycode = (~PINB)&0X0F;
while(PINB!=~0X10); //等待按键释放(消抖)

  //delay(20000);
  switch(keycode)          //读取键值
  {
  case 0X01: key=0; Digit_Move(data); digit++;decode(data);break;
  case 0X02: key=1; Digit_Move(data); digit++;decode(data);break;
  case 0X04: key=2; Digit_Move(data); digit++;decode(data);break;
  case 0X08: key=3; Digit_Move(data); digit++;decode(data);break;
  default:break;
  }
  
  PORTB = ~0X20;delay(10);
 keycode = (~PINB) & 0X0F;
  while(PINB!=~0X20);
   
//delay(20000);
  switch(keycode)
  { 
  case 0X01: key=4; Digit_Move(data); digit++;decode(data);break;
  case 0X02: key=5; Digit_Move(data); digit++;decode(data);break;
  case 0X04: key=6; Digit_Move(data); digit++;decode(data);break;
  case 0X08: key=7; Digit_Move(data); digit++;decode(data);break;
  default:break;
  }


  PORTB = ~0X40;delay(10);
  keycode = (~PINB) & 0X0F;
  while(PINB!=~0X40);
  
//delay(20000);
  switch(keycode)
  {
  case 0X01: key=8; Digit_Move(data); digit++;decode(data);break;
  case 0X02: key=9; Digit_Move(data); digit++;decode(data);break;
  case 0X04: key=10;Digit_Move(data); digit++;decode(data);break;
  case 0X08: key=11;Digit_Move(data); digit++;decode(data);break;
  default:break;
  }


  PORTB = ~0X80;delay(10);
  keycode = (~PINB) & 0X0F;
  while(PINB!=~0X80);
  
 //delay(20000);
  switch(keycode)
  {
  case 0X01: key=12;Digit_Move(data); digit++;decode(data);break;
  case 0X02: key=13;Digit_Move(data); digit++;decode(data);break;
  case 0X04: key=14;Digit_Move(data); digit++;decode(data);break;
  case 0X08: key=15;Digit_Move(data); digit++;decode(data);break;
  default:break;
  }

}

/主函数/
void main(void)
{
CLI();
IO_Init();
T1_Init() ;
SEI();
while(1)
{
PORTB = 0X0F;
keycode = (~PINB)&0X0F;

if(KEY_Press)       //检测按键是否按下
{
  KEY_Scan();
}
delay(30000);

}
}

/void delay(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<1141;j++);
}
}
/

猜你喜欢

转载自blog.csdn.net/kcsdnming/article/details/88776650
48