📄 mega16implementation.c
字号:
/*********************************************
File name : de_2.c
Chip type : ATmega16
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*********************************************/
#include <mega16.h>
#ifndef __SLEEP_DEFINED__
#define __SLEEP_DEFINED__
.EQU __se_bit=0x40
.EQU __sm_mask=0xB0
.EQU __sm_powerdown=0x20
.EQU __sm_powersave=0x30
.EQU __sm_standby=0xA0
.EQU __sm_ext_standby=0xB0
.EQU __sm_adc_noise_red=0x10
.SET power_ctrl_reg=mcucr
#endif
#include <delay.h>
unsigned char key_stime_counter; // 时间计数单元,
bit key_stime_ok;
// Timer 0 比较匹配中断服务,2ms定时
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
if (++key_stime_counter >=5)
{
key_stime_counter = 0;
key_stime_ok = 1; // 10ms到
}
}
#define key_input PIND // 按键输入口
#define key_1 0b11111110
#define key_2 0b11111101
#define key_3 0b11111011
#define key_4 0b11110111
#define key_1_0 0b01111110
#define key_2_0 0b01111101
#define key_3_0 0b01111011
#define key_4_0 0b01110111
#define key_no 0b11111111
#define key_lf 0b10000000
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
unsigned char read_key(void) //读键状态机,每10-20ms执行一次
{
static unsigned char key_state = 0,key_old,key_time = 0;
unsigned char key_press,key_return = key_no;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (key_press != key_no) key_state = key_state_1; // 键被按下,状态转换到键确认态
break;
case key_state_1: // 按键确认态
if (key_press == key_old) // 与原电平比较(消抖处理)
{
key_state = key_state_2; // 按键仍按下,状态转换到计时1
key_time=0; // 清0按键时间计数器
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态(消抖)
break;
case key_state_2:
if (key_press != key_old)
{
key_state = key_state_0; //按键已释放(或转按其它键),转换到按键初始态
key_return = key_old;
}
else if(++key_time>=100) //按键时间计数
{
key_state = key_state_3; //按下时间>1s,状态转换到计时2
key_time=0; // 清按键计数器
key_return = key_press-key_lf; //过一秒,输出连发命令
}
break;
case key_state_3:
if (key_press != key_old) key_state = key_state_0; //按键已释放(或转按其它键),转换到按键初始态
else
{
if(++key_time>=50) // 按键时间计数
{
key_time=0; // 按下时间>0.5s,清按键计数器
key_return = key_press-key_lf; //输出连发命令
}
}
break;
}
key_old = key_press;
return key_return;
}
main()
{
unsigned char key_value;
PORTC=0x00; // PC口的所有位输出"0",LED不亮
DDRC=0xFF; // 定义PC口的第0位为输出方式
PORTD=0xFF;
DDRD = 0x00; // PD7为输入方式
// 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)
{
if (key_stime_ok) //注意控制10-20ms执行一次.
{
key_stime_ok = 0; // 10ms到
key_value = read_key();
if (key_value != key_no) //判别键值并做相应的处理
{
switch (key_value)
{
case key_1:
PORTC.0 = ~PORTC.0; // PC口第0位输出取反
delay_ms(1000); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.0 = ~PORTC.0; // PC口第0位输出取反 //do samething
break;
case key_2:
PORTC.1 = ~PORTC.1; // PC口第1位输出取反
delay_ms(1000); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.1 = ~PORTC.1; // PC口第1位输出取反 //do samething
break;
case key_3:
PORTC.2 = ~PORTC.2; // PC口第2位输出取反
delay_ms(1000); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.2 = ~PORTC.2; // PC口第2位输出取反 //do samething
break;
case key_4:
PORTC.3 = ~PORTC.3; // PC口第3位输出取反
delay_ms(1000); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.3 = ~PORTC.3; // PC口第3位输出取反 //do samething
break;
case key_1_0:
PORTC.0 = ~PORTC.0; // PC口第0位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.0 = ~PORTC.0; // PC口第0位输出取反 //do samething
PORTC.1 = ~PORTC.1; // PC口第1位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.1 = ~PORTC.1; // PC口第1位输出取反 //do samething
PORTC.2 = ~PORTC.2; // PC口第2位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.2 = ~PORTC.2; // PC口第2位输出取反 //do samething
PORTC.3 = ~PORTC.3; // PC口第3位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.3 = ~PORTC.3; // PC口第3位输出取反 //do samething
break;
case key_2_0:
PORTC.3 = ~PORTC.3; // PC口第3位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.3 = ~PORTC.3; // PC口第3位输出取反 //do samething
PORTC.2 = ~PORTC.2; // PC口第2位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.2 = ~PORTC.2; // PC口第2位输出取反
PORTC.1 = ~PORTC.1; // PC口第1位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.1 = ~PORTC.1; // PC口第1位输出取反 //do samething
PORTC.0 = ~PORTC.0; // PC口第0位输出取反
delay_ms(200); // 调用CVAVR提供的毫秒延时函数,延时1s
PORTC.0 = ~PORTC.0; // PC口第0位输出取反 //do samething
break;
case key_3_0:
// do .....
break;
case key_4_0:
// do .....
break;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -