|
Atmega8 + timer1 неточный ( дешифровка rc5 сигнала ), Не могу разоборатся почему непопадает в такт совсем |
|
|
|
Aug 31 2012, 14:25
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Здравствуйте. Пытаюсь на базе 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) {
} */ } п.с. именно в этом примере что щас - этот баг виден в том - что таймер успевает натикать 14 раз, записать эти все биты, оповестить меня об этом, перезапустить всё и часть этого-же кода - запустит прерывание наново чего быть аж никак не должно
Сообщение отредактировал IgorKossak - Sep 5 2012, 12:01
Причина редактирования: [codebox] для длинного кода!!!
|
|
|
|
|
Aug 31 2012, 16:57
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Цитата(ILYAUL @ Aug 31 2012, 19:09)  именно это - нет, но ничего нового или полезного или хотя-бы не много помогающего понять в чём дело - я не увидел, к чему эта ссылка вообще? Кроме этого хотябы даже косвенно относящегось к моему вопросу чего-либо там не было... с таким-же успехом можно было дать ссылку на вики по RC5 p.s. на данном форуме я новенький, хз, мб у вас так принято, даже не вникая в суть вопроса тыкать в доки в которых нет ничего похожего на ответ, но прошу тогда хотя-бы мне лично так не делать
Сообщение отредактировал miXOnIN - Aug 31 2012, 17:00
|
|
|
|
|
Aug 31 2012, 18:45
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Цитата(ARV @ Aug 31 2012, 20:48)  а вот это?  я так и не могу понять, почему все так любят принимать ИК-команды прерываниями... ибо это единственный точный метод измерения времени в МК даже стандартный delay_ms подводить нереально, 500ms длится ~4х сек без резонатора, хорошее оправдание юзать что-то более точное для создания алгоритмов зависящих от десятитысячной доли секунды? Цитата(stfrd @ Aug 31 2012, 20:23)  Я бы для начала убедился что пакет именно такой, какой должен быть. Повысьте частоту таймера минимум в 4 раза и снимите форму входного сигнала (сбросьте эти данные на комп по uart). Если формат пакета правильный, значит что-то с частотой тактирования таймера или всего микроконтроллера. В том-то и дело что я понятия не имею какой ИМЕННО должен быть весь пакет, ибо лишь два стартовые биты это 11 остальное рандом, к тому-же рандом опять-же с единицами...
|
|
|
|
|
Aug 31 2012, 20:07
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(miXOnIN @ Aug 31 2012, 21:45)  ибо это единственный точный метод измерения времени в МК Вообще-то (уже давно - с x51), существует ещё более точный способ - захват по изменению состояния входа, далее возможно происходит прерывание или нет (если не нужно). Цитата(miXOnIN @ Aug 31 2012, 21:45)  даже стандартный delay_ms Где он стандартный интересно? В CVAVR? Нашли стандарт... А может там есть delay_us какай-нибудь? Или что-то вроде __delay_cycles? Цитата(miXOnIN @ Aug 31 2012, 21:45)  delay_ms подводить нереально, 500ms длится ~4х сек без резонатора Как это вам удаётся? Настраиваите фузы на 4 МГц, проект на кварц 12 Мгц? Цитата(miXOnIN @ Aug 31 2012, 21:45)  В том-то и дело что я понятия не имею какой ИМЕННО должен быть весь пакет, ибо лишь два стартовые биты это 11 остальное рандом, к тому-же рандом опять-же с единицами... Знакомая ситуация: как-то делали проект для работы с пультом RC-5. Но потом выяснилось что пульт работает совсем не по RC-5 (так и не узнали что за протокол). Вышли из ситуации примерно так: нажимали на кнопку, записывали какие длительности перепадов получаются, затем то же проделывали со всеми остальными кнопками. В результате получили некую эталонную таблицу с которой можно сравнивать поступающий сигнал.
|
|
|
|
|
Sep 1 2012, 07:03
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Цитата(_Артём_ @ Aug 31 2012, 23:07)  Как это вам удаётся? Настраиваите фузы на 4 МГц, проект на кварц 12 Мгц? хм, всё проще чем ты думаешь, идёшь в магаз, покупаешь чистый атмега8, приходишь домой, завариваешь себе чай, тем временем размещая мк на монтажной плате, потом открываешь cvavr, пишешь программу в 5-7 строчек, в основе которой инпортить либу делай, выставить на выход ноги, и могать в итоге лампочкой, при 500 моргает раз в 4-6 сек. о фъюзах или настройке частоты даже и речи не идёт,всё по дефолту...
|
|
|
|
|
Sep 1 2012, 08:52
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Сделал нечто вроде анализатора протокола, это явный бред......... PIND.2 TCNT1H TCNT1L ch ch - сколько полных кругов прошло OCR1AH=0xFF; OCR1AL=0xFF; TCCR1B=0x09; // 12 000 000Hz Это всё результаты на нажатие одной и той-же кнопки... CODE 0 0 0 0 1 0 6f 0 1 0 21 0 1 b7 e2 0 1 6d 60 0 1 55 e1 0 1 3c 62 0 stop! 0 0 0 0 1 0 6f 0 1 0 21 0 1 b7 e2 0 0 6d 60 0 1 55 e0 0 1 3c 60 0 stop! 0 0 0 0 1 0 6f 0 1 0 21 0 1 b7 e2 0 1 6d 63 0 1 55 e1 0 1 3c 62 0 stop! 0 0 0 0 1 0 6f 0 1 0 24 0 1 b7 e2 0 0 6d 2b 1 1 7b e2 1 stop! 0 0 0 0 1 0 6f 0 1 0 24 0 1 b7 e2 0 0 6d 9b 1 1 6b e3 1 stop! 0 0 0 0 1 0 6f 0 0 0 6b 2 0 6 e2 2 1 6d a2 2 1 24 22 2 1 c a2 2 stop!
Сообщение отредактировал IgorKossak - Sep 5 2012, 12:02
Причина редактирования: [codebox] для длинного кода!!!
|
|
|
|
|
Sep 1 2012, 10:44
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(_Pasha @ Sep 1 2012, 03:51)   этта пять, как говорят . Вы таки думаете, что это был RC5? А чёрт его теперь знает... Цитата(miXOnIN @ Sep 1 2012, 10:03)  хм, всё проще чем ты думаешь, идёшь в магаз, покупаешь чистый атмега8, приходишь домой, завариваешь себе чай, тем временем размещая мк на монтажной плате, потом открываешь cvavr, пишешь программу в 5-7 строчек, в основе которой инпортить либу делай, выставить на выход ноги, и могать в итоге лампочкой, при 500 моргает раз в 4-6 сек. о фъюзах или настройке частоты даже и речи не идёт,всё по дефолту... А какая частота осцилятора указывается в проекте?
|
|
|
|
|
Sep 1 2012, 11:09
|
Профессионал
    
Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364

|
Цитата о фъюзах или настройке частоты даже и речи не идёт,всё по дефолту... Насколько помню в М8 по дефолту идет 8МГц встроенный RC плюс делитель на 8. Т.е. тактовая ядра 1МГц. Если в проекте стоит 8 по умолчанию, вот оно в 8 раз медленнее и работает... ЗЫ. Ладно, ошибся, в М8 делителя тактовой еще не было. Там просто переключался один из 4-х RC-генераторов и генератор по умолчанию был 1МГц.
|
|
|
|
|
Sep 1 2012, 11:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
зря, господа, вы тут мой метод раскритиковали... вам шашечки или ехать? мой метод отлично работает в нескольких моих проектах. именно на _delay_us(), именно на встроенном RC-генераторе. причем даже (о ужас!) при наличии фоновых задач, выполняемых по прерываниям, которые неизбежно искажают программные задержки. например, лампа настроения на attiny13. даже и не знаю, впихнете ли вы свой алгоритм в 1К кода при наличии одного 8-битного таймера без аппаратного захвата... а мой алгоритм легко туда вошел  так что если кому охота продолжать париться с точным измерением временнЫх интервалов - как говорится, попутного ветра в спину! а тем, кто хочет попроще и побыстрее сделать устройство, рекомендую мой алгоритм. если вы будете использовать кварц или для формирования задержек задействуете таймер - мой алгоритм станет работать только лучше, хотя и так хорошо  кстати, я и для RC5 придумал примитивнейший алгоритм приема - работает, как ни странно, даже без кварца и с фоновыми прерываниями...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Sep 1 2012, 11:37
|

Группа: Новичок
Сообщений: 6
Регистрация: 31-08-12
Пользователь №: 73 332

|
Цитата(_Артём_ @ Sep 1 2012, 13:44)  Вы таки думаете, что это был RC5? А чёрт его теперь знает...
А какая частота осцилятора указывается в проекте? 1мгц, по дефолту Цитата(ArtemKAD @ Sep 1 2012, 14:09)  Если в проекте стоит 8 по умолчанию, вот оно в 8 раз медленнее и работает... я не дурак, указываю 1 при создании, через мастера создаю + если БЕЗ мастера создавать, тобишь с 0 весь код писать, там вовсе нет параметра как частота мк
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|