矩阵键盘mega16 c语言程序,Mega16按键与数码显示程序

#include #define No_key 255

#define K1_11

#define K1_22

#define K1_33

#define K1_4 4

#define K2_15

#define K2_26

#define K2_37

#define K2_4 8

#define K3_19

#define K3_20

#define K3_310

#define K3_4 11

#define K4_112

#define K4_213

#define K4_314

#define K4_4 15

#define Key_mask0b00001111

#define data PORTB.0

#define clk PORTB.1

flash unsigned char led[16]={0x28,0xeb,0x19,0x89,0xca,0x8c,0x0c,0xe9,0x08,0x88,

0xdf,0x4a,0x1c,0x3e,0x7e,0x2a};

unsigned charkey_stime_counter;

unsigned char key_temp;

bitkey_stime_ok;

//D0接键盘,低4位列线输入,高4位行线输出

unsigned char read_keyboard()

{

static unsigned char key_state = 0, key_value, key_line;

unsigned char key_return = No_key,i;

switch (key_state)

{

case 0:

key_line = 0b00010000;

for (i=1; i<=4; i++)// 扫描键盘

{

PORTA = ~key_line;// 输出行线电平

PORTA = ~key_line;// 必须送2次!!!

key_value = Key_mask & PINA;// 读列电平

if (key_value == Key_mask)

key_line <<= 1;// 没有按键,继续扫描

else

{

key_state++;// 有按键,停止扫描

break;// 转消抖确认状态

}

}

break;

case 1:

if (key_value == (Key_mask & PINA))// 再次读列电平,

{

switch (key_line | key_value)// 与状态0的相同,确认按键

{// 键盘编码,返回编码值

case 0b00011110:

key_return = K1_1;

break;

case 0b00011101:

key_return = K1_2;

break;

case 0b00011011:

key_return = K1_3;

break;

case 0b00010111:

key_return = K1_4;

break;

case 0b00101110:

key_return = K2_1;

break;

case 0b00101101:

key_return = K2_2;

break;

case 0b00101011:

key_return = K2_3;

break;

case 0b00100111:

key_return = K2_4;

break;

case 0b01001110:

key_return = K3_1;

break;

case 0b01001101:

key_return = K3_2;

break;

case 0b01001011:

key_return = K3_3;

break;

case 0b01000111:

key_return = K3_4;

break;

case 0b10001110:

key_return = K4_1;

break;

case 0b10001101:

key_return = K4_2;

break;

case 0b10001011:

key_return = K4_3;

break;

case 0b10000111:

key_return = K4_4;

break;

}

key_state++;// 转入等待按键释放状态

}

else

{

key_state--;

delay_ms(5);

}// 两次列电平不同返回状态0,(消抖处理)

break;

case 2:// 等待按键释放状态

PORTA = 0b00001111;// 行线全部输出低电平

PORTA = 0b00001111;// 重复送一次

if ( (Key_mask & PINA) == Key_mask)

key_state=0;// 列线全部为高电平返回状态0

break;

}

return key_return;

}

//向数码管送入数据

void sendbyte(unsigned char byte)

{

unsigned char num,c;

num=led[byte];

for(c=0;c<8;c++)

{

clk=0;

data=num&0x01;

clk=1;

num>>=1;

}

}

void display(void)

{

if (key_stime_ok)

{

key_stime_ok = 0;// 10ms到

key_temp = read_keyboard();// 调用键盘接口函数读键盘

if (key_temp != No_key)

{// 有按键按下

sendbyte(key_temp);

delay_ms(10);

}

}

}

void main(void)

{

DDRB = 0xFF;

//PORTC = 0xFF;// 键盘接口初始化

DDRA = 0xF0;// PD2、PD1、PD0列线,输入方式,上拉有效

// T/C0 初始化

TCCR0=0x0B;// 内部时钟,64分频(4M/64=62.5KHz),CTC模式

TCNT0=0x00;

OCR0=0x7C;// OCR0 = 0x7C(124),(124+1)/62.5=2ms

TIMSK=0x02;// 允许T/C0比较匹配中断

#asm("sei")// 开放全局中断

while (1)

{

display();

}

}

// Timer 0 比较匹配中断服务,2ms定时

interrupt [TIM0_COMP] void timer0_comp_isr(void)

{

//display();// 调用LED扫描显示

if (++key_stime_counter >=5)

{

key_stime_counter = 0;

key_stime_ok = 1;// 10ms到

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include #include #define uchar unsigned char #define uint unsigned int void main() { DDRA=0X00; DDRB=0XFF; DDRD|=0X30; TCCR1A=0x91; //8修正PWM 8000000/(64*2*256)=244.14hz TCCR1B=0x03; //clk/64 OCR1A=250; //初值占空比100% while(1) { if(PINA==0xe7)//加速前进4、5灯 { OCR1A=202;//占空比100% turn();//居中 } if(PINA==0xcf)//速度稍减前进5、6灯 { OCR1A=202;//占空比90% turnL();//左转-15度 } if(PINA==0x9f)//速度再减前进6、7灯 { OCR1A=176;//占空比80% turnLL();//左转-30度 } if(PINA==0x3f)//速度减前进7、8灯 { OCR1A=176;//占空比70% turnLLL();//左转-45度 } if(PINA==0X7f)//速度稍减前进8灯 { OCR1A=176;//占空比70% turnLLL();//右转45度 } if(PINA==0xf3)//速度稍减前进3、4灯 { OCR1A=202;//占空比90% turnR();//右转15度 } if(PINA==0Xf9)//速度再减前进2、3灯 { OCR1A=176;//占空比80% turnRR();//右转30度 } if(PINA==0Xfc)//速度稍减前进1、2灯 { OCR1A=176;//占空比70% turnRRR();//右转45度 } if(PINA==0Xfe)//速度稍减前进1灯 { OCR1A=176;//占空比70% turnRRR();//右转45度 } } } /*-45度*/ void turnLLL() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(4); } } /*-30度*/ void turnLL() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(6); } } /*-15度*/ void turnL() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(8); } } /*0度居中*/ void turn()//居中 { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(10); } } /*15度*/ void turnR() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(12); } } /*30度*/ void turnRR() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(14); } } /*45度*/ void turnRRR() { uchar i; DDRB=0XFF; PORTB=0XFF; for(i=0;i<30;i++) { PORTB&=~BIT(0); delay(18); PORTB|=BIT(0); delay(17); } } /*定时0.1MS*/ void delay(uint z) { uint i,j; for(i=0;i<z;i++) for(j=0;j<90;j++); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值