微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求助avr单片机子程序问题

求助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...
}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top