Serout2 on LCD Shows Junk Characters
I'm trying to work out whether the code below is accurately producing 0-255 values for the ADCIN command which I'm then using in conjunction with Darrel's SPWM_Int.bas, but I can't tell because my Scott Edwards Electronics ILM-216 serial LCD just shows gobbledy-gook. I've jumpered pins 6 & 8 on the LCD to get 9600bps but it's no better than the default 2600 baud.
Can anyone help me out? I bought this serial LCD as my previous one was a parallel one which uses too many pins but it's not much good to me if it can't help me debug.
Scott Edwards Electronics data sheet for the ILM-216 can be seen here.
Code:
' ***************************************************************
' Pin Connections
' ***************************************************************
' RA0 -> Middle arm of trim pot
' RC0 -> LED1
' RC1 -> LED2
' RC2 -> LED3
' RC4 -> Serial LCD output
DEFINE OSC 16 ; Set oscillator 16Mhz
;DEFINE OSC 4 ; Set oscillator 4Mhz
DEFINE ADC_BITS 8 ; Set number of bits in result
DEFINE ADC_SAMPLEUS 5 ; Set sampling time in uS
DEFINE ADC_CLOCK 3 ; Set clock source (3=rc)
' ***************************************************************
' Device Fuses
' ***************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
' ***************************************************************
' Initialization
' ***************************************************************
OSCCON = %01111000 ' 16MHz internal osc
;OSCCON = %01101000 ' 4MHz internal osc
pause 100
; Use PortA.0 (AN0) for ADCIN (trim pot reading)
ANSELA = %00000001 ; Analog on PORTA.0 (AN0) only
TRISA = %00000001 ; Input on PORTA.0 (AN0) only
;ADCON1 = %01110000 ; Left-justified results in 8-bits; Fosc/8 (2uS @ 4Mhz)
ADCON1.7 = 0 ; Left-justified results in 8-bits; Fosc/8 (2uS @ 4Mhz)
ANSELC = 0 ; Diginal only for all PortC pins
TRISC = %00000000 ; Make all PORTC pins output
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
#IFDEF USE_LCD_FOR_DEBUG
LCD_PIN VAR PORTC.4 ' Alias PORTC.4 as "LCD_PIN"
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
; LCD_BAUD CON 16780 ' Baud rate/mode 2600bps for ILM-216 2x16 character display
LCD_BAUD CON 16468 ' Baud rate/mode 9600bps for ILM-216 2x16 character display
LCD_PACE CON 1 ' Optional pace value
#ENDIF
' ***************************************************************
' Includes
' ***************************************************************
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
DEFINE SPWM_FREQ 200 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTC, 0, _DutyVar1 ; and the associated DutyCycle variables
SPWM_PIN PORTC, 1, _DutyVar2 ; Notice the underscore before variables
SPWM_PIN PORTC, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
adval VAR WORD ; stores ADCIN results
oldDutyVar1 VAR WORD
;_____________________________________________________________________________
DutyVar1 = 0
DutyVar2 = 25
DutyVar3 = 255
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["DutyVar1:", DEC DutyVar1, " "]
#ENDIF
Main:
ADCIN 0, adval
if adval <> oldDutyVar1 then
oldDutyVar1 = adval
DutyVar1 = adval
#IFDEF USE_LCD_FOR_DEBUG
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, [LCD_INST, LCD_CLR] ; clear screen
pause 5
serout2 LCD_PIN, LCD_BAUD, LCD_PACE, ["DutyVar1:", DEC DutyVar1, " "]
#ENDIF
EndIf
Pause 100
Goto Main
Re: Serout2 on LCD Shows Junk Characters
Ross,
You can't use software timed serial routines when using interrupts.
You will need to use the USART and HSEROUT.
Re: Serout2 on LCD Shows Junk Characters
Hi RossWaddell,
I used this LCD in the past and i had some problems with interrupts. If you are outputing something to the LCD and if an interrupt occurs, the data gets corrupted. If possible, you must disable the interrupt, then send the data with the serout command, and then enable interrupt, of course, if it is allowed to do in your program. When i don't use interrupts, no problem working with this LCD, with serout, serin, serout2, serin2, hserout and hserin!!
EDIT: grrr... Darrel.... get it first!!!!
Re: Serout2 on LCD Shows Junk Characters
Thanks Darrel & Gadelhas. Am I right in thinking RA0 is the USART tx pin on the PIC16F1825?
Re: Serout2 on LCD Shows Junk Characters
Yes. You can have TX on RA0 or RC4, because in this chips is possible to change between those 2 pins, by controlling the APFCON0 and APFCON1 registers.
Re: Serout2 on LCD Shows Junk Characters
If I'm using RA0, do I need to set those registers? Because without them the screen is completely blank:
Code:
'****************************************************************
'* Name : Test_SPWM.pbp *
'* Author : Darrel Taylor *
'* Date : 9/30/2006 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
; LCD serout2 command won't work when using interrupts; need to use
; HSEROUT on chip's USART tx pin instead.
' ***************************************************************
' Pin Connections
' ***************************************************************
' RA0 -> Serial LCD output
' RA1 -> Middle arm of trim pot (AN1)
' RC0 -> LED1
' RC1 -> LED2
' RC2 -> LED3
DEFINE OSC 16 ; Set oscillator 16Mhz
;DEFINE OSC 4 ; Set oscillator 4Mhz
DEFINE ADC_BITS 8 ; Set number of bits in result
DEFINE ADC_SAMPLEUS 5 ; Set sampling time in uS
DEFINE ADC_CLOCK 3 ; Set clock source (3=rc)
DEFINE HSER_TXSTA 20h ; Set transmit status and control register
DEFINE HSER_BAUD 2400 ; Set baud rate
' ***************************************************************
' Device Fuses
' ***************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
' ***************************************************************
' Initialization
' ***************************************************************
OSCCON = %01111000 ' 16MHz internal osc
;OSCCON = %01101000 ' 4MHz internal osc
pause 100
; Use PortA.1 (AN1) for ADCIN (trim pot reading)
ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only
TRISA = %00000010 ; Input on PORTA.1 (AN1) only
;ADCON1 = %01110000 ; Left-justified results in 8-bits; Fosc/8 (2uS @ 4Mhz)
ADCON1.7 = 0 ; Left-justified results in 8-bits; Fosc/8 (2uS @ 4Mhz)
ANSELC = 0 ; Diginal only for all PortC pins
TRISC = %00000000 ; Make all PORTC pins output
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
#IFDEF USE_LCD_FOR_DEBUG
LCD_PIN VAR PORTC.4 ' Alias PORTC.4 as "LCD_PIN"
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
LCD_BAUD CON 16780 ' Baud rate/mode 2600bps for ILM-216 2x16 character display
; LCD_BAUD CON 16468 ' Baud rate/mode 9600bps for ILM-216 2x16 character display
LCD_PACE CON 1 ' Optional pace value
#ENDIF
' ***************************************************************
' Includes
' ***************************************************************
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "SPWM_INT.bas" ; Software PWM module
DEFINE SPWM_FREQ 200 ; SPWM Frequency
DEFINE SPWM_RES 256 ; SPWM Resolution
DutyVars VAR BYTE[3] ; DutyCycle Variables
DutyVar1 VAR DutyVars[0] ; group them in an array for easy access
DutyVar2 VAR DutyVars[1] ; with FOR loops etc.
DutyVar3 VAR DutyVars[2]
ASM
SPWM_LIST macro ; Define Pin's to use for SPWM
SPWM_PIN PORTC, 0, _DutyVar1 ; and the associated DutyCycle variables
SPWM_PIN PORTC, 1, _DutyVar2 ; Notice the underscore before variables
SPWM_PIN PORTC, 2, _DutyVar3
endm
SPWM_INIT SPWM_LIST ; Initialize the Pins
ENDASM
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, SPWMhandler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
adval VAR WORD ; stores ADCIN results
oldDutyVar1 VAR WORD
;_____________________________________________________________________________
DutyVar1 = 0
DutyVar2 = 25
DutyVar3 = 255
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["DutyVar1=", DEC DutyVar1, 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF
Main:
ADCIN 1, adval
if adval <> oldDutyVar1 then
oldDutyVar1 = adval
DutyVar1 = adval
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [DEC DutyVar1, 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF
EndIf
Pause 100
Goto Main
Edit: Adding
Code:
APFCON0.2 = 1 ; Tx on RA0
makes the screen not blank, but it's still gobbledy-gook.
Re: Serout2 on LCD Shows Junk Characters
try with APFCON0.2 = 1, because the chip is initialized with TX on the RC4 pin, (APFCON0.2 = 0), so you must change it. datasheet page 123.
Re: Serout2 on LCD Shows Junk Characters
The Scott Edwards display is expecting Inverted serial levels.
The USART puts out True levels by default.
Add this setting ...
Code:
BAUDCON.4 = 1 ; Transmit inverted data to the TX/CK pin
Re: Serout2 on LCD Shows Junk Characters
Quote:
Originally Posted by
Darrel Taylor
The Scott Edwards display is expecting Inverted serial levels.
The USART puts out True levels by default.
Add this setting ...
Code:
BAUDCON.4 = 1 ; Transmit inverted data to the TX/CK pin
Thanks Darrel! It works now except the LCD shows a strange character in the 1st position (looks like "F1" with the "1" being a subscript).
Code:
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["DutyVar1=", DEC DutyVar1, 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF
Main:
ADCIN 1, adval
if adval <> oldDutyVar1 then
oldDutyVar1 = adval
DutyVar1 = adval
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR, LCD_L1]
HSEROUT ["DutyVar1=", DEC DutyVar1, " ", 13, 10] ' Send text followed by carriage return and linefeed
#ENDIF
EndIf
Pause 100
Goto Main
Re: Serout2 on LCD Shows Junk Characters
Quote:
HSEROUT [LCD_INST, LCD_CLR, LCD_L1]
You need at least a 2mS pause after the clear screen command.
Then you need another LCD_INST before the LCD_L1.
Or just leave out the LCD_L1 since the clear screen leaves the cursor on line 1.
Re: Serout2 on LCD Shows Junk Characters
I have a 5ms pause before the Main loop, but I think it's irrelevant since the ADCIN gets a value which is immediately different than the set value for DutyVar1 (set to 0 earlier in the code) and hence it goes straight into the IF block.
I'll add a 5ms pause in the IF block, too. And remove the LCD_L1 if it's not needed.
Thanks again, Darrel!