PDA

View Full Version : LCDOUT not working at 16mhz oscillator speed.



CuriousOne
- 11th November 2022, 07:20
Hello. I have PIC16F1939 with the following code running.
The LCD is common 1602 LCD, at 4 or 8mhz oscillator speed it works just fine. However, it does not work at 16mhz speed - either shows garbage symbols on screen, or some letters are missing, or nothing is shown.
I found that changing value of DEFINE LCD_DATAUS 44 from default 44 to say 88 or 100 partially improves situation - screen works 50% times now, but still not a solution. Increasing this value more, or changing DEFINE LCD_COMMANDUS 1500 to another value does nothing.
The only workaround I found is to switch oscillator speed before using LCD to 8mhz and then back to 16 mhz, but I don't think this is right.

Any ideas?

Here's the reference code.




;----[16F1939 Hardware Configuration]-------------------------------------------
#IF __PROCESSOR__ = "16F1939"
#DEFINE MCU_FOUND 1
#CONFIG
cfg1 = _FOSC_INTOSC ; INTOSC oscillator: I/O function on CLKIN pin
cfg1&= _WDTE_OFF ; WDT disabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_ON ; MCLR/VPP pin function is digital input
cfg1&= _CP_ON ; Program memory code protection is enabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOREN_OFF ; Brown-out Reset disabled
cfg1&= _CLKOUTEN_OFF ; CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
__CONFIG _CONFIG1, cfg1


cfg2 = _WRT_OFF ; Write protection off
cfg2&= _VCAPEN_OFF ; All VCAP pin functionality is disabled
cfg2&= _PLLEN_OFF ; 4x PLL disabled
cfg2&= _STVREN_ON ; Stack Overflow or Underflow will cause a Reset
cfg2&= _BORV_19 ; Brown-out Reset Voltage (Vbor), low trip point selected.
cfg2&= _LVP_OFF ; High-voltage on MCLR/VPP must be used for programming
__CONFIG _CONFIG2, cfg2


#ENDCONFIG


#ENDIF


;----[Verify Configs have been specified for Selected Processor]----------------
; Note: Only include this routine once, after all #CONFIG blocks
#IFNDEF MCU_FOUND
#ERROR "No CONFIGs found for [" + __PROCESSOR__ +"]"
#ENDIF


'nixie led clock electronics direct drive


DEFINE LCD_DREG PORTC
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 6
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 3
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1500
DEFINE LCD_DATAUS 44
DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (rc = 3)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in microseconds



ADCON1=%11110011 'enable adc internal reference and justify
FVRCON=%11001111 'set internal reference to 4.096V
OSCCON=%111111111 'SET INTOSC TO 16MHZ
ANSELE=%00000000 'enable adc input porte.2
ANSELA=%00001111 'disable ADC on A except 4
ANSELB=%00000000 'disable ADC on B
ANSELD=%00000000 'disable ADC on D
TRISC=%00000000 'set PORTC as output all
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00001111 'set PORTA part as input
TRISE=%00000000 'set PORTE as output all
WPUB=%00000000 'DISABLE B PULL UPS
OPTION_REG=%100000000 'disable all pull ups
LCDCON=%00000000 'disable LCD controller pins
LCDSE0=%00000000
LCDSE1=%00000000
LCDSE2=%00000000




DEFINE OSC 16 'set oscillator speed


pause 1000
lcdout $fe, $1, "test"
pause 1000
stop

richard
- 11th November 2022, 09:54
That osccon looks pretty dodgy

tumbleweed
- 11th November 2022, 12:37
That osccon looks pretty dodgy

+1

You're enabling the PLL with an osc freq of 16MHz, so it's trying to run at 64MHz.
The max for that chip is 32MHz.

CuriousOne
- 11th November 2022, 19:59
Well it runs, and runs on 16mhz, I judge this by issuing HPWM 2,127,1000 statement, and measuring output frequency :)
If I leave OSCCON same and set DEFINE OSC to 32mhz, then it outputs 500hz.

CuriousOne
- 13th November 2022, 17:15
Changed: OSCCON=%01111011

Now LCD works on 16mhz, but still misbehaves sometimes - displayed characters get distorted, say you send text "TEST TEXT" and some letters will be replaced with garbage from user character area. I tried adding filtering capacitors/etc - no luck.

mpgmike
- 14th November 2022, 21:34
You don't want filtering caps on communications lines, you want the high-low-high transitions as crisp as possible. If anything, you may adjust the SLRCONx settings.

CuriousOne
- 16th November 2022, 16:44
LOL I'm not adding filtering caps to data lines. I'm adding them to power lines :D

tumbleweed
- 16th November 2022, 22:45
Looking at the library code, if the clock is set for > 16MHz (or 24MHz in some cases) it uses a longer internal delay before asserting some of the control pins.
Try this - lie to the compiler and tell it you're running faster than you really are:
DEFINE OSC 32 'set oscillator speed

Don't change your OSCCON setting... leave it so you're still actually running at 16MHz.

CuriousOne
- 17th November 2022, 04:57
Yes I already tried that and it works just fine, but it messes up with all other timing settings in my code, which is about 16K.
Is there any way to adjust the library settings?

tumbleweed
- 17th November 2022, 11:42
Not that I see, at least not without re-writing the lib asm code.

It looks like your display just isn't compatible with the timing of LCDOUT.
Your method of changing the osc freq before/after using the LCD is probably the easiest "fix" that comes to mind.

CuriousOne
- 18th November 2022, 11:32
Yes, quite possible, since this is not usual 1602 LCD module - it has 3 character sets (JP, Western europe, Cyrilic), switchable just like in WS0010. It also ignores LCDOUT $FE,$0 statement. But I will try with other 1602 modules and write the results.

pedja089
- 19th November 2022, 10:24
Try to increase delays with defines

' Set command delay time in us
DEFINE LCD_COMMANDUS 1500
' Set data delay time in us
DEFINE LCD_DATAUS 44

CuriousOne
- 20th November 2022, 05:11
Already tried. Has very little impact.