RC-5 без использования внешнего прерывания (?)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

Здравствуйте, уважаемые коты!

Скажите, возможна ли реализация чтения протокола RC-5 (пульты ИК) без использования внешнего прерывания МК?
Может, кто-нибудь делал такое?
Контактная информация:
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Можно, только сигнал с приемника придется программно отслеживать.
Реклама
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

очень себе таки и можно.....например повесить на АЦП или на компаратор ... или на ногу захвата таймера.....это всё тоже косвенные возможности реагировать мгновенно на внешнее событие
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

Ясно, спасибо...
Просто до паяльника смогу добраться только в конце недели, а железка лежит себе рядом, так и просит запрограммироваться. :)
Только вот ИК-датчик повесил по дурости куда придется, а не на прерывание...
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Мучитель микросхем
Сообщения: 487
Зарегистрирован: Пт июн 12, 2009 19:17:35

Сообщение qwerky »

можно программно - заводите опорный таймер на 10..50кГц и в прерывании опрашивайте вход.
считайте длительность постоянного уровня до изменения на входе, эти длительности декодируйте в 0/1 и складывайте в буфер.
по заполнению буфера нужным числом перепадов - получите код посылки.
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

qwerky писал(а):можно программно - заводите опорный таймер на 10..50кГц и в прерывании опрашивайте вход.
считайте длительность постоянного уровня до изменения на входе, эти длительности декодируйте в 0/1 и складывайте в буфер.
по заполнению буфера нужным числом перепадов - получите код посылки.
+1
Я именно так и делал.
Мало того, если контроллер особо ни чего не делает, просто дождаться команды и чегото там вкл\выкл, то можно и без таймера, прям в основном цикле задержками организовать опрос входа и обработку данных.
Реклама
Мучитель микросхем
Сообщения: 487
Зарегистрирован: Пт июн 12, 2009 19:17:35

Сообщение qwerky »

С RC5 еще не сталкивался, но Sony (протокол SIRC), и Samsung (протокол NEC/JVC или похожий) декодируется на ура.
Можно сделать дополнительную прослойку-декодер в общую кодировку - тогда можно совместить в одном куске работу с пульта и локальной клавиатуры.
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Всё можно, но смысл? Они заняты? Тогда что за контроллер? У более современных серий AVR есть еще PCINT прерывания, раскиданные почти по всем ногам.
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

МК 8535, порты внешних прерываний не заняты, но по глупости при проектировке запаял дитчик не туда. А до паяльника смогу добраться только к середине недели...
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Johnson писал(а):МК 8535, порты внешних прерываний не заняты, но по глупости при проектировке запаял дитчик не туда. А до паяльника смогу добраться только к середине недели...
На какую ногу запаял, какие на ней есть аппаратные функции, может через них можно и аппаратно следить?
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

PD6 (ICP1)

Пофиг, сползаю седня до паяльника, переделаю как у всех...
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Этот пин вроде, можно использовать как внешнее прерывание захвата счетчика таймера1, вектор прерывания TIMER1 CAPT указываешь на свою процедуру, и делай там че хочешь. Ну естественно нужно настроить соотв. регистры управления, чтобы прерывания срабатывали.
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Дла срабатывания этого прерывания, нужно включить вит TICIE1 в регистре TIMSK
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

Да ладно, запаял уже на INT0...
Буду теперь по примерам разбираться как устроено всё это. :)
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

На INT0 конечно же лучше, т.к. INT0 можно настроить на срабатывание по положительному + по отрицательному фронту, а вот ICP1 только по отрицательному.
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

Хм... Пульт оказался мертвым... Выдавал всегда только одиночный импульс и не повторялся.
Взял другой пульт, он оказался с протоколом NEC.
Взял примеры в инете, но ни как не могу победить их.
Складывается такое ощущение, что таймер не так запускаю.
Подскажите, пожалуйста, ошибку.
Спойлер

Код: Выделить всё



void tmr_reset() { 
    TCCR0=0; //Выключаем счетчик 
    TCNT0=0; //Сбрасываем счетчик 
    evt_cnt=0; 
}
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
    tmr_reset(); //Если счетчик переполнен, выключаем и обнуляем его
    PORTD.3 = 1;
     
}

interrupt [EXT_INT0] void ext_int0_isr(void){
     
	if (evt_cnt == 0) TCCR0=4; //Если первое событие включаем счетчик, 15.625КГц 
	if (evt_cnt == 1 && ( TCNT0 < 130 || TCNT0 > 150 )){
        tmr_reset(); //Второе событие, если импульс не входит в интервал, выключаем счетчик
        //LCD_draw_char(1,0,'=');
        //LCD_draw_digit(1,10,TCNT0/100);
        //LCD_draw_char(1,0,'-');
    } 
	if (evt_cnt == 2) { 
		if (TCNT0 < 60 || TCNT0 > 80) { //Проверка на удержание клавиши 
			tmr_reset(); 
			if (TCNT0 < 60 && pvk[2] != 0){
                LCD_draw_char(0,0,pvkc); 
                LCD_draw_char(0,0,pvk[1]); 
                //keypress(pvkc,pvk[1]); //Вызываем функцию удержания клавиши 
            }
		}else{ //Если первое нажатие сбрасываем значения 
			pvkc=0; 
			pvk[0]=0; 
			pvk[1]=0; 
			pvk[2]=0; 
		} 
	} 
	if (TCCR0 != 0) { //Если счетчик включен 
		if (evt_cnt > 3 && evt_cnt < 67 && (evt_cnt & 1) == 0) { 
			if (evt_cnt < 36) { 
				if (TCNT0 > 21) pvkc |= 1<<(17-(evt_cnt>>1)); //Собираем по биту CUSTOM code 
			}else if(evt_cnt<52) { 
				if (TCNT0>21) pvk[1]|=1<<(25-(evt_cnt>>1)); //DATA code 
			}else{ 
				if (TCNT0>21) pvk[0]|=1<<(33-(evt_cnt>>1)); //invert DATA code 
			} 
		} 
		evt_cnt++; //Инкриминируем счетчик событий 
		if (evt_cnt > 67) { 
			tmr_reset(); //Выключам счетчик 
			if (pvk[1]==(pvk[0]^0xff)) { //Проверяем DATA code   
				pvk[2]=1; //Значит Ок 
				//keydown(pvkc,pvk[1]); //Вызываем функцию нажатия клавиши
                //LCD_draw_char(0,0,pvkc); 
                //LCD_draw_char(0,0,pvk[1]); 
			} 
		} 
		TCNT0=0; //Сбрасываем счетчик 
	} 

}

//////////////////////////////////////////////////////////
    TCCR2=0b00000100; //250 kHz
    
    TIMSK=0b01000001;   // TIM2-overflow, TIM0-overflow
    ACSR =0b10000000;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
    GICR|=0x40;
    MCUCR=0x01;
    MCUCSR=0x00;
    GIFR=0x40;

По закомментированным кускам в прерывании видно, что я пытался отследить, какое значение имеет TCNT0, но он всегда возвращал "0", и в случае TCNT0/10 и в случае TCNT0/100

Подскажите, где я опять споткнулся?

А ещё был бы очень благодарен за ссылку на статью о таймерах и рассчете их таймингов.
К примеру, таймер установлен на 15кГц. Это он переполняться будет с частотой 15кГц, или инкрементировать счетчик?
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Johnson писал(а): По закомментированным кускам в прерывании видно, что я пытался отследить, какое значение имеет TCNT0, но он всегда возвращал "0", и в случае TCNT0/10 и в случае TCNT0/100

Подскажите, где я опять споткнулся?

А ещё был бы очень благодарен за ссылку на статью о таймерах и рассчете их таймингов.
К примеру, таймер установлен на 15кГц. Это он переполняться будет с частотой 15кГц, или инкрементировать счетчик?
Когда таймер ловишь при переполнении, то он всегда будет выдавать "0", потому что он переполнился, по нулю в таймере и определяется его переполнение, тут надо расчитывать значение таймера "от обратного", т.е. 256 минусуем то что нужно и остается столько, сколько нужно записать в TCNT0.
Частота таймера: Частота МК делим на прескалер и делим на (256 минус значение TCNT0)
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

Ловлю не при переполнении таймера, а по внешнему прерываиню, срабатывающему от ИК-датчика.
Там по коду даже мне понятно как устроено, только вот не работает ни черта :)
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Какая частота МК и что за МК? А то вот эти две вещи как-то несовместимы:
....
if (evt_cnt == 0) TCCR0=4; //Если первое событие включаем счетчик, 15.625КГц
....
TCCR2=0b00000100; //250 kHz
....

ATmega16
прескалер для таймера0, таймера1:
001=1:1, 010=1:8, 011=1:64, 100=1:256, 101=1:1024

прескалер для таймера2:
001=1:1, 010=1:8, 011=1:32, 100=1:64, 101=1:128, 110=1:256, 111=1:1024
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт мар 05, 2009 08:15:25

Сообщение Johnson »

zero648 писал(а):Какая частота МК и что за МК? А то вот эти две вещи как-то несовместимы:
....
if (evt_cnt == 0) TCCR0=4; //Если первое событие включаем счетчик, 15.625КГц
....
TCCR2=0b00000100; //250 kHz
....

ATmega16
прескалер для таймера0, таймера1:
001=1:1, 010=1:8, 011=1:64, 100=1:256, 101=1:1024

прескалер для таймера2:
001=1:1, 010=1:8, 011=1:32, 100=1:64, 101=1:128, 110=1:256, 111=1:1024

Как не совместимы? Прискалер для таймера0 и таймера2 как бы...

МК у меня 8535, частота 16мГц
Контактная информация:
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»