求助avr单片机子程序问题
时间:10-02
整理:3721RD
点击:
单片机新手,想实现一个按键的双击功能,从网上参考了一个大神的程序,用ICCAVR编写,使用AVR STUDIO调试时发现主函数运行时无法调用前面写的子函数,这是为什么呢?求教!
//ICC-AVR application builder : 2017/5/22 20:28:35
// Target : M8
// Crystal: 11.059Mhz
#include <iom8v.h>
#include <macros.h>
#define key_input PIND3 // 按键输入口
#define LED1() (PORTC=0B00000001)
#define LED2() (PORTC=0B00000010)
#define LED3() (PORTC=0B00000100)
#define N_key 0 //无键
#define S_key 1 //单键
#define D_key 2 //双键
#define L_key 3 //长键
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
int time_10ms_ok ;
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x0F; //m103 output only
DDRC = 0x0F;
PORTD = 0x18;
DDRD = 0x00;
}
//TIMER0 initialize - prescale:1024
// desired value: 10mSec
// actual value: 9.908mSec (0.9%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xD9; //set count
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xD9; //reload counter value
time_10ms_ok = 1;
}
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
unsigned char key_press, key_return = N_key;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到按键消抖和确认状态
break;
case key_state_1: // 按键消抖与确认态
if (!key_press)
{
key_time = 0; //
key_state = key_state_2; // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。
break;
case key_state_2:
if(key_press)
{
key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key
key_state = key_state_0; // 转换到按键初始态
}
else if (++key_time >= 100) // 继续按下,计时加10ms(10ms为本函数循环执行间隔)
{
key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件
key_state = key_state_3; // 转换到等待按键释放状态
}
break;
case key_state_3: // 等待按键释放状态,此状态只返回无按键事件
if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态
break;
}
return key_return;
}
unsigned char key_read(void)
{
static unsigned char key_m = key_state_0, key_time_1 = 0;
unsigned char key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m)
{
case key_state_0:
if (key_temp == S_key )
{
key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击
key_m = key_state_1;
}
else
key_return = key_temp; // 对于无键、长键,返回原事件
break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定<500ms)
{
key_return = D_key; // 返回双击键事件,回初始状态
key_m = key_state_0;
}
else
{ // 这里500ms内肯定读到的都是无键事件,因为长键>1000ms,在1s前低层返回的都是无键
if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件
key_m = key_state_0; // 返回初始状态
}
}
break;
}
return key_return;
}
//
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
unsigned char key;
void main(void)
{
init_devices();
while (1)
{
if (time_10ms_ok) //每10ms执行一次,
{
time_10ms_ok =0;
key = key_read(); //《====== 10ms一次调用按键中间层函数,根据返回键值,点亮不同的LED灯,全面测试按键操作是否正常
if (key == L_key)
LED1();
//点亮A_LED,关闭B_LED和C_LED
else if(key == D_key)
LED2();
//点亮B_LED,关闭A_LED和C_LED
else if(key == S_key)
LED3();
//点亮C_LED,关闭A_LED和B_LED
}
}
//insert your functional code here...
}
//ICC-AVR application builder : 2017/5/22 20:28:35
// Target : M8
// Crystal: 11.059Mhz
#include <iom8v.h>
#include <macros.h>
#define key_input PIND3 // 按键输入口
#define LED1() (PORTC=0B00000001)
#define LED2() (PORTC=0B00000010)
#define LED3() (PORTC=0B00000100)
#define N_key 0 //无键
#define S_key 1 //单键
#define D_key 2 //双键
#define L_key 3 //长键
#define key_state_0 0
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3
int time_10ms_ok ;
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x0F; //m103 output only
DDRC = 0x0F;
PORTD = 0x18;
DDRD = 0x00;
}
//TIMER0 initialize - prescale:1024
// desired value: 10mSec
// actual value: 9.908mSec (0.9%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xD9; //set count
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xD9; //reload counter value
time_10ms_ok = 1;
}
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
unsigned char key_press, key_return = N_key;
key_press = key_input; // 读按键I/O电平
switch (key_state)
{
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到按键消抖和确认状态
break;
case key_state_1: // 按键消抖与确认态
if (!key_press)
{
key_time = 0; //
key_state = key_state_2; // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件
}
else
key_state = key_state_0; // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。
break;
case key_state_2:
if(key_press)
{
key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key
key_state = key_state_0; // 转换到按键初始态
}
else if (++key_time >= 100) // 继续按下,计时加10ms(10ms为本函数循环执行间隔)
{
key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件
key_state = key_state_3; // 转换到等待按键释放状态
}
break;
case key_state_3: // 等待按键释放状态,此状态只返回无按键事件
if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态
break;
}
return key_return;
}
unsigned char key_read(void)
{
static unsigned char key_m = key_state_0, key_time_1 = 0;
unsigned char key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m)
{
case key_state_0:
if (key_temp == S_key )
{
key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击
key_m = key_state_1;
}
else
key_return = key_temp; // 对于无键、长键,返回原事件
break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定<500ms)
{
key_return = D_key; // 返回双击键事件,回初始状态
key_m = key_state_0;
}
else
{ // 这里500ms内肯定读到的都是无键事件,因为长键>1000ms,在1s前低层返回的都是无键
if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件
key_m = key_state_0; // 返回初始状态
}
}
break;
}
return key_return;
}
//
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
unsigned char key;
void main(void)
{
init_devices();
while (1)
{
if (time_10ms_ok) //每10ms执行一次,
{
time_10ms_ok =0;
key = key_read(); //《====== 10ms一次调用按键中间层函数,根据返回键值,点亮不同的LED灯,全面测试按键操作是否正常
if (key == L_key)
LED1();
//点亮A_LED,关闭B_LED和C_LED
else if(key == D_key)
LED2();
//点亮B_LED,关闭A_LED和C_LED
else if(key == S_key)
LED3();
//点亮C_LED,关闭A_LED和B_LED
}
}
//insert your functional code here...
}