|
|
View previous topic :: View next topic |
Author |
Message |
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
PIC-EL III - FLEX LCD help? |
Posted: Tue Jul 06, 2010 7:26 pm |
|
|
I have a Pic El III demo board (www.kangaus.com/picel_iii.htm)
I know it is working properly, because when i run the diagnostics that came with it, everything checks out.
I am using a PIC 16F88A-E/P chip
PCM compiler version is 4.109
the LCD is HT44780 compatible, the RW line is used.
I can't seem to get the Flex lcd driver working.
Here is my test program
Code: |
#include <16F88.H>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP, MCLR, HS
#use delay(crystal=4Mhz)
#define LCD_DB4 PIN_B0
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_B2
#define LCD_DB7 PIN_B3
#define LCD_E PIN_B4
#define LCD_RW PIN_B5
#define LCD_RS PIN_B6
#include "flex_lcd.c"
//==========================
void main() {
setup_oscillator(OSC_4Mhz);
set_tris_b(0x00000000);
lcd_init(); // Always call this first.
delay_ms(8);
while (1) {
lcd_putc("\fHello World");
delay_ms(500);
lcd_putc("\nLine Number 2");
delay_ms(500);
}
}
|
symptoms
all dots in the 5x8 for each character position on LCD line 1 are black.
as i pass endlessly through the while loop, LCD line 2 alternates between totally blank, and a row where in every character position the top 3 rows of 5 dots are black and the bottom 5 rows are blank.
Been working in programming for 30 years, but sure can't figure this one out
Last edited by k0jdd on Wed Jul 07, 2010 7:58 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 06, 2010 8:44 pm |
|
|
1. Have you tried to make the board blink an LED, using the CCS compiler to make the program (not the built-in diagnostic program) ?
2. Are you putting the PGM/Run switch in the "run" position after
programming the PIC ? Have you tried pressing the Reset button
after doing so ?
3. Do you have a contrast circuit on Vo pin of the LCD ?
Is the contrast voltage set to about 0.4 volts ? |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
|
Posted: Wed Jul 07, 2010 5:45 am |
|
|
PCM programmer wrote: | 1. Have you tried to make the board blink an LED, using the CCS compiler to make the program (not the built-in diagnostic program) ? |
yes - if i insert this code before the lcd_init () i get a blinking LED - the LEDS and the LCD are multiplexed on a few pins
Code: | for (i=0 ; i<10; i++){
output_high(LCD_DB5);
output_high(LCD_DB6);
output_high(LCD_DB7);
delay_ms(500);
output_low(LCD_DB7);
delay_ms(500);
} |
Quote: | 2. Are you putting the PGM/Run switch in the "run" position after
programming the PIC ? Have you tried pressing the Reset button
after doing so ? |
yes to both
Quote: |
3. Do you have a contrast circuit on Vo pin of the LCD ?
Is the contrast voltage set to about 0.4 volts ? |
yes - the diagnostics would not run the LCD either if this was not set properly. btw diagnostics are not built in, they are on a PIC 16F628A which i insert into the Pic-El III
Last edited by k0jdd on Wed Jul 07, 2010 6:08 am; edited 1 time in total |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
update |
Posted: Wed Jul 07, 2010 6:08 am |
|
|
Just for grins I recompiled targeting the 16F628A that came with the diagnostics on it. Of course it works JUST FINE!
Guess I need to read-up on the 16F88A-E/P
Any thoughts? |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
No Joy... |
Posted: Wed Jul 07, 2010 5:25 pm |
|
|
Seems like a compiler bug is not the issue.
Compiler generates
Code: | .................... setup_adc(ADC_OFF);
0172: BCF 03.5
0173: BCF 1F.0
.................... setup_adc(NO_ANALOGS);
0174: BCF 1F.0
|
I added
Code: | #byte ADCON0 = 0x1F
#byte ANSEL = 0x9B
//=====================================
void main(void)
{
ADCON0 = 0; // Disable A/D converter
ANSEL = 0; // Set i/o pins to be all digital |
Any Ideas? Shall I post a complete .c and .LST file?
I would really like to use the 16F88 because I already have them in abundance and I need ADC functions for my project. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 07, 2010 7:04 pm |
|
|
Quote: |
yes - if i insert this code before the lcd_init () i get a blinking LED - the LEDS and the LCD are multiplexed on a few pins
Code:
for (i=0 ; i<10; i++){
output_high(LCD_DB5);
output_high(LCD_DB6);
output_high(LCD_DB7);
delay_ms(500);
output_low(LCD_DB7);
delay_ms(500);
}
|
1. Was this test above done with the 16F88 ?
2. Are you pretty sure that the 16F88 works on this board in all respects
except for the LCD ?
3. What's the silicon revision of your 16F88 ? Does your programmer
software report the rev ? (MPLAB with ICD2 does this).
4. What is the manufacturer and part number of your LCD ? |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
|
Posted: Wed Jul 07, 2010 7:31 pm |
|
|
PCM programmer wrote: |
1. Was this test above done with the 16F88 ? |
yes it was
Quote: |
2. Are you pretty sure that the 16F88 works on this board in all respects
except for the LCD ? |
as far as i can tell - i will try a different chip in the meantime
Quote: |
3. What's the silicon revision of your 16F88 ? Does your programmer
software report the rev ? (MPLAB with ICD2 does this | ).
I only have a pickit2 this is what it reports but I'm not sure this is what you needed
Code: | Initializing PICkit 2 version 0.0.3.63
Found PICkit 2 - Operating System Version 2.32.0
PICkit 2 Unit ID = OlHoss
Target power not detected - Powering from PICkit 2 ( 5.00V)
PIC16F88 found (Rev 0x8)
PICkit 2 Ready |
Quote: |
4. What is the manufacturer and part number of your LCD |
08LCD9 from ElectronixExpress.com |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 07, 2010 8:45 pm |
|
|
I tested your code with a 16F88 on my PicDem2-Plus board (non-Rohs
version) and it worked. I jumpered your pins over to the LCD pins on
the board. I tested it with vs. 4.109. I did have to unplug the ICD2
from the board to make it work. That's because you're using pin B6,
which is used by the ICD2. The documentation for your board says
that this isn't a problem, due to the design of your board. I don't have
the same external circuits as your board has.
My first thought is, re-install the compiler. |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
Still no joy |
Posted: Thu Jul 08, 2010 6:11 am |
|
|
uninstalled - rebooted - reinstalled from cd-rom
Same issues. I can't help think I am doing something wrong in my setup.
Can you email me your 16f88 source pgm and the hex file that worked for you?
First I can try the hex 'as is' which rules out both hardware and compiler
Then I can stare and compare your source.
I really appreciate the time you have spent on this... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 08, 2010 3:03 pm |
|
|
The source is the same as your source. The compiler version is the same.
Are you sure you're using the 16x2 "flex" driver in the code library ?
It's at this link. Make sure you're not using some modified version
of it that was posted elsewhere. Use this one:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661
Make sure you're not using the 16x1 or 20x4 flex drivers. Those are
at different links in the Code Library forum.
Also, you said you're using the R/W line. To use it, the following line
in the Flex driver code must be uncommented. It must look like this:
Code: |
#define USE_LCD_RW 1
|
CCS also has a Flex lcd driver. They added this capability to their lcd.c
driver file. The following program shows how to configure the pins for
their driver:
Code: |
#include <16F88.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(crystal=4Mhz)
#define LCD_DATA4 PIN_B0
#define LCD_DATA5 PIN_B1
#define LCD_DATA6 PIN_B2
#define LCD_DATA7 PIN_B3
#define LCD_ENABLE_PIN PIN_B4
#define LCD_RW_PIN PIN_B5
#define LCD_RS_PIN PIN_B6
// Use the CCS driver in c:\Program Files\Picc\Drivers
#include <lcd.c>
//==========================
void main()
{
lcd_init(); // Always call this first.
while(1)
{
lcd_putc("\fHello World");
delay_ms(500);
lcd_putc("\nLine Number 2");
delay_ms(500);
}
}
|
Does that work ? |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
Heavy Sigh.... |
Posted: Thu Jul 08, 2010 6:25 pm |
|
|
Using a PIC16F628A I can get the LCD to run using either the CCS lcd driver or the flex lcd driver.
Using a 16F88 I get the same old poor results...
(I thought for a moment it might be a low current to the LCD issue, so I switched to a wall wart from a battery pack with no effect.)
I received this input from the Pic-El designer, so I tried to mimic this setup as best as I understood it.
Code: |
A 16F88A-E/P works fine in the PIC-EL. I do this with a assembler, though. I
use these config tags in my app.
__config _CONFIG1, _INTRC_IO & _WDT_OFF & _BODEN_OFF & _LVP_OFF & _PWRTE_ON &
_CCP1_RB3 & _MCLR_OFF
__config _CONFIG2, _IESO_OFF & _FCMEN_OFF
Here is my initialization code (in assembler)
============
clrf INTCON ; No interrupts for now Any Bank
banksel OSCCON ; Switch to bank 1
movlw 0x70 ; Set IRCF<2:0> = 7 (for 8 MHz Internal Osc)
movwf OSCCON ; Bank 1
movlw 0x07 ; Code to turn off the analog comparitors
movwf CMCON ; Turn off comparators (CM2,CM1,CM0 = 1)
; (16F88-> Bank 1)
clrf ANSEL ; Turn off Analog ('88 ONLY) Bank 1
bcf OPTION_REG,NOT_RBPU ; Enable weak pullups (!RBPU) Bank 1
movlw b'11100111' ; RA3,4 Outputs, all others Inputs
movwf TRISA ; Bank 1
movlw b'10000000' ; Port B is
movwf TRISB ; all outputs except RB7 is input Bank 1
banksel PORTA ; Switch back to bank 0
;
; New code for timer 1 and interrupt.
;
movlw 0xC0 ; Get GIE and PEIE bits
movwf INTCON ; Enable general interrupts
banksel PIE1 ; Switch to bank 1 to enable timer 1
movlw 0x01 ; Get bit to enable timer 1 interrupt
movwf PIE1 ; Set TMR1IE
banksel PORTA ; Switch to bank 0
============
Hope this helps. You will have to change it to run your analog ports but this
may be a good starting point for getting the LCD to work.
Best Regards,
-Craig, AA0ZZ
|
Attached is my exact test program.
If you change a few lines you can switch between the two chip types and re-compile. (Note that in flex_lcd.c on my system I have commented out the pin defines at the beginning so they would not overwrite what was in my program.
Code: | #include <16F88.H>
#fuses XT, NOWDT, BROWNOUT, NOPUT, NOLVP
#use delay (internal=4MHz)
//defines for flex_lcd.c
#define LCD_DB4 PIN_B0
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_B2
#define LCD_DB7 PIN_B3
#define LCD_E PIN_B4
#define LCD_RW PIN_B5
#define LCD_RS PIN_B6
#define USE_LCD_RW 1
// defines for lcd.c
#define LCD_DATA4 PIN_B0
#define LCD_DATA5 PIN_B1
#define LCD_DATA6 PIN_B2
#define LCD_DATA7 PIN_B3
#define LCD_ENABLE_PIN PIN_B4
#define LCD_RW_PIN PIN_B5
#define LCD_RS_PIN PIN_B6
// Use the CCS driver in c:\Program Files\Picc\Drivers
//#include <lcd.c>
// use the flex_lcd.c driver in c:\Program Files\Picc\Drivers
#include <flex_lcd.c>
//==========================
void main()
{
setup_comparator(NC_NC_NC_NC);
// comment out next line for 16F628A - it has no ADC ports
setup_adc_ports(ALL_ANALOG);
set_tris_a(0x11100111);
set_tris_b(0x10000000);
port_b_pullups(true);
// flash a few LEDs
volatile int8 i;
for (i=0 ; i<3; i++){
output_high(LCD_DB5);
output_high(LCD_DB6);
output_high(LCD_DB7);
delay_ms(200);
output_low(LCD_DB7);
delay_ms(200);
}
lcd_init(); // Always call this first.
switch (restart_cause()){
case WDT_FROM_SLEEP: lcd_putc("\fWDT From Sleep");
break;
case WDT_TIMEOUT: lcd_putc("\fWDT Timeout");
break;
case MCLR_FROM_SLEEP: lcd_putc("\fMCLR From Sleep");
break;
case MCLR_FROM_RUN: lcd_putc("\fMCLR From Run");
break;
case NORMAL_POWER_UP: lcd_putc("\fNormal Power Up");
break;
case BROWNOUT_RESTART: lcd_putc("\fBrownout Restart");
break;
default: lcd_putc("\fUnknown");
}
delay_ms(2000);
while(1)
{
lcd_putc("\fHello World");
delay_ms(500);
lcd_putc("\nLine Number 2");
delay_ms(500);
}
} |
If Mr. PCM Programmer wants to take a crack at it, I am willing to send you my hardware. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 08, 2010 10:58 pm |
|
|
Ask him if he has code that will run a 16x2 LCD with the 16F88 on that
board (using the built-in LCD connector pins). Even if it's ASM code,
you could assemble it in MPLAB and at least prove that it works (or not). |
|
|
k0jdd
Joined: 06 Jul 2010 Posts: 13
|
Curiouser and Curiouser |
Posted: Fri Jul 09, 2010 6:03 pm |
|
|
I am 'this close' to concluding that the PIC16F88 will not work in my board in spite of what the designer says.
I googled up some 'hello world' ASM code (attached - apologies to Nigel)
Once again, when targeted for the 16F628A it works, but not on the 16F88.
Here is what is interesting.
On my board, there are LEDS multiplexed on the pins that drive the LCD data lines.
This ASM program is designed to spell out the messages one char at a time with delays in between. I slowed that way down. This allows me to visually track the LEDs as the program goes through the loops.
The LED patterns and timing on the 628A and the 88 are identical.
I can tell where the program is by the pattern and speed of the LEDs.
Is this an electrical problem? My completely uneducated speculation is that the LCD needs more voltage or current than the 16F88 can provide.
I am gonna ask the designer to try this code on his board.
One final thought. Any idea what the difference between 16F88-E/P(automotive spec) and 16F88-I/P (industrial spec) is besides cost and temp range. (Do I have the wrong stupid part!!!!)
Any other ideas out there in PIC land? I am truly stumped.
K0JDD
Code: | ;LCD text demo - 4 bit mode
;Nigel Goodwin 2002
; LIST p=16F628A ;tell assembler what chip we are using
; include "P16F628A.inc" ;include the defaults for the chip
LIST p=16F88 ;tell assembler what chip we are using
include "P16F88.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
; __config _WDT_OFF & _XT_OSC & _LVP_OFF
__config _CONFIG1, _WDT_OFF & _XT_OSC & _LVP_OFF & _DEBUG_OFF ;sets the configuration settings (oscillator type etc.)
__config _CONFIG2, _FCMEN_OFF & _IESO_OFF
cblock 0x20 ;start of general purpose registers
count ;used in looping routines
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
tmp1 ;temporary storage
tmp2
templcd ;temp store for 4 bit mode
templcd2
endc
LCD_PORT Equ PORTB
LCD_TRIS Equ TRISB
LCD_RS Equ 0x06 ;LCD handshake lines
LCD_RW Equ 0x05
LCD_E Equ 0x04
org 0x0000
; clrf ANSEL
movlw 0x07
movwf CMCON ;turn comparators off (make it like a 16F84)
Initialise clrf count
clrf PORTA
clrf PORTB
SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x00 ;make all pins outputs
movwf LCD_TRIS
bcf STATUS, RP0 ;select bank 0
call Delay100 ;wait for LCD to settle
call LCD_Init ;setup LCD
clrf count ;set counter register to zero
Message movf count, w ;put counter value in W
call Text ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto NextMessage
call LCD_Char
call Delay255
call Delay255
call Delay255
call Delay255
incf count, f
goto Message
NextMessage call LCD_Line2 ;move to 2nd row, first column
clrf count ;set counter register to zero
Message2 movf count, w ;put counter value in W
call Text2 ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
goto EndMessage
call LCD_Char
call Delay255
incf count, f
goto Message2
EndMessage
Stop goto Initialise ;endless loop
;Subroutines and text tables
;LCD routines
;Initialise LCD
LCD_Init
movlw 0x03
call LCD_Cmd
movlw 0x03
call LCD_Cmd
movlw 0x03
call LCD_Cmd
movlw 0x02
call LCD_Cmd
movlw 0x20 ;Set 4 bit mode
call LCD_Cmd
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
call LCD_Clr ;clear display
retlw 0x00
; command set routine
LCD_Cmd movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
call Delay5
retlw 0x00
LCD_CharD addlw 0x30
LCD_Char movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call Delay5
retlw 0x00
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
retlw 0x00
LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
retlw 0x00
LCD_Line1W addlw 0x80 ;move to 1st row, column W
call LCD_Cmd
retlw 0x00
LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
call LCD_Cmd
retlw 0x00
LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
retlw 0x00
LCD_HEX movwf tmp1
swapf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
movf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
retlw 0x00
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
Pulse_e bsf LCD_PORT, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00
;end of LCD routines
HEX_Table ADDWF PCL , f
RETLW 0x30
RETLW 0x31
RETLW 0x32
RETLW 0x33
RETLW 0x34
RETLW 0x35
RETLW 0x36
RETLW 0x37
RETLW 0x38
RETLW 0x39
RETLW 0x41
RETLW 0x42
RETLW 0x43
RETLW 0x44
RETLW 0x45
RETLW 0x46
Text addwf PCL, f
retlw 'H'
retlw 'e'
retlw 'l'
retlw 'l'
retlw 'o'
retlw 0x00
Text2 ADDWF PCL, f
RETLW 'R'
RETLW 'e'
RETLW 'a'
RETLW 'd'
RETLW 'y'
RETLW '.'
RETLW '.'
RETLW '.'
RETLW 0x00
end
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 09, 2010 6:16 pm |
|
|
I was reluctant to suggest this, because I don't know how good you are
at soldering and rework. If you don't have the skills or the rework
station, you could burn off or tear up the pads on your board.
But...
1. Isolate all circuits on the board from the LCD.
Warm up the solder on one leg of each LED resistor and pull it the leg up
so it's not in contact with the pad. You need the FET circuits in place to
program the PIC, so you can't remove them. But you could at least
move the LCD pin from pin B6 to some other pin.
or,
2. Try breadboarding the 16F88 and LCD on a 3M protostrip. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|