|
HELP! MEGA16 UART, как правильно инициализировать UART? |
|
|
|
Jul 9 2009, 18:04
|
Участник

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846

|
Столкнулся с проблемой - не получается инициализировать 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)
|
|
|
|
|
Jul 9 2009, 18:10
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Цитата(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 */ }
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Jul 9 2009, 18:20
|
Участник

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846

|
Цитата(manul78 @ Jul 9 2009, 22:10)  Пожалуйста ! Функция: ээээ, спасибо конечно, но требуется код с инициализацией регистра UCSRC у Вас я его не заметил (
|
|
|
|
|
Jul 9 2009, 18:44
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата ээээ, спасибо конечно, но требуется код с инициализацией регистра 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); }
Сообщение отредактировал mempfis_ - Jul 9 2009, 18:46
|
|
|
|
|
Jul 9 2009, 18:49
|
Участник

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846

|
Цитата(mempfis_ @ Jul 9 2009, 22:44)  Ну добавьте строчку в процедуру инициализации Код UCSRC = (1<<URSEL)|(.........); там где точки ваши настройки остальных битов регистра UCSRC это я уже видел и описано в 1 сообщении... не заработало... поэтому и интересуют варианты рабочих программ отладка проводилась как в AVRStudio, так и в IAR на JTAGICE и JTAGICE mkII (родном)
|
|
|
|
|
Jul 9 2009, 18:55
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Цитата(pimen @ Jul 9 2009, 22:20)  ээээ, спасибо конечно, но требуется код с инициализацией регистра UCSRC у Вас я его не заметил ( Не понятно зачем Вам 2стоп бита на такой "нищенской" скорости 9600 ? Кварц надеюсь "кратный" поставили ? 7.3728... и.пр... Это гораздо важнее... Не забывайте, что в отдельных микросхемах UART (в компьютере например) есть ФАПЧ..., а вот в МК их похоже нет...  В "железе" обычно гораздо больше "заноз" сидит, чем в программной части... И скажите наконец, что с чем Вы пытаетесь связать ?
Сообщение отредактировал manul78 - Jul 9 2009, 19:00
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Jul 9 2009, 18:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Цитата(pimen @ Jul 9 2009, 21:49)  это я уже видел и описано в 1 сообщении... не заработало... Так уточните что именно не заработало? Вы инициализировали уарт а на приёмной стороне нет данных? Или на RXD/TXD совсем нет никаких сигналов? Настройки уарта совпадают с настройками на приёмной стороне (битрейт, кол-во стоповых битов, настройка контроля чётности)? Какой кварц на меге стоит? А код 100% рабочий - проверено неоднократно.
|
|
|
|
|
Jul 9 2009, 19:11
|
Участник

Группа: Участник
Сообщений: 67
Регистрация: 30-11-07
Пользователь №: 32 846

|
Цитата(mempfis_ @ Jul 9 2009, 22:57)  А код 100% рабочий - проверено неоднократно. вот это я и хотел узнать какая разница какой кварц и с чем я пытаюсь связаться? вопрос был о программировании регистра управления при отладке видно, что регистр не изменяется, что также подтверждают данные, подсмотренные осцилом на нем хорошо видно пакет состоит из пяти бит (типично при UCSRC=0х0), а вот изменть на 8N1 не получилось. Спасибо за помощь
Сообщение отредактировал pimen - Jul 9 2009, 19:12
|
|
|
|
|
Jul 9 2009, 19:31
|

Профессионал
    
Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409

|
Нашёл в одном работающем проекте код инициализации уарта в 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; }
|
|
|
|
|
Jul 9 2009, 21:00
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Блин ! Чем дальше в лес, тем больше дров ! Это интересно !
По порядку... Подключил старую отладочную плату. 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 четко показывает состояние регистров ...
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Jul 9 2009, 21:47
|

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

|
Цитата(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 неправильно, ибо читает его как и все остальные регистры - однократным чтением.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 9 2009, 22:18
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Цитата(Сергей Борщ @ Jul 10 2009, 01:47)  Читайте даташиты...
Студия некорректно отбражает этот регистр - читайе описание ее багов в хелпе. Смею предположить, что и JTAGICE и JTAGICE mkII при отображении в окнах регистров также отображают UCSRC неправильно, ибо читает его как и все остальные регистры - однократным чтением. Даташиты мы исправно читаем...  Хотелось верить, что все предусмотрено в JTAG-ах... У меня другой вопрос: Я правильно рассуждаю ? Если в разряде UMSEL (режим работы) регистра UCSRC стоит ноль, то модуль работает в режиме UART и берет размер слова из регистра UCSRB CHR9=0 это 8 разрядов CHR=1 это 9 разрядов... Если в разряде UMSEL (режим работы) регистра UCSRC стоит 1 , то модуль работает в режиме USART и берет размер слова из регистра UCSRC разрядов UCSZ0, UCSZ1 и UCSRB разряда CHR9...
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
Jul 10 2009, 07:39
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Вот работающий код, 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 }
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|