реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Проблема с UART в atmega128
Whosthere
сообщение Dec 6 2011, 07:04
Сообщение #1





Группа: Новичок
Сообщений: 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. Стоп-бит использую один.

Буду благодарен за любые идеи. Заранее спасибо.

Go to the top of the page
 
+Quote Post
Whosthere
сообщение Dec 6 2011, 08:11
Сообщение #2





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



Микроконтроллер установлен на плате savvy128

Принципиальная схема


Программирую через AVR Dragon

Сообщение отредактировал Whosthere - Dec 6 2011, 08:12
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 6 2011, 09:40
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Whosthere @ Dec 6 2011, 11:04) *
Буду благодарен за любые идеи.

При работе с этим МК - типичная ошибка: не снят fuse M103C. C завода этот fuse приходит запрограммированным, необходимо его (fuse) снять!
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Dec 6 2011, 11:05
Сообщение #4


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Палыч @ Dec 6 2011, 13:40) *
...C завода этот fuse приходит запрограммированным, необходимо его (fuse) снять!


точно так же как и делитель на 8.
короче говоря - fuse в студию

(круглый)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 6 2011, 11:14
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(kolobok0 @ Dec 6 2011, 15:05) *
точно так же как и делитель на 8.

Только делитель на 8 в этом МК (ATmega128) отсутствует, это для других типов AVR. А то, ТС будет его тщетно искать...
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Dec 6 2011, 16:12
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Код
ldi r16, 18; устанавливаем режим приема

Когда разберётесь с fuse 103C , разберитесь и с - зачем Вы пишите 1 в бит который предназначен для приема 9 бита и записать в него невозможно


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Whosthere
сообщение Dec 7 2011, 17:46
Сообщение #7





Группа: Новичок
Сообщений: 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битной последовательности (со стоп и старт битами) с единицей в любом из битов.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 7 2011, 18:33
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Флаг RXC кто сбрасывать будет ?
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Dec 7 2011, 19:26
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Код , плиз , приведите конечный


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Dec 7 2011, 19:48
Сообщение #10


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 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 битного регистра скорости!!!

удачи вам
(круглый)
Go to the top of the page
 
+Quote Post
Whosthere
сообщение Dec 8 2011, 13:54
Сообщение #11





Группа: Новичок
Сообщений: 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.

Как только меня бдет возможность проверить правильность работы конечного варианта, обязательно отпишусь о наличии ошибки.
Go to the top of the page
 
+Quote Post
Whosthere
сообщение Dec 13 2011, 07:17
Сообщение #12





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



Увы,проблема не решилась, но я заметил очень странную вещь. Если при пустом UDR выполнить команду in r15,UDR0, то МК запишет в r15 значение FF, а не 00. Возможно я чего-то не понимаю. А также, поставив брейкпойнт на строчку in r15, UDR0, я заметил вот что. При пересылке с компьютера последовательности битов микроконтроллер "наступал" на брейкпоинт, но UDR всё равно оставался пустым вне зависимости от того, что я ему передавал.
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Dec 13 2011, 07:50
Сообщение #13


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(Whosthere @ Dec 13 2011, 11:17) *
Увы,проблема не решилась...


дык блин. Вы даташиты не читаете принципиально. Что вы хотите то?
регистры

UCSRnB
UCSRnC

опять странно инициализорованы.
Вы напишите, что Вы там хотите вкл/выкл?
А то смотришь в ваш код и в даташит - понимаешь что вы ленитесь. Ну и нафига вам помогать?

(круглый)
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 13 2011, 08:13
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Whosthere @ Dec 13 2011, 11:17) *
При пересылке с компьютера последовательности битов микроконтроллер "наступал" на брейкпоинт, но UDR всё равно оставался пустым вне зависимости от того, что я ему передавал.

Надеюсь, что "снимали" с Breakpoint до того, как ничинали передавать очередной байт.
Хорошо бы при останове, перед чтением UDR посмотреть регистр UCSRnA и огласить результат.
Go to the top of the page
 
+Quote Post
Whosthere
сообщение Dec 13 2011, 10:39
Сообщение #15





Группа: Новичок
Сообщений: 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.

Я нашел источник проблемы. Суть в том, что я глуп. Посмотрев во фьюзах откуда тактируется МК, я неожиданно понял, что настроен он не верно. Простите за ввод вас в заблуждение. Спасибо всем за помощь
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 06:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01531 секунд с 7
ELECTRONIX ©2004-2016