/*****************************************************
Chip type : ATtiny2313
Clock frequency : 8,000000 MHz
Data Stack size : 64
*****************************************************/
#include <tiny2313.h>
#include <delay.h>
#define digit0 PORTD.0 //питание дисплея
#define digit1 PORTD.3 //питание дисплея
flash char digits[] = { //массив с цифрами
0b01010000, //0
0b01011111, //1
0b00110010, //2
0b00010110, //3
0b00011101, //4
0b10010100, //5
0b10010000, //6
0b01011110, //7
0b00010000, //8
0b00010100 //9
};
char digit_out[2], cur_dig;
//Временные пределы
#define Tmin 40 //длинный промежуток
#define Tmax 68
#define TminK 22 //короткий промежуток
#define TmaxK 34
unsigned char sct_bit = 0; //Счетчик битов RC5
unsigned char RC5_buffer [14]; //Буфер RC5
bit centre = 0; //Флаг центра
bit not_korr = 0; //Флаг попадания в промежутки
unsigned char Timer = 0; //число в счетчике таймера
unsigned char trigger = 0; //переменная триггера
unsigned int device = 0; //переменная адреса ПДУ
unsigned char command = 0; //переменная для команды
void rc5_cl_buf(void){ //очищаем буфер
char i = 0;
for (i=0; i<14; i++){ RC5_buffer [i] = 0; }
}
void rc5_ti_stop(void){ //остановка таймера
GIMSK |=0x00;
TCCR0B = 0x00;
TCNT0 = 0;
sct_bit = 0;
}
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
Timer = TCNT0; //запоминаем значение счетчика
TCNT0 = 0; //обнуляем счетчик
not_korr = 1;
if(sct_bit==0){
TCCR0B = 0x04; //запускаем таймер (31.250 KHz)
RC5_buffer [sct_bit] = !PIND.2;//записываем в эл.массива
sct_bit++; //+1 к счётчику принятых битов
centre = 1;
}else{
if ((Timer>TminK)&&(Timer<tmaxk)){ <span="" data-mce-bogus="1" class="mceItemHidden mceItemNbsp"> // проверка короткого промежутка
if (centre) {
centre = 0;
not_korr = 0;
}else{
centre = 1;
RC5_buffer [sct_bit] = !PIND.2;
sct_bit++;
not_korr=0;
};
};
if ((Timer>Tmin)&&(Timer
RC5_buffer [sct_bit] = !PIND.2;
sct_bit++;
not_korr = 0;
};
if (not_korr == 1) { // если не попали ни в один из промежутков то
rc5_ti_stop(); //останавливаем таймер
rc5_cl_buf(); //очищаем буфер
};
if (sct_bit == 14){ // если бит последний то
rc5_ti_stop(); //останавливаем таймер
trigger = RC5_buffer [2]; //формируем переменную триггера
device = (RC5_buffer [3] << 4) |(RC5_buffer [4] << 3) |(RC5_buffer [5] << 2) |(RC5_buffer [6] << 1) |RC5_buffer [7]; //формируем адрес ПДУ
command = (RC5_buffer [8] << 5) |(RC5_buffer [9] << 4) |(RC5_buffer [10] << 3 ) |(RC5_buffer [11] << 2) |(RC5_buffer [12] << 1) |RC5_buffer [13]; //формируем команду
//выводим данные на дисплей
digit_out[0]=command%10; //перевод для 1 цифры
command=command/10; //подготовка
digit_out[1]=command%10; //перевод для 2 цифры
EIFR=0x40; // сбрасываем флаг прерывания по входу INT0
};
};
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
rc5_ti_stop(); //останавливаем таймер
rc5_cl_buf(); //очищаем буфер
GIMSK |=0x40; //разрешаем прерывания по входу
EIFR=0x40; //сбрасываем флаг прерывания (если произошло)
}
//динамическая индикация
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
PORTB=0xFF; //чтобы небыло тени
switch (cur_dig) //---
{
case 0:{digit1=0;digit0=1;break;}; //подаём питание на 1
case 1:{digit0=0;digit1=1;break;}; //подаём питание на 2
}
PORTB=digits[digit_out[cur_dig]];
cur_dig++;
if (cur_dig==2) cur_dig=0;
}
void main(void)
{
// Port A initialization
PORTA=0x00;
DDRA=0x00;
// Port B initialization
PORTB=0x00;
DDRB=0xFF;
// Port D initialization
PORTD=0x04;
DDRD=0x0B;
// Timer/Counter 0 initialization
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x40;
MCUCR=0x01;
EIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;
// Global enable interrupts
#asm("sei")
while (1)
{
};
}