Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: HELP! MEGA16 UART
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
pimen
Столкнулся с проблемой - не получается инициализировать UART в МЕГЕ16.
Причина: не получается запрограммировать регистр UCSRC, который отвечает за кол-во бит в пакете. Как известно, данный регистр по адресу (0х20(0х40)) совпадает с регистром UBRRH, а выбор того или иного осуществляется записью в бит URSEL определенного значения. Не получается запрограммировать ни тот, ни другой. Требуется РАБОТАЮЩИЙ кусок кода на С для инициализации UART.

Код
C Code Example
#define FOSC 1843200// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
void main( void )
{
:.
USART_Init ( MYUBRR );
:.
}
void USART_Init( unsigned int ubrr)
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

- это не заработало (пример из doc8154.pdf, стр 153)
manul78
Цитата(pimen @ Jul 9 2009, 22:04) *
Столкнулся с проблемой - не получается инициализировать UART в МЕГЕ16.
Требуется РАБОТАЮЩИЙ кусок кода на С для инициализации UART.


Пожалуйста ! Функция:

/* Инициализация UART при 9600 Bd, tx/rx, 8N1.*/
void uart_init(void)
{
#if F_CPU > 2000000UL && defined(U2X)
UCSRA = _BV(U2X); /* improve baud rate error by using 2x clk */
UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
UCSRB = _BV(TXEN) | _BV(RXEN); /* tx/rx enable */
}
pimen
Цитата(manul78 @ Jul 9 2009, 22:10) *
Пожалуйста ! Функция:


ээээ, спасибо конечно, но требуется код с инициализацией регистра UCSRC
у Вас я его не заметил (
mempfis_
Цитата
ээээ, спасибо конечно, но требуется код с инициализацией регистра UCSRC
у Вас я его не заметил (


Ну добавьте строчку в процедуру инициализации
Код
UCSRC = (1<<URSEL)|(.........);

там где точки ваши настройки остальных битов регистра UCSRC

Примера инициализации уарта в даташитс на atmega16 вполне работоспособен.
Как проверили что он не работает?

Код
void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
pimen
Цитата(mempfis_ @ Jul 9 2009, 22:44) *
Ну добавьте строчку в процедуру инициализации
Код
UCSRC = (1<<URSEL)|(.........);

там где точки ваши настройки остальных битов регистра UCSRC


это я уже видел и описано в 1 сообщении...
не заработало...
поэтому и интересуют варианты рабочих программ
отладка проводилась как в AVRStudio, так и в IAR на JTAGICE и JTAGICE mkII (родном)
manul78
Цитата(pimen @ Jul 9 2009, 22:20) *
ээээ, спасибо конечно, но требуется код с инициализацией регистра UCSRC
у Вас я его не заметил (


Не понятно зачем Вам 2стоп бита на такой "нищенской" скорости 9600 ? wacko.gif

Кварц надеюсь "кратный" поставили ? 7.3728... и.пр... Это гораздо важнее...
Не забывайте, что в отдельных микросхемах UART (в компьютере например) есть ФАПЧ..., а вот
в МК их похоже нет... twak.gif

В "железе" обычно гораздо больше "заноз" сидит, чем в программной части...

И скажите наконец, что с чем Вы пытаетесь связать ?
mempfis_
Цитата(pimen @ Jul 9 2009, 21:49) *
это я уже видел и описано в 1 сообщении...
не заработало...


Так уточните что именно не заработало?
Вы инициализировали уарт а на приёмной стороне нет данных?
Или на RXD/TXD совсем нет никаких сигналов?

Настройки уарта совпадают с настройками на приёмной стороне (битрейт, кол-во стоповых битов, настройка контроля чётности)?
Какой кварц на меге стоит?

А код 100% рабочий - проверено неоднократно.
pimen
Цитата(mempfis_ @ Jul 9 2009, 22:57) *
А код 100% рабочий - проверено неоднократно.


вот это я и хотел узнать
какая разница какой кварц и с чем я пытаюсь связаться?
вопрос был о программировании регистра управления
при отладке видно, что регистр не изменяется, что также подтверждают данные, подсмотренные осцилом
на нем хорошо видно пакет состоит из пяти бит (типично при UCSRC=0х0), а вот изменть на 8N1 не получилось.

Спасибо за помощь
mempfis_
Нашёл в одном работающем проекте код инициализации уарта в atmega8
Всё как по даташитс только инициализацию UBRR провожу после инициализации всех регистров.
Все прекрасно работает уже около года.

Код
void USART_Init( unsigned int baud )
{
UCSRA=0x00;
UCSRB = (1<<RXEN)|(1<<TXEN);/*включаем приёмник и передатчик */
UCSRC = (1<<URSEL)|(3<<UCSZ0);/* 8 бит, 1 стоповый, без проверки на чётность */

UBRRH = (unsigned char)(baud>>8);/* устанавливаем битрейт*/
UBRRL = (unsigned char)baud;
}
manul78
Блин ! Чем дальше в лес, тем больше дров ! Это интересно !

По порядку...
Подключил старую отладочную плату. ATmega16 через COM1 JTAG ICE , через COM2 - терминал.
Все работает и туда и оттуда ! Настройки только вот эти:

/* Инициализация UART при 9600 Bd, tx/rx, 8N1.*/
void uart_init(void)
{
#if F_CPU > 2000000UL && defined(U2X)
UCSRA = _BV(U2X); /* improve baud rate error by using 2x clk */
UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1;
#else
UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1;
#endif
UCSRB = _BV(TXEN) | _BV(RXEN); /* tx/rx enable */
}
Т.е UCSRC я не трогаю... это видно и в отладке через JTAG ! :

UBRRH 0x00 0 0 0 0 0 0 0 0
UBRRL 0x5F 0 1 0 1 1 1 1 1
UCSRA 0x62 0 1 1 0 0 0 1 0
UCSRB 0x18 0 0 0 1 1 0 0 0
UCSRC 0x00 0 0 0 0 0 0 0 0
UDR 0x00 0 0 0 0 0 0 0 0

Как видите UCSRC пуст и как пишет наш топикстартер в режиме USART должно быть 5 битов данных !
Но у меня все корректно работает ! И принимает и передает !
Т.е. модуль работает в режиме UART...
Так, что-же, если я сейчас изменю бит, и загоню его в синхронный режим, то он станет USART-ом
и перестанет работать корректно ?
Тогда вопрос такой: Как наш коллега умудрился увидеть 5 бит данных, если у него передатчик работает
в асинхронном режиме и может передавать только или 8 бит или 9 бит ?
Глюк ? Или у меня в голове глюк ? JTAG ICE четко показывает состояние регистров ...
Сергей Борщ
Цитата(manul78 @ Jul 10 2009, 00:00) *
Как видите UCSRC пуст
Как мы видим, в бите URSEL ноль, значит вы прочитали UBRRH:
Цитата
The read access is controlled by a timed sequence. Reading the I/O location once returns the UBRRH Register contents. If the register location was read in previous system clock cycle, reading the register in the current clock cycle will return the UCSRC contents. Note that the timed sequence for reading the UCSRC is an atomic operation. Interrupts must therefore be controlled (for example by disabling interrupts globally) during the read operation.
Цитата
• Bit 7 – URSEL: Register Select
This bit selects between accessing the UCSRC or the UBRRH Register. It is read as one when reading UCSRC. The URSEL must be one when writing the UCSRC.
Читайте даташиты...


Цитата(pimen @ Jul 9 2009, 21:49) *
отладка проводилась как в AVRStudio, так и в IAR на JTAGICE и JTAGICE mkII (родном)
Студия некорректно отбражает этот регистр - читайе описание ее багов в хелпе. Смею предположить, что и JTAGICE и JTAGICE mkII при отображении в окнах регистров также отображают UCSRC неправильно, ибо читает его как и все остальные регистры - однократным чтением.
manul78
Цитата(Сергей Борщ @ Jul 10 2009, 01:47) *
Читайте даташиты...

Студия некорректно отбражает этот регистр - читайе описание ее багов в хелпе. Смею предположить, что и JTAGICE и JTAGICE mkII при отображении в окнах регистров также отображают UCSRC неправильно, ибо читает его как и все остальные регистры - однократным чтением.


Даташиты мы исправно читаем... biggrin.gif Хотелось верить, что все предусмотрено в JTAG-ах...

У меня другой вопрос: Я правильно рассуждаю ?

Если в разряде UMSEL (режим работы) регистра UCSRC стоит ноль, то модуль работает в режиме UART и
берет размер слова из регистра UCSRB CHR9=0 это 8 разрядов CHR=1 это 9 разрядов...

Если в разряде UMSEL (режим работы) регистра UCSRC стоит 1 , то модуль работает в режиме USART и
берет размер слова из регистра UCSRC разрядов UCSZ0, UCSZ1 и UCSRB разряда CHR9...
Палыч
Цитата(manul78 @ Jul 10 2009, 01:18) *
Даташиты мы исправно читаем... Я правильно рассуждаю ?
Как в DS написано - так оно и работает! Про бит CHR9 в DS упоминается всего один раз и то - в сравнении USART с UART AVR. Забудте про такой бит! Бит UMSEL - это всего лишь переключение между режимами: синхронный - асинхронный (грубо говоря: определяет - есть ли между устройствами кроме проводов Rx и Tx ещё один провод XCK).
mempfis_
Цитата(manul78 @ Jul 10 2009, 01:18) *
Если в разряде UMSEL (режим работы) регистра UCSRC стоит ноль, то модуль работает в режиме UART и
берет размер слова из регистра UCSRB CHR9=0 это 8 разрядов CHR=1 это 9 разрядов...

Если в разряде UMSEL (режим работы) регистра UCSRC стоит 1 , то модуль работает в режиме USART и
берет размер слова из регистра UCSRC разрядов UCSZ0, UCSZ1 и UCSRB разряда CHR9...


Нет не правильно. UART и USART полностью во всём идеентичны. Только в режиме USART тактовая частота берётся с входа XCK.
Размер символа определяется UCSZ2-UCSZ0. Биты RXB8/TXB8 используются для считывания/передачи 9го бита символа ( если используется формат 9 бит)
TechMike
Вот работающий код, mega16+кварц 8мгц, avr studio+winavr последней версии:

Код
void USART_Init(unsigned int baud )
{
#define UBRRVAL ((F_CPU/(baud*16UL))-1)
//Set baud rate
UBRRL=UBRRVAL;        //low byte
UBRRH=(UBRRVAL>>8);    //high byte
//Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|    (0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);
//Enable Transmitter and Receiver
UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}

//функция выдает в порт RS232 один символ
void USART_Send( unsigned int Txt )
{
  while (!(UCSRA&(1<<UDRE))){};
  UDR=Txt;        //send number to USART
}
manul78
Цитата(mempfis_ @ Jul 10 2009, 09:41) *
Размер символа определяется UCSZ2-UCSZ0. Биты RXB8/TXB8 используются для считывания/передачи 9го бита символа ( если используется формат 9 бит)


Блин ! Я уже устал объяснять ! В начальных установках передатчика у меня НЕТ команд изменения USRC !

//Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)| (0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);

У меня ничего этого НЕТ !!! И все работает ! Терминал принимает и посылает информацию в режиме 8N1 !

Как такое может быть ? Т.е. по умолчанию у меня должно быть 5N1 !!!

Может у меня ATmega16 - из какой-то "кривой" партии ? Т.е. там стоит UART а не USART ?
Палыч
Цитата(manul78 @ Jul 10 2009, 10:56) *
Блин ! Я уже устал объяснять ! В начальных установках передатчика у меня НЕТ команд изменения USRC !
Вот, именно - блин! Вы в DS хоть иногда смотрите? Намекаю: начальное значение (Initial Value) регистра UCSRC.
manul78
Цитата(Палыч @ Jul 10 2009, 12:32) *
Вот, именно - блин! Вы в DS хоть иногда смотрите? Намекаю: начальное значение (Initial Value) регистра UCSRC.


Т.е Вы хотите сказать, что при старте ATmega16 бутлоадер грузит в UCSRC "базовые" значения 8N1 ?

Потому-что если UCSRC не инициализируется "святым духом" то биты UCSZ2, UCSZ1, UCSZ0 равны НУЛЮ !

Интересно как это организованно "начальное значение (Initial Value) регистра UCSRC." аппаратно или програм-
но ?
Палыч
Цитата(manul78 @ Jul 10 2009, 15:28) *
Интересно как это организованно "начальное значение (Initial Value) регистра UCSRC." аппаратно или програмно ?
Конечно - аппаратно. По reset регистры устанавливаются в Initial Value.
Сергей Борщ
Цитата(manul78 @ Jul 10 2009, 15:28) *
Потому-что если UCSRC не инициализируется "святым духом" то биты UCSZ2, UCSZ1, UCSZ0 равны НУЛЮ !
А нули там должны появляться от "святого духа", или же они являются частным случаем инициализирующего значения?
pimen
Цитата
19.5 USART Initialization
...
The following simple USART initialization code examples show one assembly and one C function
that are equal in functionality. The examples assume asynchronous operation using polling
(no interrupts enabled) and a fixed frame format. The baud rate is given as a function parameter.
For the assembly code, the baud rate parameter is assumed to be stored in the r17:r16 registers.
When the function writes to the UCSRC Register, the URSEL bit (MSB) must be set due to
the sharing of I/O location by UBRRH and UCSRC.


Цитата
19.10.2 Read Access
Doing a read access to the UBRRH or the UCSRC Register is a more complex operation. However,
in most applications, it is rarely necessary to read any of these registers.
The read access is controlled by a timed sequence. Reading the I/O location once returns the
UBRRH Register contents. If the register location was read in previous system clock cycle, reading
the register in the current clock cycle will return the UCSRC contents. Note that the timed
sequence for reading the UCSRC is an atomic operation. Interrupts must therefore be controlled
(for example by disabling interrupts globally) during the read operation.
The following code example shows how to read the UCSRC Register contents.


По русски:
запрещены прерывания во время записи и чтения регистров UBRRH и UCSRC.
для записи в UBRRH бит URSEL должен быть равен 0, для записи в регистр UCSRC бит URSEL должен быть равен 1.
для чтения UBRRH его надо считать первым. повторное чтение данного регистра вернет содержимое регистра UCSRC.

Цитата
Студия некорректно отбражает этот регистр - читайе описание ее багов в хелпе. Смею предположить, что и JTAGICE и JTAGICE mkII при отображении в окнах регистров также отображают UCSRC неправильно, ибо читает его как и все остальные регистры - однократным чтением.


подтверждаю )

Всем спасибо, разобрался
manul78
Цитата(Сергей Борщ @ Jul 10 2009, 17:08) *
А нули там должны появляться от "святого духа", или же они являются частным случаем инициализирующего значения?


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