Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: RC-5 протокол и ATmega8
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Rom20
Доброго времени суток форумчани! стоит задачка принимать команды с пульта RC-5 и обрабатывать их контроллером. Пересмотрел кучу статей по этой теме попробовал собрать несколько проектов и инета так ни чего и не заработала, уже неделю сижу парюсь, в итого только принимаю какую то ахинею и выкидываю ее в ком порт, вроде сам протокол изучи нормально как идет передача понимаю а что то не работает, вот кусок кода
ISR (INT0_vect)
{
uint8_t u;
TCCR0=(1<<CS02)|(1<<CS00);
TCNT0=0;
while(PIND&(1<<2))
{
}
u=TCNT0;
UDR=u+0x30;
}

генерирую прерывания по нарастающему фронту, а дальше пробую померить длительность каждого бита, по идеи при нажатии одной кнопки на пульте должен в ком порт получать минимум 14 символов, т.к протокол 14 бит, ну получаю всего один и то каждый раз разный. или может что ни так у меня с прерываниями прогнал программу в симуляторе AVRstudio и заметил что он из прерываний почему то не возвращаться а все время крутиться в них, при отладке в желез та же картина, где косяк в упор не вижу.
P.S плиз без троллинга!
Xenia
Цитата(Rom20 @ Aug 23 2011, 17:37) *
заметил что он из прерываний почему то не возвращаться а все время крутиться в них, при отладке в желез та же картина, где косяк в упор не вижу.

Надо избавляться от желания вставлять в процедуры прерывания циклы ожидания.

А вашу задачу лучше решить так:
1) Прерывание по INT0 програмируется в режим изменения уровня ("Any logical change on INT0 generates an interrupt request").
2) Внутри процедуры обработки прерывания от INT0:
2а) вычисляют разность между счетчиком таймера TCNT0 и старым значением таймера (под эту переменную заводят глобальную переменную oldTCNT0).
2б) обновляют значение переменной oldTCNT0 = TCNT0
2в) передают разность на USART (UDR). По величине разности можно сообразить, к какой полярности она относится. При желании можно сделать так, чтобы посылалась разность только одной полярности (например, делать посылки через раз). Тем не менее прерываться следует при каждом изменении полярности, а не только нужной, т.к. иначе разница будет включать сумму интервалов низкого и высокого уроней. Однако инфрормация о временах промежутков между сигналами тоже может оказаться полезной.
Rom20
Цитата(Xenia @ Aug 23 2011, 17:32) *
1) Прерывание по INT0 програмируется в режим изменения уровня ("Any logical change on INT0 generates an interrupt request").

Сконфигурировал МК что бы реагировал на изменение уровня сингла, изначально линия находиться в низком логическом уровне, в Proteus подаю на вход мк пачку импульсов из 14 как в протоколе RC-5 все временные выдержки импульсной пачки стоят как положено пробую принять и обработать вот по такому алгоритму:
ожидаем прихода фронта, по фронту генерируется прерывание r увеличиваем на единицу запускаем таймер, возвращаемся из прерываний, таймер считает, ждем спада как только приходит спад генерируется прерывание, r увеличивается еще на единицу (вот не знаю хорошо это или нет что я второй раз как бы запускаю таймер?), проверяем значение r оно равно двум выкидываем в терминал значение нашего таймера. Но на деле подовая на вход пачку импульсов фиксированной длинны (900мкс и 1800мкс) я получаю совершенно разные цифры, но цифры хотя бы прослеживается какая то закономерность это радует biggrin.gif . и снова у меня где то ошибка подскажите пожалуйста где, если кто видит, или может ошибка в самом алгоритме?
ISR (INT0_vect)
{
r++;
TCCR0=(1<<CS02)|(1<<CS00);
if(r==2)
{
UDR=TCNT0;
TCNT0=0;
r=0;
}
haker_fox
1. Официальная документация от Atmel предписывает выводить данные в последний порт только с обязательной проверкой соответствующего флага. Может быть USART не успевает передать данные, в то время как ему даются новые?

2. Для измерения длительности импульсов следует использовать т.н. "захват". Искать в документации по слову "Capture". К сожалению я не знаком с этим делом, поэтому более подробно ничего сказать не могу.

Ну, а цифры действительно будут разные, ибо "джиттер" ("дрожжание", "подергивание" сигнала во времени) никто не отменял crying.gif
Rom20
Цитата(haker_fox @ Aug 24 2011, 04:55) *
Ну, а цифры действительно будут разные, ибо "джиттер" ("дрожжание", "подергивание" сигнала во времени) никто не отменял crying.gif

ну поставил в в прерываниях опрос готовности сом-порта ну это все рано ни чего не дало, ну и дребезг я тут пока не учитываю как моделирую в proteuse а тут модель ближе к идеальной, длительность короткого импульса 900мкс длинного 1800мкс, а данные в сом-порт приходят одни и те же, вопрос толи счетчик считает не правильно или где то еще ошибка в моих суждениях:
ISR (INT0_vect)
{
r++;
TCCR0=(1<<CS02)|(1<<CS00);
if(r==2)
{
while(!(UCSRA&(1<<UDRE)))
{}
UDR=TCNT0;
TCNT0=0;
r=0;
}
Genadi Zawidowski
приём rc5 и складывание в буфер.
Xenia
Цитата(Genadi Zawidowski @ Aug 24 2011, 13:26) *
приём rc5 и складывание в буфер.

Жуткого размера страшная программа sm.gif
Genadi Zawidowski
Цитата(Xenia @ Aug 24 2011, 13:32) *
Жуткого размера страшная программа sm.gif


Ну что делать, если топикстартера на гугле забанили? Вот я и сложил сюда рабочий проект. Вот оригинал из двух функций:
http://faq.embedders.org/_examples_code/re...www.markh.de).c
Rom20
Цитата(Genadi Zawidowski @ Aug 24 2011, 13:26) *
приём rc5 и складывание в буфер.

за программу конечно спасибо, но я таких еще с 10 нагуглил, мне охото самому написать и во всем разобраться а не готовое решение брать......
Genadi Zawidowski
Так из многих "нагугленных" эта заработала сразу, без напильника (естественно, речь не о привязке к компилятору).
Разберётесь потом - даже можете своё сделать на основе работающей программы.
ARV
Цитата(Rom20 @ Aug 24 2011, 14:19) *
за программу конечно спасибо, но я таких еще с 10 нагуглил, мне охото самому написать и во всем разобраться а не готовое решение брать......
почитайте: http://arv.radioliga.com/content/view/219/43/ специально старался... как раз для того, чтобы сделать самому sm.gif

проверено не в одном проекте, работает (да и чего б не работать-то?). не используются прерывания, таймеры и прочее. однако, ничто не мешает их использовать и получить какой-то выигрыш...


Rom20
Народ хелп плиз. Написал программу в симуляторе AVRstudio при шаговой отладке все хорошо принимает данные с пульта, а вот в железе начинаются проблемы в сом-порт гонит в основном одни "1". Использую следующий алгоритм. изначально нога контроллера притянута к +5в
1. Разрешаю прерывания по изменению уровня сигнал заведен на PD2
2. при первом прерывании (спаду) запускаю таймер
3. при появлении высокого логического уровня снова генерируется прерывание считываю значение таймера
4. Проверяю длину импульса
4а. Если импульс длинный то однозначно я нахожусь на середине бита и можно производить считывание, считываю значение порта ложу в переменную
4б Если импульс короткий проверяю где нахожусь: если на границе битов то ничего не считываю просто запоминаю что граница, если на середине бита то считываю значение порта ложу в перемененную.
Ниже привожу кусок программы приема и обработки сигнала, пробовал варьировать задержки при считывании значения порта ни помогло, с начало думал может помехи какие возникают.


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/signal.h>
volatile int v,r,p,u=0, oldp,gr;
uint16_t j,k,f,x,y1,y2,pult;
uint8_t c,a,e,q,m=0,m1;
ISR (INT0_vect)
{
r++;//переменная r служит для подсчета для того что бы узнать где находимся на середине или на границе при коротких импульсях
TCCR0=(1<<CS02);//запускаем таймер
p=TCNT0;//считываем заначение таймера
TCNT0=0;//
if(r==2)// если находимся на середине бита то запоминаем предыдущее значение таймера
{
oldp=p;
r=0;
}
}
//прерывание по приему USART
ISR (USART_RXC_vect)
{
v=UDR;
_delay_us(5);
UDR=v;
}
// инициализация настроек
void inic()
{

DDRC=0xFF;
DDRB=0xFF;
DDRB&=~(1<<0);
PORTB=0;
PORTB|=(1<<3);
//натсраиваем скорость 19200 бот/c
UBRRL=25;
UBRRH=0;
UCSRA=0;
// настраиваем приемник передатчик
UCSRB=(1<<RXEN) |(1<<TXEN)|(1<<RXCIE);
// 8 бит данных
UCSRC=(1<<UCSZ0) |(1<<UCSZ1)|(1<<URSEL);
MCUCR=(1<<ISC00);
GICR=(1<<INT0);
}
void main()
{
inic();
while(1)
{
sei();
while(1)
{
if ((p>0x18)&&(p<0x1F))// если интервал короткий
{
if(p==oldp)//проверяем где находимся на границе или на середине бита если на середине бита то gr=1
{
gr=1;
oldp=0;
}
if (((p>0x18)&&(p<0x1F))&&gr)// если интервал короткий и мы находимся на середине то можно считывать значение порта
{

gr=0;
p=0;
j=PIND&(1<<2);
_delay_us(50);
j=PIND&(1<<2);
if(j)
{
while(!(UCSRA&(1<<UDRE)))
{}
pult|=(1<<u);
UDR='1';
}
if(!j)
{
while(!(UCSRA&(1<<UDRE)))
{}
pult&=~(1<<u);
UDR='0';
}
u++;// стчик для складирования битов
}
p=0;

}
//динный импульс
if ((p>0x37) && (p<0x3B))// если импульс длинный то мы однозначно на середине считываем значение порта
{
r=0;
gr=0;
p=0;
j=PIND&(1<<2);
_delay_us(50);
j=PIND&(1<<2);
if(j)
{
while(!(UCSRA&(1<<UDRE)))
{}
UDR='1';
pult|=(1<<u);
}
if(!j)
{
while(!(UCSRA&(1<<UDRE)))
{}
pult&=~(1<<u);
UDR='0';
}
u++;
}
if(u==14)
{
u=0;
while(!(UCSRA&(1<<UDRE)))
{}
UDR='E';
}
}
}
}


-SANYCH-
Цитата
//прерывание по приему USART
ISR (USART_RXC_vect)
{
v=UDR;
_delay_us(5);
UDR=v;
}


Может нужно вот так:

//прерывание по приему USART
ISR (USART_RXC_vect)
{
v=UDR;
while(!(UCSRA&(1<<UDRE)));
UDR=v;
}


Цитата
while(!(UCSRA&(1<<UDRE)))
{}


зачем скобочки в конце функции?
должно быть так while(!(UCSRA&(1<<UDRE)));
Rom20
Цитата(-SANYCH- @ Aug 28 2011, 14:09) *
Может нужно вот так:

//прерывание по приему USART
ISR (USART_RXC_vect)
{
v=UDR;
while(!(UCSRA&(1<<UDRE)));
UDR=v;
}




зачем скобочки в конце функции?
должно быть так while(!(UCSRA&(1<<UDRE)));

это без разницы как работает и та и так конструкция, и вообще вопрос был поставлен правильный ли алгоритм обработки сигнала, а не для того что бы к листингу программы придераться
-SANYCH-
Цитата
это без разницы как работает и та и так конструкция, и вообще вопрос был поставлен правильный ли алгоритм обработки сигнала, а не для того что бы к листингу программы придераться


Если программа Ваша написана запутано, то желание разбираться с ней нет. По этому для начала перед тем как спрашивать правильный ли алгоритм нужно навести порядок в коде. twak.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.