Why LCD won't work with RS connected to PortA.6 of 18F452?


+ Reply to Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Default Why LCD won't work with RS connected to PortA.6 of 18F452?

    I am going crazy trying to figure out answer to this question. When I connect RS to PortA.5 of the 18F452 LCD works fine. However when RS is connected to PortA.6 of the 18F452 it doesn't. I checked the data sheet and both RA5 and RA6 ports are I/O TTL pins and no indication that open drain requires pull-up resistor to be used as ouput as it does on RA4.
    Yet I notice during simulation with Proteus VSM that pin PortA.5 is held continuously at low level while LCD is working, but when PortA.6 is used, Proteus VSM shows gray value for the pin indicating it is not being held at low level when LCD is not working.
    Can anyone explain to me what is going on here and why the LCD works with PortA.5 and not with PortA.6 connected to RS? I am attaching a partial screen snapshot in a .pdf of my Proteus VSM simulation to show the logic levels on the pins. I will also list my code.
    18F452DisplayLM34temp.PDF
    Code:
    'STATUS: Compiles/assembles OK.
    '        Logs temperature measurements into EEPROM.
    '        Temperature appears accurate to +/- 1 deg
    '<FL_PIC18F452>'       ' Set MCU type for FineLine Editor
    '***********************************************************************
    '*  Name    : 18F452DisplayLM34temp.pbp                                *
    '*  Author  : John R. Ellis                                            *
    '*  Notice  : Copyright (c) 2010 LodeStar Associates, Inc.             *
    '*          : All Rights Reserved                                      *
    '*  Started : 04/05/2012                                               *
    '*  Version : 1.0                                                      *
    '*  Notes   : 1) This code was designed/devloped on an EasyPic6        *
    '*  Compiler: PICBASIC PRO Compiler 2.60C from microEngineering Labs   *
    '*  Device  : 18F452  w/ LM34 wired onto an Easy Connect module        *
    '*            and connected via PortA expansion port to pin RA0 as     *
    '*            installed on an EasyPic6.                                *
    '*  Memory  : 1,272 bytes of Program Memory required.                  *
    '*  Ref:    : 1) Temperature subroutine of this code is adapted from   *
    '*          : code written by Bruce Rentron(see URL below)             *
    '*            http://www.rentron.com/PicBasic/LM34.htm                 *
    '*                                                                     *
    '***********************************************************************
    ' -----------------------[ Program Description ]--------------------------
    '  PICBASIC PRO program to set RTC & demo operation of a LCD/4-bit mode  *
    '    1)  Initializes 2x16 or 2x8 LCD display with EasyPic6.              *
    '    2)  Measures temperature via LM34, stores in EEPROM & displays      *
    '                                                                        *
    '*************************************************************************
    ' -----------------------[ Revision History ]-----------------------------
    ' Version 1.0   Started on 04/05/2012
    
    '-----------------18F452 Port/PIN Connections ]--------------------
    'I/O pin connections to the 18F452 MCU are as follows:
    'PORTB.4 (37) RB4 connected to Green LED to indicate USB connected & power on.
    'PORTC.0 (15) RC0 connected as an output to a Green LED for hearbeat/progress.
    'PORTC.1 (16) RC1 connected as an output to a Red LED for battery low.
    'PORTE.0  (8) RE0 connected to Vout of LM34 for A/D measurement
    'PORTE.1  (9) RC0 connected to control external power to Ultrasonic sensors.
    
    '--------------[ Define EEPROM usage ]-----------------------------------
       '09  = day_cnt  ' Most recent day_cnt
       '10  = J        ' Index for counting interrupts received
       '11  = hr       ' Hour time from RTC after setting RTC
       '12  = MINs     ' Minutes time from RTC after setting RTC
       '13  = sec      ' Seconds time from RTC after setting RTC
       '14  = A1hr     ' Alarm1 hour time from RTC after setting RTC
       '15  = A1MINs   ' Alarm1 minutes time from RTC after setting RTC
       '16+J = hr      ' Log Hour
       '17+J = MINs    ' Log Minutes
       '18+J + sec     ' Log Seconds
       '240 = ID(0)    ' LSB of device ID
       '241 = ID(1)    ' MSB of device ID
       '242 = mon      ' Month when clock was set
       '243 = date     ' Date when clock was set
       '244 = yr       ' Year when clock was set
    
    'INCLUDE "CodeSize.pbp"     'FOR TEST ONLY
    DEFINE Measure 1
    ;@ StartSize(LOOKUP)        'FOR TEST ONLY
    
    Pause 10     ' This statement is placed at beginning of code for ICD use
    
    'Disable Debug
    ;-- if you un-comment these, you must comment the ones in the .inc file --
    ;ASM  ; 18F2550/4550, 8mhz crystal
    ;   __CONFIG    _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC4_PLL6_1L & _USBDIV_2_1L
    ;   __CONFIG    _CONFIG1H, _FOSC_HSPLL_HS_1H
    ;   __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
    ;   __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
    ;   __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
    ;   __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ;ENDASM
    
    '--------------[ Define Hardware / Set Registers ]------------------------
        DEFINE OSC 8
        DEFINE I2C_SLOW 1   ' Set i2c to the standard speed
        DEFINE I2C_HOLD 1   ' Enable recieving i2c device to pause communication
    
        Include "Modedefs.Bas" ' Mode definitions for Debug,Serin/out,
                               ' Shiftin/out, Xin/out.
        INCLUDE "ALLDIGITAL.pbp"  ' Sets all registers for digital ops.
                                  ' User must make sure AllDigital.pbp file
                                  ' is in same or higher directory location as
                                  ' this source code before compiling.
            'DEFINE SHOWDIGITAL 1 ' When uncommented will show analog settings
                                  ' in Assembler Results window.
            ' A/D & Comparators disabled for digital ops
            ' All of these statements should be commented out when using the
            ' INCLUDE "AllDigital.pbp" statement to set digital ops.
                'ADCON1 = 001111
                'CMCON = 7
        'INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
        'INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP high priority interrupts
                                    ' Allows re-entry to PBP from a High Priority
                                    ' ASM interrupt. Must have DT_INTS-18.bas
                                    ' loaded first.
       'OSCCON.7 = 0          ' Clear IDLEN bit to allow SLEEP mode
          ' According to data sheet, must clear CONFIG2H.0 (WDTEN bit)
          ' in order to use WDTCON. Not clear from Data sheet how to reach
          ' WDTEN bit with with config fuses??
            'WDTCON.0 = 1          ' Set SWDTEN bit to turn on WDT
        TRISA = 0           ' PortA all outputs for LCD use
        TRISB = 0           ' PortB all outputs
        TRISC = 000000   ' PortC.0 is output to LED_GRN
                            ' PortC.1 is output to LED_RED
                            ' PortC.2 is output to the LCD R/W connection
                            ' PortC.3 is output to SCL on I2C bus
                            ' PortC.4 is output to SDA on I2C bus
                            ' PortC.5 is not connected
                            ' PortC.6 is TX output to the RX connection on WiFi
                            ' PortC.7 is Rx input from the TX connection on WiFi
        TRISE = 000001   ' PortE.0 is A/D input for AN5 from LM34 output
                            ' PortE.1 is output for controlling exteranl SF02 power
        ADCON1=7
    CLEAR
    
    '--- Variables -----------------------------------------------------------
    day_cnt     VAR BYTE      ' Counter for day number during monthly epoch
    deviceID1   VAR BYTE      ' Serial # of MCU (MSB)
    deviceID2   VAR BYTE      ' Serial # of MCU (LSB)
    ext_pwr     VAR PortE.1   ' MCU controlled external power to A/D & SRF02
    I           VAR Byte      ' Index for loop counters
    ID          VAR BYTE(8)   ' Array for storing device ID parameters
    J           VAR BYTE      ' Index to EEPROM address for logging
    LCD_Flag    VAR Bit       ' Flag when set indicates LCD is installed/used
    LED_RED     VAR PortC.1   ' Red LED
    LED_GRN     VAR PortC.0   ' Green LED used to indicate Routine entries
    logflag     VAR BYTE      ' Flag used in ISR to indicate to log time stamp
    LowVolt     VAR BYTE      ' Flag used in ISR to indicate low supply voltage
    SCL         VAR PORTC.3   ' I2C clock pin
    SDA         VAR PORTC.4   ' I2C data pin
    Spare_1     VAR PORTB.7   ' PGD for ICSP & Spare I/O for normal ops
    Spare_2     VAR PORTB.6   ' PGC for ICSP & Spare I/O for normal op
    temp        VAR WORD      ' Stores measured temperature
    list        VAR BYTE      ' Used as embedded step variable for troubleshooting
    
    'ENABLE DEBUG
    '--- Initialize ----------------------------------------------------------
        ' Set FLAGS for current configuration
             LCD_Flag = 1      ' Set for LCD installed/used; cleared otherwise
    
    ;--- Read MCU Serial Number from device ID Locations
        TBLPTRU=$20                 ' Address $200000
        TBLPTRH=$00
        TBLPTRL=$00
        For i = 0 To 7
    @  TBLRD*+                  ; Get value and increment the address
            ID(i) = TABLAT          ; Store the byte as ID(i)
        Next
        deviceID1 = ID(0)           ' MSB of MCU Device Serial Number
        deviceID2 = ID(1)           ' LSB of MCU Device Serial Number
        WRITE 240, ID(0)            ' Write fixed values to EEPROM for test
        WRITE 241, ID(1)
    
    '--- Initialize epoch indexes at time of powerup/reset
        day_cnt = 0
        WRITE 9, day_cnt     ' Store new epoch initialized day_count
    
    GOTO JumpPoint ' Jump over all subroutines so they don't execute on powerup
    
    ' ----------------------[ START SUBROUTINES ]--------------------------
    
    InitializeDisplay:  ' Subroutine to initialize 2X16 or 2x8 LCD display
    '=================
      '-----SETUP FOR USING 2x16 or 2x8 LCD THAT IS INSTALLED IN EASYPIC6--------
         ' LCD DEFINES FOR USING 2x16 LCD with PortA in EASYPIC6
               DEFINE LCD_DREG PORTA    ' Use PORTA for LCD Data
               DEFINE LCD_DBIT 0        ' Use lower(4) 4 bits of PORTA
                                          ' PORTA.0 thru PORTB.3 connect to
                                          ' LCD DB4 thru LCD DB-7 respectively
               DEFINE LCD_RSREG PORTA   ' PORTA for RegisterSelect (RS) bit
               DEFINE LCD_RSBIT 5       ' PORTA.5 pin for LCD's RS line
               DEFINE LCD_RWREG PORTC   ' LCD read/write port to GND
               DEFINE LCD_RWBIT 2       ' LCD read/write bit
               DEFINE LCD_EREG PORTA    ' PORTA for Enable (E) bit
               DEFINE LCD_EBIT 4        ' PORTA.4 pin for LCD's E line
               DEFINE LCD_BITS 4        ' Using 4-bit bus
               DEFINE LCD_LINES 2       ' Using 2 line Display
               DEFINE LCD_COMMANDUS 2000' Command Delay (uS)
               DEFINE LCD_DATAUS 50     ' Data Delay (uS)
    
        ' DEFINE LCD Control Constants
               Line1   CON 128          ' Point to beginning of line 1 ($80)
               Line2   CON 192          ' Point to beginning of line 2 ($C0)
    
        ' Test the LCD during initialization
               LED_RED = 1     ' Blink red LED during LCD initialization
               LCDOut $fe,1:FLAGS=0:Pause 250    ' Clear Display
               LCDOUT $fe,Line1,"POWER ON"       ' Display on 1st line
               LCDOUT $fe,Line2,"LCD TEST"       ' Display on 2nd line
               PAUSE 2000
               LED_RED = 0     ' Blink red LED during LCD initialization
    Return
    
    Temperature:        ' Subroutine to measure temperature from LM34
    '===========
    ' This subroutine is an adaptation from below reference to 10-bit A/D
    '****************************************************************
    '*  Name    : LM34.BAS                                          *
    '*  Author  : Bruce Reynolds                                    *
    '*  Date    : 10/23/2001                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :  8-bit A/D temperature conversion with National   *
    '*          ;  LM34CAZ analog temperature sensor.               *
    '*          :  See http://www.rentron.com/PicBasic/LM34.htm     *
    '****************************************************************
    
    'DEFINE osc 8           ' Using a 16 MHz oscillator..already defined
    DEFINE ADC_BITS 10      ' Set A/D for 10-bit operation
    DEFINE ADC_CLOCK 5      ' Set A/D clock Fosc/16
    DEFINE ADC_SAMPLEUS 50  ' Set A/D sampling time @ 50 uS
    samples VAR WORD        ' Multiple A/D sample accumulator
    sample  VAR BYTE        ' Holds number of samples to take
    value   VAR WORD        ' Holds LM34 measured temperature value
    samples = 0             ' Clear samples accumulator on entry
    W0      VAR WORD        '
    
        ' Setup registers for A/D input per Sec 21.0 of datasheet
        '1. Configure the A/D module:
          '  Configure analog pins, voltage reference AND I/O (ADCON1)
              ADCON1 = 000000 'right justified,Fosc/16, all analog
          '  SELECT A/D INPUT channel (ADCON0)
              ADCON0 = 101000  'Fosc/16,Disable AN5 (PORTE.0),powered down
          '  SELECT A/D acquisition time & A/D conversion clock (ADCON2)
              'ADCON2 = 110101  'Right justified;TAD=16;A/D clock=Fosc/16
          '  Turn ON A/D module (ADCON0)
              ADCON0.0 = 1  'Power up the A/D module
        '2. Configure A/D INTERRUPT (IF desired):
            '  CLEAR ADIF BIT
            '  Set ADIE BIT
            '  Set GIE BIT
        '3. WAIT the required acquisition time (IF required).
            'PAUSE 250          ' Wait approximately 1/4 seconds per loop
        '4. Start conversion-Set GO/DONE BIT (ADCON0 register)
            ADCON0.2 = 1
        '5. WAIT FOR A/D conversion TO complete, by either:
            '  Polling FOR the GO/DONE BIT TO be cleared
                'OR
            '  Waiting FOR the A/D INTERRUPT
        FOR sample = 1 TO 10    ' Take 10 samples
            ADCIN 5, value      ' Read channel 5 into temp variable
            'PAUSE 2
            ' or use alternative manual method to read A/D input
                'WHILE ADCON0.1 : WEND
                '6. READ A/D Result registers (ADRESH:ADRESL);
                    'CLEAR BIT ADIF, if required.
                   'W0.HIGHBYTE = ADRESH
                   'W0.LOWBYTE = ADRESL
             samples = samples + value ' Accumulate 10 samples
            '7. FOR NEXT conversion, go TO STEP 1 or STEP 2, as
                'required. The A/D conversion time per BIT IS
                'defined as TAD. A minimum WAIT of 3 TAD IS
                'required before the NEXT acquisition starts.
            PAUSE 250          ' Wait approximately 1/4 seconds per loop
        NEXT sample
        value = samples/20      ' Determine average of 20 measurements
        'ADC Math for 10-bit A/D when using Vdd as referenc
            'ADC Resolution = 4.99 V/1024 COUNT = 4.912109 mV/COUNT
            '=> LM34DZ OUTPUT voltage (mV) = 2 x COUNT
            'Temperature ( F) = LM34 OUTPUT voltage in mV/10
            '=> Temperature ( F) = 4.912109 x COUNT/10 = 0.4912109*COUNT
            ' Therefore temp = 0.4912109*Count or approx. = Count/2.036
        ' To avoid floating point math, multiply by 1000 and then DIV32
        'value  = 1000 * value
        'temp = DIV32 2036
        temp = value
        samples = 0             ' Clear old sample accumulator for next cycle
        ADCON1=7                ' Return to digital ops.
    
    RETURN
    
    ' ----------------------[ END OF SUBROUTINES ]--------------------------
    
    JumpPoint:
        'Setup for starting Main Program
        IF LCD_Flag = 1 THEN GOSUB InitializeDisplay  ' Initialize LCD before
                                                      ' starting mainloop
    
        IF LCD_Flag = 1 THEN ' This code block FOR TESTING ONLY
            LCDOUT $fe,1' Clear Display
            LCDOUT $fe,Line1,"Entered"
            LCDOUT $fe,Line2,"JumpPoint"
            PAUSE 2000
        ENDIF
    
        'Initialize epoch indexes at time of powerup/reset
            Pause 20
            J = 0                ' Initialize EEPROM logging index
            'WRITE 11,hr          ' Log program start time
            'WRITE 12,MINs
            'WRITE 13,sec
            'WRITE 242,mon        ' Log program start date
            'WRITE 243,date
            'WRITE 244,yr
    
        'Initialize LEDs to off
            LED_GRN = 0
            LED_RED = 0
        ' Enable the interrupts that are to be active during main loop.
            'logflag = 0          ' Clear flags before mainloop
            'LowVolt = 0
    ;@    INT_ENABLE   INT2_INT     ; enable DT_18-INTS interrupts
    ;@    INT_ENABLE   HLVD_INT
    
    '--------------------[ Begin Main Program Loop ]-------------------------
    ;@ StartSize(MainLoop)    ; FOR TEST ONLY
    mainloop:
    
            ' Put code here for temperature measurement
                FOR I = 0 TO 1    ' Blink Green LED 2x due to ISR entry
                    LED_GRN = 1
                    PAUSE 250
                    LED_GRN = 0
                    PAUSE 250
                NEXT
                IF J > 220 THEN  ' If logging space is full start over with logging
                   J = 0     ' Reset logging index to start of logging space
                             ' Logging space covers time stamps for 220 interrupts
                ENDIF
    
                'Put code here to measure/log temperature from LM34 analog sensor
                    temp = 0          'Initialize temperature variable
                    ext_pwr = 1       'Power up temperature circuit
                    GOSUB Temperature
                    ext_pwr = 0      'Power-down temperature circuit
    
                IF J > 220 THEN  ' If logging space is full start over with logging
                   J = 0     ' Reset logging index to start of logging space
                             ' Logging space covers time stamps for 220 interrupts
                ENDIF
                WRITE 16+J, temp   ' temperature value to EEPROM
                J = J+1
    
                'If LCD installed reset to all digital ops before display of temperature
                    IF LCD_Flag = 1 THEN ' This code block FOR TESTING ONLY
                        ADCON1 = 7   ' All Digital
                        LCDOUT $fe,1 ' Clear Display
                        LCDOUT $fe,Line1,"Temp:"  ' Display measured temperature
                        LCDOUT $FE,Line2, DEC temp, " DEG F"
                        PAUSE 1000
                        ' Will be reset to analog use in Temperature routine
                    ENDIF
    GOTO mainloop
    ;@ EndSize(MainLoop)    ; Uncomment FOR TEST ONLY
    
    '--------------------[ Begin Interrupt Handlers ]------------------------
    ' ISRs all commented out for this application.
    ;Alarm:
            ;logflag = 1    ' Set flag for logging this interrupt
    ;@ INT_RETURN
    
    'VoltLow:
            'LowVolt = 1    ' Set flag for low voltage warning
    ;@ INT_RETURN
    
    '------------------{ End of Interrupt Handlers }-------------------------
    End     ' Safety measure to insure program stops if reaches here
    ;@ EndSize(LOOKUP)       ; FOR TEST ONLY
    ;@ LibrarySize           ; FOR TEST ONLY
    ;@ UserSize              ; FOR TEST ONLY
    ;@ TotalSize             ; FOR TEST ONLY
    Last edited by jellis00; - 7th April 2012 at 23:17.

  2. #2
    Join Date
    May 2008
    Location
    Italy
    Posts
    825

    Default Re: Why LCD won't work with RS connected to PortA.6 of 18F452?

    Change the define lcd_rsbit for porta.6

    Cheers

    Al.
    All progress began with an idea

  3. #3
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Default Re: Why LCD won't work with RS connected to PortA.6 of 18F452?

    Quote Originally Posted by aratti View Post
    Change the define lcd_rsbit for porta.6
    I made that change and it made no difference....LCD still doesn't work. Wiring still the same as previously posted .pdf, but here is latest code after changes and after eliminating some of the superfolous comments:
    Code:
    Pause 10     ' This statement is placed at beginning of code for ICD use
    
    'Disable Debug
    ;-- if you un-comment these, you must comment the ones in the .inc file --
    ;ASM  ; 18F2550/4550, 8mhz crystal
    ;   __CONFIG    _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC4_PLL6_1L & _USBDIV_2_1L
    ;   __CONFIG    _CONFIG1H, _FOSC_HSPLL_HS_1H
    ;   __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
    ;   __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
    ;   __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
    ;   __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ;ENDASM
    
    '--------------[ Define Hardware / Set Registers ]------------------------
        DEFINE OSC 8
        DEFINE I2C_SLOW 1   ' Set i2c to the standard speed
        DEFINE I2C_HOLD 1   ' Enable recieving i2c device to pause communication
    
        Include "Modedefs.Bas" ' Mode definitions for Debug,Serin/out,
                               ' Shiftin/out, Xin/out.
        INCLUDE "ALLDIGITAL.pbp"  ' Sets all registers for digital ops.
                                  ' User must make sure AllDigital.pbp file
                                  ' is in same or higher directory location as
                                  ' this source code before compiling.
            'DEFINE SHOWDIGITAL 1 ' When uncommented will show analog settings
                                  ' in Assembler Results window.
            ' A/D & Comparators disabled for digital ops
            ' All of these statements should be commented out when using the
            ' INCLUDE "AllDigital.pbp" statement to set digital ops.
                'ADCON1 = %00001111
                'CMCON = 7
        'INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
        'INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP high priority interrupts
                                    ' Allows re-entry to PBP from a High Priority
                                    ' ASM interrupt. Must have DT_INTS-18.bas
                                    ' loaded first.
       'OSCCON.7 = 0          ' Clear IDLEN bit to allow SLEEP mode
          ' According to data sheet, must clear CONFIG2H.0 (WDTEN bit)
          ' in order to use WDTCON. Not clear from Data sheet how to reach
          ' WDTEN bit with with config fuses??
            'WDTCON.0 = 1          ' Set SWDTEN bit to turn on WDT
        TRISA = 0           ' PortA all outputs for LCD use
        TRISB = 0           ' PortB all outputs
        TRISC = %10000000   ' PortC.0 is output to LED_GRN
                            ' PortC.1 is output to LED_RED
                            ' PortC.2 is output to the LCD R/W connection
                            ' PortC.3 is output to SCL on I2C bus
                            ' PortC.4 is output to SDA on I2C bus
                            ' PortC.5 is not connected
                            ' PortC.6 is TX output to the RX connection on WiFi
                            ' PortC.7 is Rx input from the TX connection on WiFi
        TRISE = %00000001   ' PortE.0 is A/D input for AN5 from LM34 output
                            ' PortE.1 is output for controlling exteranl SF02 power
        ADCON1=7
    CLEAR
    
    '--- Variables -----------------------------------------------------------
    day_cnt     VAR BYTE      ' Counter for day number during monthly epoch
    deviceID1   VAR BYTE      ' Serial # of MCU (MSB)
    deviceID2   VAR BYTE      ' Serial # of MCU (LSB)
    ext_pwr     VAR PortE.1   ' MCU controlled external power to A/D & SRF02
    I           VAR Byte      ' Index for loop counters
    ID          VAR BYTE(8)   ' Array for storing device ID parameters
    J           VAR BYTE      ' Index to EEPROM address for logging
    LCD_Flag    VAR Bit       ' Flag when set indicates LCD is installed/used
    LED_RED     VAR PortC.1   ' Red LED
    LED_GRN     VAR PortC.0   ' Green LED used to indicate Routine entries
    logflag     VAR BYTE      ' Flag used in ISR to indicate to log time stamp
    LowVolt     VAR BYTE      ' Flag used in ISR to indicate low supply voltage
    SCL         VAR PORTC.3   ' I2C clock pin
    SDA         VAR PORTC.4   ' I2C data pin
    Spare_1     VAR PORTB.7   ' PGD for ICSP & Spare I/O for normal ops
    Spare_2     VAR PORTB.6   ' PGC for ICSP & Spare I/O for normal op
    temp        VAR WORD      ' Stores measured temperature
    list        VAR BYTE      ' Used as embedded step variable for troubleshooting
    
    'ENABLE DEBUG
    '--- Initialize ----------------------------------------------------------
        ' Set FLAGS for current configuration
             LCD_Flag = 1      ' Set for LCD installed/used; cleared otherwise
    
    ;--- Read MCU Serial Number from device ID Locations
        TBLPTRU=$20                 ' Address $200000
        TBLPTRH=$00
        TBLPTRL=$00
        For i = 0 To 7
    @  TBLRD*+                  ; Get value and increment the address
            ID(i) = TABLAT          ; Store the byte as ID(i)
        Next
        deviceID1 = ID(0)           ' MSB of MCU Device Serial Number
        deviceID2 = ID(1)           ' LSB of MCU Device Serial Number
        WRITE 240, ID(0)            ' Write fixed values to EEPROM for test
        WRITE 241, ID(1)
    
    '--- Initialize epoch indexes at time of powerup/reset
        day_cnt = 0
        WRITE 9, day_cnt     ' Store new epoch initialized day_count
    
    GOTO JumpPoint ' Jump over all subroutines so they don't execute on powerup
    
    ' ----------------------[ START SUBROUTINES ]--------------------------
    
    InitializeDisplay:  ' Subroutine to initialize 2X16 or 2x8 LCD display
    '=================
      '-----SETUP FOR USING 2x16 or 2x8 LCD THAT IS INSTALLED IN EASYPIC6--------
         ' LCD DEFINES FOR USING 2x16 LCD with PortA in EASYPIC6
               DEFINE LCD_DREG PORTA    ' Use PORTA for LCD Data
               DEFINE LCD_DBIT 0        ' Use lower(4) 4 bits of PORTA
                                          ' PORTA.0 thru PORTB.3 connect to
                                          ' LCD DB4 thru LCD DB-7 respectively
               DEFINE LCD_RSREG PORTA   ' PORTA for RegisterSelect (RS) bit
               DEFINE LCD_RSBIT 6       ' PORTA.6 pin for LCD's RS line
               DEFINE LCD_RWREG PORTC   ' LCD read/write port to GND
               DEFINE LCD_RWBIT 2       ' LCD read/write bit
               DEFINE LCD_EREG PORTA    ' PORTA for Enable (E) bit
               DEFINE LCD_EBIT 4        ' PORTA.4 pin for LCD's E line
               DEFINE LCD_BITS 4        ' Using 4-bit bus
               DEFINE LCD_LINES 2       ' Using 2 line Display
               DEFINE LCD_COMMANDUS 2000' Command Delay (uS)
               DEFINE LCD_DATAUS 50     ' Data Delay (uS)
    
        ' DEFINE LCD Control Constants
               Line1   CON 128          ' Point to beginning of line 1 ($80)
               Line2   CON 192          ' Point to beginning of line 2 ($C0)
    
        ' Test the LCD during initialization
               LED_RED = 1     ' Blink red LED during LCD initialization
               LCDOut $fe,1:FLAGS=0:Pause 250    ' Clear Display
               LCDOUT $fe,Line1,"POWER ON"       ' Display on 1st line
               LCDOUT $fe,Line2,"LCD TEST"       ' Display on 2nd line
               PAUSE 2000
               LED_RED = 0     ' Blink red LED during LCD initialization
    Return
    
    Temperature:        ' Subroutine to measure temperature from LM34
    '===========
    ' This subroutine is an adaptation from below reference to 10-bit A/D
    '****************************************************************
    '*  Name    : LM34.BAS                                          *
    '*  Author  : Bruce Reynolds                                    *
    '*  Date    : 10/23/2001                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :  8-bit A/D temperature conversion with National   *
    '*          ;  LM34CAZ analog temperature sensor.               *
    '*          :  See http://www.rentron.com/PicBasic/LM34.htm     *
    '****************************************************************
    
    'DEFINE osc 8           ' Using a 16 MHz oscillator..already defined
    DEFINE ADC_BITS 10      ' Set A/D for 10-bit operation
    DEFINE ADC_CLOCK 5      ' Set A/D clock Fosc/16
    DEFINE ADC_SAMPLEUS 50  ' Set A/D sampling time @ 50 uS
    samples VAR WORD        ' Multiple A/D sample accumulator
    sample  VAR BYTE        ' Holds number of samples to take
    value   VAR WORD        ' Holds LM34 measured temperature value
    samples = 0             ' Clear samples accumulator on entry
    W0      VAR WORD        '
    
    IF LCD_Flag = 1 THEN ' This code block FOR TESTING ONLY
            LCDOUT $fe,1' Clear Display
            LCDOUT $fe,Line1,"Temp"
            LCDOUT $fe,Line2,"Measurement"
            PAUSE 1000
    ENDIF
    
        ' Setup registers for A/D input per Sec 21.0 of datasheet
        '1. Configure the A/D module:
          '  Configure analog pins, voltage reference AND I/O (ADCON1)
              ADCON1 = %11000000 'right justified,Fosc/16, all analog
          '  SELECT A/D INPUT channel (ADCON0)
              ADCON0 = %01101000  'Fosc/16,Disable AN5 (PORTE.0),powered down
          '  SELECT A/D acquisition time & A/D conversion clock (ADCON2)
              'ADCON2 = %10110101  'Right justified;TAD=16;A/D clock=Fosc/16
          '  Turn ON A/D module (ADCON0)
              ADCON0.0 = 1  'Power up the A/D module
        '2. Configure A/D INTERRUPT (IF desired):
            '  CLEAR ADIF BIT
            '  Set ADIE BIT
            '  Set GIE BIT
        '3. WAIT the required acquisition time (IF required).
            'PAUSE 250          ' Wait approximately 1/4 seconds per loop
        '4. Start conversion-Set GO/DONE BIT (ADCON0 register)
            ADCON0.2 = 1
        '5. WAIT FOR A/D conversion TO complete, by either:
            '  Polling FOR the GO/DONE BIT TO be cleared
                'OR
            '  Waiting FOR the A/D INTERRUPT
        FOR sample = 1 TO 10    ' Take 10 samples
            ADCIN 5, value      ' Read channel 5 into temp variable
            'PAUSE 2
            ' or use alternative manual method to read A/D input
                'WHILE ADCON0.1 : WEND
                '6. READ A/D Result registers (ADRESH:ADRESL);
                    'CLEAR BIT ADIF, if required.
                   'W0.HIGHBYTE = ADRESH
                   'W0.LOWBYTE = ADRESL
             samples = samples + value ' Accumulate 10 samples
            '7. FOR NEXT conversion, go TO STEP 1 or STEP 2, as
                'required. The A/D conversion time per BIT IS
                'defined as TAD. A minimum WAIT of 3 TAD IS
                'required before the NEXT acquisition starts.
            PAUSE 250          ' Wait approximately 1/4 seconds per loop
        NEXT sample
        value = samples/10      ' Determine average of 10 measurements
        'ADC Math for 10-bit A/D when using Vdd as referenc
            'ADC Resolution = 4.99 V/1024 COUNT = 4.912109 mV/COUNT
            '=> LM34DZ OUTPUT voltage (mV) = 2 x COUNT
            'Temperature ( F) = LM34 OUTPUT voltage in mV/10
            '=> Temperature ( F) = 4.912109 x COUNT/10 = 0.4912109*COUNT
            ' Therefore temp = 0.4912109*Count or approx. = Count/2.036
        ' To avoid floating point math, multiply by 1000 and then DIV32
        value  = 1000 * value
        temp = DIV32 2036
        samples = 0             ' Clear old sample accumulator for next cycle
        ADCON1=7                ' Return to digital ops.
    
    RETURN
    
    ' ----------------------[ END OF SUBROUTINES ]--------------------------
    
    JumpPoint:
        'Setup for starting Main Program
        IF LCD_Flag = 1 THEN GOSUB InitializeDisplay  ' Initialize LCD before
                                                      ' starting mainloop
    
        IF LCD_Flag = 1 THEN ' This code block FOR TESTING ONLY
            LCDOUT $fe,1' Clear Display
            LCDOUT $fe,Line1,"Entered"
            LCDOUT $fe,Line2,"JumpPoint"
            PAUSE 1000
        ENDIF
    
        'Initialize epoch indexes at time of powerup/reset
            Pause 20
            J = 0                ' Initialize EEPROM logging index
            'WRITE 11,hr          ' Log program start time
            'WRITE 12,MINs
            'WRITE 13,sec
            'WRITE 242,mon        ' Log program start date
            'WRITE 243,date
            'WRITE 244,yr
    
        'Initialize LEDs to off
            LED_GRN = 0
            LED_RED = 0
        ' Enable the interrupts that are to be active during main loop.
            'logflag = 0          ' Clear flags before mainloop
            'LowVolt = 0
    ;@    INT_ENABLE   INT2_INT     ; enable DT_18-INTS interrupts
    ;@    INT_ENABLE   HLVD_INT
    
    '--------------------[ Begin Main Program Loop ]-------------------------
    ;@ StartSize(MainLoop)    ; FOR TEST ONLY
    mainloop:
    
            ' Put code here for temperature measurement
                ' Blink Green LED as heartbeat
                    LED_GRN = 1
                    PAUSE 250
                    LED_GRN = 0
                    PAUSE 250
    
                'Put code here to measure/log temperature from LM34 analog sensor
                    temp = 0          'Initialize temperature variable
                    ext_pwr = 1       'Power up temperature circuit
                    GOSUB Temperature
                    ext_pwr = 0      'Power-down temperature circuit
    
                IF J > 220 THEN  ' If logging space is full start over with logging
                   J = 0     ' Reset logging index to start of logging space
                             ' Logging space covers time stamps for 220 interrupts
                ENDIF
                WRITE 16+J, temp   ' temperature value to EEPROM
                J = J+1
    
                'If LCD installed reset to all digital ops before display of temperature
                    IF LCD_Flag = 1 THEN ' This code block FOR TESTING ONLY
                        ADCON1 = 7   ' All Digital
                        LCDOUT $fe,1 ' Clear Display
                        LCDOUT $fe,Line1,"Temp:"  ' Display measured temperature
                        LCDOUT $FE,Line2, DEC temp, " DEG F"
                        PAUSE 1000
                        ' Will be reset to analog use in Temperature routine
                    ENDIF
    GOTO mainloop
    ;@ EndSize(MainLoop)    ; Uncomment FOR TEST ONLY
    
    '--------------------[ Begin Interrupt Handlers ]------------------------
    ' ISRs all commented out for this application.
    ;Alarm:
            ;logflag = 1    ' Set flag for logging this interrupt
    ;@ INT_RETURN
    
    'VoltLow:
            'LowVolt = 1    ' Set flag for low voltage warning
    ;@ INT_RETURN
    
    '------------------{ End of Interrupt Handlers }-------------------------
    End     ' Safety measure to insure program stops if reaches here

  4. #4
    Join Date
    May 2008
    Location
    Italy
    Posts
    825

    Default Re: Why LCD won't work with RS connected to PortA.6 of 18F452?

    Did you read the following notes on page 31 of the datasheet:

    5: Bit 6 of PORTA, LATA, and TRISA are enabled in ECIO and RCIO Oscillator modes only. In all other
    Oscillator modes, they are disabled and read ’0’.
    6: Bit 6 of PORTA, LATA and TRISA are not available on all devices. When unimplemented, they are read ’0’.

    Al.
    All progress began with an idea

  5. #5
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Default Re: Why LCD won't work with RS connected to PortA.6 of 18F452?

    Thanks Al! That little bit of pertinent info is well hidden in the data sheet. The I/O section doesn't even mention this limitaton for pin PortA.6. Since my device has this pin I guess item 5: as you listed applies in my case.
    Now I have to figure out how to set Oscillator ECIO or RCIO mode. I'm now trying to figure out how to set the configs to do this for the 18F452.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts