Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ST7066U 20x4 LCD problems(Solved)

Status
Not open for further replies.
That is strange but all's well that ends well.

Here's the code with the limits in,
Code:
ISR            MOVWF   W_TEMP            ; SAVE OFF CURRENT W REGISTER CONTENTS
                MOVF    STATUS,W          ; MOVE STATUS REGISTER INTO W REGISTER
                MOVWF   STATUS_TEMP       ; SAVE OFF CONTENTS OF STATUS REGISTER
                BCF            STATUS,RP0
                BCF             PIR1,TMR2IF
                RLF     previous,F
                RLF     previous,W
                ANDLW   0X0C                    ;KEEP ONLY BITS 2 & 3
                BTFSS   PORTA,0                ;MOVE ENCODER BITS
                IORLW   1                            ;TO BITS 0 & 1
                BTFSS   PORTA,1
                IORLW   2
                MOVWF   previous                ;KEEP FOR NEXT TIME
                CALL    ENC_TABLE
                ADDWF        clicks,F
                MOVLW        4
                XORWF        clicks,W
                BTFSS        STATUS,Z
                GOTO        CHECK_DOWN
                CLRF        clicks                    ;added this line
                MOVLW        high 10800            ;test if frequency has reached 108MHz
                XORWF        freqHigh,W
                BTFSS        STATUS,Z
                GOTO        DOINC                        ;high bytes don't match so do increment
                MOVLW        low 10800
                XORWF        freqLow,W
                BTFSC        STATUS,Z                ;low bytes don't match so do increment
                GOTO        EXIT                        ;if it has, exit
DOINC        INCF    freqHigh,F            ;if not then increment it
                INCFSZ  freqLow,F
                DECF    freqHigh,F
                GOTO        EXIT
CHECK_DOWN
                MOVLW        0XFC            ;-4
                XORWF        clicks,W
                BTFSS        STATUS,Z
                GOTO        EXIT
                CLRF        clicks                    ;added this line
                MOVLW        high 8700
                XORWF        freqHigh,W
                BTFSS        STATUS,Z
                GOTO        DODEC
                MOVLW        low 8700
                XORWF        freqLow,W
                BTFSC        STATUS,Z
                GOTO        EXIT
DODEC        MOVF    freqLow,F
                SKPNZ
                DECF    freqHigh,F
                DECF    freqLow,F
          ;;      GOTO        EXIT     ;;not needed
;         RESTORE CONTEXT BEFORE RETURNING FROM INTERRUPT
EXIT        MOVF    STATUS_TEMP,W     ; RETRIEVE COPY OF STATUS REGISTER
                MOVWF   STATUS            ; RESTORE PRE-ISR STATUS REGISTER CONTENTS
                SWAPF   W_TEMP,F
                SWAPF   W_TEMP,W          ; RESTORE PRE-ISR W REGISTER CONTENTS
                RETFIE                    ; RETURN FROM INTERRUPT

Mike.
 
Mike - thankyou very much, that part is now all working, I owe you you a glass or two of your favourite tipple if you are ever in the area.

Now to plug on with the LCD problem and try and work out what is happening - one thing I have noticed - I have the cursor turned on and on the 16x2, you can't see it as it refreshes the frequency but on the 20x4, it is much slower and easily visible as it retraces all the numbers.

Going to put this down for now and have a rest - again, thankyou very much.
 
Maybe the 4x20 is slower and needs the busy check back in. I noticed a bug in your busy test code, you test the port after switching off the enable pin. You need to test the busy flag while the enable line is still high.
I.E.
Code:
busy_check
    banksel  TRISB               ; Switch to bank for Tris operation
    movlw    b'00001111'         ; Set ALL 4 to input, others outputs
    movwf    TRISB
    banksel  PORTB
    bcf      PORTB,LCD_rs        ; Set up LCD for Read Busy Flag (RS = 0)
    bsf      PORTB,LCD_rw        ; Set up LCD for Read (RW = 1)
    bsf      PORTB,LCD_e         ; Set E high
LCD_is_busy
    btfsc   PORTB,LCD_busy       ; Is Busy Flag (RB3) clear?
    goto    LCD_is_busy
    bcf     PORTB,LCD_e          ; Set E low
    banksel TRISB                ; Switch to bank 1 for Tristate operation
    clrf    TRISB                ; All pins (RB7..RB0) are back to outputs
    banksel PORTB                ; Switch to bank 0
    RETURN
Note, the 4 lower bits of portb all have to be input. Although you're only interested in B3 the other LCD pins will also be outputs (when you read) and will cause a conflict.

Mike.
BTW, did you know the banksel macro sets both bank bits RP0 and RP1. It doesn't matter here but if you run out of code space, it's good to know.
 
Last edited:
That's one of the other things that wasn't working with the 20x4 and why it was commented out (but of course it works fine with the 16x2 LCD).

I'll dig in to that tomorrow if I don't get called out.
 
A lot of the new displays that are HD44780 compatible are much faster and are never busy so checking the busy flag is irrelevant but you never know which you have. I'd guess your 16x2 is a newer faster version and your 20x4 is like the original.

Mike.
 
Actually, the 16x2 is in excess of 10 years old, I bought them as surplus stock not long before I closed the shop.

The 20x4 is another story, I believe bought off Ebay about 8 months ago and sent out to my by my friend in Greece, so it could be anything - just looked at the back - manufactured mid 2017.

Re your previous about the busy routine and PORTB, some of it has to be outputs during the busy read as it carries the R/W, R/S & E lines as well as the data lines.
 
1. Occasionally when first powering up it will add or subtract a step without touching the encoder.
1, You have to read dummy first as the code will go from 00 to whatever..
2. No!1 Its a state machine, the bounce will take care of itself.. If pin a bounces the count wil go up down fast and remain good... A state machine need to see "states" to count... I use a small lookup for that very reason, but Dan's code will work without debounce as well..
 
Thanks Ian.

Mike, I knew I had seen the Timer2 start info somewhere - the Mid Range Manual viz:

Example 13-1: Timer2 Initialization
Code:
CLRF T2CON  ; Stop Timer2, Prescaler = 1:1,
; Postscaler = 1:1
CLRF TMR2     ; Clear Timer2 register
CLRF INTCON ; Disable interrupts
BSF STATUS, RP0 ; Bank1
CLRF PIE1 ; Disable peripheral interrupts
BCF STATUS, RP0 ; Bank0
CLRF PIR1 ; Clear peripheral interrupts Flags
MOVLW 0x72 ; Postscaler = 1:15, Prescaler = 1:16
MOVWF T2CON ; Timer2 is off
BSF T2CON, TMR2ON ; Timer2 starts to increment <------------------------
 
Re your previous about the busy routine and PORTB, some of it has to be outputs during the busy read as it carries the R/W, R/S & E lines as well as the data lines.
Yes, the higher nibble has to be output but the bottom 4 bits must be input or they will fight with the LCD pins as both will be output.

I checked my busy routine in some recent code and as it's in 4 bit mode I read two nibbles from the LCD, the second being a dummy read. This may not be necessary but it may be one of those things that varies between LCDs.
Something like this might work,
Code:
busy_check
    banksel  TRISB               ;Switch to bank for Tris operation
    movlw    b'00001111'         ;Set ALL 4 to input, others outputs
    movwf    TRISB
    banksel  PORTB
    bcf      PORTB,LCD_rs        ;Set up LCD for Read Busy Flag (RS = 0)
    bsf      PORTB,LCD_rw        ;Set up LCD for Read (RW = 1)
LCD_is_busy
    bsf      PORTB,LCD_e         ;Set E high
    NOP
    movfw    PORTB               ;move busy flag into W
    bcf      PORTB,LCD_e         ;Set E low
    NOP
    bsf      PORTB,LCD_e         ;perform dummy read
    NOP
    bcf      PORTB,LCD_e         ;Set E low        
    andlw    1<<LCD_busy
    BTFSS    STATUS,Z
    GOTO     LCD_is_busy
    banksel  TRISB                ;Switch to bank 1 for Tristate operation
    clrf     TRISB                ;All pins (RB7..RB0) are back to outputs
    banksel  PORTB                ;Switch to bank 0
    RETURN


Mike.
 
augustinetez,

To keep this as simple as possible I have created an application that "should" run unchanged in your hardware.

This application will:
  • Initialize a 20x4 LCD character module.
  • Debounce quadrature encoder inputs.
  • Decode the quadrature encoder position changes to CW and CCW steps.
  • Show the change of encoder position as a character on line four position 20 of the LCD character module.

Let us know if this code builds and runs on your hardware:
Code:
;
; https://www.electro-tech-online.com/threads/st7066u-20x4-lcd-problems.160879/
;
    list        n=0,c=255
    radix       dec
    errorlevel  -302        ; Suppress the not in bank 0 warning message
    processor   16F628A
; 
; File:   main.c
; Author: dan1138
; Target: PIC16F628A
; 
; Created on March 2, 2021, 9:38 AM
; Description:
;
;   This is an example of one way to implement the 4-bit parallel
;   mode interface for a Hitachi HD44780 LCD module controller.
; 
;                                  PIC16F628A
;                           +----------:_:----------+
;                      <> 1 : RA2               RA1 : 18 <> ENCODER A
;                      <> 2 : RA3               RA0 : 17 <> ENCODER B
;                      <> 3 : RA4          OSC1/RA7 : 16 <> 
;                  VPP -> 4 : RA5/VPP      OSC2/RA6 : 15 <> 
;                  GND -> 5 : VSS               VDD : 14 <- 5v0
;  LCD_D4              <> 6 : RB0/INT       PGD/RB7 : 13 <> PGD/DLEN(SAA1057)
;  LCD_D5              <> 7 : RB1/RX/DT     PGC/RB6 : 12 <> PGC/LCD_RS
;  LCD_D6/CLK(SAA1057) <> 8 : RB2/RX/CK         RB5 : 11 <>     LCD_RW
;  LCD_D7/DAT(SAA1057) <> 9 : RB3/CCP       PGM/RB4 : 10 <>     LCD_E
;                           +-----------------------:
;                                    DIP-18
;
; LCD display module is SC2004CULB-SO-GB-K
;
; SUNLIKE DISPLAY Model No: SC2004C 
; https://electronlab.com.ua/files/_prod/Sunl_337/SC2004CULB-XH-GS.pdf 
;
; Samsung KS0066 LCD controller
; https://www.lcd-module.de/eng/pdf/zubehoer/ks0066.pdf
;
; pin  1 - VSS Ground
; pin  2 - VDD +5
; pin  3 - Vo  Contrast
; pin  4 - RS  Register select
; pin  5 - RW  Read/Write select
; pin  6 - E   Enable active high strobe
; pin  7 - DB0 Data bit 0
; pin  8 - DB0 Data bit 1
; pin  9 - DB0 Data bit 2
; pin 10 - DB0 Data bit 3
; pin 11 - DB0 Data bit 4
; pin 12 - DB0 Data bit 5
; pin 13 - DB0 Data bit 6
; pin 14 - DB0 Data bit 7
;
; Definitions of target specific Special Function Registers
;
    include     <P16F628A.INC>
;
; Target specific configuration words
;
    __config    _CP_OFF&_LVP_OFF&_BODEN_OFF&_MCLRE_ON&_PWRTE_ON&_WDT_OFF& _INTOSC_OSC_NOCLKOUT
;
; Define macros to help with
; bank selection
;
#define BANK0  (h'000')
#define BANK1  (h'080')
#define BANK2  (h'100')
#define BANK3  (h'180')
;
; Macro to message from ROM to LCD display
;
Show_LCD_Message MACRO LCD_message
    movlw   LOW(LCD_message)
    movwf   pszLCD_RomStr
    movlw   HIGH(LCD_message)
    movwf   pszLCD_RomStr+1
    call    LCD_putrs
    ENDM
;
; Constants used in application
;
; The StartFreq constant has units of MHz times 100
;
#define StartFreq (8700)
;
; Start address of each line on LCD module
;
#define LINE_ONE    0x00
#define LINE_TWO    0x40
#define LINE_THREE  0x14
#define LINE_FOUR   0x54
;
; Data used for ISR and LCD
;
  cblock 0x70       ; memory present in all banks
    WREG_save     : 1
    STATUS_save   : 1
    PCLATH_save   : 1
    LCD_Temp      : 1
    pszLCD_RomStr : 2
    Sample_AB     : 1
    Valid_AB      : 1
  endc
  
  cblock 0x60       ; memory present in bank 0
    EncoderCount  : 1
    Last_AC       : 1
  endc
;
; Reset vector
;
    org     0x000                     ; processor reset vector
    nop                               ; ICD2 needs this
    goto    Start                     ; go to beginning of program
;
; Interrupt vector
;
    org     0x004
    movwf   WREG_save               ; Save register that
    movf    STATUS,W                ; must be restored to
    movwf   STATUS_save             ; preserve the context
    clrf    STATUS                  ; Use BANK 0 as default
;
; This is the area where your interrupt service routines go
;
;        KEEP THEIR EXECUTION TIME AS SHORT AS POSSIBLE.
; DO NOT DO WORK THAT SHOULD BE DONE IN THE APPLICATION LOOP!
;
    btfss   INTCON,TMR0IE
    goto    TMR0_Exit
    btfss   INTCON,TMR0IF
    goto    TMR0_Exit
    bcf     INTCON,TMR0IF
;
; Debounce quadrature encoder inputs
;
    banksel PORTA
    movf    PORTA,W     ; Sample quadrature encoder inputs
    xorwf   Sample_AB,W
    andlw   3
    xorwf   Sample_AB,F ; Update sample, W = change of AB inputs
    iorlw   0
    movlw   3
    btfss   STATUS,Z    ; Skip if inputs did not change since last sample
    andwf   Sample_AB,F ; reset debounce count
    movlw   0x10
    btfss   Sample_AB,6 ; skip when debounce done
    addwf   Sample_AB,F ; increment debounce count
    movf    Sample_AB,W
    andlw   3
    btfsc   Sample_AB,6 ; skip when debounce not done
    movwf   Valid_AB    ; update debounced quadrature encoder inputs
TMR0_Exit:

    movf    STATUS_save,W
    movwf   STATUS
    swapf   WREG_save,F
    swapf   WREG_save,W
    retfie
;
; Application start
;
Start:
    clrf    INTCON      ; Disable all interrupt sources
    banksel PIE1
    clrf    PIE1
    banksel CMCON       ; Make all GPIO use digital I/O
    movlw   0x07
    movwf   CMCON
;
; Setup TIMER0 to assert an interrupt every 1.024 milliseconds
;
    banksel OPTION_REG
    movlw   0xC1        ; TIMER0 clock = FOSC/4, prescale = 1:4
    movwf   OPTION_REG
    banksel TMR0
    clrf    TMR0
    bcf     INTCON,TMR0IF
    bsf     INTCON,TMR0IE
    bsf     INTCON,GIE
;
; Initialize the LCD module
;
    call    LCD_Init    ; Initialize LCD module
;
; Show the initial LCD screen
;
    movlw   LINE_ONE
    call    LCD_SetPosition
    Show_LCD_Message LCD_message1
    
    movlw   LINE_TWO
    call    LCD_SetPosition
    Show_LCD_Message LCD_message2
    
    movlw   LINE_THREE
    call    LCD_SetPosition
    Show_LCD_Message LCD_message3
    
    movlw   LINE_FOUR
    call    LCD_SetPosition
    Show_LCD_Message LCD_message4
;
; Application loop
;
    call    QuadCheck       ; Initialize quadrature decoder
    banksel EncoderCount
    clrf    EncoderCount
AppLoop:
    call    QuadCheck
    banksel EncoderCount
    addwf   EncoderCount,F
    iorlw   0
    skpnz
    goto    AppLoop
    movlw   LINE_FOUR+19
    call    LCD_SetPosition
    movlw   0x3F
    andwf   EncoderCount,W
    addlw   '@'
    call    LCD_WriteData
    goto    AppLoop
;
; The current sample is AC.
; The previous sample is ac.
;
; Clockwise direction:
; c = a XOR b
; ab  ac  AC  AC-ac
; 00  00  01   01
; 01  01  10   01
; 11  10  11   01
; 10  11  00   01
;
; Counter Clockwise direction:
; c = a XOR b
; ab  ac  AC  AC-ac
; 00  00  11   11
; 10  11  10   11
; 11  10  01   11
; 01  01  00   11
;
;
; RA1 = A , RA0 = B
;
QuadCheck:
    banksel Last_AC
    movf    Valid_AB,W  ; Get debounced quadrature encoder inputs
    btfsc   Valid_AB,1  ; check of A input is one
    xorlw   1           ; Make C = A xor B, Convert 2-bit Gray code to binary
    andlw   3           ; mask for bits AC
    xorwf   Last_AC,W   ; Use three XORs to swap the
    xorwf   Last_AC,F   ; current sample with
    xorwf   Last_AC,W   ; the last sample.
    subwf   Last_AC,W   ; Calculate the difference (Current-Last)
    andlw   3           ; W = 01 for CW step, W = 11 for CCW step
    xorlw   1           ; Test for Clockwise step
    btfsc   STATUS,Z    ; skip if not CW step
    retlw   +1
    xorlw   2           ; Test for Counter Clockwise step
    btfsc   STATUS,Z    ; skip if not CCW step
    retlw   -1
    retlw   0
;
; LCD functions
;
#define LCD_PORT PORTB
#define LCD_DATA_BITS (0x0F)
#define LCD_RS PORTB,RB6
#define LCD_RW PORTB,RB5
#define LCD_E  PORTB,RB4
;
;*****************************************************************
; Subroutine Name: LCD_Init
; Function: Initialize the LCD interface.
;
; Inputs:  none
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_Init:
    call    Delay_4us       ; Used to test the timing 
    call    Delay_40us      ; of the delay functions
    call    Delay_5ms       ; with the simulator.
    call    LCD_POR_Delay
    banksel BANK1
    movlw   ~LCD_DATA_BITS  ; Make GPIO bits for
    andwf   LCD_PORT,F      ; LCD interface output bits
    bcf     LCD_E
    bcf     LCD_RW
    bcf     LCD_RS
    banksel BANK0
    andwf   LCD_PORT,F
    bcf     LCD_E
    bcf     LCD_RW
    bcf     LCD_RS
;
; Force LCD module to 4-bit parallel mode
;
    movlw   0x33
    andlw   LCD_DATA_BITS
    movwf   LCD_PORT
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    call    Delay_5ms
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    call    Delay_5ms
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    call    Delay_5ms
    movlw   0x22
    andlw   LCD_DATA_BITS
    movwf   LCD_PORT
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    call    Delay_5ms
;
; Configure 20x4 LCD character module
;
    movlw   (0x28)          ; 4-bit parallel, 5x7, multiline mode
    call    LCD_WriteCommand

    movlw   (0x08)          ; Display off, cursor off, blink off
    call    LCD_WriteCommand

    movlw   (0x01)          ; Clear display
    call    LCD_WriteCommand

    movlw   (0x0C)          ; Display on, cursor off, blink off
    call    LCD_WriteCommand

    movlw   (0x13)          ; Cursor shifts to the left
    call    LCD_WriteCommand

    return
;
;*****************************************************************
; Subroutine Name: Delay_4us, Delay_20us, Delay_40us
; Function: provides a delay for 4, 20 or 40 microseconds
;           Code relies on a 4MHz system oscillator
;
; Inputs:  none
;
; Outputs: none
;
;*****************************************************************

Delay_40us:
    call    Delay_20us              ; Wait at least 40 microseconds
Delay_20us:                         ; for command to complete.
    call    Delay_4us
    call    Delay_4us
    call    Delay_4us
    call    Delay_4us
    goto    Delay_4us
;
;*****************************************************************
; Subroutine Name: Delay_5ms
; Function: Provides a delay for at least 5 milliseconds
;           Code relies on a 4MHz system oscillator
;
; Inputs:  none
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
Delay_5ms:
    call    Dly0
    call    Dly0
Dly0:
    movlw   208     ; Magic number to get 5 milliseconds of delay
Dly1:
    call    Delay_4us
    addlw   -1
    bnz     Dly1
Delay_4us:
    return
;
;*****************************************************************
; Subroutine Name: LCD_POR_Delay
; Function: provides a delay for at least 15 milliseconds
;
; Inputs:  none
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_POR_Delay:
    call    Delay_5ms
    call    Delay_5ms
    goto    Delay_5ms
;
;*****************************************************************
; Subroutine Name: LCD_WriteCommand
; Function: Set LCD_RS to command mode
;           Write command byte to PORTB
;           Pulse the LCD_E high for 4 microseconds
;           Wait for 5 milliseconds
;
; Inputs:  WREG     Command to be sent to LCD module
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_WriteCommand:
    banksel LCD_PORT
    bcf     LCD_RW          ; Assert LCD_RW low
    bcf     LCD_RS          ; Assert LCD_RS low
    call    LCD_Write1
    goto    Delay_5ms
;
;*****************************************************************
; Subroutine Name: LCD_WriteData
; Function: Set LCD_RS to data mode
;           Write command byte to PORTB
;           Pulse the LCD_E high for 4 microseconds
;           Wait for 40 microseconds
;
; Inputs:  WREG     Data to be sent to LCD module
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_WriteData:
    banksel LCD_PORT
    bcf     LCD_RW          ; Assert LCD_RW low
    bsf     LCD_RS          ; Assert LCD_RS high
LCD_Write1:
    movwf   LCD_Temp
 if (LCD_DATA_BITS & 0x0F)
    swapf   LCD_Temp,F
    movf    LCD_Temp,W
 endif
    xorwf   LCD_PORT,W
    andlw   LCD_DATA_BITS
    xorwf   LCD_PORT,F      ; Write high nibble
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    call    Delay_4us
    swapf   LCD_Temp,W
    xorwf   LCD_PORT,W
    andlw   LCD_DATA_BITS
    xorwf   LCD_PORT,F      ; Write low nibble
    bsf     LCD_E           ; Assert LCD_E high
    call    Delay_4us
    bcf     LCD_E           ; Assert LCD_E low
    goto    Delay_40us
;
;*****************************************************************
; Subroutine Name: LCD_SetPosition
; Function: Set the position where character are to be 
;           written to the LCD display.
;
; Inputs:  WREG     Line and position on that lone
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_SetPosition:
    iorlw   0x80        ; Set position LCD module command
    goto    LCD_WriteCommand
;
;*****************************************************************
; Subroutine Name: LCD_putrs
;
; Function: This routine writes a string of bytes to the
;           Hitachi HD44780 LCD controller. 
;
; Inputs:  pszLCD_RomStr: pointer to string;
;
; Outputs: none
;
; Uses:    WREG, STATUS
;
;*****************************************************************
LCD_putrs:
    call    TableLookUp
    iorlw   0
    skpnz
    return
    call    LCD_WriteData
    incf    pszLCD_RomStr,F
    skpnz
    incf    pszLCD_RomStr+1,F
    goto    LCD_putrs
    
TableLookUp:
    movfw   pszLCD_RomStr+1
    movwf   PCLATH
    movfw   pszLCD_RomStr
    movwf   PCL
;
; ROM based LCD messages
;
LCD_message1:
    dt  "Ver 1.0 - 20x4 LCD",0
LCD_message2:
    dt  "Line 2 2021-MAR-04",0
LCD_message3:
    dt  "Line 3 20:00:29",0
LCD_message4:
    dt  "                    ",0
;
; Initialize EEPROM data
;
    ORG         0x2100
    ;startup frequency bytes must be next 4 bytes of EEPROM
    DATA        StartFreq>>8    ; Most significant byte
    DATA        StartFreq&0xFF  ; Least significant byte (87MHz)
    DATA        0
    DATA        0
    
    END
It is up to you to add SAA1057 support to this application.
 
Thanks Dan, will try that one in a minute.

Mike, thankyou, will also try that one.
There is a line in the datasheet for the ST7066 about not holding E high when doing a busy read, I'll dig the appropriate bit out a little later.

If I disappear from here without leaving a message, it means the phone has rung and I have had to go in a hurry (why are urgent things never that urgent when you get there?).
 
Dan, attached photo is what I get with your code, as posted above.

DSCF1117.JPG
Code builds without any errors.

No action from the encoder or indication on the LCD at line 4 pos 20.
 
Dan, attached photo is what I get with your code, as posted above.

View attachment 130126
Code builds without any errors.

No action from the encoder or indication on the LCD at line 4 pos 20.
There is at least one good thing in that the LCD code is working correctly on your 20x4 LCD module.

I tested the code with the MPLAB v8.92 simulator so I know the encoder logic works but there may be some issue with real hardware. I will try it tomorrow.

In the meanwhile try using a pair of toggle switches in place or your encoder.

Start with RA0 and RA1 low, make RA0 high, then RA1 high, then RA0 low, then RA1 low. You should see the character on line 4 position 20 change at least 3 times. If this happens then you must have a really crap encoder as it is bouncing way too much.

Another thing that could cause the observed behavior is if either the interrupt system or TIMER0 does not work on your controller. This is a VERY far fetched speculation but in a prior post you said you have had issues with interrupts.
 
Last edited:
Using Timer2 and with Mikes help that is all sorted and working (it is only for his encoder routine - not used for anything else).

Was going to try switches, but hadn't thought of using them with the encoder code, will try that shortly.
 
All right so switches or encoder do not cause a character to appear.

I know this is a stupid question but:

Are pins 18 and 17 on your PIC actually changing state?
 
Not a stupid question because I'm beginning to believe anything is possible at the moment, including ghoulies, goblins and other weird little creatures.

The answer to that is that other code that uses the rotary encoder on those pins works, but, to be sure I will put a meter on them.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top