Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
KIG
Здравствуйте!
Пытаюсь передать цифру 5 через USART ATmega16 на компьютер в программу Terminal. На компьютере принамаю вместо одной цифры три, причем среди них нет ни одной пятерки. В программе Terminal установил скорость передачи в 115200 кбит/с, 2 стоповых бита, 8 бит в кадре. Код программы привел ниже. В чем причина, что я делаю неправильно?

#include <iom16v.h>
#include <macros.h>

void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UBRRL = 0x01; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRC = 0x8E;
UCSRB = 0x08;
}

void putchar(char ch)
{ while (!(UCSRA&(1<<UDRE)));
UDR=ch;
}

void main(void)
{CLI(); //disable all interrupts
uart0_init();
SEI(); //re-enable interrupts
putchar(5);
while(1);
}
KRS
Цитата(KIG @ Jul 25 2007, 14:13) *
На компьютере принамаю вместо одной цифры три, причем среди них нет ни одной пятерки.

Так на меге baudrate не правильно задан. у вас на какой частоте она работает?
сейчас baud rate CLOCK_FREQ/16/2
prottoss
По поводу baudrate : я делаю так

Код
#define CPU_CLOCK     14745600U /* clock in Hz */
...
#define USART_BAUD_RATE  115200U    /* USART baud rate */
...
#define USART_BAUD_RATE_CONST  (((CPU_CLOCK / 16) / USART_BAUD_RATE) - 1)
...
...
void USART0_Init(void)
{
   /* setup baud rate */
    UBRR0L = (UCHAR)(USART0_BAUD_RATE_CONST);
    UBRR0H = (UCHAR)(USART0_BAUD_RATE_CONST >> 8);

   /* setup frame and enable USART */
    UCSR0C = (USART0_FRAME_SETUP);
    UCSR0B = ((1 << RXEN0) | (1 << TXEN0) | (1 << TXCIE0));

   ...
}



PS: ИМХО записи типа UCSR0C = 0хА2 ну оччень не наглядны, особливо если работаешь на нескольких платформах и периодически их меняешь... А мож у мя память девичья biggrin.gif
=GM=
Цитата(KIG @ Jul 25 2007, 09:13) *
Пытаюсь передать цифру 5 через USART ATmega16 на компьютер в программу Terminal.
void putchar(char ch)
{ while (!(UCSRA&(1<<UDRE)));
UDR=ch;
}

Чтобы принять цифру 5 (как символ), надо послать код азки 0х35, а не код 0х05, как делаете вы.

Поставьте putchar(ch) после while, чтобы в цикле была непрерывная передача, легче смотреть
Цитата(KIG @ Jul 25 2007, 09:13) *
void main(void)
{
- - - - - - -
while(1)
{
putchar(0х30);
}
}

Если не поможет, смотрите скорость передачи.
Сергей Борщ
Цитата(prottoss @ Jul 25 2007, 13:47) *
Код
#define USART_BAUD_RATE_CONST  (((CPU_CLOCK / 16) / USART_BAUD_RATE) - 1)
Такая формула может давать погрешность из-за отсекания дробной части результата вместо округления. Вот так будет правильнее:
Код
#define USART_BAUD_RATE_CONST  ((((CPU_CLOCK) / 16) + ((USART_BAUD_RATE) / 2 - 1) / (USART_BAUD_RATE) - 1)
KIG
Цитата(KRS @ Jul 25 2007, 13:19) *
Так на меге baudrate не правильно задан. у вас на какой частоте она работает?
сейчас baud rate CLOCK_FREQ/16/2


Частота кварца 3.6864МГц. Согласно вашего уравнения baud rate задан верно (115200).
prottoss
Цитата(Сергей Борщ @ Jul 25 2007, 20:21) *
Такая формула может давать погрешность из-за отсекания дробной части результата вместо округления. Вот так будет правильнее:
Код
#define USART_BAUD_RATE_CONST  ((((CPU_CLOCK) / 16) + ((USART_BAUD_RATE) / 2 - 1) / (USART_BAUD_RATE) - 1)


Спасибо за поправку beer.gif Я, правда использовал свою формулу всегда с "правильными", для USART, кварцами и "правильными" baudrate, по этому, наверное, ошибок никогда не было smile.gif

Но теперь Вашу формулу возьму на вооружение...

Со скобками чуть чуть у Вас неточность - забыли одну:



((((CPU_CLOCK) / 16) + ((USART0_BAUD_RATE) / 2 - 1) ) / (USART0_BAUD_RATE) - 1)
Igor26
А почему два стоп-бита?
Сергей Борщ
Цитата(Igor26 @ Jul 25 2007, 15:59) *
А почему два стоп-бита?
Чтобы уменьшить влияние ошибки скорости. На приеме все равно анализируется только первый, а второй играет роль защитной паузы.
=GM=
Цитата(Сергей Борщ @ Jul 25 2007, 13:05) *
Чтобы уменьшить влияние ошибки скорости. На приеме все равно анализируется только первый, а второй играет роль защитной паузы

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

На самом деле второй стоп-бит был предназначен для обработки принятого символа медленными устройствами, существовавшими на заре развития вычтехники, а именно, телетайпами и принтерами.

В настоящее время время второй стоп-бит никакого практического значения не имеет.
Сергей Борщ
Цитата(=GM= @ Jul 26 2007, 15:12) *
Ну здесь вы немного погорячились(:-). Вгрубе так: два стоп-бита никак не влияют на уменьшение влияния ошибки скорости. Если частоты передачи и приема расходятся, то вторым стоп битом ничего поправить нельзя, увы.
Боюсь, что здесь вы заблуждаетесь. Если скорость передачи несколько (на пределе) больше заданной, а скорость приема несколько меньше заданной, то в точка семлирования стоп-бита может залезть на второй стоп-бит и сбоя не будет, а если бы второго стоп-бита не было - в этом месте оказался бы следующий старт-бит с вытекающим frame-error.
=GM=
Цитата(Сергей Борщ @ Jul 26 2007, 13:45) *
Боюсь, что здесь вы заблуждаетесь. Если скорость передачи несколько (на пределе) больше заданной, а скорость приема несколько меньше заданной, то в точка семлирования стоп-бита может залезть на второй стоп-бит и сбоя не будет, а если бы второго стоп-бита не было - в этом месте оказался бы следующий старт-бит с вытекающим frame-error.

Ничего не заблуждаюсь. Давайте посчитаем. Пусть частоты скорости передатчика и приёмника различаются в плюс. Первый старт-бит будет определен не точно в середине а чуть ближе к концу, первый бит - ещё чуть дальше, последний девятый бит должен прийтись на самый край, то есть относительная ошибка двух частот не должна быть больше, чем (То/2)/(9*То)=+5.5%. Если ошибка будет чуть больше, то вместо 7 бита данных запишется стоп-бит. Что будет происходить дальше, уже неважно, поскольку произошла ошибка в приеме данных. Её ничем нельзя исправить, хоть 2 стоп-бита ставьте, хоть три...

Можно было бы вообще отказаться от стоп-бита, к примеру раньше был такой код МТК-2 без стоп-бита, он состоял из нулевого старт-бита и 5-ти бит данных. Ничё, нормально всё работало...
SasaVitebsk
Даже ещё усугублю немножко. smile.gif Я тут хомутнул и на IBM выставил 5 бит. Использовал куски готовые и компоненту которую раньше использовал. Но в компоненте забыл выставить параметры, ну а по умолчанию было 5-N-1. Протокол у меня с CRC. Ну а на микрухе выставил всё правильно.

При тестировании передавалась посылка - с десяток байт. Так вы не поверите - на приём в однокристалке всё работало правильно, а вот с приёмом IBM были проблемы. Обрезались старшие биты. То есть похоже (честно не разбирался) что IBM всё равно передаёт 8 бит просто заполняет их как-то. Иначе не пойму как у меня это всё работало. Точнее не IBM, а FTDI. Забыл сказать, ft232rl стояла.

В книге Агурова "Последовательные интерфейсы ПК" реализуется 7ми битный режим передачи с помощью простого восьмибитного путём добавления 1 в старший бит. А я, баран, в своё время не догадался. Надо мне было, так я программно его. smile.gif

Теперь два стоп-бита практически не используются, но если зарядить два стоп-бита, то такая система беспроблемно будет работать с системой, на другом конце провода, на которой выставлен 1 стоп-бит. Может понадобится разве что если вы не справляетесь с обработкой байта после приёма.
colombo_2007
Я так и не понял решилась ли у вас проблема. Если не решилась проверьте фьюзы, контроллер может работать от внутреннего генератора с меньшей частотой.
KIG
Цитата(colombo_2007 @ Jul 27 2007, 08:50) *
Я так и не понял решилась ли у вас проблема. Если не решилась проверьте фьюзы, контроллер может работать от внутреннего генератора с меньшей частотой.



Проблема решилась частично. Действительно МК работал от внутреннего генератора. Установив фьюзы, запитал от внешнего кварца. Решил проверить путем передачи цифры '5' одну за другой, но принять что хотел не удалось. В зависимости от момента подключения программы Terminal к COM-порту на экране появлялись разные цифры, но не '5' (пару раз все же удалось вовремя подключиться и принимать '5', но отключившись и снова подключившись принимал другие цифры). От проблемы избавился путем установки задержки по времени между отправками '5'. Почему все-таки не удавалось принимать пятерку при её отправлении без задержки? ( Пробовал разные Baude rate - всё также).
prottoss
Цитата(KIG @ Jul 28 2007, 00:45) *
Проблема решилась частично........

В зависимости от момента подключения программы Terminal к COM-порту на экране появлялись разные цифры, но не '5' (пару раз все же удалось вовремя подключиться и принимать '5', но отключившись и снова подключившись принимал другие цифры)..................
не пойму зависимости подключения программы Terminal smile.gif ... Запускаешь Terminal, идешь на кухню, наливаешь кофе, приходишь к компьютеру, жмешь ресет или еще чегойто на макетной плате, видишь цифру 5 smile.gif ...

Или я еще чего упустил?
=GM=
Цитата(KIG @ Jul 27 2007, 16:45) *
В зависимости от момента подключения программы Terminal к COM-порту на экране появлялись разные цифры, но не '5' (пару раз все же удалось вовремя подключиться и принимать '5', но отключившись и снова подключившись принимал другие цифры). От проблемы избавился путем установки задержки по времени между отправками '5'. Почему все-таки не удавалось принимать пятерку при её отправлении без задержки?

Потому что вы передаёте байты, плотно пристыкованные друг к другу, используя UDRE. Поскольку вы включаете терминал в произвольный момент времени, вы попадаете на произвольный бит непрерывной последовательности. Если это нулевой бит, то программа терминал считает, что она зацепилась за старт-бит, ну и всё повторяется циклически.

Чтобы избежать подобного положения вещей, сначала включите программу терминал, затем подайте питание на МК. Приёмный уарт в ПК засинхронизируется от первого байта и вы получите то, что хотите.

Кстати, какой байт вы шлёте: 0х05 или 0х35?
Petka
Цитата(=GM= @ Jul 28 2007, 01:42) *
Чтобы избежать подобного положения вещей, сначала включите программу терминал, затем подайте питание на МК. Приёмный уарт в ПК засинхронизируется от первого байта и вы получите то, что хотите.


ещё есть способ засинхронизовать передачу. для этого в начале передачи или с некоторым периодом посылать в УАРТ 0xFF, 0x00. в этой последовательности не существует ложных старт и стоп битов =)
KIG
Спасибо за помощь! Постараюсь сегодня попробовать!:)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.