⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 event.c

📁 AVR红外遥控
💻 C
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>
#include <avr/wdt.h>

#include "cc.h"
#include "event.h"
#include "display.h"

// device = ATMEGA8
// OSC =    3686400Hz
// interrupt mode and function: SIGNAL(){}; or INTERRUPT(){}; or EMPTY_INTERRUPT();

// define I/O
#define FV        PB0
#define FI        PD3



// 中断事件标志
volatile u8_t flag0;



// INT1 次数
volatile u16_t cnt_int1;

// ICP1 次数
volatile u16_t cnt_icp1;    // 记录ICP1发生的次数


// T0 次数
volatile u8_t cnt_t0;       // 记录T0发生的次数

// T1 次数
volatile u16_t cnt_t1;      // 记录T1发生的次数
volatile u16_t sample_v;    // ICP1总数/秒
volatile u16_t sample_i;    // INT1总数/秒


// T2 次数
volatile u8_t cnt_t2;       // 记录T2发生的次数


// 定时器初值
/*#define TIME0       0xd4      // T0初值, 8bit; 用于13个 LED刷新显示,一次轮巡100Hz不闪烁
#define TIME1       0x1f00    // T1初值, 16bit;精确1秒!
#define TIME2       0x4c      // T2: 50mS
*/
#define TIME0       0xe0      // T0初值, 8bit; 用于13个 LED刷新显示,一次轮巡100Hz不闪烁
#define TIME1       0x8f80    // T1初值, 16bit;精确1秒!
#define TIME2       0x10      // T2: 30mS



// =========================================================================
void init_interrupt(void){
  
  cli();
  // FV 输入于ICP1,空闲为高(低边缘检测)
  DDRB &= ~_BV(FV);
  PORTB |= _BV(FV);
  // FI 输入于INT1,空闲为高(低边缘检测)
  DDRD &= ~_BV(FI);
  PORTD |= _BV(FI);
  
  flag0 = 0;
  
  // setup T0;
  TCNT0 = TIME0;
 // TCCR0 = (_BV(CS01)|_BV(CS00));    //  fosc/64
 
    #ifdef MCU_MEGA8
    TCCR0 = _BV(CS02);    //  fosc/256
    #else
    TCCR0B = _BV(CS02);
    #endif
  
    #ifdef MCU_MEGA8
    TIMSK |= _BV(TOIE0);      // enable T0 interrupt
    #else
    TIMSK0 |= _BV(TOIE0);
    #endif
    
  cnt_t0 = 0;

  // setup T1; T1 is always runing....
  TCNT1 = TIME1;
    
    #ifdef MCU_MEGA8
    TIMSK |= _BV(TOIE1);      // enable T1 interrupt
    #else
    TIMSK1 |= _BV(TOIE1);
    #endif
  
  cnt_t1 = 0;

  // ICP1
  TCCR1A = 0x00;   // 输出捕捉模式普通
  
    #ifdef MCU_MEGA8
    TIMSK |= _BV(TICIE1);
    #else
    TIMSK1 |= _BV(ICIE1);
    #endif
  // 允许滤波、下降沿、fosc/64
//  TCCR1B = (_BV(ICNC1)|_BV(CS11)|_BV(CS10)); // 同样也是 T1的分频数
  TCCR1B = (_BV(ICNC1)|_BV(CS12)); // 同样也是 T1的分频数
  cnt_icp1 = 0;


  // T2:
  TCNT2 = TIME2;
  #ifdef MCU_MEGA8
  TCCR2 = (_BV(CS22)|_BV(CS21)|_BV(CS20));    //  fosc/1024
  #else
  TCCR2B = (_BV(CS22)|_BV(CS21)|_BV(CS20));    //  fosc/1024
  #endif
  
  #ifdef MCU_MEGA8
  TIMSK |= _BV(TOIE2);      // enable T2 interrupt
  #else
  TIMSK2 |= _BV(TOIE2);
  #endif
  
  cnt_t2 = 0;
  
  // INT1: 
  #ifdef MCU_MEGA8
  MCUCR |= _BV(ISC11);      // 下降沿有效
  #else
  EICRA |= _BV(ISC11);
  #endif
  
  #ifdef MCU_MEGA8
  GICR |= _BV(INT1);        // enable
  #else
  EIMSK |= _BV(INT1);
  #endif
  
  cnt_int1 = 0;
  
  // INT0:
  #ifdef MCU_MEGA8
  MCUCR |= _BV(ISC01)|_BV(ISC00);  // 上升沿有效
  #else
  EICRA |= _BV(ISC01)|_BV(ISC00);  // 上升沿有效
  #endif
  
  #ifdef MCU_MEGA8
  GICR |= _BV(INT0);    // enable
  #else
  EIMSK |= _BV(INT0);    // enable
  #endif
  

  // enable 
  sei();
  
  return;
  
}




// interrup rounting
SIGNAL(SIG_INTERRUPT0) {
  
  cli();
  flag0 |= _BV(FLAG0_INT0);
  
}


SIGNAL(SIG_INTERRUPT1) {
  
  ++cnt_int1;
  
}

#ifdef MCU_MEGA8
EMPTY_INTERRUPT(SIG_OUTPUT_COMPARE2);
#endif

// T2
SIGNAL(SIG_OVERFLOW2) {
  
  TCNT2 = TIME2;
  
  ++cnt_t2;
  
  wdt_reset();

}

// ICP1 输入捕捉
SIGNAL(SIG_INPUT_CAPTURE1) {

  ++cnt_icp1;
  
}

EMPTY_INTERRUPT(SIG_OUTPUT_COMPARE1A);

EMPTY_INTERRUPT(SIG_OUTPUT_COMPARE1B);


// T1: 精确1秒
SIGNAL(SIG_OVERFLOW1) {

  TCNT1 = TIME1;
  
  sample_v = cnt_icp1;
  cnt_icp1 = 0;

  sample_i = cnt_int1;
  cnt_int1 = 0;

  flag0 |= _BV(FLAG0_T1);
  ++cnt_t1;
  
}


// T0: 刷新LED不闪烁 
SIGNAL(SIG_OVERFLOW0) {
  
  TCNT0 = TIME0;

  if ((bcd_buf[cnt_t0] & 0xf0) == 0) {
    led_putchar((bcd_buf[cnt_t0] & 0x0f), cnt_t0, 0);
  }
  else {
    led_putchar((bcd_buf[cnt_t0] & 0x0f), cnt_t0, 1);
  }    
  
  cnt_t0 = (cnt_t0 == 12) ? 0 : (cnt_t0 + 1); // 下一个位

}


/*
EMPTY_INTERRUPT(SIG_SPI);

EMPTY_INTERRUPT(SIG_UART_RECV);

EMPTY_INTERRUPT(SIG_UART_DATA);

EMPTY_INTERRUPT(SIG_UART_TRANS);

EMPTY_INTERRUPT(SIG_ADC);

EMPTY_INTERRUPT(SIG_EEPROM_READY);

EMPTY_INTERRUPT(SIG_COMPARATOR);

EMPTY_INTERRUPT(SIG_2WIRE_SERIAL);

EMPTY_INTERRUPT(SIG_SPM_READY);
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -