CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help with 2.5 Digit 7-Segment LCD Code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

Help with 2.5 Digit 7-Segment LCD Code
PostPosted: Thu Apr 18, 2013 8:21 pm     Reply with quote

The following code was compiled in CCS and counts from 0-9 w/ output to the following LCD (Common Cathode)

http://www.lumex.com/specs/LCD-S2X1C50TR.pdf

This code works but I'm trying to make two modifications:

1) Add a second digit without multiplexing
2) Substitute a 2 or 3 digit variable instead of the counter

The PIC has a built in LCD controller (16F914).

Any help in terms of how this might be coded would be greatly appreciated.

Thanks!

Code:


/*  Connections
Seg   Port   
A1 – RC1
B1 – RC2
C1 – RC4
D1 – RC3
E1 – RB4
F1 – RB1
G1 – RB0
 
A2 – RD1
B2 – RD7
C2 – RD4
D2 – RD3
E2 – RD5
F2 – RD6
G2 – RD0
1BC – RD6
Com/Cath - Gnd
*/
#include <16F914.h>
#use delay (clock=4000000) // oscillator frequency for delay_ms()
 
/***** CONFIGURATION *****/
// ext reset, no code protect, no watchdog, 4 MHz int clock
#fuses MCLR,NOPROTECT,NOWDT,INTRC_IO
 
/***** LOOKUP TABLES *****/
 
// pattern table for 7 segment display on ports B and C
const int8 pat7seg[10] = {
// RC4:1,RB4,RB1:0 = CDBAEFG
0b1111110, // 0
0b1010000, // 1
0b0111101, // 2
0b1111001, // 3
0b1010011, // 4
0b1101011, // 5
0b1101111, // 6
0b1011000, // 7
0b1111111, // 8
0b1111011 // 9
};
/***** MAIN PROGRAM *****/
void main()
{
unsigned int8 digit; // digit to be displayed
//*** Initialization
// configure ports
setup_adc_ports(NO_ANALOGS); // disable all analog and comparator inputs
setup_comparator(NC_NC_NC_NC); // -> RB0, RB1, RC0, RC1 digital
 
//*** Main loop
while (TRUE)
{
// display each digit from 0 to 9 for 1 sec
for (digit = 0; digit < 20; digit++)
{
// display digit by extracting pattern bits for all pins
output_b((pat7seg[digit] & 1<<2) << 2 | // RB4
(pat7seg[digit] & 0b00000011)); // RB0-1
output_c((pat7seg[digit] >> 2) & 0b011110); // RC1-4
// delay 1 sec
delay_ms(1000);
}
}
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 18, 2013 10:07 pm     Reply with quote

Quote:
The following code was compiled in CCS and counts from 0-9 w/ output to the following LCD (Common Cathode)
http://www.lumex.com/specs/LCD-S2X1C50TR.pdf

Com/Cath - Gnd

The link is not to a common-cathode led display. The link is an LCD.
LCD's don't have a common-cathode. They have a COM pin, which
must have continuous signal on it. A 7-segment LED display would
have a common-cathode pin which could be connected to ground,
as you are doing.

Quote:
The PIC has a built in LCD controller (16F914).

It does, but you're not using it, and you very likely don't have an
lcd, so you can't use the built-in controller. Your current program
drives i/o pins on the PIC with code.
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 4:05 am     Reply with quote

Yes, thanks for the clarification. Will change com pin but looking for help on solving the two issues stated - conceptually or example code based on a pin to pin setup. Thanks!
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 4:30 am     Reply with quote

..it is definitely a 7 segment non multiplexed LCD. Are you saying that this LCD cannot be (properly) driven on a pin to segment basis? (count up & output are working now up to 9).
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 5:06 am     Reply with quote

You've got me rather confused.

1) I'm assuming that you really are using a static driven LCD display.
2) The data sheet, you link to, is not crystal clear about how to drive it.
3) You say 0-9 works, we have to assume that COM to 0V is OK.
4) You've got TWO LCD pins connected to RD6!
5) You've got the LCD segments wired in different order for the separate digits.
6) You could create a driver for the second digit, but you're making it difficult.
7) Do one task at a time.
8) Sort out the LCD drive first, then worry enhancements.

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9244
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 5:34 am     Reply with quote

I used similar displays in the past(3/4" tall aka DMM size).When you read the datasheet you'll see it's direct drive(PIC i/o pin per segment is OK), but operating voltage is AC.
The COM terminal is supposed to be fed from an alternating source.Simply use a PWM output to feed it, or just toggle an I/O pin will do.Something around 100HZ should work fine.
If you just tie it to ground then over time you'll 'burn' the segments into the display,similar to CRTs and plasma displays.It could take months of use though, all depends on how long a segment is on for.So for 'test' purposes, it'd be OK to just ground COM,getting your program 'up and running'.

hth
jay
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 8:05 am     Reply with quote

Quote:
I used similar displays in the past(3/4" tall aka DMM size).When you read the datasheet you'll see it's direct drive(PIC i/o pin per segment is OK), but operating voltage is AC.
So:-

1) Mean DC voltage from any segment to common must be ~zero.
2) Common goes up and down with 50% duty. (Say @ 100Hz.)
3) Off segments go up and down in phase with common.
4) On segments go up and down out of phase with common.

Mike
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 9:24 am     Reply with quote

Thanks all for the help - I'm obviously new at this. Based on the comments, it seems it may be best to start over and use the static 7-segment LCD capabilities of the PIC.

PCM Programmer - I was searching for code to accomplish the above and came across code you posted several years ago. It compiles fine and I can modify for 2.5 vs 3 digits (I hope Smile ) . Are the +numbers (i.e.COM0+16) the segment it is connected to on the PIC? With this code, which pin would the COM from the LCD go to?

Code:

// Digit segments  A        B        C        D        E        F        G       
//                 b7       b6       b5       b4       b3       b2       b1       
#define DIGIT3  COM0+16, COM0+17, COM0+18, COM0+19, COM0+20, COM0+21, COM0+22
#define DIGIT2  COM0+8,  COM0+9,  COM0+10, COM0+11, COM0+12, COM0+13, COM0+14
#define DIGIT1  COM0+0   COM0+1,  COM0+2,  COM0+3,  COM0+4,  COM0+5,  COM0+6


//                            0    1    2    3    4    5    6    7    8    9
int8 const Digit_Map[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xE6};


#define BLANK 0  // For a blank digit, don't turn on any segments.


#byte LCDDATA0 = 0x110
#byte LCDDATA1 = 0x111
#byte LCDDATA2 = 0x112


// These functions allow you to turn each decimal point On/Off.
#define display_DP2(x) x ? bit_set(LCDDATA0, 7) : bit_clear(LCDDATA0, 7)
#define display_DP3(x) x ? bit_set(LCDDATA1, 7) : bit_clear(LCDDATA1, 7)
#define display_DP4(x) x ? bit_set(LCDDATA2, 7) : bit_clear(LCDDATA2, 7)


int8 lcd_pos = 1;

//-----------------------------------------------
// This function was revised to add decimal points.

void lcd_putc(char c)
{
int8 segments;

if(c == '\f')
  {
   lcd_pos = 1;
   return;
  }

if(c == '.')
  {
   switch(lcd_pos)
     {
      case 1:
        display_DP4(TRUE);
        display_DP3(FALSE);
        display_DP2(FALSE);
        break;

      case 2:
        display_DP4(FALSE);
        display_DP3(TRUE);
        display_DP2(FALSE);
        break;

      case 3:
        display_DP4(FALSE);
        display_DP3(FALSE);
        display_DP2(TRUE);
        break;
     }
  }

if(isamong(c, " 0123456789"))
  {
   if(c == ' ')
      segments = BLANK;
   else
      segments = Digit_Map[c - '0'];

   switch(lcd_pos)
     {
      case 1: lcd_symbol(segments, DIGIT3); break; // 100's digit
      case 2: lcd_symbol(segments, DIGIT2); break; // 10's digit
      case 3: lcd_symbol(segments, DIGIT1); break; // 1's digit
     }

   lcd_pos++;
  }

}

//---------------------------
void clear_lcd(void)
{
LCDDATA0 = 0;
LCDDATA1 = 0;
LCDDATA2 = 0;
}


//===================================
void main()
{
// Setup for a static LCD and enable all 24 segment pins.
setup_lcd(LCD_STATIC, 0, 0xFFFFFF);
clear_lcd();

lcd_putc("\f1.23");

while(1);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 2:21 pm     Reply with quote

Two things.

First, it would have been a courtesy to post a link to where you got
that code. Then I wouldn't have had to go search for it.
(Since you only posted a fragment of it). This is it:
http://www.ccsinfo.com/forum/viewtopic.php?t=32774&start=40

2nd thing, you want to know what pin is COM0 on the PIC.
A good place to start would be, you know, the 16F914 data sheet.
Go to Google, type in PIC16F914 and you'll get a link to it.
Download the PDF, and look at the pin diagram which is always in
the first few pages. Find the pin that's labeled COM0.
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 3:36 pm     Reply with quote

With all due respect, I asked what where the common pin was attached - not where COM0 was on the PIC. I understand that had I had more knowledge I would have known that the common was supposed to go to COM0 - Pin 37.

I also asked if the + numbers after the COMO references in the code represented the pins on the pic so that I can map the segments. Since you didn't answer this, I'm assuming this is the case? I don't really appreciate the tone of your comments as I may not have much knowledge but I'm not lazy and have spent many hours with the datasheets.

Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 19, 2013 4:31 pm     Reply with quote

My tone was caused by the company owner constantly bringing out more
cups of hot coffee and placing them in front of me all morning.
I apologize for that.

This post explains that the COMx+YY numbers are the segments:
http://www.ccsinfo.com/forum/viewtopic.php?t=32774&start=22
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Apr 20, 2013 1:34 am     Reply with quote

Quote:
4) You've got TWO LCD pins connected to RD6!
5) You've got the LCD segments wired in different order for the separate digits.
6) You could create a driver for the second digit, but you're making it difficult.

What I was getting at here was:-

a) Dedicate a complete port to each digit.
b) Wire both digit segments in the same order.
c) Conversion to segment data then MUCH simpler.
d) Conversion for each digit almost identical (just a different port).

Mike
dkw



Joined: 18 Apr 2013
Posts: 6

View user's profile Send private message

PostPosted: Tue Apr 23, 2013 7:09 pm     Reply with quote

Thanks all for your help! Got everything working. I can post the code if anyone wants; however, I ended up using the compiler that I started working with (thought it might be considered bad form to post it on a dedicated forum).

Again, thank you. I have only been at this a short while and owe all my (very limited) knowledge to helpful people on forums like this.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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