Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Software UART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Kuzmi4
Здравствуйте.
Есть у меня макетка с 32-й мегой - решил прикрутить туда 2-й UART, зачем - долго рассказывать..
В опсчем пересмотрел я гору исходников - и атмеловских AVR304,AVR305 - и так, что люди писали - в принципе не сильно от атмеловских отличается - проникся я значит главной мыслёй - и решил написать с нуля своё. Ну и естественно "...вдруг откуда не возьмись..." начали возникать проблемы - и что не странно именно с приёмом - потому как с передачей там всё чётко и ясно - сначала сделал приём на INT2 - по спадающему фронту и провёл такой тест - когда МК ловит 5 байт - отсылает их обратно. В опсчем отсылал я 3 байта - например 0хАА,0хАВ,0хАС - ручками на кнопочки макросов нажимал в которые были забиты байты - тобто последовательно - и после отправки 3-х сразу получал ответ - в ответе было как и положено 5 байт, токо выглядели они как то хитро 0хАА,0xFF,0хАВ,0xFF,0хАС - проверил - действительно за приёмом байта идёт сразу есчё 1-но прерывание - в принципе просимулил процесс в студии - ничего такого не заметил. Как добрался до осцилографа - тыканулся посмотреть - увидел что за байтом практически всегда идёт эдакий шум - при чём бывает очень сильный провал - ну где то 0.7 -1 вольт от 5. В студии я получал похожую ситуацию когда ручками проваливал значение на лапке.. Значит поменял я INT2 на INT0 - как в примерах даётся - и сделал прерывание по низкому уровню. Пропала эта белиберда с 0xFF - то есть отсылаю 5 байт - получаю 5 байт. Но тут возникли опять траблы - тобто они и были когда UART был на INT2 - нельзя было отправить в терминале сразу пачку - то есть
отправляю сразу 1 байт '1' - ok
отправляю сразу 2 байта '12' - ok
отправляю сразу 3 байта '123' - err
отправляю сразу 4 байта '1234' - err

Просмотрел код - ну вроде всё верно - не должно такого быть - но тогда почему не работает ??
В опсчем код не сильно маленький - прикрутил аттачем.
Там загорается красный лед у меня на макетке когда ошибка. Зелёный лед не загорался (там в коде описано: загорается красный - когда ошибка фрейма после 1-го полученного байта, зелёный - после 2,3 и так далее.. ).
Буду признателен за любые конструктивные предложения.
Спасибо.
SasaVitebsk
Цитата(Kuzmi4 @ Jan 23 2008, 13:03) *
Как добрался до осцилографа - тыканулся посмотреть - увидел что за байтом практически всегда идёт эдакий шум - при чём бывает очень сильный провал - ну где то 0.7 -1 вольт от 5. В студии я получал похожую ситуацию когда ручками проваливал значение на лапке..


Такое бывает если данные с трансформатора какого-то идут. Иначе быть не должно. Что то не так у вас.
Проверьте может после приёма байта каким-то образом подпорка сбрасывается?

Бороться с ошибками не разобравшись в них - не стоит. Возможно вы их просто маскируете. Поэтому верните прерывание на "по свалу" и если у вас с подпоркой всё нормально разберитесь откуда идёт помеха. Если это схемотехническая хрень, то подоприте внешним резистором 1кОм.
Dog Pawlowa
Цитата(Kuzmi4 @ Jan 23 2008, 13:03) *
Буду признателен за любые конструктивные предложения.

Поскольку у меня все работает, то все должно работать smile.gif
Интересует, на какой скорости проверяете и есть ли в системе другие прерывания.
GOTO клинит, да и в таком виде тексты не особенно читаемы.
Kuzmi4
2 SasaVitebsk - на счёт подтяжки - ставил - 8к2 - всё равно каки с 0хFF не пропали - провалы были. Заменил на low level int - всё стало ок. Потому и пришёл к выводу что в экзамплах было low level int - из-за этих как.

2 Dog Pawlowa - скорость - 9600, 8N1. Интов в системе кроме 0 - больше нет. На счёт гото - когда писал на асме - джампы всегда работали нормально - понимаю что надо стараться их избегать в коде - но использовал потому как код маленький - лапши не должно было получится..
На счёт читабельности - старался комментить где мона - чтоб понятно было - типа алгоритм переводил с бумажного..

Хочется узнать а делал ли кто на INT2(как я) - если да - можно ли исходник - сравнить.
Если нет - тогда хотелось бы узнать на счёт пачковой посылки для примера на INT0(или другом - но похожем) - работало ли ? если да - то желательно было б посмотреть на исходник - сравнит с моим.
Спасибо.
SasaVitebsk
Цитата(Kuzmi4 @ Jan 24 2008, 13:53) *
2 SasaVitebsk - на счёт подтяжки - ставил - 8к2 - всё равно каки с 0хFF не пропали - провалы были. Заменил на low level int - всё стало ок. Потому и пришёл к выводу что в экзамплах было low level int - из-за этих как.


Приведите пож входную часть схемы включая часть до формирователей. Пожалуйста точную.
Kuzmi4
2 SasaVitebsk - схему приложил (извиняйте за гиф - просто схематика нету особо ввиду простоты реализации) - всё просто до немогу, красный овал означает что там был разрыв - то есть, проводки подходили к пинхэдам на макетке а потом я проводками перебрасывал их на макетку с МАХ232(на соответствуюсчие пинхэды) - так было сделано , потому как на макетке с мегой на МАХ 232 жёстко заведны дорожки с ТХ, RX пинов.

Сначало на RX была лапа PB2 - INT2 , потом - PD2 - INT0.
=GM=
Цитата(Kuzmi4 @ Jan 23 2008, 09:03) *
Просмотрел код - ну вроде всё верно - не должно такого быть - но тогда почему не работает ??

1) У вас логическая ошибка, которая заключается в следующем. После полного приёма первого байта вы должны начать приём сначала, т.е. разрешить прерывание инт0, сбросить флаги, настроить счётчики и т.д. Вы этого не делаете.

2) У вас ошибка в определении констант при приёме старт-бита и бит данных. Для вашей частоты и предделителя должно быть 192/288, у вас почему-то 195/254.

3) Устанавливать TCNT0=0 в прерывании по сравнению не надо, поскольку таймер сбрасывается при сравнении. И даже опасно, могут измениться времена считывания бит.

4) cli() не надо ставить в прерывании, это делается автоматически при входе в прерывание.

5) Переменная мс используется при приёме первого байта, для следующих она не сбрасывается.
Kuzmi4
2 =GM= - на счёт 1-го - спасибо - действительно, как то просчёлкал я....стыдно....
На счёт 2-го - ну на счёт настройки таймера - 192 от 195 - не сильно отличается - комп должен кушать- что он в принципе и делает, а на счёт 288/254 - я то понимаю что это выжидание в полтора байта, чтоб после старта начать проверять в середине значения - "0" или "1". Я в принципе проверяю не в середине - ближе к краю - знаю чем чревато, но скушало ж....
На счёт 3-го - действительно TCNT0 сбрасывается в прерывании по сравнению, однако код не маленький и у меня таймер успевает натикать 3 раза - вот я его с брасываю - понимаю что не очень корректно - каюсь...
На счёт 5-го - та мне и нужно было проверить 1 раз..

А вот на счёт 4-го я с вами не согласен - читал как то документацию на SIGNAL и INTERRUPT в WinAVR`е , да и где то на форуме даже дискуссия была по этому поводу - в обсчем суть в том что в SIGNAL нету кли а в INTERRUPT - есть. Хардварно ж флажок I не сбрасывается при вызове любого прерывания.... Поправть или ткните носом если не прав.
=GM=
Цитата(Kuzmi4 @ Jan 25 2008, 09:16) *
На счёт 2-го - ну на счёт настройки таймера - 192 от 195 - не сильно отличается - комп должен кушать- что он в принципе и делает, а на счёт 288/254 - я то понимаю что это выжидание в полтора байта, чтоб после старта начать проверять в середине значения - "0" или "1". Я в принципе проверяю не в середине - ближе к краю - знаю чем чревато, но скушало ж...

Неправильный подход. Для асинхронного протокола и так всего 5% на разницу скоростей, а вы своими руками её уменьшаете, спрашивается, зачем? Да, на столе и в тепличных условиях иногда будет работать, а в реале не будет. Кроме того, надо менять подход, вы не сможете записать 288 в 8-битный таймер, там максимум 255. Проще всего сделать так. В прерывании инт0 поставить константу=144, т.е. на длительность половины бита, и счетчик бит установить на 9 (фиктивный счет старт-бита).

Цитата(Kuzmi4 @ Jan 25 2008, 09:16) *
На счёт 3-го - действительно TCNT0 сбрасывается в прерывании по сравнению, однако код не маленький и у меня таймер успевает натикать 3 раза - вот я его сбрасываю - понимаю что не очень корректно - каюсь...

Так нельзя делать, кто ж подводит часы каждый раз после приёма бита? А если длина кода изменится, подводить по-другому? Пусть они себе тикают сами по себе и щёлкают точно в середине бита - это максимально достижимый оптимум.

Цитата(Kuzmi4 @ Jan 25 2008, 09:16) *
На счёт 5-го - та мне и нужно было проверить 1 раз..

Ну вы ж принимаете несколько байт, значит, потенциально мс может быть 1, 2, 3 и т.д. А проверяете почему-то на 1. А если мс=2 - это не ошибка?

Цитата(Kuzmi4 @ Jan 25 2008, 09:16) *
А вот на счёт 4-го я с вами не согласен - читал как то документацию на SIGNAL и INTERRUPT в WinAVR`е , да и где то на форуме даже дискуссия была по этому поводу - в обсчем суть в том что в SIGNAL нету кли а в INTERRUPT - есть. Хардварно ж флажок I не сбрасывается при вызове любого прерывания.... Поправьте или ткните носом, если не прав


Неправы, вот цитата из doc2466o, page 14
When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts
are disabled. The user software can write logic one to the I-bit to enable nested interrupts.
All enabled interrupts can then interrupt the current interrupt routine. The I-bit is
automatically set when a Return from Interrupt instruction – RETI – is executed.
Qwertty
Цитата(Kuzmi4 @ Jan 25 2008, 12:16) *
На счёт 3-го - действительно TCNT0 сбрасывается в прерывании по сравнению, однако код не маленький и у меня таймер успевает натикать 3 раза - вот я его с брасываю - понимаю что не очень корректно - каюсь...

Чем больще код, тем вреднее обнуление TCNT. Особенно если в обработчике много условий - получается "переменный битрейт" smile.gif

Цитата(Kuzmi4 @ Jan 25 2008, 12:16) *
А вот на счёт 4-го я с вами не согласен - читал как то документацию на SIGNAL и INTERRUPT в WinAVR`е , да и где то на форуме даже дискуссия была по этому поводу - в обсчем суть в том что в SIGNAL нету кли а в INTERRUPT - есть. Хардварно ж флажок I не сбрасывается при вызове любого прерывания.... Поправть или ткните носом если не прав.

SIGNAL и INTERRUPT устарели. Сейчас модно ISR(_vektor_name_), прерывания в нем запрещены. Хардварно флаг I регистра SREG сбрасывается при вызове ЛЮБОГО прерывания, и восстанавливается при выходе командой reti.
Kuzmi4
2 Qwertty - на счёт ISR - я сижу на 2006-м потому как знаю его - меня пока всё устраивает.

На счёт "...восстанавливается при выходе командой reti..." - тут я не спорю, а вот на счёт "...Хардварно флаг I регистра SREG сбрасывается при вызове ЛЮБОГО прерывания..." - можете тыкануть носом ?

Поздно прочитал пост =GM= , счас читаю doc2466......

Можно уточнить - что это за документ такой - doc2466o чтото не нашёл..
Нашёл 2466 - это ДШ на мегу 16-ю.....
Qwertty
Цитата(Kuzmi4 @ Jan 25 2008, 13:37) *
2 Qwertty - на счёт ISR - я сижу на 2006-м потому как знаю его - меня пока всё устраивает.

ISR- в 2006 году как раз и появился. Во всяком случае почитайте interrupt.h - найдете такие строки:
Do not use SIGNAL() in new code. Use ISR() instead.

Цитата(Kuzmi4 @ Jan 25 2008, 13:37) *
На счёт "...восстанавливается при выходе командой reti..." - тут я не спорю, а вот на счёт "...Хардварно флаг I регистра SREG сбрасывается при вызове ЛЮБОГО прерывания..." - можете тыкануть носом ?

Поздно прочитал пост =GM= , счас читаю doc2466......

Можно уточнить - что это за документ такой - doc2466o чтото не нашёл..
Нашёл 2466 - это ДШ на мегу 16-ю.....

Ну тогда Ваша страница - 12.

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts
are disabled. The user software can write logic one to the I-bit to enable nested inter-
rupts. All enabled interrupts can then interrupt the current interrupt routine. The I-bit is
automatically set when a Return from Interrupt instruction – RETI – is executed.
IgorKossak
Цитата(Kuzmi4 @ Jan 25 2008, 12:37) *
Можно уточнить - что это за документ такой - doc2466o чтото не нашёл..
Нашёл 2466 - это ДШ на мегу 16-ю.....

Очевидно имелся в виду документ ревизии O.
Сейчас на сайте доступна ревизия P.
Kuzmi4
2 Qwertty - спасибо, прочитал - в замешательстве....

А на счёт остального - спасибо всем что помогли разобраться - как доберусь к железке сегодня - обязательно перекрою программу.

Хотя мучает вопрос - зачем же в SIGNAL нету кли а в INTERRUPT - есть ??
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.