Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ткните носом чо не так то (AVR USART)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
vazz
Вобщем как-то пару месяцев назад игрался я с USARTом атмеги16 типа "первые шаги" и что самое удивительное припоминаю что у меня даже что-то получалось, т.е. принималось отправлялось, но потом как всегда бывает возникли задачи поважнее и я енто дело отложил. Сейчас имеется необходимость все закрепить и поиграться уже по взрослому. Короче пол дня уже сижу и так и эдак и ничего не получается, принять даж не получается ничего(( Кварц у меня 11,0592МГц (по ДШ без удвоения скорости в делитель UBRR нуна 11 записать)

Код
;
;  +-------------------------------------------------------------------------+
;  |                           инциализация USART                            |
;  +-------------------------------------------------------------------------+
;
;
    ldi        temp1,0b10000110    ;устанавливаем регистр UCSRC
    out        UCSRC,temp1    ;7-URSEL = 1 (выбор регистра 0=UBRRH, 1=UCSRC)
;                    ;6-UMSEL = 0 (0=асинхр., 1=синхр.)
;                    ;5-UPM1  = 0 (выбор контроля четности
;                    ;4-UPM0  = 0 (нет контроля))
;                    ;3-USBS  = 0 (кол-во стоп-битов (1=2 стоп-бита))
;                    ;2-UCSZ1 = 1 (количество бит (0-1-1=8бит),
;                    ;1-UCSZ0 = 1  см.UCSZ2 в рег.UCSRB)
;                    ;0-UCPOL = 0 (при синхр.передаче, см.ДШ)
    ldi        temp1,0b00000000    ;устанавливаем регистр UBRRH
    out        UBRRH,temp1    ;7-URSEL = 0 (выбор регистра 0=UBRRH, 1=UCSRC)
;                    ;6-NU
;                    ;5-NU
;                    ;4-NU
;                    ;3-UBRR11= 0 (установка битрэйта, старшая
;                    ;2-UBRR10= 0  тетрада UBRR)
;                    ;1-UBRR9 = 0
;                    ;0-UBRR8 = 0
    ldi        temp1,0b00001011    ;устанавливаем регистр UBRRL (57600кбод)
    out        UBRRL,temp1    ;UBRR7...0 = 11 (младший байт битрэйта)
    ldi        temp1,0b00000000    ;уст. регистр A упр. и статуса UCSRA
    out        UCSRA,temp1    ;7-RXC   = 0 (флаг завершения приёма)
;                    ;6-TXC   = 0 (флаг завершения передачи)
;                    ;5-UDRE  = 0 (флаг освобождения регистра данных)
;                    ;4-FE    = 0 (ошибка приёма (нет стоп-бита)
;                    ;3-DOR   = 0 (флаг переполнения (при заполнении принят очередной старт-бит))
;                    ;2-UPE   = 0 (ошибка условия четности, в ДШ название просто "PE")
;                    ;1-U2X   = 0 (1=удвоение скорости)
;                    ;0-MPCM  = 0 (1=многопроцессорный обмен (фильтруются посылки без адреса))
    ldi        temp1,0b11011000    ;уст. регистр B упр. и статуса UCSRB
    out        UCSRB,temp1    ;7-RXCIE = 1 (1=разр.прерывание USARTRXC)
;                    ;6-TXCIE = 1 (1=разр.прерывание USARTTXC)
;                    ;5-UDRIE = 0 (1=разр.прерывание USARTDRE)
;                    ;4-RXEN  = 1 (1=разр.работу приёмника)
;                    ;3-TXEN  = 1 (1=разр.работу передатчика)
;                    ;2-UCSZ2 = 0 (кол-во бит, см.рег.UCSRC)
;                    ;1-RXB8  = 0 (9ый бит приёма (при 9ти битах))
;                    ;0-TXB8  = 0 (9ый бит перед. (при 9ти битах))
;

А это у меня вектор по приему:

;
;  +-------------------------------------------------------------------------+
;  |                         Приём по USART завершен                         |
;  +-------------------------------------------------------------------------+
USARTRXC:
    in        temp1,UDR
    ldi        ZH,1
    ldi        ZL,108
    st        Z,temp1
    reti


Ну а дальше в основном теле я беру данные из этой ячейки SRAM и отправляю их на дисплей

Прибор уже полностью работает, осталось тока 485-интерфейс воткнуть с модбасом(

Ткните носом где я чего не так сделал, в симуляторе AVRStudio отследить ничего не получается

(исходные замечания: модуль работы с дисплеем работает 100%, преобразователь 232/485 тоже живой 100%, контактной болезни нет, процессор живой, программа для работы с com-портами тоже не раз пользованая, явно что-то в программе не то делаю)
Serhiy_UA
http://easyelectronics.ru/avr-uchebnyj-kur...herez-uart.html
http://compconnect.ru/2010/03/opisanie-rab...ntrollerov-avr/
http://www.123avr.com/
http://avr.ru/beginer/avrsbs/step5.html

и т.д. от Google

Есть и на асме, но это было давно, надо искать. Нашел, пример для ASM в приложении, это был цифровой фильтр на AVR, там есть и UART.
Конечно, проше на С в IAR.

Код
//-----------------------------------------------------------------------------
#define xtal 16000000l// Hz ATMEL
#define baud 19200   //Baud for RS-232
void init_uart(void)
{UBRRH = (byte)((xtal/16/baud-1)>>8);   //Set baud rate for UART
UBRRL = (byte)(xtal/16/baud-1);
UCSRB=((1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN)); //Enable RX & TX (RXEN,TXEN) and interrupt (RXCIE,TXCIE)
UCSRC=(1<<URSEL)|(1<<USBS)|(3<<UCSZ0);}//Frame format: 2stop bit, 8data (Select 1<<URSEL)
//-----------------------------------------------------------------------------
#pragma vector = USART_RXC_vect           //Receive RS-232
__interrupt  void UART_Receive( void )    //
{byte a; a=UDR;
if(RiT<RiTmax){if(RsI<255)RsI++;else(RsI=255);}else{RsI=0;};Ri[RsI]=a;RiT=0;}
//-----------------------------------------------------------------------------
#pragma vector = USART_TXC_vect           //Transmit RS-232
__interrupt  void UART_Transmit( void )   //
{RsO++; if(RsO!=RsN)UDR=Ro[RsO];else {}; UCSRA|=(1<<TXC);RoT=0;}
ILYAUL
Скорость обычно пишут так.

ldi temp,SYSCLK/(16*USARTSPEED1)-1
sts UBRR1L,temp
В Вашем случае OUT

И проверьте прерывание попадает на свой адрес. т.е таблицу прерываний и куда по прерывание скачет адрес
zltigo
QUOTE (ILYAUL @ Aug 3 2010, 18:48) *
ldi temp,SYSCLK/(16*USARTSPEED1)-1

Ну тогда уж совсем правильно будет так:
ldi temp,(SYSCLK)/(16*(USARTSPEED1)) - 1
vazz
Цитата(ILYAUL @ Aug 3 2010, 18:48) *
Скорость обычно пишут так.

ldi temp,SYSCLK/(16*USARTSPEED1)-1
sts UBRR1L,temp
В Вашем случае OUT

И проверьте прерывание попадает на свой адрес. т.е таблицу прерываний и куда по прерывание скачет адрес


Приехал в краснодар.. Фиг знает, все вроде в норме, попробовал зациклить программу при переходе на прерывание по приему байта (jmp поставил сразу при переходе на метку прерывания на туже метку), но прибор работает не зацикливаясь когда ему байт отправляю с порта. Думал уже микруха 485 сдохла или с портом чо-то не то, перепрошил старую прошивку (предыдущего программиста), она работает посылки принимаются и ответы на них есть. Блин, наверняка где-то мелкий косяк, буду искать. Исходников его у меня нет к сожалению да и связи тоже никакой. Уже вроде и с модбасом разобрался и с подсчетом crc16, думал вчера сяду и все доделаю отлажу, потому что точно помню что у меня получалось когда-то этот usart заставлять и принимать и отправлять.. Хрень какая-то, надо чаще отдыхать, мозг совсем устал видимо.. А может я где-то что-то упустил в плане начальной инициализации usart, ну может есть какие-то биты в регистрах специального назначения для управления работой MCU или еще где.. перерыл все, ничо такого не нашел
Serhiy_UA
Цитата(vazz @ Aug 4 2010, 15:02) *
.. перерыл все, ничо такого не нашел


рыть надо еще, смотри здесь, а также что ранее выслано
http://atmel.efo.ru/Articles/Atmel12.htm
http://atmel.efo.ru/Articles/Atmel12_app.htm

a здесь для mega16 примеры
http://www.atmel.com/dyn/resources/prod_do...nts/doc2466.pdf
подпрограмма инициализации стр.150
USART_Init:
; Set baud rate
out UBRRH, r17
out UBRRL, r16
; Enable receiver and transmitter
ldi r16, (1<<RXEN)|(1<<TXEN)
out UCSRB,r16
; Set frame format: 8data, 2stop bit
ldi r16, (1<<URSEL)|(1<<USBS)|(3<<UCSZ0)
out UCSRC,r16
ret

а также подпрограмма передачи стр.152
USART_Transmit:
; Wait for empty transmit buffer
sbis UCSRA,UDRE
rjmp USART_Transmit
; Put data (r16) into buffer, sends the data
out UDR,r16
ret
vazz
Цитата(Serhiy_UA @ Aug 4 2010, 15:56) *
рыть надо еще, смотри здесь, а также что ранее выслано
http://atmel.efo.ru/Articles/Atmel12.htm
http://atmel.efo.ru/Articles/Atmel12_app.htm

a здесь для mega16 примеры
http://www.atmel.com/dyn/resources/prod_do...nts/doc2466.pdf


Спасибо большое за ссылки, но как я и предполагал основная проблема в мозгах)))) забыл я про пин у 485 микрухи, который управляет режимом прием/передача (он у меня на PORTD.2 заведен), короче если б я начал вспоминать как чо и к чему с этим usart с проверки в режиме передачи, то работало все сразу)) а так у меня этот пин был все время в состоянии лог.1 (т.е. передача) поэтому и прием у меня никак не получался.. тупанул
Dog Pawlowa
Цитата(vazz @ Aug 5 2010, 07:23) *
забыл я про пин у 485 микрухи

В таких случаях осциллограф - лучший друг программиста! smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.