logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Błąd kompilacji UART w WinAVR dla ATmega8535 - `UBRR` niezadeklarowane

Karollo_82 06 Maj 2005 16:56 1997 7
  • #1 1467006
    Karollo_82
    Poziom 15  
    Posty: 181
    Pomógł: 4
    Ocena: 7
    Napisałem kawałek kodu na inicjację interfejsu UART i nie mogę skompilować. Gdzie jest błąd? Kompiluję w WinAVR a mój procek to mega8535

    #include <avr/io.h>
    
    #define F_CPU	11059200ul
    #define UART_BAUD	9600ul
    #define UART_CONST	(F_CPU/(16ul*UART_BAUD)-1)
    
    void init(void)
    {
    	DDRA=0xFF;
    	DDRC=0xFF;
    	outp((unsigned char)UART_CONST, UBRR);
    }
    
    int main (void)
    {
    init();
    
    while(1)
       {
    	
       }
    }


    Wywala następujący błąd:

    UARTMain.c:20: error: `UBRR' undeclared (first use in this function)
    UARTMain.c:20: error: (Each undeclared identifier is reported only once
    UARTMain.c:20: error: for each function it appears in.)

    Robiłem zgodnie z tym: http://www.freepgs.com/robkry/?t=avrgcc/uart
  • #2 1467028
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    UBRR w nowszych prockach jest 12-bit, więc jest UBRRL i UBRRH, a kod pochodzi pewnie z AT90S... Nie zapomnij zajrzeć do pfd-a po szczegóły... ;) No i nie zapomnij o tym, że w nowszej wersji avrgcc nie ma cbi/sbi - zawartego na wspomnianej stronie, co było już wspomniane niejednokrotnie na tym forum, wraz z metodami zastąpienia instrukcjami przypisania.
  • #3 1467467
    frohme
    Poziom 21  
    Posty: 421
    Pomógł: 25
    Ocena: 15
    A przeglądnij plik który włączyłeś - tam nie ma deklaracji co to jest UBRR, ale są odwołania do dalszych plików definiujących procesory - wybierz ten tobie potrzebny przez #define __AVR_ATmega8535__ , lub jeszcze raz # include <avr/iom8535.h>
  • #4 1468119
    Karollo_82
    Poziom 15  
    Posty: 181
    Pomógł: 4
    Ocena: 7
    Ok, to może teraz ktoś napisze mi prostą funkcję wysyłającą coś do portu UART, bo nie mogę sobie z tym poradzić.
  • #5 1468720
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    A oto prosta funkcja (kompiluje się w najnowszym AVRStudio) :D :
    #include <ATmega8535.h>
    .include "m8535def.inc" ; Prohibits use of non-implemented instructions (ATmega8535)
    #define XTAL   11059200
    #define USART_BAUD   19200
    #define _UBBR(_X,_X_BAUD) ((_X/(16*_X_BAUD))-1)
    #message "_UBBR ==" (_UBBR(XTAL, USART_BAUD))
    #define PARITY_NONE 0
    #define PARITY_EVEN (1<<UPM1)
    #define PARITY_ODD ((1<<UPM1)|(1<<UPM0))
    #define STOP_BITS_1 0
    #define STOP_BITS_2 (1<<USBS)
    #define DATA_BITS_5 0
    #define DATA_BITS_6 (1<<UCSZ0)
    #define DATA_BITS_7 (1<<UCSZ1)
    #define DATA_BITS_8 ((1<<UCSZ1)|(1<<UCSZ0))
    #define DATA_BITS_9 ((1<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0))
    .equ	    RAMSTART=0x0060 ; 96 bytes I/O before.
    .def	FalseOrZero =		r13
    .def	TrueOrOne =			r14
    .def	DataByte =			r16
    .def	TempA =				r17
    .def	TempB =				r18
    #define X x
    #define Y y
    #define Z z
    #define LOW low
    #define HIGH high
    .cseg
    ;————————————————————————————————————————————————————————————
    .org	$00 ; Reset Handle
    	rjmp RESET
    ;————————————————————————————————————————————————————————————
    .org	INT0addr ; External Interrupt0 Handle
    	reti
    ;	rjmp EXT_INT0
    ;————————————————————————————————————————————————————————————
    .org	INT1addr ; External Interrupt1 Handle
    	reti
    ;	rjmp EXT_INT1
    ;————————————————————————————————————————————————————————————
    .org	OC2addr ; Output Compare2 (Timer/Counter2 Compare Match) Interrupt Handle
    	reti
    ;	rjmp TIM2_COMP
    ;————————————————————————————————————————————————————————————
    .org	OVF2addr ; Timer/Counter2 Overflow Interrupt Handle
    	reti
    ;	rjmp TIM2_OVR ; --> Timer2ovr.asm
    ;————————————————————————————————————————————————————————————
    .org	ICP1addr ; Input Capture1 (Timer/Counter1 Capture Event) Interrupt Handle
    	reti
    ;	rjmp  TIMER1_CAPT
    ;————————————————————————————————————————————————————————————
    .org	OC1Aaddr ; Output Compare1A (Timer/Counter1 Compare Match A)Interrupt Handle
    	reti
    ;	rjmp TIM1_COMPA 
    ;————————————————————————————————————————————————————————————
    .org	OC1Baddr ; Output Compare1B (Timer/Counter1 Compare Match B) Interrupt Handle
    	reti
    ;	rjmp TIM1_COMPB
    ;————————————————————————————————————————————————————————————
    .org	OVF1addr ; Timer/Counter1 Overflow Interrupt Handle
    	reti
    ;	rjmp TIM1_OVR
    ;————————————————————————————————————————————————————————————
    .org	OVF0addr ; Timer/Counter0 Overflow Interrupt Handle
    	reti
    ;	rjmp TIM0_OVR ; --> Timer0ovr.asm
    ;————————————————————————————————————————————————————————————
    .org	SPIaddr ; SPI (Serial Transfer Complete) Interrupt Handle
    	reti
    ;	rjmp SPI_STC
    ;————————————————————————————————————————————————————————————
    .org	URXCaddr ; USART Receive Complete Interrupt Handle
    	reti
    ;	rjmp USART_RXC
    ;————————————————————————————————————————————————————————————
    .org	UDREaddr ; USART Data Register Empty Interrupt Handle
    	reti
    ;	rjmp USART_DDRE
    ;————————————————————————————————————————————————————————————
    .org	UTXCaddr ; USART Transmit Complete Interrupt Handle
    	reti
    ;	rjmp USART_TXC
    ;————————————————————————————————————————————————————————————
    .org	ADCCaddr ; ADC Conversion Complete Interrupt Handle
    	reti
    ;	rjmp ADC_COMPL
    ;————————————————————————————————————————————————————————————
    .org	ERDYaddr ; EEPROM Ready Interrupt Handle
    	reti
    ;	rjmp EE_RDY
    ;————————————————————————————————————————————————————————————
    .org	ACIaddr ; Analog Comparator Interrupt Handle
    	reti
    ;		rjmp ANA_COMP
    ;————————————————————————————————————————————————————————————
    .org    TWIaddr ; Irq. Handle for Two-Wire Interface
    	reti
    ;	rjmp TWSI
    ;————————————————————————————————————————————————————————————
    .org	INT2addr ; External Interrupt2 Handle
    	reti
    ;	rjmp EXT_INT2
    ;————————————————————————————————————————————————————————————
    .org    OC0addr ; Output Compare0 Interrupt Handle (Timer/Counter0 Compare Match)
    	reti
    ;	rjmp TIM0_COMP
    ;————————————————————————————————————————————————————————————
    .org	SPMRaddr ; SPM complete (Store Program memory Ready) Interrupt Handle
    	reti
    ;	rjmp SPM_RDY
    ;————————————————————————————————————————————————————————————
    .dseg
    .org RAMSTART
    .cseg
    .macro LoadZ_LpmAddr
    	ldi ZL, low(@0<<1) ; Load Z register low
    	ldi ZH, high(@0<<1) ; Load Z register high 
    .endmacro
    HexAToAB:
    	mov TempB, TempA
    	swap TempA
    	cbr TempA, 0xF0
    	cpi TempA, 0x0A
    	brcc TempAGt10
    	subi TempA, -0x30
    	rjmp HexTempB
    TempAGt10:
    	subi TempA, -0x37	; AddByte = 0x37 for adding 0x0A-0x0F
    HexTempB:
    	cbr TempB, 0xF0
    	cpi TempB, 0x0A
    	brcc TempBGt10
    	subi TempB, -0x30
    	ret
    TempBGt10:
    	subi TempB, -0x37	; AddByte = 0x37 for adding 0x0A-0x0F
    	ret
    InitRS232:
    ;———————————Outputs———————————————
    	ldi DataByte, HIGH(_UBBR(XTAL, USART_BAUD))
    	out UBRRH, DataByte
    	ldi DataByte, LOW(_UBBR(XTAL, USART_BAUD))
    	out UBRRL, DataByte
    ; - - - - - - - - - - - - - - - -
    	ldi DataByte, 1<<URSEL|DATA_BITS_8|PARITY_NONE|STOP_BITS_1
    	out UCSRC, DataByte
    ; - - - - - - - - - - - - - - - -
    	sbi UCSRB, TXEN ; Transmitter On
    ; - - - - - - - - - - - - - - - -
    	ret
    .dseg
    bTxBuff:
    .byte 0x01
    lpSendFlshTxt:
    .byte 0x02
    DigTxBuff:
    .byte 0x04
    cDigTxBuff:
    .byte 0x01
    lpSendDigTxt:
    .byte 0x02
    .cseg
    USARTTxFlshTxtInit:
    	sts bTxBuff, TrueOrOne
    	sts lpSendFlshTxt, ZL
    	sts lpSendFlshTxt+1, ZH
    	sts cDigTxBuff, FalseOrZero
    	ret
    USARTTxFlshDebgTxt:
    	sbis UCSRA, UDRE
    	rjmp USARTTxFlshTxtEnd
    	lds TempA, bTxBuff
    	tst TempA
    	breq USARTTxFlshTxtEnd
    	lds TempA, cDigTxBuff
    	tst TempA
    	breq USARTTxFlshNext
    ;- - - - - - - - - - - - - - - - - - -
    	lds XL, lpSendDigTxt
    	lds XH, lpSendDigTxt+1
    	ld DataByte, X+
    	out UDR, DataByte
    	dec TempA
    	sts lpSendDigTxt, XL
    	sts lpSendDigTxt+1, XH
    	sts cDigTxBuff, TempA
    	rjmp USARTTxFlshTxtEnd
    ;- - - - - - - - - - - - - - - - - - -
    USARTTxFlshNext:
    	lds ZL, lpSendFlshTxt
    	lds ZH, lpSendFlshTxt+1
    	lpm DataByte, Z+
    	tst DataByte ; Zero - end of string
    	breq USARTTxBadOrEndFlshData
    ;- - - - - - - - - - - - - - - - - - -
    USARTTxFlshTstHex:
    	cpi DataByte, 0x24 ; "$"
    	brne USARTTxFlshTxt
    ;- - - - - - - - - - - - - - - - - - -
    	lpm DataByte, Z+
    	cpi DataByte, 0x24 ; "$"
    	breq USARTTxFlshTxt ; double "$" means one...
    ;- - - - - - - - - - - - - - - - - - -
    	sbr DataByte, 0x20 ; ASCII higher to lower...
    	cpi DataByte, 0x73 ; "s" - means SRAM Data
    	breq USARTTxFlshSendSRAMHex
    USARTTxBadOrEndFlshData:
    	sts bTxBuff, FalseOrZero
    	rjmp USARTTxFlshTxtEnd
    ;- - - - - - - - - - - - - - - - - - -
    USARTTxFlshSendSRAMHex:
    	lpm XL, Z+
    	lpm XH, Z+
    	ld TempA, X+
    	rcall HexAToAB
    	out UDR, TempA
    	sts DigTxBuff, TempB
    	ldi TempA, LOW(DigTxBuff)
    	sts lpSendDigTxt, TempA
    	ldi TempA, HIGH(DigTxBuff)
    	sts lpSendDigTxt+1, TempA
    	sts cDigTxBuff, TrueOrOne
    	rjmp USARTTxFlshStoreZ
    ;- - - - - - - - - - - - - - - - - - -
    USARTTxFlshTxt:
    	out UDR, DataByte
    USARTTxFlshStoreZ:
    	sts lpSendFlshTxt, ZL
    	sts lpSendFlshTxt+1, ZH
    USARTTxFlshTxtEnd:
    	ret
    InitSRAM:
    	in XL, SPL
    	in XH, SPH
    	cli
    	ld TempA, X+ ; inc XL:XH
    InitSRAMClr:
    	st  -X, FalseOrZero
    InitSRAMLo:
    	cpi XL, LOW(RAMSTART)
    	brne InitSRAMClr
    InitSRAMHi:
    	cpi XH, HIGH(RAMSTART)
    	brne InitSRAMClr
    InitSRAMEnd:
    	sei
    	ret
    TxtDebugKey:
    .db "TestVariable == 0x$s", LOW(TestVariable), HIGH(TestVariable)
    .db "      ", 13, 0
    RESET:
    ;Proc InitStack()
    InitStack:
    ; It must be not to be a subroutine, because must
    ; be stack point initialised before call it
    ; Inicialise Stack Point - push decrement it, pop increment
    	clr FalseOrZero ; fast Access Bool logic FALSE register
    	ldi TempA, 1
    	mov TrueOrOne, TempA ; fast Access Bool logic TRUE register
    	ldi TempA, HIGH(RAMEND)
    	out SPH, TempA
    	ldi TempA, LOW(RAMEND)
    	out SPL, TempA
    	rcall InitSRAM ; ——> sRAM.asm
    	rcall InitRS232 ; ——> RS232.asm
    .dseg
    TestVariable:
    .byte 0x01
    .cseg
    	sei
    MainProc:
    	rcall USARTTxFlshDebgTxt ; ——> RS232.asm
    	lds TempB, bTxBuff
    	tst TempB
    	brne MainProc
    	lds DataByte, TestVariable ; TestVariable
    	inc DataByte
    	sts TestVariable, DataByte ; TestVariable
    ; - - - - - - - - - - - - - - - -
    	LoadZ_LpmAddr TxtDebugKey
    	rcall USARTTxFlshTxtInit
    	rjmp MainProc
    Procedura wyrzuca na terminalu cyklicznie zmieniającą się zmienną 8-bit, wraz z stałym tekstem (zawartym pod etykietą TxtDebugKey).
    W załączniku skompilowany hex, powinien działać pod ATmega8535 i bodajże ATmega16/32 (Nie mam w tej chwili ani sztuki, aby sprawdzić, procedurka w trochę innym kształcie działała na ATmega8515). Czekam na testy... ;)
    Pozdr. Light'I
    Załączniki:
    • USART-TxTest.11.0592.hex.zip (548 Bajtów) Musisz być zalogowany, aby pobrać ten załącznik.
  • #6 1471424
    Karollo_82
    Poziom 15  
    Posty: 181
    Pomógł: 4
    Ocena: 7
    Light'I napisał:
    ­Czekam na testy...

    Otóż testy zostały wykonane. Załadowałem heksa którego mi wysłałeś (dzięki) no i działa na mega8535. Na terminalu widać:

    TestVariable == 0xXX
    gdzie: XX - w tym miesjcu pojawiają się hexadecymalne wartości (8-bit)

    Light'­­­­I napisał:
    A oto prosta funkcja


    Przyjmę to jako żart :) Hehe, ja dopiero zaczynam przygodę programowania mikrokontrolerów w C, a co dopiero w asm!! (jedynie Bascoma znam można powiedzieć dosyć dobrze) A tam większość to wstawki assemblerowe. Żeby rozszyfrować ten program będę potrzebował trochę czasu, ciekawe czy wogóle kiedyś rozszyfruję ;)
  • #7 1471513
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Karollo_82 napisał:
    Przyjmę to jako żart
    Można uznać to za żart, bo to jest pod asembler AVRasm2(AVRStudio)... ;) Tak więc jest tu tylko parę wstawek w C(preprocesor)... ;) No i kod jest proceduralny, większość pochodzi z fragmentów moich własnych, już napisanych bibliotek procedur, więc głównie moja zabawa z pisaniem polegała na Kopiuj+Wklej+Lekko zmień... Może się ktoś pokusi o translację na C ? ;)
  • #8 1471870
    Karollo_82
    Poziom 15  
    Posty: 181
    Pomógł: 4
    Ocena: 7
    Zacytuję kogoś z forum (już nie pamiętam kto to napisał): Oklaski dla tego kto przerobi to na C ;)

Podsumowanie tematu

LABEL_AI_GENERATED
Problem dotyczy błędu kompilacji w środowisku WinAVR dla mikrokontrolera ATmega8535, gdzie symbol `UBRR` jest niezadeklarowany podczas próby inicjalizacji interfejsu UART. Przyczyną jest różnica w rejestrach baud rate między starszymi a nowszymi mikrokontrolerami AVR – w ATmega8535 rejestr podzielony jest na dwa 8-bitowe rejestry UBRRL i UBRRH, a nie pojedynczy 16-bitowy UBRR. Konieczne jest uwzględnienie właściwego pliku nagłówkowego, np. ``, lub zdefiniowanie symbolu `__AVR_ATmega8535__`, aby kompilator poprawnie rozpoznał rejestry specyficzne dla tego modelu. Dodatkowo, w nowszych wersjach AVR-GCC nie ma instrukcji cbi/sbi, które należy zastąpić odpowiednimi operacjami bitowymi. W dyskusji pojawił się także przykład prostej funkcji do wysyłania danych przez UART, jednak w asemblerze AVR, co wymaga translacji na C. Użytkownik potwierdził działanie przykładowego kodu na ATmega8535, choć przyznał, że dopiero zaczyna naukę programowania mikrokontrolerów w C.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA