ADuC842 - Wyświetlanie licznika na LCD


(Bartlomiej Gawlak) #1

Witam,

 

Mam napisany program, który powinien na LCD wyświetlić licznik wg poniższego algorytmu:

#include <stdio.h>

int main(){
 int x,i;
 x=0;

 inc:
  for(i=x;i<10;i++){
   printf("Powiekszanie: %d\n",x);
   x++;}
  return 0;
}

Obecnie pracuję nad tym wyświetleniem ale marnie to idzie. Wyświetlam w 1szej linii Powiekszenie a w 2giej licznik, ale zamiast niego otrzymuję ciąg dziwnych znaków. Dodam, że jestem wysokopoziomowcem i piszę ten kod na wyczucie korzystając z ogólnodostępnych materiałów. Z początku chciałem porównywać za pomocą CJNE licznik i wyświetlić tablicę z T_#, ale ja chcę od razu go wyświetlić.

$MOD842 ; use 8052 predefined symbols

; definicja polaczenia lcd z uC
LCD_D4 EQU P2.1
LCD_D5 EQU P2.0
LCD_D6 EQU P2.3
LCD_D7 EQU P2.2
LCD_E EQU P2.5
LCD_RW EQU P2.4
LCD_RS EQU P2.7
LCD_KEY EQU P2.6
LCD_PORT EQU P2

LCD_DATA EQU 30h ; KOMORKA PAMIÊCI Z KTOREJ BAJT WYSYúANY 
                        ; DO WYSWIETLACZA
LICZNIK EQU 100h

ORG 0000h

call LCD_INIT ;Inicjalizacja wyswietlacza LCD

; Zapisanie polskich znaków do CG RAM

 MOV LCD_DATA,#40h ;Ustawienie kursora na pierwszy  
 ACALL LCD_ROZKAZ ;znak pamiêci CG RAM

 MOV DPTR,#TAB_3
 call ciag_zn ;Wyslanie do LCD ciagu znakow z 
                    ;z tablicy 3 do CG RAM o adresie
                    ;podanym w DPTR koñcz¹cego sie 80h  

 mov LICZNIK, #2
 jmp INC_L

INC_L:
    MOV LCD_DATA,#01h ; czyszczenie ekranu
    ACALL LCD_ROZKAZ

    MOV LCD_DATA,#80h ; kursor na 1 linii
    ACALL LCD_ROZKAZ

    MOV DPTR,#INC_TXT ; mój tekst
    call ciag_zn

    MOV LCD_DATA,#0c0h ; kursor na 2 linii
    ACALL LCD_ROZKAZ
; =====================
    mov A, LICZNIK
    MOVC A, @A+DPTR
    MOV DPTR, #0
    movx @DPTR, A
    call ciag_zn
; ====================

    acall DLY

    inc LICZNIK ; LICZNIK++
    MOV A, LICZNIK
    CJNE A, #39h, INC_L ; do 9
    mov licznik, #0 ; jak 9 to LICZNIK=0
    jmp PTL ; i do pętli nieskończonej

DLY:
    MOV R6, #25h
    DL0:
        MOV R2, #049h
    DL1:
        MOV R3, #01Fh			
        DJNZ R3,$	
        DJNZ R2,DL1      
		DJNZ R6,DL0		
        RET	

PTL:
    JMP PTL

; -----------------------------------------------------------
; Initializacja LCD
; -----------------------------------------------------------
LCD_INIT:

 MOV LCD_PORT,#00h

 MOV LCD_DATA,#33h ;Pierwsze s³owo dodatkowe progr. LCD 
 ACALL LCD_ROZKAZ

 MOV LCD_DATA,#32h ;Drugie s³owo dodatkowe progr. LCD
 ACALL LCD_ROZKAZ
  
 MOV LCD_DATA,#28h ;Czterobitowy interfejs (F) 
                    ;Dwa wiersze, znak 5x7 punktów
; MOV LCD_DATA,#2Ch ;Cterobitowy interfejs (F) 
; ;Dwa wiersze, znak 5x10 punktów

 ACALL LCD_ROZKAZ       
   
 MOV LCD_DATA,#01h ;Czyszcz. ekranu, kursor na 0
 ACALL LCD_ROZKAZ ;(A)
  
 MOV LCD_DATA,#0Fh ;Wlaczenie ekranu i kursora  
 ACALL LCD_ROZKAZ ;mrugajacego (D)
  
 RET
; -----------------------------------------------------------
;Wyslanie pojedynczego rozkazu z LCD_DATA do wyswietlacza
; -----------------------------------------------------------
LCD_ROZKAZ: MOV LCD_PORT,#00h
  ACALL LCD_WRITE4
  ACALL LCD_WRITE4  
  ACALL DELAY

 ret

; -----------------------------------------------------------
; Wyswietlenie pojedynczego znaku z LCD_DATA na wyswietlacz
; -----------------------------------------------------------
LCD_DISPLAY_CHAR:

 SETB LCD_RS
 
 ACALL LCD_WRITE4
 ACALL LCD_WRITE4
 ACALL DELAY
 
 RET

delay:
 push LCD_PORT ; Odczyt BF

 clr lcd_rs
 setb lcd_d7
 setb lcd_rw
 setb lcd_e
 jb LCD_D7,$ ;Oczekiwanie na zgłoszenie gotowosci

 setb lcd_key


 pop LCD_PORT
 ret

LCD_WRITE4:
 
 PUSH ACC
 
 CLR LCD_E
 
 MOV A, LCD_DATA
 
 RLC A
 MOV LCD_D7, C ; D7
 RLC A
 MOV LCD_D6, C ; D6
 RLC A
 MOV LCD_D5, C ; D5
 RLC A
 MOV LCD_D4, C ; D4


 SETB LCD_E ; STROB
 CLR LCD_E
 
 MOV LCD_DATA, A   
 
 POP ACC

 RET
 
; -----------------------------------------------------------
; Wylanie ciagu znakow rozpoczynajacych sie 
; od adresu podanego w DPTR i zakonczonego 80h
; (jest to znak nie definiujacy znak wywietlany na
; wyswietlaczu oraz znak do CG RAM )
; -----------------------------------------------------------

ciag_zn: NOP

K_ZNAK: MOV A,#0
  MOVC A,@A+DPTR
  ADD A,#80H
  JZ K_STR


  ADD A,#80H
  INC DPTR
  MOV LCD_DATA,A
  CALL LCD_DISPLAY_CHAR
  JMP K_ZNAK
 
K_STR: RET

; -----------------------------------------------------------

T_0:
 DB '0'
 DB 80h

T_1:
 DB '1'
 DB 80h

T_2:
 DB '2'
 DB 80h

T_3:
 DB '3'
 DB 80h

T_4:
 DB '4'
 DB 80h

T_5:
 DB '5'
 DB 80h

T_6:
 DB '6'
 DB 80h

T_7:
 DB '7'
 DB 80h

T_8:
 DB '8'
 DB 80h

T_9:
 DB '9'
 DB 80h

T_X:
 db ']['
 db 80h

INC_TXT:
 DB 'Powiekszanie :'
 DB 80h

DEC_TXT:
 DB 'Pomniejszanie :'
 DB 80h

; zdefiniowane polskie znaki
TAB_3:
 DB 0,0,14,1,15,17,15,2 ;znak ą o kodzie 0
 DB 4,0,15,16,16,17,15,0 ;znak ć o kodzie 1
 DB 0,0,14,17,31,16,14,2 ;znak ę o kodzie 2
 DB 12,4,6,4,12,4,14,0 ;znak ł o kodzie 3
 DB 2,4,14,17,17,17,14,0 ;znak ó o kodzie 4
 DB 2,4,22,25,17,17,17,0 ;znak ń o kodzie 5
 DB 2,4,14,16,14,1,30,0 ;znak ź o kodzie 6
 DB 4,0,31,2,4,8,31,0 ;znak ż o kodzie 7
 
 DB 80h

 end

Wątpliwości pojawiają się w INC_L w zaznaczonym obszarze pomiędzy kreskami.

 

Pytanie 2, czy opóźnienie (DLY) też chyba źle napisałem, dokładnie chciałbym 1s abym widział, jak się licznik powiększa.

 

Za jakąkolwiek pomoc dziękuję z góry.


(Bartlomiej Gawlak) #2