Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
15.07.2011, 15:56
|
#31
|
Прописка
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от artyomugr
|
так у меня на внутренний генератор и настроена работа МК. Частота 8мегагерц так на внутренний ген. работать будет? Много декодеров самопальных видел, большинство работают на внутренний ген.
|
Если все правильно настроено,то должно работать. Чай не RTC делаете...
|
|
|
|
15.07.2011, 16:06
|
#32
|
Вид на жительство
Регистрация: 05.04.2008
Адрес: Украина, Ахтырка
Сообщений: 302
Сказал спасибо: 148
Сказали Спасибо 31 раз(а) в 30 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от artyomugr
|
Я хочу разобраться с декодером ИК лучей Я все понимаю и алгоритм тоже
но вот не получается у меня фиксировать данные и точка! ![Обижен](images/smilies/icon_beee.gif)
Вот код например этот я выдрал с форума радиокот, но по моим подсчетам там не правильно настроен таймер...
я его настраиваю так как считаю правильным и не работает....
привожу оригинальный исходник
и исходник редактированный мною.
Оригинал:
Код:
|
/************************************************** ***
Chip type : ATmega16
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
************************************************** ***/
#include ‹mega16.h›
#include ‹delay.h›
unsigned int tick = 0; //счетчик тиков таймера
unsigned char b_cnt = 0; //счетчик принятых бит
bit start_cond = 0; //флаг стартового условия
bit repeat_cond = 0; //флаг повтора
unsigned char addr = 0; //байт адреса
unsigned char cmd = 0; //байт команды
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xFD; //запускаем таймер
TCCR0=0x04;
if (tick ›= 250 && tick ‹ 350) //если случилось от 250 до 350 тиков
{
start_cond = 1; //фиксируем стартовое условие
addr = cmd = 0; //обнуляем ранее полученную команду и адрес
}
if (tick ›= 18 && tick ‹ 50 && start_cond) //если случилось от 18 до 50 тиков
{
++b_cnt; //приняли "1" и увеличили счетчик битов
if (b_cnt ‹ 8) cmd = (cmd ‹‹ 1) + 1; //первые 7 бит - команда
if (b_cnt ›= 8) addr = (addr ‹‹ 1) + 1; //вторые 5 бит - адрес
}
if (tick ›= 12 && tick ‹ 18 && start_cond) //если случилось от 12 до 18 тиков
{
++b_cnt; //приняли "0" и увеличили счетчик битов
if (b_cnt ‹ 8) cmd = (cmd ‹‹ 1); //далее - аналогично по битам
if (b_cnt ›= 8) addr = (addr ‹‹ 1);
}
tick = 0; //обнулили тики
if (b_cnt == 12) //если приняли уже все 12 битов
{
b_cnt = 0; //обнулили счетчик битов
start_cond = 0; //сбросили стартовое условие
TCCR0=0x00; //остановили таймер
TCNT0=0x00;
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xFD; //переинициализировали таймер - отсчитывает 96мкс
if (++tick › 1200) //если насчитали более 1200 тиков
{
TCCR0=0x00; //сбросили все к исходному состоянию
TCNT0=0x00;
tick = 0;
start_cond = 0;
}
}
void __sign (char digit) //индикатор
{
switch (digit)
{
case 0 : PORTB = 0b01110111; break;
case 1 : PORTB = 0b00000101; break;
case 2 : PORTB = 0b01111001; break;
case 3 : PORTB = 0b00111101; break;
case 4 : PORTB = 0b00001111; break;
case 5 : PORTB = 0b00111110; break;
case 6 : PORTB = 0b01111110; break;
case 7 : PORTB = 0b00010101; break;
case 8 : PORTB = 0b01111111; break;
case 9 : PORTB = 0b00111111; break;
case 10 : PORTB = 0b01011111; break; //'a'
case 11 : PORTB = 0b01101110; break; //'b'
case 12 : PORTB = 0b01110010; break; //'c'
case 13 : PORTB = 0b01101101; break; //'d'
case 14 : PORTB = 0b01111010; break; //'e'
case 15 : PORTB = 0b01011010; break; //'f'
case 16 : PORTB = 0b00000000; break; //' '
default: PORTB = 0b00111000;
}
}
void __print (char a, char b, char c, char d, char e, char f, int t) //Процедура вывода на индикатор символов с номерами a, b, с и d в течение t мс
{
int i = 0;
//if (a == 0) a = 20; //Если первый символ равен 0 - ничего не выводим
while (i ‹ t/12)
{
__sign (a);
PORTC.7 = 1;
delay_ms(2);
PORTC.7 = 0;
__sign (b);
PORTC.6 = 1;
delay_ms(2);
PORTC.6 = 0;
__sign (c);
PORTC.5 = 1;
delay_ms(2);
PORTC.5 = 0;
__sign (d);
PORTC.2 = 1;
delay_ms(2);
PORTC.2 = 0;
__sign (e);
PORTC.3 = 1;
delay_ms(2);
PORTC.3 = 0;
__sign (f);
PORTC.4 = 1;
delay_ms(2);
PORTC.4 = 0;
i++;
}
}
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=P State1=0 State0=P
PORTA=0x05;
DDRA=0x02;
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0xFF;
// Port C initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0xFF;
// 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=P State1=T State0=T
PORTD=0x04;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT2: Off
GICR|=0x40;
MCUCR=0x02;
MCUCSR=0x00;
GIFR=0x40;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
#asm ("sei")
while (1) __print (start_cond, 16, cmd/16, cmd%16, addr/16, addr%16, 12);
} |
моя переделка временных интервалов:
Код:
|
/ External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
TCNT0=0xFD; //запускаем таймер
TCCR0=0x04;
if (tick ›= 55 && tick ‹ 75) //если случилось от 250 до 350 тиков
{
start_cond = 1; //фиксируем стартовое условие
addr = cmd = 0; //обнуляем ранее полученную команду и адрес
}
if (tick ›= 25 && tick ‹ 50 && start_cond) //если случилось от 18 до 50 тиков
{
++b_cnt; //приняли "1" и увеличили счетчик битов
if (b_cnt ‹ 8) cmd = (cmd ‹‹ 1) + 1; //первые 7 бит - команда
if (b_cnt ›= 8) addr = (addr ‹‹ 1) + 1; //вторые 5 бит - адрес
}
if (tick ›= 10 && tick ‹ 24 && start_cond) //если случилось от 12 до 18 тиков
{
++b_cnt; //приняли "0" и увеличили счетчик битов
if (b_cnt ‹ 8) cmd = (cmd ‹‹ 1); //далее - аналогично по битам
if (b_cnt ›= 8) addr = (addr ‹‹ 1);
}
tick = 0; //обнулили тики
if (b_cnt == 12) //если приняли уже все 12 битов
{
b_cnt = 0; //обнулили счетчик битов
start_cond = 0; //сбросили стартовое условие
TCCR0=0x00; //остановили таймер
TCNT0=0x00;
}
}
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xFD; //переинициализировали таймер - отсчитывает 96мкс
if (++tick › 1200) //если насчитали более 1200 тиков
{
TCCR0=0x00; //сбросили все к исходному состоянию
TCNT0=0x00;
tick = 0;
start_cond = 0;
}
} |
мой код заточен под мега8
Но команды с пульта сони декодер не хочет принимать...
С трудом ловлю старт бит... и то старт биты пультов разных протоколов...
В чем дело? Помогите мне пожалуйста разобраться с настройкой таймера...
Пробовал заливать оригинал, так он вообще не работает...
|
Привожу оба кода еще раз! Вот первый код я считаю что работать он не будет!! Вы это поймете сами! Зачем в статье выкладывать не рабочий исходник - загадка....
А второй вариант мой, перелопачены значения таймера, настроены с запасом как в меньшую сторону так же с запасом и в большую сторону...
Дайте простой исходник работающего декодеру по протоколу сони, я буду разбираться почему у меня не работает...
В обеих кодах тактовая равна 8 мГц!
Последний раз редактировалось artyomugr; 15.07.2011 в 16:08.
|
|
|
|
15.07.2011, 16:25
|
#33
|
Прописка
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Т.е. если я правильно понимаю вы влетаете в перывание со спаду сигнала то IR и смотрите что вам насчитал таймер?
У Вас какой фотоприемник? Чаще всего попадаются приемники которые выдают 0 при поступлении на них сигнала (правда попадаются и с инверсным выходом). При такой настройке прерывания вы попадаете в него в начале стартового импульса. Т.е. надо сбросить тики,перенастроить прерывание на Rise и ждать след. прер. только тогда анализировать тики. А лучше настроить прер. по изменению уровня. См.пост выше
Последний раз редактировалось heady69; 15.07.2011 в 16:30.
|
|
|
|
15.07.2011, 16:33
|
#34
|
Вид на жительство
Регистрация: 05.04.2008
Адрес: Украина, Ахтырка
Сообщений: 302
Сказал спасибо: 148
Сказали Спасибо 31 раз(а) в 30 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от heady69
|
Т.е. если я правильно понимаю вы влетаете в перывание со спаду сигнала то IR и смотрите что вам насчитал таймер?
У Вас какой фотоприемник? Чаще всего попадаются приемники которые выдают 0 при поступлении на них сигнала (правда попадаются и с инверсным выходом). При такой настройке прерывания вы попадаете в него в начале стартового импульса. Т.е. надо сбросить тики,перенастроить прерывание на Rise и ждать след. прер. только тогда анализировать тики. А лучше настроить прер. по изменению уровня. См.пост выше
|
Да, прерывание у меня срабатывает, я вставлял в код прерывания светодиод, он мигает при событиях, приемник при поступлении лучей выдает лог. ноль. Но старт бит я зафиксировать не могу.... а если делаю шире диапазон значений таймера ловлю старт бит но ловлю старт биты всех пультов.....
|
|
|
|
15.07.2011, 16:35
|
#35
|
Вид на жительство
Регистрация: 05.04.2008
Адрес: Украина, Ахтырка
Сообщений: 302
Сказал спасибо: 148
Сказали Спасибо 31 раз(а) в 30 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от heady69
|
Т.е. если я правильно понимаю вы влетаете в перывание со спаду сигнала то IR и смотрите что вам насчитал таймер?
|
Да, я настраиваю прерывание по спаду когда ловлю прерывание запускаю таймер, при следующем прерывании останавливаю таймер и считываю значения и так до конца пакета...
|
|
|
|
15.07.2011, 16:39
|
#36
|
Вид на жительство
Регистрация: 05.04.2008
Адрес: Украина, Ахтырка
Сообщений: 302
Сказал спасибо: 148
Сказали Спасибо 31 раз(а) в 30 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от heady69
|
При такой настройке прерывания вы попадаете в него в начале стартового импульса. Т.е. надо сбросить тики,перенастроить прерывание на Rise и ждать след. прер. только тогда анализировать тики. А лучше настроить прер. по изменению уровня. См.пост выше
|
Так вроди так и есть, перед началом запуска таймера, все переменные имеют значение ноль а таймер значение 0xFD .
|
|
|
|
15.07.2011, 16:43
|
#37
|
Прописка
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Так ессессно если Вы анлизируете тикт не в тот момент будет каша. Возможно программа реагирует на паузы между пакетами данных, они продолжительные и уровень подходящий
|
|
|
|
15.07.2011, 16:48
|
#38
|
Прописка
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от artyomugr
|
Да, я настраиваю прерывание по спаду когда ловлю прерывание запускаю таймер, при следующем прерывании останавливаю таймер и считываю значения и так до конца пакета...
|
А смысл его останавливать и запускать пусть себе тики инкрементирует. Когда нужно просто сбросите счетчик тиков(у меня так было под RC5, а там кодировка посложнее будет и тарахтело все на 51 мк 12MHz плюс он занимался еще много чем)
Последний раз редактировалось heady69; 15.07.2011 в 16:55.
|
|
|
|
15.07.2011, 16:53
|
#39
|
Прописка
Регистрация: 25.09.2009
Адрес: Ivanovo
Сообщений: 156
Сказал спасибо: 3
Сказали Спасибо 67 раз(а) в 60 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Сообщение от artyomugr
|
при следующем прерывании останавливаю таймер и считываю значения и так до конца пакета...
|
Так след. придет после паузы между данными или даже между пакетами данных,как то не айс...
|
|
|
|
15.07.2011, 18:12
|
#40
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Помогите разобраться с таймером в Atmega8
Обычно я не просматриваю длинные проги - как правило это пустая трата времени. А автор должен локализовать проблему и сжато её представить публике. Но сейчас я в отпуске. )) Глянул - проникся. ))) Автор суров!!!!
Этож каким надо быть монстром, чтобы так кодить. )))
п/п __sign, как писал незабвенный Гашек - это "один и не самый яркий пример того, какие ослы ещё рождаются под луной".
Обычно реализуется так ...
unsigned char const Digit[16] = {0x77, 0x05,... };
вместо __sign(a), к примеру, пишется
PORTB = Digit[a];
п/п __print - это надо полагать пример динамической индикации, в понимании автора. Я не кровожадный человек, но в некоторых странах мира, за такое бы казнили всю семью.
Если вы, artyomugr, планируете и дальше этими исходниками пользоваться, то в принципе могу помочь. Но всётаки общие рекомендации я бы дал совершенно другого плана.
===
Но для начала вопрос по аппаратной части. Там фотоприёмник должен быть с тем же фильтром, что и пульт. Это соблюдено?
|
|
|
Сказали "Спасибо" SasaVitebsk
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 05:04.
|
|