|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jan 31, 2008 6:18 pm |
|
|
Here is the driver that I did for the PicDem LCD board. It's based on
the CCS example driver file, Ex_92lcd.c. I don't have that board, so
I can't test this driver in hardware. But I looked at all the documentation
available, so I think it has a good chance to work.
The #define statements for the digits (DIGIT8_H, etc.) were determined
by looking at the #defines in lcdboard.inc (from the PicDem LCD sample
files) and Table 22-6 in the 18F8490 data sheet. I had to make two
#define statements for each digit in the LCD (_H and _L) because the
lcd_symbol() function has a bug in 16-bit mode in vs. 4.066. But it
works if you use 8-bit mode. That's why in the switch-case statement
you'll see two calls to lcd_symbol for each digit. Half of the segments
in each digit are done in each call.
The Digit_Map values were determined by realizing that CCS left-justifies
the digit segments in a 16-bit word, with segment 'a' being in bit 15.
As you can see below, I made a drawing of a 14-segment digit and then
added the bit numbers in place of the letter names for the segments.
This page shows what 14-segment numbers should look like (0 to 9).
See the middle drawing on this page:
http://www.altia.com/demos/libraries/infotainment/infotainment_fonts.htm
While looking at that drawing, I was able to determine what segments
to "turn on" for each digit. I wrote them down in binary format, as
shown below. Then I converted the binary values into 16-bit hex, and
put those values into the Digit_Map[] array.
This program uses INTRC_IO oscillator mode, at 8 MHz. That's because
the PicDem LCD board also does that. The values that are calculated for
the setup_lcd() statement depend upon the oscillator frequency. The
sample ASM code for the PicDem LCD board (from Microchip) calculates
the values at compile-time with several equations. I didn't want to
bother with that, so I just hard-coded the setup_lcd() value for the 8 MHz
internal oscillator.
Code: |
#include <18F8490.h>
#fuses INTRC_IO,NOWDT,NOPROTECT
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// A B C D E F G H
#define DIGIT8_H COM0+28, COM1+28, COM2+28, COM3+31, COM2+31, COM1+31, COM1+30, COM0+30
#define DIGIT8_L COM0+29, COM1+29, COM2+29, COM2+30, COM3+30, COM3+29, COM3+28, COM0+31
// I J K L M N 8DP 9X
#define DIGIT7_H COM0+24, COM1+24, COM2+24, COM3+27, COM2+27, COM1+27, COM1+26, COM0+26
#define DIGIT7_L COM0+25, COM1+25, COM2+25, COM2+26, COM3+26, COM3+25, COM3+24, COM0+27
#define DIGIT6_H COM0+20, COM1+20, COM2+20, COM3+23, COM2+23, COM1+23, COM1+22, COM0+22
#define DIGIT6_L COM0+21, COM1+21, COM2+21, COM2+22, COM3+22, COM3+21, COM3+20, COM0+23
#define DIGIT5_H COM0+16, COM1+16, COM2+16, COM3+19, COM2+19, COM1+19, COM1+18, COM0+18
#define DIGIT5_L COM0+17, COM1+17, COM2+17, COM2+18, COM3+18, COM3+17, COM3+16, COM0+19
#define DIGIT4_H COM0+12, COM1+12, COM2+12, COM3+15, COM2+15, COM1+15, COM1+14, COM0+14
#define DIGIT4_L COM0+13, COM1+13, COM2+13, COM2+14, COM3+14, COM3+13, COM3+12, COM0+15
#define DIGIT3_H COM0 +8, COM1 +8, COM2 +8, COM3+11, COM2+11, COM1+11, COM1+10, COM0+10
#define DIGIT3_L COM0 +9, COM1 +9, COM2 +9, COM2+10, COM3+10, COM3 +9, COM3 +8, COM0+11
#define DIGIT2_H COM0 +4, COM1 +4, COM2 +4, COM3 +7, COM2 +7, COM1 +7, COM1 +6, COM0 +6
#define DIGIT2_L COM0 +5, COM1 +5, COM2 +5, COM2 +6, COM3 +6, COM3 +5, COM3 +4, COM0 +7
#define DIGIT1_H COM0 +0, COM1 +0, COM2 +0, COM3 +3, COM2 +3, COM1 +3, COM1 +2, COM0 +2
#define DIGIT1_L COM0 +1, COM1 +1, COM2 +1, COM2 +2, COM3 +2, COM3 +1, COM3 +0, COM0 +3
// Digit numbers:
// 8 7 6 5 4 3 2 1
// ----- ----- ----- ----- ----- ----- ----- -----
// |\|/| |\|/| |\|/| |\|/| |\|/| |\|/| |\|/| |\|/|
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// |/|\| |/|\| |/|\| |/|\| |/|\| |/|\| |/|\| |/|\|
// ----- ----- ----- ----- ----- ----- ----- -----
//
// Segment Segment bit
// letters: numbers:
//
// a 15
// ------- -------
// |\ i| /| |\ 7| /|
// f| \ | / |b 10| \ | / |14
// | h\|/j | | 8\|/6 |
// g--- ---k 9--- ---5
// | l/|\n | | 4/|\2 |
// e| / | \ |c 11| / | \ |13
// |/ m| \| |/ 3| \|
// ------- -------
// d 12
//
// Segment bit numbers: Segment
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 hex code:
// 0 1 1 1 1 1 1 - - - 1 - 1 - - - - 0xFC50
// 1 - 1 1 - - - - - - - - - - - - - 0x6000
// 2 1 1 - 1 1 - 1 - - - 1 - - - - - 0xDA20
// 3 1 1 1 1 - - 1 - - - 1 - - - - - 0xF220
// 4 - 1 1 - - 1 1 - - - 1 - - - - - 0x6620
// 5 1 - 1 1 - 1 1 - - - 1 - - - - - 0xB620
// 6 1 - 1 1 1 1 1 - - - 1 - - - - - 0xBE20
// 7 1 1 1 - - - - - - - - - - - - - 0xE000
// 8 1 1 1 1 1 1 1 - - - 1 - - - - - 0xFE20
// 9 1 1 1 1 - 1 1 - - - 1 - - - - - 0xF620
//
//
int16 const Digit_Map[10] =
{0xFC50,0x6000,0xDA20,0xF220,0x6620,0xB620,0xBE20,0xE000,0xFE20,0xF620};
// 0 1 2 3 4 5 6 7 8 9
#define BLANK 0 // For a blank digit, don't turn on any segments.
int8 lcd_pos = 0;
//-----------------------------------------------
void lcd_putc(char c)
{
int16 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: // Digit on left side of LCD.
lcd_symbol(segments >> 8, DIGIT8_H);
lcd_symbol(segments, DIGIT8_L);
break;
case 2:
lcd_symbol(segments >> 8, DIGIT7_H);
lcd_symbol(segments, DIGIT7_L);
break;
case 3:
lcd_symbol(segments >> 8, DIGIT6_H);
lcd_symbol(segments, DIGIT6_L);
break;
case 4:
lcd_symbol(segments >> 8, DIGIT5_H);
lcd_symbol(segments, DIGIT5_L);
break;
case 5:
lcd_symbol(segments >> 8, DIGIT4_H);
lcd_symbol(segments, DIGIT4_L);
break;
case 6:
lcd_symbol(segments >> 8, DIGIT3_H);
lcd_symbol(segments, DIGIT3_L);
break;
case 7:
lcd_symbol(segments >> 8, DIGIT2_H);
lcd_symbol(segments, DIGIT2_L);
break;
case 8: // Digit on right side of LCD.
lcd_symbol(segments >> 8, DIGIT1_H);
lcd_symbol(segments, DIGIT1_L);
break;
}
}
lcd_pos++;
}
//-------------------------------------------
void clear_lcd(void)
{
int16 addr;
int8 i;
addr = 0xF60; // LCDDATA0 register address
for(i=0; i < 24; i++) // Clear the LCD data registers
*addr++ = 0;
}
//==================================
void main(void)
{
int32 number;
clear_lcd();
setup_lcd(LCD_MUX14 | LCD_INTRC, 2);
number = 12345678;
printf(lcd_putc,"\f%8lu", number);
while(1);
} |
|
|
|
cbarberis
Joined: 01 Oct 2003 Posts: 172 Location: Punta Gorda, Florida USA
|
|
Posted: Fri Feb 01, 2008 10:38 am |
|
|
PCM programmer, I don't know how to thank you for all the time you have invested to solve and answer the above, I really appreciate this and I am sure many others like me, who first experience using the PICDEM LCD with the CCS compiler will also be thankful to you............THANK YOU |
|
|
cbarberis
Joined: 01 Oct 2003 Posts: 172 Location: Punta Gorda, Florida USA
|
|
Posted: Fri Feb 01, 2008 12:34 pm |
|
|
BTW I tested it on the PICDEM LCD board and it all works fine! |
|
|
SolarGuy Guest
|
Thanks PCM |
Posted: Sat Mar 06, 2010 7:06 pm |
|
|
Thanks a million for this source code for the PicDem LCD.
I have a project in which I am trying to use the LCD.
These routines work perfect with the included 18F8490.
SG |
|
|
|
|
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
|