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

Dlaczego Atmega16 nie współpracuje z LCD 2x20 w asemblerze?

aschamed 03 Lut 2007 20:38 1734 1
REKLAMA
  • #1 3524461
    aschamed
    Poziom 11  
    Posty: 69
    Pomógł: 1
    Ocena: 3
    Witam!
    Mógłby mi ktoś pomóc i powiedzieć dlaczego mie nie działa ten wyświetlacz? Z góry dziekuje.

    .include "m16def.inc"

    .equ E = 0
    .equ RS = 1
    .equ DATA = PORTA
    ; do portu A podlaczona szyna danych 8 bitowa
    ; port C pin 0 -- E
    ; port C pin 1 -- RS
    .list
    .cseg
    .org 0
    ldi R16,HIGH(RAMEND)
    out SPH,R16
    ldi R16,LOW(RAMEND)
    out SPL,R16

    ldi R16, 0xFF
    out DDRA, R16

    ldi R16, 3
    out DDRC, R16

    sbi PORTC, E

    Main:

    cbi PORTC, RS
    ;ustawienie LCD
    ldi R16, 0x28
    out DATA, R16
    rjmp zapisz
    ;wlaczenie LCD i korsora
    ldi R16, 0x0F
    out DATA, R16
    rjmp zapisz
    ;wybor miejsca na LCD
    ldi R16, 0x45
    out DATA, R16
    rjmp zapisz
    sbi PORTC, RS
    ldi R16, 0
    wprowadz:
    inc R16
    out DATA, R16
    rjmp zapisz
    sbrs R16, 6
    rjmp wprowadz
    petla:
    rjmp petla

    rjmp Main


    zapisz:
    cbi PORTC, E
    nop
    nop
    sbi PORTC, E
    nop
    nop
    ret
  • REKLAMA
  • #2 3526693
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Pozwoliłem sobie uczytelnić kod dla pokazania jak można sobie ułatwić pisanie kodu - zmieniamy w jednym miejscu, a zmiany są uwzględniane w całym kodzie... Daje to bezbolesną możliwość dowolnego przepięcia linii sygnałowych pod inne wyprowadzenia µC przy minimalnych zmianach w kodzie (podobnie jak w językach wyższego poziomu).
    #include <m16def.inc> ; Prohibits use of non-implemented instructions (ATmega16)
    .list
    #define _USART
    .dseg
    .org SRAM_START
    .cseg
    // Tabela wektorów przerwań i Reset-u
    ;————————————————————————————————————————————————————————————
    .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
    ;————————————————————————————————————————————————————————————
    ; Definicje podł±czeń :
    ; - do portu A podlaczona szyna danych 8 bitowa
    .equ LCD_DATA = PORTA
    ; - port C pin 0 -- E
    .equ LCD_CTRL = PORTC
    .equ E = PC0
    ; - port C pin 1 -- RS
    .equ RS = PC1
    .def	DataAcc			=	r16
    RESET:
    ldi	DataAcc,HIGH(RAMEND)
    out	SPH,DataAcc		
    ldi	DataAcc,LOW(RAMEND)	
    out	SPL,DataAcc
    			
    ser DataAcc
    out LCD_DATA-1, DataAcc ; Korzystamy z właściwości, że adres DDERX jest zawsze o 1 mniejszy od PORTX
    
    ldi DataAcc, 1<<E|1<<RS
    out LCD_CTRL-1, DataAcc
    
    sbi LCD_CTRL, E
    
    Main:
    
    cbi LCD_CTRL, RS
    ;ustawienie LCD
    ldi DataAcc, 0x28
    out LCD_DATA, DataAcc
    rjmp zapisz
    ;wlaczenie LCD i korsora
    ldi DataAcc, 0x0F
    out LCD_DATA, DataAcc
    rjmp zapisz
    ;wybor miejsca na LCD
    ldi DataAcc, 0x45
    out LCD_DATA, DataAcc
    rjmp zapisz
    sbi LCD_CTRL, RS
    ldi DataAcc, 0
    wprowadz:
    inc DataAcc
    out LCD_DATA, DataAcc
    rjmp zapisz
    sbrs DataAcc, 6
    rjmp wprowadz
    petla:
    rjmp petla
    
    rjmp Main
    
    
    zapisz:
    cbi LCD_CTRL, E
    nop
    nop
    sbi LCD_CTRL, E
    nop
    nop
    ret
    Jak na moje oko, brak ustalonych zależności czasowych od częstotliwości zegara systemowego, co czyni µC za szybkim dla wyświetlacza. Najprościej wprowadzić opóźnienia, aż minie zadany czas w/g karty katalogowej producenta wyświetlacza (najczęściej 40 µs) przed wysłaniem czegokolwiek do LCD. Oczywiście czas dla inicjalizacji/resetu całego LCD jest odpowiednio dłuższy. Oprócz tego pominięto standardową tabelę wektorów typową dla każdego z AVR.
    Polecam do poczytania : http://www.ue.eti.pg.gda.pl/~wujek/lab_prog/info_lcd/info_lcd.html oraz http://home.iae.nl/users/pouweha/lcd/lcd0.shtml
    Nie wykluczam też pominięcia wyłączenia JTAG oraz wielu typowych problemów z ATmega16 i układami AVR z ADC, omawianych w tym dziale oraz FAQ.
REKLAMA