Пытаюсь на базе atmega8 + кварц на 12MHz + tsop1736 сделать приёмник ИК диапазона от пультов ДУ.
Спустя сутки гугла сделал вроде-как рабочую программу, но есть огромная проблема, не пойму в чём дело.
И так, теоретическая часть:
Частота МК 12 000 000мгц, на таймере установлен делитель до 1 500 000мгц (1.5кк операций/сек как я понимаю)
В стандарте протокола написано, что длина одного бита 1.8ms, всего 14 битов
Тобишь, чтоб отсчитать 1.8ms ровно, при частоте 1 500 000 счётчик должен досчитать до: 1500000/1000*1.8=2700
Так в программе и сделал, счётчик установлен до 2700, после чего пишу бит, и обнуляю счётчик ожидая следующего бита, и так 14 бит
НО вот тут то и собака зарыта! Он вроде всё норм считает, но биты идут ДАЛЬШЕ 14го! (высчитал прерыванием) между первым и последним прирыванием счётчик успевает досчитать до 26-28, вот и главный вопрос - ПОЧЕМУ ТАК?
ошибка в таймере, слишком быстро считает? или частота резонатора кривая? (эти 2версии маловероятны, ибо я в ручную при ниже частоте отсчитывал и сравнивал кол-во цикла и прошедшего времени), но если он считает с норм скоростью, то почему тогда данные дальше принимаются? проверил 2 пульта ДУ, и там и там одно и то-же, тобишь вариант что это пульт нестандартный не с RC5 скорее всего отпадает
вот код на CVARV (тут + передача инфы с МК по rs232 через uart)
CODE
#include <mega8.h>
#include <stdio.h>
unsigned int bytes[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned int tmp=1;
unsigned int i=0;
unsigned int status=0;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(status==1)return;
status=1;
// #asm("cli")
bytes[0]=PIND.2;
TCCR1B=0x0A;
}
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if(tmp<14)bytes[tmp]=PIND.2;
tmp++;
if(tmp>=14){
TCCR1B=0x00; // вырубаем счётчик
TCNT1H=0x00; // сбрасываем часть 1
TCNT1L=0x00; // сбрасываем часть 2
tmp=1;
printf("!%u %u %u %u %u %u %u %u %u %u %u %u %u %u\r",bytes[0],bytes[0],bytes[1],bytes[2],bytes[3],bytes[4],bytes[5],
bytes[6],bytes[7],bytes[8],bytes[9],bytes[10],bytes[11],bytes[12],bytes[13]);
for(i=0;i<14;i++)bytes[i]=0;
status=0;
// #asm("sei")
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1500,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00; // TCCR1B=0x0A; // 1 500 000Hz
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x0A; //1.8ms
OCR1AL=0x8C; //1.8ms
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
GICR|=0x40;
MCUCR=0x01;
GIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x4D;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Global enable interrupts
printf("sei\r");
#asm("sei")
/*
while (1)
{
}
*/
}
#include <stdio.h>
unsigned int bytes[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned int tmp=1;
unsigned int i=0;
unsigned int status=0;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(status==1)return;
status=1;
// #asm("cli")
bytes[0]=PIND.2;
TCCR1B=0x0A;
}
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if(tmp<14)bytes[tmp]=PIND.2;
tmp++;
if(tmp>=14){
TCCR1B=0x00; // вырубаем счётчик
TCNT1H=0x00; // сбрасываем часть 1
TCNT1L=0x00; // сбрасываем часть 2
tmp=1;
printf("!%u %u %u %u %u %u %u %u %u %u %u %u %u %u\r",bytes[0],bytes[0],bytes[1],bytes[2],bytes[3],bytes[4],bytes[5],
bytes[6],bytes[7],bytes[8],bytes[9],bytes[10],bytes[11],bytes[12],bytes[13]);
for(i=0;i<14;i++)bytes[i]=0;
status=0;
// #asm("sei")
}
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 1500,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00; // TCCR1B=0x0A; // 1 500 000Hz
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x0A; //1.8ms
OCR1AL=0x8C; //1.8ms
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
GICR|=0x40;
MCUCR=0x01;
GIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x4D;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Global enable interrupts
printf("sei\r");
#asm("sei")
/*
while (1)
{
}
*/
}
п.с. именно в этом примере что щас - этот баг виден в том - что таймер успевает натикать 14 раз, записать эти все биты, оповестить меня об этом, перезапустить всё и часть этого-же кода - запустит прерывание наново чего быть аж никак не должно