реклама на сайте
подробности

 
 
> USART
KIG
сообщение Jul 25 2007, 10:13
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



Здравствуйте!
Пытаюсь передать цифру 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);
}
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
KRS
сообщение Jul 25 2007, 10:19
Сообщение #2


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(KIG @ Jul 25 2007, 14:13) *
На компьютере принамаю вместо одной цифры три, причем среди них нет ни одной пятерки.

Так на меге baudrate не правильно задан. у вас на какой частоте она работает?
сейчас baud rate CLOCK_FREQ/16/2
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 25 2007, 10:47
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



По поводу 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


--------------------
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jul 25 2007, 12:13
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(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);
}
}

Если не поможет, смотрите скорость передачи.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 25 2007, 12:21
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(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)


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
KIG
сообщение Jul 25 2007, 12:22
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



Цитата(KRS @ Jul 25 2007, 13:19) *
Так на меге baudrate не правильно задан. у вас на какой частоте она работает?
сейчас baud rate CLOCK_FREQ/16/2


Частота кварца 3.6864МГц. Согласно вашего уравнения baud rate задан верно (115200).
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 25 2007, 12:46
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Сергей Борщ @ 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)


--------------------
Go to the top of the page
 
+Quote Post
Igor26
сообщение Jul 25 2007, 12:59
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 521
Регистрация: 10-02-05
Пользователь №: 2 544



А почему два стоп-бита?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 25 2007, 14:05
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Igor26 @ Jul 25 2007, 15:59) *
А почему два стоп-бита?
Чтобы уменьшить влияние ошибки скорости. На приеме все равно анализируется только первый, а второй играет роль защитной паузы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jul 26 2007, 12:12
Сообщение #10


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Сергей Борщ @ Jul 25 2007, 13:05) *
Чтобы уменьшить влияние ошибки скорости. На приеме все равно анализируется только первый, а второй играет роль защитной паузы

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

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

В настоящее время время второй стоп-бит никакого практического значения не имеет.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 26 2007, 14:45
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jul 26 2007, 15:18
Сообщение #12


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



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

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

Можно было бы вообще отказаться от стоп-бита, к примеру раньше был такой код МТК-2 без стоп-бита, он состоял из нулевого старт-бита и 5-ти бит данных. Ничё, нормально всё работало...


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 26 2007, 20:20
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



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

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

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

Теперь два стоп-бита практически не используются, но если зарядить два стоп-бита, то такая система беспроблемно будет работать с системой, на другом конце провода, на которой выставлен 1 стоп-бит. Может понадобится разве что если вы не справляетесь с обработкой байта после приёма.
Go to the top of the page
 
+Quote Post
colombo_2007
сообщение Jul 27 2007, 05:50
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 19-07-07
Пользователь №: 29 221



Я так и не понял решилась ли у вас проблема. Если не решилась проверьте фьюзы, контроллер может работать от внутреннего генератора с меньшей частотой.


--------------------
Все просто, но нам не заметно
Go to the top of the page
 
+Quote Post
KIG
сообщение Jul 27 2007, 16:45
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



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



Проблема решилась частично. Действительно МК работал от внутреннего генератора. Установив фьюзы, запитал от внешнего кварца. Решил проверить путем передачи цифры '5' одну за другой, но принять что хотел не удалось. В зависимости от момента подключения программы Terminal к COM-порту на экране появлялись разные цифры, но не '5' (пару раз все же удалось вовремя подключиться и принимать '5', но отключившись и снова подключившись принимал другие цифры). От проблемы избавился путем установки задержки по времени между отправками '5'. Почему все-таки не удавалось принимать пятерку при её отправлении без задержки? ( Пробовал разные Baude rate - всё также).
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 27 2007, 17:02
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(KIG @ Jul 28 2007, 00:45) *
Проблема решилась частично........

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

Или я еще чего упустил?


--------------------
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jul 27 2007, 21:42
Сообщение #17


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



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

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

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

Кстати, какой байт вы шлёте: 0х05 или 0х35?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Petka
сообщение Jul 28 2007, 08:18
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



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


ещё есть способ засинхронизовать передачу. для этого в начале передачи или с некоторым периодом посылать в УАРТ 0xFF, 0x00. в этой последовательности не существует ложных старт и стоп битов =)
Go to the top of the page
 
+Quote Post
KIG
сообщение Jul 30 2007, 07:50
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 25-12-06
Пользователь №: 23 884



Спасибо за помощь! Постараюсь сегодня попробовать!:)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 20:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01514 секунд с 7
ELECTRONIX ©2004-2016