|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
Problems Driving an LCD with the PIC18F8490 |
Posted: Wed Sep 14, 2005 2:14 pm |
|
|
I cannot get the lcd to display anything. This program should just count up too 1999 and then start over again. Any ideas...
Code: |
#include <18F8490.h>
#device adc=10
#FUSES WDT32 //Watch Dog Timer uses 1:32 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV28 //Brownout reset at 2.8V
#FUSES NOPUT //No Power Up Timer
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOMCLR //Master Clear pin enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=1000000)
/////////////////////////////////////////////////////////////////////////////////////////
// LCD Configuration //
/////////////////////////////////////////////////////////////////////////////////////////
// Digit segments A B C D E F G DP
// b7 b6 b5 b4 b3 b2 b1 b0
#define DIGIT1 COM1+38, COM0+31, COM1+31, COM1+37, COM0+37, COM0+35, COM0+47, COM1+36
#define DIGIT2 COM0+1, COM0+2, COM1+2, COM1+3, COM1+0, COM0+0, COM1+1, COM0+3
#define DIGIT3 COM0+5, COM0+6, COM1+6, COM1+7, COM1+4, COM0+4, COM1+5, COM0+7
#define DIGIT4 COM0+33, COM0+34, COM1+34, COM1+35, COM1+32, COM0+32, COM1+33, COM0+35 // DP=X2
//
// character 0 1 2 3 4 5 6 7 8 9
byte const Digit_Map[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6};
#define BLANK 0
#define DASH 11
/////////////////////////////////////////////////////////////////////////////////////////
void test();
byte lcd_pos;
void main() {
setup_oscillator(OSC_1MHZ|OSC_INTRC);
//setup_oscillator(OSC_1MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
setup_wdt(WDT_ON);
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_spi(SPI_SLAVE|SPI_SS_DISABLED);
//setup_lcd(LCD_MUX12);
//enable_interrupts(INT_RB);
//enable_interrupts(INT_SSP);
//enable_interrupts(GLOBAL);
setup_low_volt_detect(FALSE);
test();
}
void lcd_putc(char c) {
byte segments;
if(c=='\f')
lcd_pos=0;
else {
if((c>='0')&&(c<='9'))
segments=Digit_Map[c-'0'];
else
segments=BLANK;
switch(lcd_pos) {
case 1 : lcd_symbol(segments,DIGIT4); break; // fill 1000s place
case 2 : lcd_symbol(segments,DIGIT3); break; // fill 100s place
case 3 : lcd_symbol(segments,DIGIT2); break; // fill 10s place
case 4 : lcd_symbol(segments,DIGIT1); break; // fill 1s place
}
}
lcd_pos++;
}
void test() {
long number = 0;
setup_lcd(LCD_MUX12,4,ALL_LCD_PINS);
while(TRUE) {
printf(lcd_putc,"\f%4lu",number);
if(number++==1999)
number=0;
delay_ms(1000);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 14, 2005 2:57 pm |
|
|
You're using the Watchdog Timer but you're never restarting it
with the restart_wdt() function.
I suggest that you disable the Watchdog Timer while you're
testing the LCD functions.
Also, a 1 MHz clock speed is incredibly slow. Are you sure you
want to run at such a slow speed ? |
|
|
Guest
|
|
Posted: Wed Sep 14, 2005 3:07 pm |
|
|
I have disabled the wdt, but still no luck.
Power consumption is very important, so I have the clock speed low.
This isn't the actual code I will use, but just an example to verify everything is working. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 14, 2005 3:23 pm |
|
|
What version of PCH are you using ? This will be a number like 3.191
or 3.234, etc. You'll find it at the top of the .LST file which is created
when you compile a program. |
|
|
Guest
|
|
Posted: Wed Sep 14, 2005 3:27 pm |
|
|
CCS PCH C Compiler, Version 3.210, 25442 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 14, 2005 3:45 pm |
|
|
I don't have that version. I didn't renew my PCH subscription until
just recently. If I did have it, I would check the .LST file to see if
the LCD functions work properly with your version.
CCS has this statement on their versions page:
Quote: | 3.223 LCD support for the newest parts with direct LCD drive has been added |
I don't know if your PIC is supported by vs. 3.210. You could email
CCS and ask them, or you could post the portion of your .LST file
that pertains to these two lines and I could see if it looks correct.
I would compare it to the code from vs. 3.234 and to the data sheet.
Code: | setup_lcd(LCD_MUX12,4,ALL_LCD_PINS);
case 1 : lcd_symbol(segments,DIGIT4); break; |
|
|
|
Guest
|
|
Posted: Wed Sep 14, 2005 3:56 pm |
|
|
I sent them an e-mail, but here is that part of the file. Thanks!
.................... setup_lcd(LCD_MUX12,4,ALL_LCD_PINS);
03FA: MOVLW 81
03FC: MOVLB 1
03FE: MOVWF x0F
0400: MOVLW 04
0402: MOVWF x0E
0404: MOVLW FF
0406: MOVWF x0D
....................
.................... case 1 : lcd_symbol(segments,DIGIT4); break; // fill 1000s place
0056: MOVFF 12,00
005A: BTFSC 12.7
005C: BRA 0064
005E: MOVLB 1
0060: BCF x14.1
0062: MOVLB 0
0064: BTFSS 00.7
0066: BRA 006E
0068: MOVLB 1
006A: BSF x14.1
006C: MOVLB 0
006E: BTFSC 00.6
0070: BRA 0078
0072: MOVLB 1
0074: BCF x14.2
0076: MOVLB 0
0078: BTFSS 00.6
007A: BRA 0082
007C: MOVLB 1
007E: BSF x14.2
0080: MOVLB 0
0082: BTFSC 00.5
0084: BRA 008C
0086: MOVLB 1
0088: BCF x18.2
008A: MOVLB 0
008C: BTFSS 00.5
008E: BRA 0096
0090: MOVLB 1
0092: BSF x18.2
0094: MOVLB 0
0096: BTFSC 00.4
0098: BRA 00A0
009A: MOVLB 1
009C: BCF x18.3
009E: MOVLB 0
00A0: BTFSS 00.4
00A2: BRA 00AA
00A4: MOVLB 1
00A6: BSF x18.3
00A8: MOVLB 0
00AA: BTFSC 00.3
00AC: BRA 00B4
00AE: MOVLB 1
00B0: BCF x18.0
00B2: MOVLB 0
00B4: BTFSS 00.3
00B6: BRA 00BE
00B8: MOVLB 1
00BA: BSF x18.0
00BC: MOVLB 0
00BE: BTFSC 00.2
00C0: BRA 00C8
00C2: MOVLB 1
00C4: BCF x14.0
00C6: MOVLB 0
00C8: BTFSS 00.2
00CA: BRA 00D2
00CC: MOVLB 1
00CE: BSF x14.0
00D0: MOVLB 0
00D2: BTFSC 00.1
00D4: BRA 00DC
00D6: MOVLB 1
00D8: BCF x18.1
00DA: MOVLB 0
00DC: BTFSS 00.1
00DE: BRA 00E6
00E0: MOVLB 1
00E2: BSF x18.1
00E4: MOVLB 0
00E6: BTFSC 00.0
00E8: BRA 00F0
00EA: MOVLB 1
00EC: BCF x14.3
00EE: MOVLB 0
00F0: BTFSS 00.0
00F2: BRA 00FA
00F4: MOVLB 1
00F6: BSF x14.3
00F8: MOVLB 0
00FA: BCF FD8.6
00FC: BRA 02F6
.................... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 14, 2005 4:05 pm |
|
|
In PCH vs. 3.234, it doesn't even have the segment pins defined
in the 18F8490.H file. I noticed that immediately because it gave
me an error on the ALL_LCD_PINS symbol.
This is all that it has. I question whether this version works with
the 18F8490.
Code: | // LCD Functions: SETUP_LCD, LCD_SYMBOL, LCD_LOAD
// Constants used in setup_lcd() are:
#define LCD_DISABLED 0
#define LCD_STATIC 0x80
#define LCD_MUX12 0x81
#define LCD_MUX13 0x82
#define LCD_MUX14 0x83
#define STOP_ON_SLEEP 0x40
#define USE_TIMER_1 0x04
#define INTRC 0x08
#define LCD_HALF_BIAS 0x4000
#define LCD_TYPE_B_WAVE 0x8000
// Constants used in lcd_symbol() are:
#define COM0 0
#define COM1 48
#define COM2 96
#define COM3 144 |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 14, 2005 4:40 pm |
|
|
I compiled the setup_lcd() function in your program for the 16C923
with PCM vs. 3.234. It's moving 0x81 into register 0x10F, which is
the LCDCON register. It's also writing to registers 0x10E and 0x10D,
which are LCD registers for that PIC. See below:
Code: |
0000 00848 ... setup_lcd(LCD_MUX12,4,ALL_LCD_PINS);
01EC 3081 00849 MOVLW 81
01ED 1703 00850 BSF 03.6
01EE 008F 00851 MOVWF 0F
01EF 3004 00852 MOVLW 04
01F0 008E 00853 MOVWF 0E
01F1 30FF 00854 MOVLW FF
01F2 008D 00855 MOVWF 0D
|
Here's your code, below. It's writing to registers at the same addresses.
But there's a problem. The LCD registers in the 18F8490 are not at
0x10F, etc. LCDCON is at 0xF59. The others are in the same region.
So this explains (in part) why your program doesn't run.
Code: |
.... setup_lcd(LCD_MUX12,4,ALL_LCD_PINS);
03FA: MOVLW 81
03FC: MOVLB 1
03FE: MOVWF x0F
0400: MOVLW 04
0402: MOVWF x0E
0404: MOVLW FF
0406: MOVWF x0D
|
I then compiled the same line with PCH vs. 3.234. As I said in my
previous post, the .H file is missing the "ALL_LCD_PINS" definition,
so I just stuck 255 in there to get it to compile. This version at
least is writing to the correct register addresses.
Code: | .................... setup_lcd(LCD_MUX12, 4, 255);
003A: MOVLW 81
003C: MOVWF x59
003E: MOVLW 24
0040: MOVWF x58 |
So if you want to use the 18F8490 with your version of the compiler, you'll
have to setup the registers manually, with code. If you upgrade, there's
no guarantee (IMO) that it will work with the 18F8490. I didn't go
through all the lcd functions for that chip in detail to see if they work.
Also there's the issue of the missing segment definitions in the
18F8490.H file. CCS ought to fix that. |
|
|
Guest
|
|
Posted: Thu Sep 15, 2005 6:38 am |
|
|
Thats strange. The code below is from my 18F8490.h file. When I compile it in the PCW Compiler, it works...when I try and compile it through MPLAB it doesnt. I get the same error message saying it doesn't know what ALL_LCD_PINS is.
Code: |
////////////////////////////////////////////////////////////////// LCD
// LCD Functions: SETUP_LCD, LCD_SYMBOL, LCD_LOAD
// Constants used in setup_lcd() are:
#define LCD_DISABLED 0
#define LCD_STATIC 0x80
#define LCD_MUX12 0x81
#define LCD_MUX13 0x82
#define LCD_MUX14 0x83
#define STOP_ON_SLEEP 0x40
#define USE_TIMER_1 0x04
#define SEG0_4 1
#define SEG5_8 2
#define SEG9_11 4
#define SEG12_15 8
#define SEG16_19 16
#define SEG20_26 32
#define SEG27_28 64
#define SEG29_31 128
#define ALL_LCD_PINS 255
// Constants used in lcd_symbol() are:
#define COM0 0
#define COM1 32
#define COM2 64
#define COM3 96
|
As far as the registers being wrong, how do I fix this? |
|
|
Guest
|
|
Posted: Thu Sep 15, 2005 8:33 am |
|
|
Another thing I noticed is that for the 18F6490, there are 32 segments for the lcd. For the 18F8490 there are 48 segments.
From the 18F8490.h file it only goes up to 32 segments.
Code: |
#define SEG0_4 1
#define SEG5_8 2
#define SEG9_11 4
#define SEG12_15 8
#define SEG16_19 16
#define SEG20_26 32
#define SEG27_28 64
#define SEG29_31 128
#define ALL_LCD_PINS 255
|
|
|
|
Guest
|
|
Posted: Fri Sep 16, 2005 8:31 am |
|
|
It works now. The new PCH updated the function contents. There was still no help on how to use them, so I just configured the lcd like this:
Code: |
setup_lcd(0b10001101, 0b01110000); // The 3rd location isn't used for this device.
|
|
|
|
|
|
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
|