|
|
  |
Проблема с UART в atmega128 |
|
|
|
Dec 14 2011, 11:04
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Whosthere @ Dec 13 2011, 14:39)  Вероятно такая запись будет больше понятна. Код .. ldi r16,(1 << RXEN0)|(1 << UCSZ02) ldi r17,(1 << UCSZ01)|(1 << UCSZ00) sts UCSR0C, r17 out UCSR0B, r16 ... Посмотрев во фьюзах откуда тактируется МК, я неожиданно понял, что настроен он не верно. Простите за ввод вас в заблуждение. Спасибо всем за помощь я вот специально обращал Ваше внимание на эти регистры... смотрим даташит... Table 80. UCSZn Bits Settings UCSZn2 UCSZn1 UCSZn0 Character Size 0 0 0 5-bit 0 0 1 6-bit 0 1 0 7-bit 0 1 1 8-bit 1 0 0 Reserved 1 0 1 Reserved 1 1 0 Reserved 1 1 1 9-bit как видно - Вы выставили 9 бит. вроде как выше надо было 8бит? (круглый)
|
|
|
|
|
Dec 15 2011, 12:22
|
Участник

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

|
у меня вопрос очень похожий: что то прием идет не так как надо по UARTу. Использую Atmega8515, отлаживаю на STK500. задача: мк принимает данные и в двоичном коде показывает их на восьми светодиодах. Данные посылаю через програмку “Terminal v1.9b”. число вроде отображает, но на PB4 и PB7 всегда лог.1, то есть посылаю “0″ должен показать 00000000 но показывает 10010000 посылаю “1″ должен показать 00000001 но показывает 10010001 посылаю “2″ должен показать 00000010 но показывает 10010010 и так далее..
обработчик прерывания простейший: PriemZavershen: in r16,UDR out PortB,r16 reti
|
|
|
|
|
Dec 16 2011, 07:57
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(slavik.ksu @ Dec 15 2011, 16:22)  ...но на PB4 и PB7 всегда лог.1... очень смахивает на конфликт с настройками. 1) посмотрите фуз бит SPIEN отключен SPI? 2) попробуйте вывести в другой порт и посчупать осцилом. (круглый)
|
|
|
|
|
Dec 19 2011, 06:53
|
Участник

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

|
Цитата(kolobok0 @ Dec 16 2011, 11:57)  очень смахивает на конфликт с настройками. 1) посмотрите фуз бит SPIEN отключен SPI? 2) попробуйте вывести в другой порт и посчупать осцилом. пробовал на порта А подключать, та же ситуация. Fuse вкладка выглядит так:
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 19 2011, 11:17
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(slavik.ksu @ Dec 19 2011, 10:53)  пробовал на порта А подключать, та же ситуация.... программку всю. инициализация порта со стороны форточек правильная(скорость, чётность и т.п.)? (круглый)
|
|
|
|
|
Dec 19 2011, 18:00
|
Участник

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

|
; выполняемые функции: через модуль UART от компьютера принимаем числа ; которые отображаются на 8 СИДах в двоичном коде.
.device ATmega8515 .nolist .include "m8515def.inc" .list
;================ ; Объявления
.def temp = r16
; FLASH =========================================== .CSEG ; Кодовый сегмент
;====== Таблица векторов прерываний================
.ORG 0x0000 ; RESET - Аппаратный сброс RJMP Init .ORG 0x0001 ; INT0 - External Interrupt0 Vector Address; Внешнее прерывание 0 ; RETI .ORG 0x0002 ; INT1 - External Interrupt1 Vector Address; Внешнее прерывание 1 ; RETI ; Ничего не делаем, возвращаемся в основную программу .ORG 0x0003 ; ICP1 - Input Capture1 Interrupt Vector Address; Событие захват Таймера/Счетчика 1 ; RETI .ORG 0x0004 ; OC1A - Output Compare1A Interrupt Vector Address ;Событие "совпадение A" Таймера/Счетчика 1 ; RETI .ORG 0x0005 ; OC1B - Output Compare1B Interrupt Vector Address; Событие "совпадение B" Таймера/Счетчика 1 ; RETI .ORG 0x0006 ; OVF1 - Overflow1 Interrupt Vector Address; Переполнение Таймера/Счетчика 1 ; RETI .ORG 0x0007 ; OVF0 - Overflow0 Interrupt Vector Address; Переполнение Таймера/Счетчика 0 ; RETI .ORG 0x0008 ; SPI - SPI Interrupt Vector Address; Передача данных по SPI завершена RETI .ORG 0x0009 ; URXC - UART Receive Complete Interrupt Vector Address; Прием данных по UART завершена rjmp PriemZavershen ; Переходим к обработчику прерывания .ORG 0x000a ; UDRE - UART Data Register Empty Interrupt Vector Address; Регистр данных UART пуст RETI .ORG 0x000b ; UTXC - UART Transmit Complete Interrupt Vector Address; Передача данных по UART завершен reti; .ORG 0x000c ; ACI - Analog Comparator Interrupt Vector Address; Готов результат аналогового компаратора RETI .ORG 0x000d ; INT2 - External Interrupt2 Vector Address RETI .ORG 0x000e ; OC0 - Output Compare0 Interrupt Vector Address RETI .ORG 0x000f ; ERDY - EEPROM Interrupt Vector Address RETI .ORG 0x0010 ; SPM - SPM complete Interrupt Vector Address RETI ;.ORG 0x0011 ; SPMR - SPM complete Interrupt Vector Address ; RETI
; .ORG INT_VECTORS_SIZE
;================ ; Конец таблицы векторов прерываний===
;============ Блок подпрограмм обработки прерываний =========== PriemZavershen: in temp,UDR out PortB,temp reti
;============ конец Блока подпрограмм обработки прерываний ===========
;=================== Основная программа ====================== Init: ;++++++++++++++ Сдержимое файла INITCORE.INC +++++++++++++++++++++++++ ;==== Инициализация ядра: Память; Регистры; Стек ============= .include "INITCORE.inc" ;++++++++++++++ Конец Содержимого файла INITCORE.INC +++++++++++++++++
;======= Инициализация внутренних периферийных устройств:====== ldi temp , 0b11111111 ; определяем входы\выходы порта В, out DDRB , temp ; 1 делает вывод выходом, 0 - входом! ldi temp , 0b00000000 ; определяем в\в порта D out DDRD , temp
ldi temp , 0b11111111 ; включаем подтяжку (1) для входов порта В out portB , temp ; и задаем начальние состояния выходов ldi temp , 0b00000000 ; то же самое для D out portD , temp
ldi temp, 1<<RXEN|1<<RXCIE ; разрешаем прием и прерывание по приему по UART out UCSRB, temp
ldi temp,25 ; задаем скорость UART = 9600 out UBRRL, temp
ldi r16, (1<<URSEL|1<<UCSZ0|1<<UCSZ1) ; 8-мибитный формат посылки out UCSRC,r16 sei ; глобально разрешаем прерывания!
;==== Коенц Инициализация внутренних периферийных устройств====
;========================= Главный цикл =======================
Start: nop rjmp Start
;++++++++++++++ Сдержимое файла INITCORE.INC +++++++++++++++++++++++++ ;==== Инициализация ядра: Память; Регистры; Стек ============= ;================= Инициализация Памяти ====================== RAM_Flush: LDI ZL,Low(SRAM_START) ; Адрес начала ОЗУ в индекс LDI ZH,High(SRAM_START) CLR R16 ; Очищаем R16 Flush: ST Z+,R16 ; Сохраняем 0 в ячейку памяти CPI ZH,High(RAMEND) ; Достигли конца ОЗУ? BRNE Flush ; Нет! Крутимся дальше! ; Старший байт достиг конца ОЗУ!!! ; Заполняем оставшиеся 255 байт ОЗУ нулями. CPI ZL,Low(RAMEND) ; Младший байт достиг конца ОЗУ? BRNE Flush ; Нет! Крутимся дальше, до конца ОЗУ. ST Z , r16 ; Да? тогда очиаем последний адрес и выходим из цикла ;=============== Инициализация регистров ===================== ; Очищаем 32 индексных регистра R0-R31 ldi ZL, 30 ; ZL есть регистр R30 CLR ZH ; ZH есть регистр R31 dec Zl st Z,ZH BRNE PC-2
;================ Инициализация стека ======================== LDI R16,Low(RAMEND) ; Обязательно!!! OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 CLR R16 ;++++++++++++++ Конец Содержимого файла INITCORE.INC +++++++++++++++++
|
|
|
|
|
Dec 20 2011, 14:12
|
Участник

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

|
Да, МК работает на 4МГц. Добавил инициализацию верхней половинки регистра UBRR ldi temp, 0 out UBRRH,temp работает также с ошибкой.
|
|
|
|
|
Dec 21 2011, 11:11
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(slavik.ksu @ Dec 20 2011, 18:12)  ..работает также с ошибкой. у вас в программе стоит вывод в порт B Посмотрите даташит. 2 страницу. распиновку. PB0 = порт B, OC0/T0 PB1 = порт B, T1 PB2 = порт B, AIN0 PB3 = порт B, AIN1 PB4 = порт B, SS PB5 = порт B, MOSI PB6 = порт B, MISO PB7 = порт B, SCK смотрим в фузы SPIEN = включён. (я так понимаю что вы программируете в панельке, можно перейти на программирование не по SPI. читайте инструкцию по STK500) Смотрим, что такое SPI (стр. 123) Это сигналы MISO MOSI SCK SS т.е. пины PB4, PB5, PB6, PB7 юзаются именно как SPI. либо отключайте SPI, либо выводите в порт A или С (как пример) (круглый)
|
|
|
|
|
Dec 22 2011, 05:57
|
Участник

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

|
Цитата(ILYAUL @ Dec 20 2011, 22:51)  1. После Init: поставьте cli
Init: ;++++++++++++++ Сдержимое файла INITCORE.INC +++++++++++++++++++++++++ ;==== Инициализация ядра: Память; Регистры; Стек ============= .include "INITCORE.inc" ;++++++++++++++ Конец Содержимого файла INITCORE.INC +++++++++++++++++ ;======= Инициализация внутренних периферийных устройств:====== ldi temp , 0b11111111 ; определяем входы\выходы порта В, out DDRB , temp ; 1 делает вывод выходом, 0 - входом! ldi temp , 0b00000000 ; определяем в\в порта D out DDRD , temp ldi temp , 0b11111111 ; включаем подтяжку (1) для входов порта В out portB , temp ; и задаем начальние состояния выходов ldi temp , 0b00000000 ; то же самое для D out portD , temp ldi temp, 1<<RXEN|1<<RXCIE|1<<TXen ; разрешаем прием и прерывание по приему по UART out UCSRB, temp ;ldi temp, 1<<TXEN|1<<TXCIE ; разрешаем передачу и прерывание по передачи по UART ;out UCSRB, temp ldi temp,25 ; задаем скорость UART = 9600 out UBRRL, temp ldi temp, 0 out UBRRH,temp ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 ; 8-мибитный формат посылки out UCSRC,r16 in temp , UCSRC ;UBRRH; out POrtB,temp cli дальше там простто цикл: Start: nop rjmp Start Цитата(ILYAUL @ Dec 20 2011, 22:51)  2. Прочтите регистры UBRRH и UCSRC после записи в них вот здесь не пойму как правильно прочитать: ведь эти два регистра с одним адресом памяти, и поэтому читаются странно, показываю все варианты как пробовал считывать: 1вариант ldi temp,25 ; UART = 9600 out UBRRL, temp ldi temp, 0 out UBRRH,temp in temp , UBRRH out POrtB,temp ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 на светодиодах показывает 00000000(как и предполагалось) 2вариант ldi temp, 0 out UBRRH,temp ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UBRRH out POrtB,temp на светодиодах показывает 00000000(как и предполагалось) 3вариант ldi temp, 0 out UBRRH,temp ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UCSRC out POrtB,temp на светодиодах показывает 00000000(вот здесь уже не то что предполагал) 4вариант ldi temp, 0 out UBRRH,temp ldi r16,1<<URSEL out UCSRC,r16 ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UCSRC out POrtB,temp на светодиодах показывает 00000000 5вариант ldi temp, 0 out UBRRH,temp ldi r16,1<<URSEL out UCSRC,r16 ldi r16, 1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UCSRC out POrtB,temp на светодиодах показывает 00000110 (добились что надо, НО! если последние две строки заменяем на in temp , UBRRH out POrtB,temp получаем 00000110,то есть то же самое) Вывод: то что мы записываем в UCSRC, то же самое записывается в UBRRH ? получается бит URSELникак е влияет на запись регистров что ли? Цитата(kolobok0 @ Dec 21 2011, 15:11)  выводите в порт A или С (как пример) вывел порт С, та же ситуация! видимо что то другое..
|
|
|
|
|
Dec 22 2011, 12:15
|

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

|
Здесь , где жолжна быть cliCODE Init:
cli
;++++++++++++++ Сдержимое файла INITCORE.INC +++++++++++++++++++++++++ ;==== Инициализация ядра: Память; Регистры; Стек ============= .include "INITCORE.inc" ;++++++++++++++ Конец Содержимого файла INITCORE.INC +++++++++++++++++
;======= Инициализация внутренних периферийных устройств:====== ldi temp , 0b11111111 ; определяем входы\выходы порта В, out DDRB , temp ; 1 делает вывод выходом, 0 - входом! ldi temp , 0b00000000 ; определяем в\в порта D out DDRD , temp
ldi temp , 0b11111111 ; включаем подтяжку (1) для входов порта В out portB , temp ; и задаем начальние состояния выходов ldi temp , 0b00000000 ; то же самое для D out portD , temp
ldi temp, 1<<RXEN|1<<RXCIE|1<<TXen ; разрешаем прием и прерывание по приему по UART out UCSRB, temp
;ldi temp, 1<<TXEN|1<<TXCIE ; разрешаем передачу и прерывание по передачи по UART ;out UCSRB, temp
ldi temp,25 ; задаем скорость UART = 9600 out UBRRL, temp ldi temp, 0 out UBRRH,temp
ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 ; 8-мибитный формат посылки out UCSRC,r16
in temp , UCSRC ;UBRRH; out POrtB,temp
sei
дальше там простто цикл: Start: nop rjmp Start
2. Прочтите регистры UBRRH и UCSRC после записи в них вот здесь не пойму как правильно прочитать: ведь эти два регистра с одним адресом памяти, и поэтому читаются странно, показываю все варианты как пробовал считывать: Код ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UCSRC out PortB,temp ldi temp,25 ; UART = 9600 out UBRRL, temp ldi temp, 0 out UBRRH,temp in temp , UBRRH out PortB,temp Цитата in temp , UCSRC out POrtB,temp на светодиодах показывает 00000110 (добились что надо, НО! если последние две строки заменяем на in temp , UBRRH out POrtB,temp получаем 00000110,то есть то же самое) Вывод: то что мы записываем в UCSRC, то же самое записывается в UBRRH ? получается бит URSELникак е влияет на запись регистров что ли? Вы не изменили направление чтения , поэтому прочитался снова UCSRC
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Dec 23 2011, 07:06
|
Участник

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

|
Цитата(ILYAUL @ Dec 22 2011, 16:15)  2. Прочтите регистры UBRRH и UCSRC после записи в них вот здесь не пойму как правильно прочитать: ведь эти два регистра с одним адресом памяти, и поэтому читаются странно, показываю все варианты как пробовал считывать: Код ldi r16, 1<<URSEL|1<<UCSZ0|1<<UCSZ1 out UCSRC,r16 in temp , UCSRC out PortB,temp ldi temp,25; UART = 9600 out UBRRL, temp ldi temp, 0 out UBRRH,temp in temp , UBRRH out PortB,temp Вы не изменили направление чтения , поэтому прочитался снова UCSRC По очереди компилирую первое"out PortB,temp" и второе"out PortB,temp",то есть по этому коду сначала на портВ вывожу UCSRC показывает 00000000, потом реистр UBRRH тоже показывает 00000000 Как же все таки правильно их считать и увидеть что мы там записали? in temp , UBRRH in temp , UCSRC out PortB,temp Оказывается так надо считывать! в естеaееве написано на стр 488: " Для выбора регистра при чтении используется временная последова- тельность. При первом обращении по указанным адресам возвращается значение регистра UBRRH (UBRRHn). При повторном обращении по этим адресам в следующем такте возвращается значение регистра UCSRC (UCSRnC), как показано в приведенных ниже примерах. Прерывания при выполнении этой последовательности команд должны быть запре- щены." теперь отвечаю на ваш вопрос Цитата(ILYAUL @ Dec 20 2011, 22:51)  Прочтите регистры UBRRH и UCSRC после записи в них в UBRRH как и предполагалось 00000000 UCSRC = 10000110 Все вроде правильно?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|