|
|
  |
Проблема с UART в atmega128 |
|
|
|
Dec 6 2011, 07:04
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Добрый день. Возникла проблема с приемом по UART от компа на микроконтроллер ATMEGA128. Код программы такой: Код .cseg in r15,UDR0 ldi r17, 47; устанавливаем скорость 9600 out UBRR0L,r17 ldi r16, 18; устанавливаем режим приема out UCSR0B, r16; данных в 8битном пакете Receive: sbis UCSR0A, RXC0; ожидаем приема полного пакета данных rjmp receive in r15, UDR0; загружаем данные в R15 rjmp receive Микроконтроллер тактируется от кварцевого генератора с частотой 7,3728 МГц. Программирую в AVRStudio5. Суть самой проблемы: Сигнал на вход микроконтроллера приходит такой, как надо (проверено осциллографом). Но! Посылая что-то, отличное от 0000 0000, я получаю в регистре R15 0хFF. Скорость передачи и там, и там выставлена 9600. Стоп-бит использую один. Буду благодарен за любые идеи. Заранее спасибо.
|
|
|
|
|
Dec 6 2011, 08:11
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Микроконтроллер установлен на плате savvy128 Принципиальная схема
Программирую через AVR Dragon
Сообщение отредактировал Whosthere - Dec 6 2011, 08:12
|
|
|
|
|
Dec 6 2011, 11:05
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Палыч @ Dec 6 2011, 13:40)  ...C завода этот fuse приходит запрограммированным, необходимо его (fuse) снять! точно так же как и делитель на 8. короче говоря - fuse в студию (круглый)
|
|
|
|
|
Dec 7 2011, 17:46
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Насколько я понимаю, fuse 103C у меня отключен (в AVR Studio 5 галочка в нем не стоит). С записью в регистр UCSR0B значения 00010100 разобрался. В этом регистре я устанавливаю RXEN0 и UCSZ02 в 1, а также в регистре UCSR0C устанавливаю UCSZ0 и UCSZ1 в 1. Тогда бит RXB80 установится в единицу при запуске программы.
Но, тем не менее, процессор продолжает записывать в R15 0хFF при передаче на него любой 8битной последовательности (со стоп и старт битами) с единицей в любом из битов.
|
|
|
|
|
Dec 7 2011, 19:48
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Whosthere @ Dec 6 2011, 11:04)  ..ATMEGA128. Код .cseg in r15,UDR0 ldi r17, 47; устанавливаем скорость 9600 out UBRR0L,r17 регистр UBRRxn 16 битный. А вы сколько в него пихаете? В даташите есть примеры. нафига не используете опыт ранее накопленный до вас? правильный код (даташит) (входные регистры r17:r16 - тут приведу инициализацию их) Код ldi r16,low(47) ldi r17,high(47) ; Set baud rate out UBRR0H, r17 out UBRR0L, r16 ышо правильнее за место 47 объявить дефайн константу и юзать её... Цитата(Whosthere @ Dec 6 2011, 11:04)  Код ldi r16, 18; устанавливаем режим приема out UCSR0B, r16; данных в 8битном пакете Давайте посчитаем... 18(10) = 0b00010010(2) это Вы взводите биты RXEN0 и RXB80 как уже было сказано выше - 1 бит - это вы погорячились... достаточно (для поллинга как у вас ниже) бита RXEN0 и ещё. чтоб не путаться и наглядно принято писать такие комбинации: Код ldi r16,(1 << RXEN0) всякие стоп биты, чётности и т.д. инициализируются в регистре UCSR0C этого в вашем примере нет. ещё пять копеек: прерывания надо запрещать перед тем как это всё делать. после - восстанавливать (а не разрешать) - это так к слову.. Цитата(Whosthere @ Dec 6 2011, 11:04)  Код Receive: sbis UCSR0A, RXC0; ожидаем приема полного пакета данных rjmp receive
in r15, UDR0; загружаем данные в R15 rjmp receive Микроконтроллер тактируется от кварцевого генератора с частотой 7,3728 МГц..... это конечно же круто. но лучше пример из даташита: Код USART_Receive: ; Wait for data to be received sbis UCSRA, RXC rjmp USART_Receive ; Get status and 9th bit, then data from buffer in r18, UCSRA in r17, UCSRB in r16, UDR ; If error, return -1 andi r18,(1<<FE)|(1<<DOR)|(1<<UPE) breq USART_ReceiveNoError ldi r17, HIGH(-1) ldi r16, LOW(-1) USART_ReceiveNoError: ; Filter the 9th bit, then return lsr r17 andi r17, 0x01 ret выкинем 9 бит и имеем Код USART_Receive: ; Wait for data to be received sbis UCSRA, RXC rjmp USART_Receive ; Get status then data from buffer in r18, UCSRA in r16, UDR ; If error, return -1 andi r18,(1<<FE)|(1<<DOR)|(1<<UPE) breq USART_ReceiveNoError ldi r16, LOW(-1) USART_ReceiveNoError: .... ; далее ваш текст программы. ретурн, возврат на начало приёма - хз. единственное хочу сказать, что результат надо куда то выпихивать, сохранять, контролировать...а не тупо просто циклить. а то можно и не увидеть самого главного нечаянно. при вашей скорости кварца значения делителя 47. При U2X0 = 0 и указанного кварца - он верный. Fuse выставлен на внешний кварц. из приведённого вами куска, больше всего подозрение вызывает: не правильная инициализация 16 битного регистра скорости!!! удачи вам (круглый)
|
|
|
|
|
Dec 8 2011, 13:54
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Спасибо за советы. Пока проверить возможности нет. Про 16-битность регистра UBBR я знал, но не загржал в старшие 8 бит ничего, так как по незнанию своему считал, что там изначально нули во всех битах. Не пользовался я копипастой из даташита только потому, что изначально написать мне всегда удобней, а программа небольшая и объем работы практически никакой. Код .cseg in r15,UDR0 ldi r16, low(47); ldi r17, high(47); устанавливаем скорость 9600 out UBRR0L,r16 sts UBRR0H, r17 ldi r16, 20; устанавливаем режим приема ldi r17, 06; данных в 8битном пакете sts UCSR0C, r17 out UCSR0B, r16 Receive: sbis UCSR0A, RXC0; ожидаем приема полного пакета данных rjmp receive in r15, UDR0; загружаем данные в R15 rjmp receive Вот конечный вариант программы. Цитата Флаг RXC кто сбрасывать будет ? Насколько я понимаю, он сбрасывается при прочтении UDR0. Как только меня бдет возможность проверить правильность работы конечного варианта, обязательно отпишусь о наличии ошибки.
|
|
|
|
|
Dec 13 2011, 07:17
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Увы,проблема не решилась, но я заметил очень странную вещь. Если при пустом UDR выполнить команду in r15,UDR0, то МК запишет в r15 значение FF, а не 00. Возможно я чего-то не понимаю. А также, поставив брейкпойнт на строчку in r15, UDR0, я заметил вот что. При пересылке с компьютера последовательности битов микроконтроллер "наступал" на брейкпоинт, но UDR всё равно оставался пустым вне зависимости от того, что я ему передавал.
|
|
|
|
|
Dec 13 2011, 07:50
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Whosthere @ Dec 13 2011, 11:17)  Увы,проблема не решилась... дык блин. Вы даташиты не читаете принципиально. Что вы хотите то? регистры UCSRnB UCSRnC опять странно инициализорованы. Вы напишите, что Вы там хотите вкл/выкл? А то смотришь в ваш код и в даташит - понимаешь что вы ленитесь. Ну и нафига вам помогать? (круглый)
|
|
|
|
|
Dec 13 2011, 10:39
|
Группа: Новичок
Сообщений: 8
Регистрация: 6-12-11
Пользователь №: 68 700

|
Вероятно такая запись будет больше понятна. Код .cseg in r15,UDR0 ldi r16, low(47); ldi r17, high(47); устанавливаем скорость 9600 out UBRR0L, r16 sts UBRR0H, r17 ldi r16,(1 << RXEN0)|(1 << UCSZ02) ldi r17,(1 << UCSZ01)|(1 << UCSZ00) sts UCSR0C, r17 out UCSR0B, r16 Receive: sbis UCSR0A, RXC0; ожидаем приема полного пакета данных rjmp receive in r14, UCSR0A in r15, UDR0; загружаем данные в R15 out DDRB,r15 rjmp receive В регистре r14 сразу после останова были установлены RXC0 и UDRE0, что соответствует произошедшей передаче и пустому UDR0. Я нашел источник проблемы. Суть в том, что я глуп. Посмотрев во фьюзах откуда тактируется МК, я неожиданно понял, что настроен он не верно. Простите за ввод вас в заблуждение. Спасибо всем за помощь
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|