📄 event.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 + -