Обсуждаем контроллеры компании Atmel.
Ответить

9-ти битный UART

Пн июн 07, 2021 23:36:12

Здравия вам товарищи коты) Возник вопрос при изучении 9 битного варта. Смысл такой, написал программу для двух мк 168 меги, в программе они обмениваются по варту бегущими огнями (посылки 9 бит). При получении посылки сначала считываются три бита ошибок варта (FE0, DOR0, UPE0) и каждый бит выводится на свой пин индикации (светодиоды), ну и сами 9 бит посылки выводятся на порт индикации, засада в том, по принятию посылки, где установлен 9-ый бит возникает ошибка кадрирования (FE0) , как только принимается следующая посылка с нулевым значением 9-го бита флаг ошибки кадрирования сбрасывается, почему так?
ниже исходник для обоих мк, в исходнике в коментах все подробно написано


Re: 9-ти битный UART

Вт июн 08, 2021 13:09:22

Не у кого нет никаких мыслей по этому поводу?

Re: 9-ти битный UART

Ср июн 09, 2021 11:08:08

Не у кого нет никаких мыслей по этому поводу.
Видимо UART больше никто не использует (устарело).
Есть куча других интерфейсов и протоколов.
схема_1.jpg
(196.87 KiB) Скачиваний: 134

:tea:

Re: 9-ти битный UART

Ср июн 09, 2021 22:24:37

roman.com, что то не могу себе представить, что UART не используется)))
сама программа работает, отправляет принимает, биты не теряются, просто хочу выяснить я где то схалтурил или такая особенность у микроконтроллеров атмеловских?
ну еще правда в даташите на 168 мегу приводится такая функция приема посылки о 9 битах

Код:
unsigned int USART_Receive( void )                     // Получим статус и 9-й бит, затем данные из буфера приемника
{
     unsigned char status, resh, resl;                 // объявим переменные
                                                     
     while ( !(UCSR0A & (1<<RXC0)) );                  // ожидаем завершения приема (получение данных)

     status = UCSR0A;                                  // считываем значение регистра статуса (UCSR0A) в переменную (status), ( тут у нас флаги FE0, DOR0, UPE0)
     resh = UCSR0B;                                    // считываем значение регистра управления (UCSR0B) в переменную (resh), в нем же 9 по счету бит (RXB80)
     resl = UDR0;                                      // считываем полученный 8 битный байт данных из регистра данных (UDR0)
                                                   
     if ( status & (1<<FE0)|(1<<DOR0)|(1<<UPE0) )      // проверяем установлены ли биты (FE0, DOR0, UPE0), если хоть один бит установлен, то выполняем код в скобках
     {                                                 
          return -1;                                   // ошибка приемопередачи модуля USART0
     }     
                                               
   resh = (resh >> 1) & 0x01;                     // сместим байт (resh) на одну позицию вправо, тем самым бит принимаемых данных (RXB80) с 1 позиции в байте перейдет на 0 позицию,
                                                  // затем затем на этот байт  набросим маску 0x01 и все разряды обнулятся кроме нулевого разряда, в нем будет значение бита (RXB80)

    return ((resh << 8) | resl);                       // сместим бит (RXB80) в 9 по счету бит, а в восемь остальных младших бит поместим значение из (UDR0)

}


как может быть return -1 ? там же на выходе unsigned int? не понимаю....
короче я переделал эту функцию как по моему пониманию она должна работать

Код:
uint16_t USART_Receive( void )                 // прием 9-ти битной посылки в режиме (9-N-1). выдаем из функции через ретурн 2-х байтное слово
{                                                //                                             8-0-ой разряд ---------- младший байт посылки                               
                                              //                                             9-ой разряд   ---  бит  (RXB80)   -- 9 бит посылки
                                              //                                             10-ый разряд  ---  бит  (UPE0)    -- Флаг ошибки контроля четности
                                              //                                             11-ой разряд  ---  бит  (DOR0)    -- Флаг переполнения
                                              //                                             12-ий разряд  ---  бит  (FE0)     -- Флаг ошибки кадрирования
    while ( !(UCSR0A & (1<<RXC0)) );           // ожидаем завершения приема (  ПРИМЕНЯЕМ ЭТУ СТРОКУ, ЕСЛИ ФУНКЦИЯ РАБОТАЕТ НЕ В ПРЕРЫВАНИИ ПО ЗАВЕРШЕНИЮ ПРИЕМА)                                    
                                    
   uint8_t status, resh, resl, err_stat;      // объявим переменные

   status = UCSR0A;                           // считываем значение регистра статуса (UCSR0A) в переменную (status), ( тут у нас флаги FE0, DOR0, UPE0)
   resh = UCSR0B;                             // считываем значение регистра управления (UCSR0B) в переменную (resh), в нем же 9 бит (RXB80)
   resl = UDR0;                               // считываем полученый 8 битный байт данных из регистра данных (UDR0)
   
   status = (status >> 1) & 0x0E;             // сместим байт (status) на одну позицию вправо, тем самым бит (UPE0) со 2-го разряда перейдет в 1-ой, бит (DOR0) с 3-го
                                              // во 2-ый, бит (FE0) с 4-го в 3-ой, затем на байт  набросим маску 0x0E и все разряды обнулятся кроме 1,2,3 в которых
                                             // теперь наши статусные биты (FE0, DOR0, UPE0)
   
   if (resh & 0x02)                           // проверяем 1 разряд переменной (resh) он же (RXB80) , если этот бит = 1, то выполняется выражение в скобках
   {
      status |= (1<<0);                       // установить в 1 нулевой разряд переменной (status), остальные биты не трогаем       
   }
    else                                       // иначе если 1 бит переменной (resh) равен 0 , то выполняется выражение в скобках
   {
      status &= ~(1<<0);                      // сбросить в 0  нулевой разряд  переменной (status), остальные биты не трогаем
   }   
                                               // теперь в переменной (status) у нас биты:    0-ой разряд   ---  бит  (RXB80)
                                               //                                             1-ый разряд   ---  бит  (UPE0)
                                               //                                             2-ой разряд   ---  бит  (DOR0)
                                               //                                             3-ий разряд   ---  бит  (FE0)     
   
   return ((status << 8) | resl);             // сместим байт (status) в старший байт двухбайтового слова и получится такая картина--   
                                               //                                             9-ой разряд   ---  бит  (RXB80)   -- 9 бит посылки
                                               //                                             10-ый разряд  ---  бит  (UPE0)    -- Флаг ошибки контроля четности
                                               //                                             11-ой разряд  ---  бит  (DOR0)    -- Флаг переполнения
                                               //                                             12-ий разряд  ---  бит  (FE0)     -- Флаг ошибки кадрирования                                                                                                                            
                                              // а в восемь остальных младших бит поместим значение из (UDR0)



может дело в этом? мне правда интересно разобраться в чем тут дело , товарищи полосатые кто обладает знанием подсобите?

Re: 9-ти битный UART

Пн июн 14, 2021 22:59:02

На си писал очень давно и не под AVR. Поэтому не особо вникал в код. Плюс не совсем понятно поставлена вами задача, которую вы пытаетесь решить; и совершенно непонятно, какие действия вы проделывали, чтобы проверить, что вы хотя бы отправляете правильный сигнал по UART. И да, вы не привели схему вашего устройства.

Попытаюсь помочь экстрасенсорно. Для начала перепроверьте все ваши инициализации. Откройте даташит на МК (оригинал) и пройдитесь по всем управляющим регистрам и явно определите инициализируемые значения для ВСЕХ регистров UART (даже для казалось бы не используемых). Ни в коем случае не доверяйте указанным в даташите значениям по умолчанию, иногда они бывают другими, я лично на это натыкался.

Про логику вашей программы я ничего сказать не могу. Для проверки сигнала вы можете сделать следующее. Выставите скорость UART такой, чтобы длительность импульсов переключения была достаточно низкочастотной. Подключите через подходящий делитель на резисторах выход UART к звуковому входу компьютера и запишите сигнал в каком-нибудь аудиоредакторе (например, Sony Sound Forge). Внимательно изучите записанный сигнал и убедитесь, что в сигнале правильная последовательность импульсов правильной длины. Важно заметить, что иногда звуковые карты (особенно при записи через микрофонный вход, а не через линейный) инвертируют фазу сигнала. Это тоже надо проверить. Если у вас есть супернавороченный цифровой осциллограф, позволяющий записать сигнал, а потом изучить его в своё удовольствие со всеми подробностями — тем лучше.

Приведённый вами код совершенно неудобочитаем. Если хотите, чтобы кто-то в него серьёзно повникал, отредактируйте его так, чтобы не было переносов комментариев через строчку. Рекомендую включить в вашем редакторе кода ограничение в 80 символов (стандартная величина), и не выпускать код за это значение. Если в настройках нет ничего подобного, то можно прикинуть величину и уменьшить окно редактирования, так чтобы его размер указывал вам ограничение.

Re: 9-ти битный UART

Вт июн 15, 2021 23:16:17

B@R5uk, дело в том, что в авр студии и в нотепаде код с комментариями как раз четнко в строчку со всеми пробелами и отступами, сюда вставляю и тут с переносами и тд.. В Notepad++ или в авр студии можно его открыть, чтоб аккуратным он был. это не устройство, просто тупо две 168 атмеги пересылают по 9-ти битному варту бегущий огонек, биты и байты не пропускаются, логическим анализатором в железе смотрю и на светодиодах индикации тоже вижу правильную последовательность бегущего огонька на обоих мк. задача простая, в железе проверить и изучить работу аппаратного варта на атмеге 168р. в протеусе тоже самое поведение

сишный файл прилагаю
Вложения
main.c
(14.39 KiB) Скачиваний: 76
Ответить