Visa olika meddelanden på LCD mha switch

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
hatt
Inlägg: 39
Blev medlem: 6 mars 2004, 16:50:31

Visa olika meddelanden på LCD mha switch

Inlägg av hatt »

Sitter och försöker gör som rubriken lyder:

Kod: Markera allt

;**********************************************************************
;   Enkelt test av HD44780 LCD display.
;   Använder en standard 16x2 LCD.
;   För PIC16F886
;
;**********************************************************************
;                                                                     *
;    Filename:     HD44780_16F886.asm
;    Date:          20070702
;    File Version:  1.0
;
;    Author:        Jan-Erik Söderholm
;    Company:       Jan-Erik Söderholm Consulting AB
;
;**********************************************************************
;
;    Files required:  P16F886.INC
;                     16F690.LKR
;
;**********************************************************************
;
;   Notes:
;   Använder intosc på 4 Mhz.
;
;   E : RC0
;   RS: RC1
;   D4-D7 : RC4-RC7
;   R/W kopplad till GND (d.v.s ingen läsning av Busy-signalen).
;
;**********************************************************************
;
;
 list      p=16f690             ; list directive to define processor
 #include <p16F690.inc>
;__CONFIG ( _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT)
;
 __CONFIG _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
       ERRORLEVEL -224        ;  supress annoying message from tris
       ERRORLEVEL -302        ;  supress message from page change
;
     cblock     0x20
Delay1              ; Assign an address to label Delay1
Delay2
Display             ; define a variable to hold the diplay
Direction
LookingFor
     endc
;
    #define     LCD_E       PORTA, 1
    #define     LCD_RS      PORTA, 0
    #define     LCD_PORT    PORTC
;   
;
;**********************************************************************
RESET_VECTOR    CODE    0x000       ; processor reset vector
     goto    start               ; go to beginning of program
;
;
INT_VECTOR      CODE    0x004       ; interrupt vector location
        retfie                      ; Ingen interrupt kod...
;        
;
;**********************************************************************
; Macro för att skicka en text till LCD.
;
lcd_text    macro   text_label
        banksel eeadr               ; byt till rätt bank...
        movlw   high text_label     ; bit 8-15 av adressen till texten
        movwf   eeadrh
        movlw   low text_label      ; bit 0-7 av adressen till texten
        movwf   eeadr
;
; Nu är de två adressregistren laddade med rätt adress.
; Anropa subrutinen för att hämta texten och skriva ut den.
;
        call    lcd_send_text
        banksel porta               ; Lämna rutinen i bank 0.
;
        endm
;
;**********************************************************************
; Huvudkoden.
; Här hamnar vi vid reset eller power-on (från RESET_VECTOR)
;
;
MAIN    CODE
start
;
; Först normal uppstart ej specifik för LCD
;
        banksel ansel               ; Stäng av alla analoga funktioner
        clrf    ansel
        clrf    anselh
        banksel trisa               ; Alla pinnar utgångar...
        clrf    trisa
        clrf    trisb
        clrf    trisc
        movlw   b'00000000'
        MOVWF TRISA
;        
        banksel intcon
        clrf    intcon
        banksel porta               ; se till att vi är på bank 0.
        clrf    porta
        clrf    portb
        clrf    portc
        clrf      Direction
        clrf      LookingFor
;
; Så då var grundinställningen av processorn klar.
; Nu går vi vidare med LCD hanteringen...
;

       call        lcd_init_hd44780    ; Ställ in LCD'n.
;
; Skriv ut ett par texter på LCD'n...
;
;
;
MainLoop:
     btfsc     LookingFor,0
     goto      LookingFor1
LookingFor0:
     btfsc     PORTA,3        ; is the switch pressed (0)
     goto      Rotate
     bsf       LookingFor,0   ; yes  Next we'll be looking for a 1
     movlw     0xFF           ; load the W register incase we need it
     xorwf     Direction,f    ; yes, flip the direction bit
     movlw   b'00000010'     ; Display/curs home
     call    lcd_send_cmd
     movlw   b'00000001'     ; Display clear
     call    lcd_send_cmd
     goto      Rotate
LookingFor1:
     btfsc     PORTA,3        ; is the switch pressed (0)
     bcf       LookingFor,0    
Rotate:
     bcf       STATUS,C       ; ensure the carry bit is clear
     btfss     Direction,0
     goto      RotateLeft
RotateRight:
      lcd_text lcd_text1
      lcd_text lcd_text2
     goto      MainLoop
RotateLeft:
     lcd_text lcd_text3
     lcd_text lcd_text4
     goto MainLoop

return
;
loop    goto loop                       ; Gör ingenting....
;
;**********************************************************************
; Subs för HD44780
;
; Nägra temp variabler som används av LCD rutinerna.
; Lägger dom i "shared memory" så slipper vi banksel...
;
LCD_VARS        UDATA_SHR
LCD_TMP1        RES 1
LCD_TMP2        RES 1
;
; Slut på variabler, här kommer koden...
;
LCD_CODE        CODE
;
lcd_init_hd44780
;
        call    delay_1s        ; Ge LCD'n tid att starta...
        bcf     LCD_E           ; Se till att E och RS är
        bcf     LCD_RS          ; nollade...
;
; Skicka initkoder enligt manual för HD44780.
; För detaljer, se manual för HD44780 eller datablad för en LCD.
;
        movlw   h'30'
        call    lcd_send_4_bit
        call    delay_5ms
        movlw   h'30'
        call    lcd_send_4_bit
        call    delay_5ms
        movlw   h'30'
        call    >till LCD som "data".
;
        banksel lcd_port
        bsf     LCD_RS          ; RS = "1" för data
        call    lcd_send_byte   ; Skicka
        call    delay_100us     ; Ge LCD'n tid att bearbeta datat.
        return
;
lcd_send_byte
; Data i W överförs till LCD som två 4-bitars bitar.
;
        movwf   lcd_tmp2        ; Spara W tillfälligt
        movlw   B'11110000'     ; Mask för bit 4-7
        andwf   lcd_tmp2, w     ; Nolla bit 0-3
        call    lcd_send_4_bit  ; Skicka bit 4-7
        swapf   lcd_tmp2, f     ; Byt plats på 0-3 <-> 4-7
        movlw   B'11110000'     ; Mask för bit 4-7 (nu 0-3 !!)
        andwf   lcd_tmp2, w     ; Nolla bit 0-3 (nu 4-7 !!)
        call    lcd_send_4_bit  ; Skicka bit 4-7 (nu 0-3 !!)
        return
;
lcd_send_text
; Sänd en fast text till LCD.
; När rutinen anropas ska EEADR och EEADRH vara initierade
; med adressen i flash till text-bufferten. T.ex genom det
; lcd_text macro som finns i detta program.
; Beräkningen av rad/kol -> LCD-pos är just nu anpassad
; till 16x2 LCD'er. Får justeras för att passa andra...
;
; Läs första positionen i texten ("LCD-rad")
;
        call read_flash
        movwf   lcd_tmp1        ; Lagra (radnummer på LCD)
;
; Hämta nästa pos i textraden (pos på LCD raden...)
;
        call    inc_eeadr
        call    read_flash
        movwf   lcd_tmp2        ; Lagra (position på raden på LCD)
;
; Justering av rad/pos väden
;
        decf    lcd_tmp1, f     ; Rad 1-2 => 0-1
        bcf     status, c
        rrf     lcd_tmp1, f
        rrf     lcd_tmp1, f
        rrf     lcd_tmp1, f     ; Nu är lcd_tmp1 h'00' eller h'40'...
        decf    lcd_tmp2, f     ; Pos 1-40 => 0-39
;
; Nu är rad och pos färdiga att addera ihop och skicka till LCD'n...
;
        movlw   h'80'           ; Bas-kommandot för LCD-position.
        addwf   lcd_tmp1, w     ; Lägg till rad (h'00' eller h'40')
        addwf   lcd_tmp2, w     ; Lägg till pos.
        call    lcd_send_cmd    ; Skicka kommandot (i W-reg)
;
; Nu läser vi resten av texten fram till h'00' poch skickar
; till LCD'n.
;
send_text_loop
;
; Läs nästa position ("LCD-text") och skicka.
; Avsluta om datat/tecknet = h'00'
;
        call    inc_eeadr
        call    read_flash
        btfsc   status, z       ; Var det h'00' (slut på text) ?
        goto    send_text_end   ; Ja, avsluta.
                                ; Nej, fortsätt...      
        call    lcd_send_data   ; Skicka tecken med data i W-reg.
        goto    send_text_loop  ; Om igen...
;
send_text_end
; Slut på text...
;
        return
;
read_flash
;
; Läs en byte från flash
; EEADR och EEADRH ska redan vara initierade.
;
        banksel eecon1
        bsf     eecon1, eepgd   ; Läs från flash...
        bsf     eecon1, rd      ; Sätt läs-flaggan...
        nop                     ; Vänta på att läsning
        nop                     ; ska gå klart... 
        banksel eedat
        movf    eedat, w        ; Nu har vi värdet i W-reg.
        return
;
; Räkna fram eeadr/eeadrh till nästa position
;
inc_eeadr
        banksel eeadr
        incf    eeadrh, f       ; öka först eeadrh
        incfsz  eeadr, f        ; öka eeadr, = 0 ?
        decf    eeadrh, f       ; eeadr <> 0, återställ eeadrh...
        return
;
;        
;**********************************************************************
; Diverse delay rutiner.
; Alla delay rutiner generade med kodgeneratorn här :
; http://www.piclist.com/techref/piclist/codegen/delay.htm
; OBS generatade för 4 Mhz processorhastighet. 
;
DLY_VAR      UDATA_SHR
d1           RES 1
d2           RES 1
d3           RES 1
;
;
DLY_CODE        CODE
;
delay_1s
 movlw 0x08
 movwf d1
 movlw 0x2F
 movwf d2
 movlw 0x03
 movwf d3
Delay_1s_0
 decfsz d1, f
 goto $+2
 decfsz d2, f
 goto $+2
 decfsz d3, f
 goto Delay_1s_0
 goto $+1
 nop
    return
;
delay_5ms
        movlw 0xE7
     movwf d1
     movlw 0x04
     movwf d2
Delay_5ms_0
     decfsz d1, f
     goto $+2
     decfsz d2, f
     goto Delay_5ms_0
     goto $+1
        return
;
delay_100us
     movlw 0x21
     movwf d1
Delay_100us_0
     decfsz d1, f
     goto Delay_100us_0
        return
; 
;**********************************************************************
LCD_texts   CODE
; Fasta texter för LCDn.
; Två första värderna i varje text är rad (1,2,3 eller 4)
; och position (1-40). Resten är text fram till h'00'.
;

lcd_text3   data    d'1', d'1', 'I', 'N', 'N', 'E', ':','2','2', 0xDF,'C', h'00'
lcd_text4   data    d'2', d'1', 'U', 'T', 'E', ':', '2','1',0xDF,'C', h'00'
lcd_text1   data    d'1', d'1', 'V','V', ':', '6','0',0xDF,'C', h'00'
lcd_text2   data    d'2', d'1', 'V','B', ':', '2','8',0xDF,'C', h'00'
;
;**********************************************************************
    end
Vilka bättre (rätta) sätt finns?
Hjälp tack
Användarvisningsbild
E85
Inlägg: 1274
Blev medlem: 29 maj 2007, 16:24:19
Ort: Övik

Re: Visa olika meddelanden på LCD mha switch

Inlägg av E85 »

Vad är problemet? Det är ganska mycket kod att gå igenom.
hatt
Inlägg: 39
Blev medlem: 6 mars 2004, 16:50:31

Re: Visa olika meddelanden på LCD mha switch

Inlägg av hatt »

Kod: Markera allt

MainLoop:
     btfsc     LookingFor,0
     goto      LookingFor1
LookingFor0:
     btfsc     PORTA,3        ; is the switch pressed (0)
     goto      Rotate
     bsf       LookingFor,0   ; yes  Next we'll be looking for a 1
     movlw     0xFF           ; load the W register incase we need it
     xorwf     Direction,f    ; yes, flip the direction bit
     movlw   b'00000010'     ; Display/curs home
     call    lcd_send_cmd
     movlw   b'00000001'     ; Display clear
     call    lcd_send_cmd
     goto      Rotate
LookingFor1:
     btfsc     PORTA,3        ; is the switch pressed (0)
     bcf       LookingFor,0    
Rotate:
     bcf       STATUS,C       ; ensure the carry bit is clear
     btfss     Direction,0
     goto      RotateLeft
RotateRight:
      lcd_text lcd_text1
      lcd_text lcd_text2
     goto      MainLoop
RotateLeft:
     lcd_text lcd_text3
     lcd_text lcd_text4
     goto MainLoop

return
Denna kod fungerar, men lcd:n skrivs om för varje loop. Jag vill alltså byta mellan två texter när jag trycker på knapppen.
danielr112
Inlägg: 8092
Blev medlem: 18 januari 2009, 00:48:24
Ort: Alvesta, Småland

Re: Visa olika meddelanden på LCD mha switch

Inlägg av danielr112 »

:loop
if switch != oldstate then
write lcd (msg)
else
goto loop
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Visa olika meddelanden på LCD mha switch

Inlägg av sodjan »

Ser allt OK ut i MAP filen ? Inga krockar mellan UDATA variablerna och dina CBLOCK's ?

(Naturligstvis helt fel att definiera symboler med CBLOCK som sedan *används* som
adresser eftersom koden redan är relocatable och använder UDATA (UDATA_SHR) för minnesallokeringar.
Beroende på hur du har gjort så kan du få överlappande variabler, alltså två variabler som
använder samma adress...)

Om dina CBLOCK's ligger i "unbanked memory" har du med BANKSEL där det behövs ?
*Jag* har inte och tänker inte kolla...

Går koden att köra i MPLAB/SIM ? Och allt ser OK ut där ?
Det är ju bättre att SIM kollar det än att andra ska kolla koden. :-)

Sen så är ju även ditt förstainlägg väldigt slarvigt och snabbt ihopkastat. Bättre kan du säkert.
Vad är problemet ? Vad är det som inte fungerar ? *Är* det något som inte fungerar ?
Om du har använt en redan fungerande mall, vad är i så fall ändrat ?
Eller är det kanske så att det faktiskt fungerar, men du vill bara ha kommentarer kring koden ?
Säg det lite tydligare i så fall.
(Jag ser att du har lagt till lite senare, men detta var riktat mot just första-inlägget...)

Om det nu är så att det faktiskt fungerar, så är det största (potentiella) problemet just CBLOCK.
Det kanske fungerar just nu men det är i alla fall helt fel.
hatt
Inlägg: 39
Blev medlem: 6 mars 2004, 16:50:31

Re: Visa olika meddelanden på LCD mha switch

Inlägg av hatt »

Koden fungerar, men skärmen "blinkar" eftersom texten på skärmen skrivs om vid varje loop. Jag vill alltså att texten bara ska uppdateras/skrivas om då den ändras, dvs jag trycker på knappen.
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Visa olika meddelanden på LCD mha switch

Inlägg av bos »

> Jag vill alltså att texten bara ska uppdateras/skrivas om då den ändras, dvs jag trycker på knappen.

danielr112 visade lösningen, men den struntade du tydligen i.
hatt
Inlägg: 39
Blev medlem: 6 mars 2004, 16:50:31

Re: Visa olika meddelanden på LCD mha switch

Inlägg av hatt »

Då jag har otur då jag tänker :vissla: , postar jag följande kod:
Har jag fattat principen rätt?
Hur jag sedan gör detta i asm får bli nästa utmaning.

Kod: Markera allt

Main:
state = 0
goto Text1

loop:
if switch = pressed
goto changeState
else goto loop

changeState:
if state = 0
newstate = 1
else
newstate = 0
goto changeText

changeText:
if newstate = 0
goto Text1
else
goto Text2

Text1:
writelcd(text1)
goto loop

Text2
writelcd(text2)
goto loop
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Visa olika meddelanden på LCD mha switch

Inlägg av bos »

Principen ser rätt ut, även om den är rätt krångligt.
hatt
Inlägg: 39
Blev medlem: 6 mars 2004, 16:50:31

Re: Visa olika meddelanden på LCD mha switch

Inlägg av hatt »

Har bara kommit så långt att texten ändras när jag håller in knappen och återgår till första texten när jag släpper.
Jag antar att man sätter nån form av flagga på vilken text som är aktiv och att flaggan ändras när jag trycker in knappen. Kan man be om lite kod som hjälp. Principen fattar jag, men hur gör jag detta konkret?

Kod: Markera allt

MainLoop:
  goto Text1

loop:
  btfss	PORTA,3
  goto text1
  goto text2

Text1:
  lcd_text lcd_text1
  lcd_text lcd_text2
  goto loop

Text2:
  lcd_text lcd_text3
  lcd_text lcd_text4
  goto loop
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Visa olika meddelanden på LCD mha switch

Inlägg av sodjan »

> Jag antar att man sätter nån form av flagga på vilken text som är aktiv
> och att flaggan ändras när jag trycker in knappen.

Ja, korrekt.

> Principen fattar jag, men hur gör jag detta konkret?

- Allokera ett register/variablel som du använder för flaggan.
- Bestäm en bit i registret för just denna flagga (t.ex med #define)
- Sätt/nolla flaggan på lämpliga ställen med BSF/BCF.
- Lägg till kod för att kolla flaggan där det beövs (BTFSC/BTFSS).
bos
Inlägg: 2311
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Visa olika meddelanden på LCD mha switch

Inlägg av bos »

Nåt sånt här kanske (otestat):

Kod: Markera allt

which_text res 1




  clrf  which_text
loop:
  btfsc   PORTA, 3
   goto loop1
  goto loop
loop1:
  btfss   PORTA, 3
   goto change_text
  goto loop1

change_text:
  clrw
  xorwf  which_text
  btfsc  STATUS, Z
   goto Text1
  goto Text2

Text1:
  clrf  which_text
  lcd_text lcd_text1
  lcd_text lcd_text2
  goto loop

Text2:
  movwf   1
  movfw   which_text
  lcd_text lcd_text3
  lcd_text lcd_text4
  goto loop
Skriv svar