gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Всем категорически безошибочного кода! Второй день бьюсь над передачей данных по USART. Исключил все промежуточные звенья, упростил до минимума и не понимаю, где ошибка. int main(void) { uint16_t ui16_ubrr; ui16_ubrr = F_CPU / 9600 / 16 - 1; UBRR0H = (unsigned char)( ui16_ubrr >> 8 ); UBRR0L = (unsigned char) ui16_ubrr; UCSR0C = (0 << USBS0)|(3 << UCSZ00); // 1 Stop-bits, 8 Data-bits UCSR0B = _BV(TXEN0); // Wait for empty transmit buffer while ( !( UCSR0A & (1<<UDRE0)) ) ; UDR0 = 'G'; // 0x47 // Wait for empty transmit buffer while ( !( UCSR0A & (1<<UDRE0)) ) ; UDR0 = 'H'; //0x48 } То есть, убрал вообще всё. Прерывания не разрешены. F_CPU=4000000UL. В UBRR0 попадает число 25, прямо как в табличке в ДШ. Согласно этой же табличке, отклонение 0.2% из допустимых +-2% При этом получаю не ожидаемые 0x47,0x48 а вместо них - 0x87,0x98 Пытался отправить "всю ASCII". Реализовал цикл 0...255 и смотрел, что приходит. Получил крайне странный результат. Полученная последовательность была такой: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x18, 0x19, 0x1A, ... , 0x1F, 0x20, 0x21, ... , 0x27, 0x38, 0x39, ... , далее аналогично до 0xFF, 0x00 и сначала. У кого был подобный прецедент? Удалось ли решить? Может ли это быть какая-то особенность или "косяк" в самом МК? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Скорости не совпадают. Например, из-за того что запрограммирован "Fuse bit" CKDIV8, оли вообще Fuses установлены по умолчанию, и поэтому МК тактируется совсем не от предполагаемого вами источника. Или имеет место ошибка в программе. Если есть осциллограф, можете определить реальную скорость на порту, это облегчит поиск причины описанной вами проблемы ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Just now, kovigor said: Скорости не совпадают. Например, из-за того что запрограммирован "Fuse bit" CKDIV8, оли вообще Fuses установлены по умолчанию, и поэтому МК тактируется совсем не от того источника, который вы предполагаете. Ну или ошибка в программе ... Пробовал на разных скоростях: 2400, 4800, 19200. На остальных процент ошибки вне допустимого. Даже пробовал 250k (ошибка 0%), хотя выше 14400 обычно стараюсь не подниматься - для решаемых задач хватает. Результат одинаковый (читать - такой же). Фузы выставлены, CKDIV8 точно нет. Осциллографом не отслеживал, но запускал таймер, моргал раз в секунду светодиодом, подсчитывал количество за минуту - тактовая больше похожа на те самые 4МГц... Весь код закомментирован, осталось только то, что приведено в первом посте плюс директивы #include... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Я в таких случаях пользуюсь осциллографом. Гадать можно до бесконечности ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба 6 minutes ago, kovigor said: в таких случаях пользуюсь осциллографом Непосредственно на TX линии? Или речь о контроле тактёра? P.S.: пробовал пускать два стоповых бита, но результат тот же. Неужели такое бывает непосредственно внутри кристалла? Ощущение, что при передаче 4 бит всегда "тащит" за собой установку 5го... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Да, на ней. Просто встаньте на нее осциллографом и зациклите программу на передаче одного и того же символа, а именно - 0x55 или 0xAA. Сразу многое прояснится - вы сможете определить длительность бита и даже их количество. Подойдет любой осциллограф, но лучше, конечно же, цифровой. Я раньше обходился и советскими аналоговыми. И еще, как-то случилось так, что некорректно работал в сторону машины передатчик на MAX232 (я забыл подпаять к нему один из конденсаторов). Так что схему, монтаж и собственно выход передатчика тоже проверьте ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Хорошо, спасибо за совет по контролю обвязки. Сейчас кристалл так ведет себя на двух отладочных платах, в том числе, на STK500. С другим МК проблемы не возникают. К сожалению, под руками нет другой mega328, чтобы исключить сам контроллер Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба No comments. Вчитываться в даташиты и чужой код у меня нет возможности. Я вам дал простейший рецепт - используйте осциллограф. Если его нет, напроситесь на чай с печеньками к знакомому, у которого он таки есть, это сэкономит вагон сил и времени. "Исключать" контроллер нечего. Я не представляю себе, что нужно с ним сделать, чтобы UART начал выдавать битые посылки. Разве что подпалить порт или запитать его нештатным напряжением. При чем тут напряжение ? Как-то запитал AT89C51 от 3.3В, а ему требуется минимум четыре. Все работало, но ... некорректно работала команда ADD (т.е. при суммировании получались неверные результаты). Исправилось это подъемом питающего напряжения до соотв. уровня ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба Ну, тут [пока] других ошибок не обнаружено, за исключением, получается, "битого" регистра UDR0 (кстати, в ДШ он почему-то просто UDR и это не единственное "несовпадение" между ДШ и данными в AtmelStudio именно по этому МК, раньше подобного не замечал, но и диапазон контроллеров, с которыми работал, не так уж широк). Получается, вне зависимости от того, отправляю я или получаю, посылка превращается: 0b???10??? -> 0b???11??? и, аналогично, 0b???01??? -> 0b???11???. При этом корректно ходят байты 0b???00??? Для меня просто удивление вызвало, что такое может быть только с конкретным регистром. В моем восприятии, почему-то либо не должно работать совсем, либо... :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба No comments, еще раз. У вас чисто программистский подход. В случае с персоналками это проходит. А вот в случае с МК - далеко не всегда. Я вам предложил начать с самого простого, а "большую науку" оставить на потом. Ваше дело - игнорировать мой совет или воспользоваться им ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ikm 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба 1 час назад, gretis сказал: То есть, убрал вообще всё. Прерывания не разрешены Вы про какие прерывание пишите, про Rx TX буфер тоже отключили, тогда зачем проверяете 1<<UDRE0? В чистом виде без буфера пробовали передавать? На всякий настройки чистого USART // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: On // USART Transmitter: On // USART0 Mode: Asynchronous // USART Baud Rate: 9600 UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0); UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80); UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0); UBRR0H=0x00; UBRR0L=0x33; ну и соотвевенно отправляёте символы через printf/puts/putchar не знаю какие есть в вашем компиляторе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба 1 minute ago, ikm said: В чистом виде без буфера пробовали передавать? ну и соотвевенно отправляёте символы через printf/puts/putchar не знаю какие есть в вашем компиляторе. В чистом виде, непосредственно кладу в регистр, без всяких printX/putX/... даже по одному байтику, без всяких ожиданий, прерываний, проверок... результат один и тот же. Сейчас собираюсь идти вынимать осциллограф, чтобы убедиться в том, что baudrate правильный. Да уж. Давно так не проваливался )) Как студент на первом экзамене... На одной отладке пока неясно, в чем была причина, на STK500 стоял джампер, переключающий тактёр не на том положении. Скорее от безысходности (до осциллографа еще не добрался, он дома, а я еще нет). Раскопал arduino платку и на 16МГц при той же ошибке все заработало... По крайней мере, дело было не в регистре. Да... Спасибо kovigor за настойчивость проверить осциллографом. Я даже уже нашел, как :) надо непрерывно слать 'U' и это будет соответствовать коду 010101.... при 9600-8-N-1 В данный момент подозрения с контроллера сняты, вопрос решен. Стоило только о форуме вспомнить. А сколько времени потеряно!... Да уж. Посыпаю голову пеплом Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 5 9 октября, 2018 Опубликовано 9 октября, 2018 · Жалоба 5 minutes ago, gretis said: Я даже уже нашел, как :) надо непрерывно слать 'U' и это будет соответствовать коду 010101.... при 9600-8-N-1 Да, именно так, вы все правильно поняли ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться