|
Глючит FT232BL |
|
|
|
May 15 2009, 23:42
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
ATMega48 соединена с FT232BL через TDX/RDX. По нажатию кнопки передаётся два байта на FT232BL: Код #define USART_BAUD 9600ul #define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)
void USART_vInit(void) { // Set baud rate unsigned short int UBRRH = USART_UBBR_VALUE>>8; unsigned short int UBRRL = USART_UBBR_VALUE;
// Set frame format to 8 data bits, no parity, 1 stop bit UCSR0C = (0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ00);
// Enable receiver and transmitter UCSR0B = (1<<RXEN0)|(1<<TXEN0); }
void USART_vSendByte(unsigned short int u8Data) { // Wait if a byte is being transmitted while((UCSR0A&(1<<UDRE0)) == 0); // Transmit data UDR0 = u8Data; }
unsigned short int USART_vReceiveByte() { if ((UCSR0A&(1<<RXC0)) == 0) {return UDR0;} else {return 0;} }
int main(void) // начало основой программы {
...
(ежесекундно проверяется статус кнопки, и, если кнопка нажата, то)
{ мигнуть лампочкой; USART_vSendByte(10); USART_vSendByte(15); }
} } Однако результат следующий. Во-первых, за раз отправляется только один байт. Во-вторых, он всегда равен 127 (в 7-битном режиме) или 255 (в 8-битном режиме). В-третьих, даже этот неверный байт отсылается не стабильно: в 60-70% случаев байт не отправляется, хотя лампочка мигает (т.е. условие нажатия выполняется). Кроме того, приём байта вообще не работает. Подозреваю, что причина - в неправильной работе с UART.
|
|
|
|
|
May 16 2009, 12:31
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
Угу. Исправил. Теперь глючит немного по-другому.
Если отправить байты "10" и "15", то на ПК считывает три (!) байта: 152,152,248
Если отправить один байт "10", считываются два байта: 152,248.
Если отправить один байт "15", считываются два байта: 152,248.
Если изменить скорость UART на 19200 и отправить байт "15", то считывается два байта: 254,252.
Скорости UART, ессно уставнавливались на ATMEGA48 и FT245BL одинаковые (сначала 9600, потом 19200). Формат передачи - 8-битный (пробовал и 7-битный - результат тот же, только получаемые байты другие).
|
|
|
|
|
May 16 2009, 13:37
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(uuu2 @ May 16 2009, 03:42)  Код // Set frame format to 8 data bits, no parity, 1 stop bit UCSR0C = (0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ00); Тут или код врёт, или комментарий к нему  Copy\paste - великий источник ошибок в программе. Впрочем, все равно может не работать. Потому что еще надо фьюзы выбора источника тактирования и деления частоты проверить. И значение F_CPU. Цитата(uuu2 @ May 16 2009, 03:42)  Подозреваю, что причина - в неправильной работе с UART. Ага, около того. Неплохо было бы заголовок темы сменить, а?
Сообщение отредактировал SysRq - May 16 2009, 13:39
|
|
|
|
|
May 16 2009, 15:41
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
Цитата(SysRq @ May 16 2009, 17:37)  Тут или код врёт, или комментарий к нему  Copy\paste - великий источник ошибок в программе. Начинать приходится с copy/paste. А потом разбираться с кодом.  Код #define F_CPU 2000000UL #define USART_BAUD 19200ul #define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)
UBRR0H = USART_UBBR_VALUE>>8; UBRR0L = USART_UBBR_VALUE;
[b]UCSR0C = (0<<UPM00)|(0<<UPM01) // проверка четн.откл |(0<<USBS0) // 1 стоп-бит |(1<<UCSZ00)|(1<<UCSZ01) // 8 бит фрейм |(0<<UMSEL00); // асинхронный[/b]
...
// Передача байта при нажатии кнопки USART_vSendByte(10); Биты регистра установил на основе данной странички (http://mcu.narod.ru/HARDANDSOFT/AVR_UART.htm). Там, правда, написано о ATMEGA128, но наименования битов в iom48p.h должны быть такими же (?). На ПК (драйвер микросхемы FT232BL) установлено: Код ... FT_Current_Baud:=19200; FT_Current_StopBits:=FT_STOP_BITS_1; FT_Current_Parity:=FT_PARITY_NONE; FT_Current_DataBits:=6; Set_USB_Device_DataCharacteristics; ... Результат передачи данных всё тот же: вместо 1 байта передается 2 неправильных. Тут, правда я не совесем понял. Начальный и стоп-биты входят во фрейм или нет? Т.е. если я установил фрейм в 8 бит и 1 стоп-бит, то получится 6 бит данных? Правильно? Кроме того, я посмотрел файл iom48.h Код #define UCSR0B _SFR_MEM8(0xC1) #define TXB80 0 #define RXB80 1 #define UCSZ02 2 #define TXEN0 3 #define RXEN0 4 #define UDRIE0 5 #define TXCIE0 6 #define RXCIE0 7
#define UCSR0C _SFR_MEM8(0xC2) #define UCPOL0 0 #define UCSZ00 1 #define UCPHA0 1 #define UCSZ01 2 #define UDORD0 2 #define USBS0 3 #define UPM00 4 #define UPM01 5 #define UMSEL00 6 #define UMSEL01 7 Это нормально, что биты UCSZ00 и UCPHA0 занимают одно и то же место в регистре? И почему бит UCSZ02 находится в регистре UCSR0B, а остальны 2 бита (UCSZ00 и UCSZ01) в регистре UCSR0С? Тут (http://mcu.narod.ru/HARDANDSOFT/AVR_UART.htm) все они расположены во одном регистре. А если установить UCSZ02 в единицу (чтобы передать 9-битный фрейм), то передача реально вообще не происходит. Цитата(SysRq @ May 16 2009, 17:37)  Ага, около того. Неплохо было бы заголовок темы сменить, а? Можно и сменить. Только я не модератор, как я его сменю?
|
|
|
|
|
May 16 2009, 16:04
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(uuu2 @ May 16 2009, 19:41)  Код |(1<<UCSZ00)|(1<<UCSZ01) // 8 бит фрейм Не фрейма, а данных размер это. Цитата(uuu2 @ May 16 2009, 19:41)  Код FT_Current_DataBits:=6; А это не фрейма, это данных размер... Цитата(uuu2 @ May 16 2009, 19:41)  ...наименования битов в iom48p.h должны быть такими же (?). Почему бы не взять официальный документ от Atmel на МК и не посмотреть (Яндекс\Google знает)? Для всех МК все по-разному. PS: USART в асинхронном режиме на 19200 работать при 2МГц не будет. Слишком велика ошибка - 7%. Оставьте 9600.
|
|
|
|
|
May 16 2009, 19:20
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
Цитата(SysRq @ May 16 2009, 20:04)  Не фрейма, а данных размер это.
PS: USART в асинхронном режиме на 19200 работать при 2МГц не будет. Слишком велика ошибка - 7%. Оставьте 9600. Т.е. и там, и там надо поставить по 8 бит? Стартовые и стоп-биты считаются отдельно? Насчёт скорости - поставил 9600. Потом поставил 7200. Потом поставил 300. Результат аналогичный. Причём обнаружена некоторая закономерность: Код 0 -> 0 0000 0000 1 -> 6,128 0000 0110 2 -> 24,128 0001 1000 3 -> 30,128 0001 1110 4 -> 96,128 0110 0000 5 -> 102,128 0110 0110 6 -> 120,128 0111 1000 7 -> 126,128 0111 1110 8 -> 128,128 1000 0000 9 -> 134,128 1000 0110 10 -> 152,128 1001 1000 11 -> 158,128 1001 1110 12 -> 224,128 1110 0000 13 -> 230,128 1110 0110 14 -> 248,128 1111 1000 15 -> 254,128 1111 1110 Слева указан байт (в виде десятичного числа), передаваемый через USART_vSendByte. Правее - два байта, получаемых на ПК. Ещё правее - двоичный вид первого полученного байта. Нетрудно заметить, что 7-й бит первого полученного числа равен 3-му биту изначального числа; 6-й и 5-й бит равен 2-му биту изначального числа; 4-й и 3-й - 1-му биту изначального числа; 2-й и 1-й - 0-му биту изначального числа; 0-й бит всегда равен нулю. При этом первый полученный байт чередуется через 16, т.е первый байт для "изначальных" чисел 0,16,32,48... - один и тот же. Во втором полученном байте также есть закономерности, но не столь явные (т.е конкретных битов вычленить невозможно). Единственно, что 0-й бит там тоже всегда равен нулю. Кроме того, для некоторых чисел выдается одна и та же пара бит (например, для "изначальных" чисел 112 и 160 выдаётся "0,254"). Т.е. получается, что получаемые данные не определяют однозначно отправленное число.
|
|
|
|
|
May 16 2009, 19:40
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(uuu2 @ May 16 2009, 23:20)  Причём обнаружена некоторая закономерность: Очевидно, что скорость передатчика примерно вдвое ниже скорости приемника. Цитата(uuu2 @ May 16 2009, 23:20)  Т.е. и там, и там надо поставить по 8 бит? Стартовые и стоп-биты считаются отдельно? Да.
|
|
|
|
|
May 16 2009, 19:51
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Пока сообщение набивал, да отвлекался, все уже до меня рассказали  Цитата(uuu2 @ May 16 2009, 23:20)  Т.е. получается, что получаемые данные не определяют однозначно отправленное число. Попытка "восстановить" исходные данные по "результату" достойна уважения Выставляйте одинаковые параметры фрейма 8-N-1 (8 бит данных, четности нет, стоповый один), в МК 9600, а на компе пробуйте 4800 (судя по всему, МК на 1МГц работает). PS: поинтересуйтесь в качестве чтива на ночь как работает асинхронный USART: состав фрейма, как детектируется начало посылки, как передаются данные и как они восстанавливаются на приёмной стороне, зачем нужен стоп-бит, как детектируются ошибка фрейма, ошибка четности. В инете описаний масса.
Сообщение отредактировал SysRq - May 16 2009, 19:51
|
|
|
|
|
May 16 2009, 20:23
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
Гыг! Именно это я и сделал. На МК поставил 9600, на ПК 19200. Кроме того, на МК поставил 8 бит данных, а на ПК - 7 бит. И заработало.  Только я не понял: 1) Почему заработало? Ещё можно предположить, что МК работает на 1 Мгц (щас полезу в документацию), то при чём тут количество бит данных? (если биты данных на МК и ПК сделать равными, то вместо 0 выдаётся 128, вместо 1 - 129 и т.п.) 2) Как передать 8-битную структуру? Сейчас, выходит, передаётся по 7 бит (?). 3) Как вы поняли, что скорость передатчика вдвое ниже скорости приёмника? Потому два бита подряд дублируются? Но почему передача начинается с 3-го бита, а не с 7-го?
|
|
|
|
|
May 16 2009, 22:49
|
Участник

Группа: Участник
Сообщений: 50
Регистрация: 23-04-09
Пользователь №: 48 156

|
Ознакомился. Как оказалось, передача всё-таки работала неправильно. По-видимому, вместо последнего (старшего) бита читался стоповый бит, в результате вместо 0 появлялось значение 128. Я элегантно "исправил" это недоразумение, установив на ПК 7-битный формат данных. Правда, дальше проявилась другая ошибка - иногда заменялся один из бит (т.е. полученное число оказывалось на 2^N больше/меньше, чем оригинальное). Пришлось умерить свои амбиции и установить битрейт в 4800. При этом 8-битный пакет данных стал читаться нормально (стоповый бит не проявлялся), ошибочный бит появляться перестал. Всё хорошо. Только вот 4200 бит! И это в 21-м веке, когда космические коабли бороздят просторы Вселенной! Маловато. Кроме того, МК работает на 1 Мгц (а я сначала думал - на 2), значит, на передачу бита уходит 238 "тиков". Если установить битрейт 9600, то будет 119 тиков. Неужели это так мало? Я ещё понимаю, что при 5-10-15 тиках могут (и должны) быть ошибки в отлове битов, но 119 тиков!!! Хотя, конечно, могут (а могут?!) быть погрешности в частоте кварца: вместо 1 МГц реально там 0,9 МГц, в итоге сигнал "растягивается", и появляются ошибки. Но я не знаю, 10%-я погрешность - это нормально для встроенного в МК (!) генератора фирмы Atmel?!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|