Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глючит FT232BL
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
uuu2
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.
aaarrr
Код
    unsigned short int UBRRH = USART_UBBR_VALUE>>8;
    unsigned short int UBRRL = USART_UBBR_VALUE;

Вы присваиваете значение делителя локальным переменным с именами UBRRH и UBRRL, а не регистрам.
uuu2
Угу. Исправил. Теперь глючит немного по-другому.

Если отправить байты "10" и "15", то на ПК считывает три (!) байта: 152,152,248

Если отправить один байт "10", считываются два байта: 152,248.

Если отправить один байт "15", считываются два байта: 152,248.

Если изменить скорость UART на 19200 и отправить байт "15", то считывается два байта: 254,252.

Скорости UART, ессно уставнавливались на ATMEGA48 и FT245BL одинаковые (сначала 9600, потом 19200). Формат передачи - 8-битный (пробовал и 7-битный - результат тот же, только получаемые байты другие).
SysRq
Цитата(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);
Тут или код врёт, или комментарий к нему smile.gif Copy\paste - великий источник ошибок в программе.

Впрочем, все равно может не работать. Потому что еще надо фьюзы выбора источника тактирования и деления частоты проверить. И значение F_CPU.

Цитата(uuu2 @ May 16 2009, 03:42) *
Подозреваю, что причина - в неправильной работе с UART.
Ага, около того. Неплохо было бы заголовок темы сменить, а?
uuu2
Цитата(SysRq @ May 16 2009, 17:37) *
Тут или код врёт, или комментарий к нему smile.gif Copy\paste - великий источник ошибок в программе.


Начинать приходится с copy/paste. А потом разбираться с кодом. smile.gif

Код
#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) *
Ага, около того. Неплохо было бы заголовок темы сменить, а?
Можно и сменить. Только я не модератор, как я его сменю?
SysRq
Цитата(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.
uuu2
Цитата(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"). Т.е. получается, что получаемые данные не определяют однозначно отправленное число.
aaarrr
Цитата(uuu2 @ May 16 2009, 23:20) *
Причём обнаружена некоторая закономерность:

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

Цитата(uuu2 @ May 16 2009, 23:20) *
Т.е. и там, и там надо поставить по 8 бит? Стартовые и стоп-биты считаются отдельно?

Да.
SysRq
Пока сообщение набивал, да отвлекался, все уже до меня рассказали smile.gif

Цитата(uuu2 @ May 16 2009, 23:20) *
Т.е. получается, что получаемые данные не определяют однозначно отправленное число.
Попытка "восстановить" исходные данные по "результату" достойна уважения biggrin.gif
Выставляйте одинаковые параметры фрейма 8-N-1 (8 бит данных, четности нет, стоповый один), в МК 9600, а на компе пробуйте 4800 (судя по всему, МК на 1МГц работает).

PS: поинтересуйтесь в качестве чтива на ночь как работает асинхронный USART: состав фрейма, как детектируется начало посылки, как передаются данные и как они восстанавливаются на приёмной стороне, зачем нужен стоп-бит, как детектируются ошибка фрейма, ошибка четности. В инете описаний масса.
uuu2
Гыг! Именно это я и сделал. На МК поставил 9600, на ПК 19200. Кроме того, на МК поставил 8 бит данных, а на ПК - 7 бит. И заработало. smile.gif

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

Больше ничего не подскажу принципиально laughing.gif
Цитата(SysRq @ May 16 2009, 23:51) *
PS: поинтересуйтесь в качестве чтива на ночь как работает асинхронный USART: состав фрейма, как детектируется начало посылки, как передаются данные и как они восстанавливаются на приёмной стороне, зачем нужен стоп-бит, как детектируются ошибка фрейма, ошибка четности. В инете описаний масса.
uuu2
Ознакомился. Как оказалось, передача всё-таки работала неправильно. По-видимому, вместо последнего (старшего) бита читался стоповый бит, в результате вместо 0 появлялось значение 128. Я элегантно "исправил" это недоразумение, установив на ПК 7-битный формат данных.

Правда, дальше проявилась другая ошибка - иногда заменялся один из бит (т.е. полученное число оказывалось на 2^N больше/меньше, чем оригинальное). Пришлось умерить свои амбиции и установить битрейт в 4800. При этом 8-битный пакет данных стал читаться нормально (стоповый бит не проявлялся), ошибочный бит появляться перестал.

Всё хорошо. Только вот 4200 бит! И это в 21-м веке, когда космические коабли бороздят просторы Вселенной! Маловато. smile.gif

Кроме того, МК работает на 1 Мгц (а я сначала думал - на 2), значит, на передачу бита уходит 238 "тиков". Если установить битрейт 9600, то будет 119 тиков. Неужели это так мало? Я ещё понимаю, что при 5-10-15 тиках могут (и должны) быть ошибки в отлове битов, но 119 тиков!!! Хотя, конечно, могут (а могут?!) быть погрешности в частоте кварца: вместо 1 МГц реально там 0,9 МГц, в итоге сигнал "растягивается", и появляются ошибки. Но я не знаю, 10%-я погрешность - это нормально для встроенного в МК (!) генератора фирмы Atmel?!
DpInRock
Мама дорогая.
В древности отроков, которые даташитов не читают - пороли на конюшне.
Уберите галочку у CLKDIV8, если понипрог используете.
И думайте, что МК работает на 8МГц. Типо, предположите...
aaarrr
Чтобы обеспечить стабильную работу UART, отклонение частоты не должно превышать 1.5%. Внутренний RC без калибровки тут не подходит.
DpInRock
Чисто случайно юзаю мегу48 на 9600 уже давно. Наблюдаю устройства в небольшой серии (сотни).
Как раз на внутреннем генераторе. На 9600 проблем нет.

Хотя с внутренним генератором стараюсь не делать ничего. Просто удобнее не думать о погрешностях. И черт с ней, с ценой.
Просто совсем малопотребляющие делать с внешним кварцем не сильно кошерно.
uuu2
Цитата(DpInRock @ May 17 2009, 03:21) *
Уберите галочку у CLKDIV8, если понипрог используете.
И думайте, что МК работает на 8МГц. Типо, предположите...

Да знаю я про эту галочку CLKDIV8! Мне интересно было сначала установить, какой возможен максимальный битрейт при текущих настройках тактового генератора, отладить хоть какую-то связь с FT245. А уже потом лезть в fuse bits, увеличивать частоту и т.п.
Цитата(aaarrr)
Чтобы обеспечить стабильную работу UART, отклонение частоты не должно превышать 1.5%. Внутренний RC без калибровки тут не подходит.
Получается, внутренний генератор имеет погрешность больше 1,5%? А у внешнего кварцевого резонатора какая погрешность?
aaarrr
Цитата(uuu2 @ May 17 2009, 04:19) *
Мне интересно было сначала установить, какой возможен максимальный битрейт при текущих настройках тактового генератора, отладить хоть какую-то связь с FT245.

В DS есть табличка, больше 9600 на 1MHz не получить.

Цитата(uuu2 @ May 17 2009, 04:19) *
Получается, внутренний генератор имеет погрешность больше 1,5%? А у внешнего кварцевого резонатора какая погрешность?

Частота RC в значительной степени зависит от напряжения питания и температуры - посмотрите в DS соответствующие графики.
У кварцевого резонатора погрешность составляет тысячные доли процента.

Цитата(DpInRock @ May 17 2009, 03:45) *
Просто совсем малопотребляющие делать с внешним кварцем не сильно кошерно.

Ну, еще можно калибровать RC по часовому кварцу.
DpInRock
Цитата
Да знаю я про эту галочку CLKDIV8

Ага.
@Ark
Цитата(aaarrr @ May 17 2009, 03:28) *
Чтобы обеспечить стабильную работу UART, отклонение частоты не должно превышать 1.5%. Внутренний RC без калибровки тут не подходит.

Когда внешнего кварца нет, а внутренний генератор не обеспечивает достаточную точность, имеет смысл отказаться от встроенного аппаратного UART-а и реализовать его функции программно. Калибровать сам внутренний генератор в этом случае нет необходимости. Процедура калибровки будет заключаться в программном определении длительности передачи одного бита (в тиках) на данной тактовой частоте. Самый простой способ - определение путем приема заранее известного значения байта. Измеряете интервал от начала стартового до начала стопового бита в тиках и делите на 9 (при 8-битном формате данных). Полученную длительность бита используете для приема и передачи. Можно сохранить полученное значение, но правильнее производить такую калибровку в начале каждого сеанса связи. Это решение имеет смысл использовать даже в том случае, если тактовый генератор обеспечивает нужную точность, так как фактически - это процедура автоопределения скорости обмена.
SysRq
Цитата(aaarrr @ May 17 2009, 04:35) *
В DS есть табличка, больше 9600 на 1MHz не получить.
Не обязательно использовать бодовую сокрость из стандартной сетки частот. FT232BL же наверняка способна поддерживать обмен практически на любых скоростях (лень уточнять в документации). Можно вполне попробовать хоть максимально доступные на 1МГц 62500 бод, исключив таким образом несоотвествие скоростей обмена в последовательном асинхронном канале, и оставив только влияние нестабильности внутренного RC МК.
aaarrr
Цитата(SysRq @ May 17 2009, 18:52) *
...оставив только влияние нестабильности внутренного RC МК.

Ее более чем достаточно.

Да и к чему все эти фантазии с autobaud'ом и нестандартными частотами? Автору топика они не помогут ни разу.
uuu2
Ну, решил я установить "более точный" внешний резонатор. В итоге доигрался - МК отрубился. Код не выполняется, программатор МК не видит.

Фузы поставлены по документации. Выдержки приведены на картинке, а внизу скриншот фузов. Резонатор на 8 Мгц, конденсаторы на 27 пФ. К МК всё подключено нормально.

Нажмите для просмотра прикрепленного файла
aaarrr
Ну, бывает. Заводите внешнюю частоту и проверяйте фьюзы.
uuu2
Цитата(aaarrr @ May 18 2009, 03:49) *
Ну, бывает. Заводите внешнюю частоту и проверяйте фьюзы.
При чем тут внешняя частота, если установлен "Full Swing Crystall Oscillator" (CKSEL3..1=0111)? "External Clock" имеет другие биты - 0000.

Правда, тут кое-что не понятно. В битах SUT1..0 установлено, что "BOD enabled", а "Start-up time" равен 16K. С другой стороны, в битах BODLEVEL установлено, что "BOD Disabled". Что это значит? Биты SUT и BODLEVEL я не трогал - они не менялись.
aaarrr
Цитата(uuu2 @ May 18 2009, 04:20) *
При чем тут внешняя частота, если установлен "Full Swing Crystall Oscillator" (CKSEL3..1=0111)? "External Clock" имеет другие биты - 0000.

При том, что вам процессор оживить надо, а для этого желательно убедиться, что в FUSE-битах стоит то, что вы думаете, а не что-то другое.

Цитата(uuu2 @ May 18 2009, 04:20) *
Правда, тут кое-что не понятно. В битах SUT1..0 установлено, что "BOD enabled", а "Start-up time" равен 16K. С другой стороны, в битах BODLEVEL установлено, что "BOD Disabled". Что это значит? Биты SUT и BODLEVEL я не трогал - они не менялись.

В битах SUT установлено "Crystal Oscillator, fast rising power" SUT1..0=10, CKSEL0=1.

Попробуйте для начала конденсаторы от кварца отодрать.
uuu2
Отодрал. Заработал. Что это значит: конденсаторы не нужны? Или следует поставить конденсаторы меньшего номинала? А чем отличаются режимы fast rising power и low rising power с точки зрения надежности/точности и т.п.?
aaarrr
Цитата(uuu2 @ May 18 2009, 04:42) *
Отодрал. Заработал. Что это значит: конденсаторы не нужны? Или следует поставить конденсаторы меньшего номинала?

Номиналы не те, грязь на плате и т.п.

Цитата(uuu2 @ May 18 2009, 04:42) *
А чем отличаются режимы fast rising power и low rising power с точки зрения надежности/точности и т.п.?

Задержка перед стартом процессора во втором случае больше. Если поставить "fast rising power" при медленно нарастающем питании, то программа может некоторое время работать не с той частотой.
uuu2
М-да. Конденсаторы-то разные. Впаял один кондер не того номинала. Они же похожие, рыжие. smile.gif

А насчёт UART - на внешнем 8 Мгц резонаторе всё успешно бегает с битрейтом 250000. Что гораздо лучше, чем 4800. smile.gif
aaarrr
Цитата(uuu2 @ May 18 2009, 05:25) *
М-да. Конденсаторы-то разные. Впаял один кондер не того номинала. Они же похожие, рыжие. smile.gif

Вот поэтому у меня всегда первая мысль отрывать конденсаторы, когда кварц не запускается - мало ли, что там припаяли.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.