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

[ATmega128][ASM]Uruchomienie LCD 128x64

wojtek999 20 Gru 2008 12:29 4552 7
REKLAMA
  • #1 5880845
    wojtek999
    Poziom 16  
    Nie mogę poradzić sobie z uruchomieniem tego wyświetlacza:
    Link

    Na początek chciałbym włączyć go i mam taki program:

    
    .EQU	K_LCD_DANE			= DDRF			;kierunek portu wyświetlacza
    .EQU	I_LCD_DANE			= PINF			;wejście portu wyświetlacza
    .EQU	O_LCD_DANE			= PORTF			;wyjście portu wyświetlacza
    .EQU    DB0					= 0	
    
    .EQU	K_LCD_STER		= DDRB			;kierunek portu sterowania wyświetlacza
    .EQU	I_LCD_STER		= PINB			;wejście portu sterowania wyświetlacza
    .EQU	O_LCD_STER		= PORTB		;wyjście portu sterowania wyświetlacza
    .EQU    _CS1			= 1	
    .EQU    _CS2			= 2
    .EQU   	_RST			= 3
    .EQU   	LED_LCD			= 4
    .EQU   	E				= 5
    .EQU   	R_W				= 6
    .EQU    RS				= 7
    
    	ldi r16, 50
    	ldi r17, 2
    	rcall Czekaj_ms			;odczekaj 100ms
    
    
    	cbi O_LCD_STER, _CS1	;wybór obu kontrolerów
    	cbi O_LCD_STER, _CS2	
    	cbi	O_LCD_STER, RS		;zeruj RS (instrukcje)
    	cbi	O_LCD_STER, R_W		;zeruj R_W (zapis)	
    	
    	ldi r16, 0b00111111		;włącz LCD
    	sts O_LCD_DANE, r16		;sts a nie out bo w Atmega128 tak trzeba wpisywać do portu F
    	sbi O_LCD_STER, E
    	rcall LCD_delay
    	cbi O_LCD_STER, E
    
    	sbi O_LCD_STER, _CS1
    	sbi O_LCD_STER, _CS2
    
    LCD_delay:
    	nop
    	nop
    	nop
    	nop
    ret
    


    Przecież to powinno zadziałać. Sprawdzałem już wielokrotnie w dokumentacjach i tak powinien wyglądać program.
    Do wysyłania danych mam taki podprogram:
    
    LCD_zapisz:					;dana do wyświetlenia w r16
    	ldi r17, 0b11111111
    	sts K_LCD_DANE, r17		;linie danych LCD jako wyjście
    	lds r17, LCD_X
    	cpi r17, 63				;sprawdź współrzędną X wyświetlacz
    	brsh LCD_zapisz_CS2
    	cbi O_LCD_STER, _CS1	;jeśli <63 to wybór _CS1
    	jmp LCD_zapisz_1
      LCD_zapisz_CS2:
      	cbi O_LCD_STER, _CS2	;jeśli >63 to wybór _CS2
      LCD_zapisz_1:
      	sbi	O_LCD_STER, RS		;ustaw RS (dane)
    	cbi	O_LCD_STER, R_W		;zeruj R_W (zapis)
    	
    	sts O_LCD_DANE, r16		;wystaw daną na port
    	sbi O_LCD_STER, E		;strob 
    	rcall LCD_delay
    	cbi O_LCD_STER, E		;koniec strobu 
    	inc r17					;zwiększ współrzędną X 
    	cpi r17, 127			;sprawdź współrzędną X wyświetlacza
    	brlo LCD_zapisz_2
    	ldi r17, 0				;jeśli X>127 to X=0
       LCD_zapisz_2:
       	sts LCD_X, r17
       	sbi O_LCD_STER, _CS1
    	sbi O_LCD_STER, _CS2	
    ret
    


    Wszystkie połączenia są poprawne, sprawdzałem kilka razy. Tryb Atmega103 wyłączony, JTAG wyłączony. Jak napisze program by wysłał same zera na port O_LCD_DANE i O_LCD_STER to rzeczywiście są tam zera. Tak samo jedynki - sprawdzane miernikiem.
    Jak znacie jakieś dobre strony to mnie pokierujcie, ale już sam szukałem i wszędzie jest tak jak ja piszę.....

    Cały program jest następujący:
    
    							; SEGMENT DEKLARACJI
    .INCLUDE "m128def.inc"		; dołącz plik nagłówkowy dla ATmega128
    .INCLUDE "def_porty.inc"	; definicje portów
    
    	
    
    
    .DSEG
    .ORG 0x0100			;początek SRAM
    
    .INCLUDE "def_zmienne.inc"	; definicje zmiennych
    
    
    
    .CSEG					; SEGMENT PROGRAMU
    
    .org	0					;RESET
    	rjmp	Reset					
    .org	OVF1addr
    	reti
    .org	URXC0addr
    	reti
    
    ;********************************************************************
    ;********************************************************************
    ;********************************************************************
    
    
    Reset:
    	ldi	R17, high(RAMEND)	; inicjalizacja wskaźnika stosu
    	ldi	R16, low(RAMEND)
    	out	SPH, R17
    	out	SPL, R16
    
    	ldi r16, (1<<_CS1)|(1<<_CS2)|(1<<_RST)|(1<<LED_LCD)|(1<<E)|(1<<R_W)|(1<<RS) 
    	out K_LCD_STER, r16		;ustaw kierunek lini (1=wyjście)
    	ldi r16, (1<<_CS1)|(1<<_CS2)|(1<<_RST)|(1<<LED_LCD)|(0<<E)|(1<<R_W)|(1<<RS)
    	out O_LCD_STER, r16		;stan linii sterujących					
    	ldi r16, 0b11111111
    	sts K_LCD_DANE, r16		;ustaw kierunek lini danych LCD jako wyjście
    
    
    	ldi R16, 0	
    	sts LCD_X, R16
    	sts LCD_Y, R16			;zerowanie zmiennych w pamięci SRAM
    
    	
    .INCLUDE "ini_sprzet.inc"	
    .INCLUDE "czekaj_ms.inc"
    
    	sei 
    ;********************************************************************
    ;********************************************************************
    	ldi r16, 50
    	ldi r17, 2
    	rcall Czekaj_ms			;odczekaj 100ms
    
    
    	cbi O_LCD_STER, _CS1	;wybór obu kontrolerów
    	cbi O_LCD_STER, _CS2	
    	cbi	O_LCD_STER, RS		;zeruj RS (instrukcje)
    	cbi	O_LCD_STER, R_W		;zeruj R_W (zapis)	
    	
    	ldi r16, 0b00111111		;włącz LCD
    	sts O_LCD_DANE, r16		;sts a nie out bo w Atmega128 tak trzeba wpisywać do portu F
    	sbi O_LCD_STER, E
    	rcall LCD_delay
    	cbi O_LCD_STER, E
    
    	sbi O_LCD_STER, _CS1
    	sbi O_LCD_STER, _CS2
    
    
    Main:
    	
    rjmp Main
    ;
    ;--------------------------------
    ;--------------------------------
    ;--------------------------------
    ;--------------------------------
    LCD_wspolrzedne:		;X(0-127)=r16     Y(0-7)=r17
    	push r18
    
    	sts LCD_X, r16
    	sts LCD_Y, r17		;przypisanie zmiennym globalnym nowych wartości
    	cpi r16, 63
    	brsh LCD_wspolrzedne_CS2	;jeśli X>63 to skocz do....
    
    	cbi O_LCD_STER, _CS1		;aktywny pierwszy kontroler
    	lds r18, 0b01000000
    	or r16, r18					;do r16 komenda ustawienia pozycji Y adress (0-63)
    	rcall LCD_instrukcja		;ustaw pozycję Y adress (0-63)
    	lds r18, 0b10111000			;do r16 komenda ustawienia pozycji X adress (0-7)
    	mov r16, r17
    	or r16, r18
    	rcall LCD_instrukcja		;ustaw pozycję X adress (0-7)
    	sbi O_LCD_STER, _CS1 	
    
    	jmp LCD_wspolrzedne_0
       LCD_wspolrzedne_CS2:	
       	cbi O_LCD_STER, _CS2		;aktywny drugi kontroler
    	lds r18, 0b01000000
    	subi r16, 64				;odejmij od współrzędnej 64 bo drugi kontroler
    	or r16, r18					;do r16 komenda ustawienia pozycji Y adress (0-63)
    	rcall LCD_instrukcja		;ustaw pozycję Y adress (0-63)
    	lds r18, 0b10111000			;do r16 komenda ustawienia pozycji X adress (0-7)
    	mov r16, r17
    	or r16, r18
    	rcall LCD_instrukcja		;ustaw pozycję X adress (0-7)
    	sbi O_LCD_STER, _CS2
       LCD_wspolrzedne_0:
       	cbi O_LCD_STER, _CS1
    	ldi r16, 0b11000000
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS1
    	cbi O_LCD_STER, _CS2
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS2
       pop r18
    ret
    ;--------------------------------
    LCD_cls:
    ;	void lcdCls(void)
    ;	{
    ;	unsigned char x, y; // pomocnicze zmienne
    ;	for (y = 0; y < 8; y++) // 8-krotne powtórzenie pętli
    ;	{
    ;	lcdGoTo(0,y); // ustawienie współrzędnej y wyświetlacza
    ;	for (x = 0; x < 128; x++) // 128-krotne powtórzenie pętli
    ;	lcdWriteData(0x00); // zapis do wyświetlacza
    ;	}
    ;	lcdGoTo(0,0); // ustawienie początkowych współrzędnych
    ;	}
    	push r16
    	push r17
    	ldi r16,0
    	ldi r17,0
    
    
    
    	pop r17
    	pop r16
    ret
    ;--------------------------------
    LCD_off:
    	push r16
    	cbi O_LCD_STER, _CS1	;aktywny pierwszy kontroler
    	ldi r16, 0b00111110		
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS1
    	cbi O_LCD_STER, _CS2	;aktywny drugi kontroler
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS2
    	pop r16		
    ret
    ;--------------------------------
    
    ;--------------------------------
    LCD_on:
    	push r16
    	cbi O_LCD_STER, _CS1	;aktywny pierwszy kontroler
    	ldi r16, 0b00111111		
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS1
    	cbi O_LCD_STER, _CS2	;aktywny drugi kontroler
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS2
    	pop r16		
    ret
    ;--------------------------------
    LCD_instrukcja:				;instrukcja do wysłania w r16   //zapisuje tylko DO JEDNEGO STEROWNIKA
    	ldi r17, 0b11111111
    	sts K_LCD_DANE, r17		;linie danych LCD jako wyjście
    	rcall LCD_czekaj		;czekaj aż się zwolni sterownik
    	cbi	O_LCD_STER, RS		;zeruj RS (instrukcje)
    	cbi	O_LCD_STER, R_W		;zeruj R_W (zapis)	
    	sts O_LCD_DANE, r16		;wystaw instrukcję na port
    	sbi O_LCD_STER, E		;strob 
    	rcall LCD_delay
    	cbi O_LCD_STER, E		;koniec strobu 
    ret
    ;--------------------------------
    LCD_zapisz:					;dana do wyświetlenia w r16
    	ldi r17, 0b11111111
    	sts K_LCD_DANE, r17		;linie danych LCD jako wyjście
    	lds r17, LCD_X
    	cpi r17, 63				;sprawdź współrzędną X wyświetlacz
    	brsh LCD_zapisz_CS2
    	cbi O_LCD_STER, _CS1	;jeśli <63 to wybór _CS1
    	jmp LCD_zapisz_1
      LCD_zapisz_CS2:
      	cbi O_LCD_STER, _CS2	;jeśli >63 to wybór _CS2
      LCD_zapisz_1:
      	sbi	O_LCD_STER, RS		;ustaw RS (dane)
    	cbi	O_LCD_STER, R_W		;zeruj R_W (zapis)
    	
    	sts O_LCD_DANE, r16		;wystaw daną na port
    	sbi O_LCD_STER, E		;strob 
    	rcall LCD_delay
    	cbi O_LCD_STER, E		;koniec strobu 
    	inc r17					;zwiększ współrzędną X 
    	cpi r17, 127			;sprawdź współrzędną X wyświetlacza
    	brlo LCD_zapisz_2
    	ldi r17, 0				;jeśli X>127 to X=0
       LCD_zapisz_2:
       	sts LCD_X, r17
       	sbi O_LCD_STER, _CS1
    	sbi O_LCD_STER, _CS2	
    ret
    ;--------------------------------
    LCD_czekaj:					;Sprawdzanie zajętości JEDNEGO sterownika LCD
    	push r16
    	ldi r16, 0b00000000
    	sts K_LCD_DANE, r16		;ustaw kierunek lini danych LCD jako wejście
    	cbi	O_LCD_STER, RS		;zeruj RS (instrukcje)
    	sbi O_LCD_STER, R_W		;ustaw R_W (odczyt)
     	;Pętla oczekująca na zwolnienie sterownika:
    	LCD_czekaj0:
    		rcall LCD_delay
    		sbi O_LCD_STER, E		;strob 
    		rcall LCD_delay
    		cbi O_LCD_STER, E		;koniec strobu 
    		sbic I_LCD_DANE, 7		;pomiń jeśli flaga BUSY=0 (czyli sterownik gotowy)
     	jmp LCD_czekaj0
    	pop r16
    ret
    ;--------------------------------
    LCD_delay:
    	nop
    	nop
    	nop
    	nop
    ret
    ;--------------------------------
    
    ;===========================================================================
    Timer1:
    
    	
    reti
    

    Poprawiłem tytuł - regulamin p.11
    [zumek]
  • REKLAMA
  • #2 5884042
    asembler
    Poziom 32  
    A masz procedure do inicjalizacji wyswietlaczas?
    trzeba właczyc wyswietlacz ustawic wypelnienie i inne takie
  • REKLAMA
  • #3 5886861
    wojtek999
    Poziom 16  
    Inicjalizacja jest zgodnie z fragmentem kodu na samym początku postu. Trzeba tylko włączyć wyświetlanie danych z pamięci LCD-ka. Nie ma potrzeby ustawiania wypełnienia itp. w tym typie wyświetlaczy.
  • REKLAMA
  • #4 5886904
    asembler
    Poziom 32  
    Mam podobny wysiwetlacz tyle ze o matrycy 122x32 i posiada on kilka rejestrów sterujący pracą wyswietlacza. np mozna go przełaczyc w tryb stand-by. Po włącznie wartości w tych rejestrach niekoniecznie muszą byc taki aby poprawnie mozna było wyswietlac piksele jedynie po wyslaniu odpowiednich stanow na linie wysiwetlacza (DATA,CS1,CS2 I.T.P)
  • #5 5886920
    wojtek999
    Poziom 16  
    Jaki sterownik masz w wyświetlaczu? Ja KS108A i nie ma w dokumentacji nic o jakiś dodatkowych ustawieniach oprócz włączenia wyświetlania danych z pamięci.
  • REKLAMA
  • #7 5914195
    wojtek999
    Poziom 16  
    Wyświetlacz udało mi się częściowo uruchomić. Z wysyłaniem danych do wyświetlenia nie ma problemu, gorzej jest z instrukcjami, np fragment kodu:
    
            ldi r16, 0b10111000	        ;ustaw wiersz
    
    	cbi O_LCD_STER, _CS1	;aktywny pierwszy kontroler
    	rcall LCD_instrukcja
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS1
    
    	cbi O_LCD_STER, _CS2	;aktywny drugi kontroler
    	rcall LCD_instrukcja
    	rcall LCD_instrukcja
    	sbi O_LCD_STER, _CS2
    

    ..ustawia adres na pierwszy wiersz. W tym przypadku działa, ale powinno wystarczyć jednokrotne wywołanie procedury LCD_instrukcja - wtedy jednak nie działa. Muszą być 2 wywołania jak tutaj. Poza tym mogę zaadresować tylko wiersz 1,2,5 oraz dwa ostatnie. Czterech środkowych nie da się i gdy ustawie adres na 3 wiersz to zapisuje na 7, gdy zaadresuję na 4 to zapisuje na 8, na 5 jest dobrze a na 6 znowu pisze na 8 wierszu. Już sam nie wiem o co chodzi. Zabieram się za pisanie programu od podstaw bo już parę dni siedzę bezskutecznie. Wyświetlacz jest dobry, bo sprawdzałem 2, tak samo procesor. Nawet podpiąłem wyświetlacz na inną płytkę w której siedzi atmega16 i tam też jest tak samo...:(
    Linia danych jest na porcie F, sterowanie na B. Tryb zgodności z Atmega103 wyłączony, JTAG wyłączony.
  • #8 6024358
    wojtek999
    Poziom 16  
    Problem już rozwiązany jakiś czas temu. Był niewielki błąd w procedurze oczekującej na zwolnienie sterownika. W załączniku kod a assemblerze do obsługi KS108 który napisałem. Może komuś się przyda. Pewne rzeczy trochę nietypowo robiłem ale tak mi było łatwiej.
REKLAMA