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 support@ccsinfo.com

String Manipulation
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

String Manipulation
PostPosted: Fri Aug 26, 2011 8:01 pm     Reply with quote

I am using a PIC16F887 with a New Haven Display LCD (16x2) and I had troubles using LCD.C...could only get 8 characters dimly and then the PIC would freeze up. I can display perfectly using the long drawn out program of displaying one digit/character at a time via regular programming i/o functions, but I'd like to simplify that. I am new to C and only do this in my spare time as a hobby. I can get the results I want if i attempt one character at a time. However, is there a way to load a string to memory/variable and then extract one character at a time from that location/variable? I'm generally not one to ask for help...I usually figure things out on my own so they stick better, but this one is really causing me some trouble. Any help is much appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 26, 2011 8:58 pm     Reply with quote

Quote:
then the PIC would freeze up

Use the Flex lcd driver:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661


Quote:
could only get 8 characters dimly

Make sure you have a contrast circuit connected to the contrast pin on the LCD.
This thread has a schematic of two resistors connected as a voltage
divider to get the contrast voltage:
http://www.ccsinfo.com/forum/viewtopic.php?t=33292&start=11
Or you can use a 10K trimpot. Connect the two ends to +5v and ground,
and connect the wiper pin to the LCD's contrast pin. Set it for about
0.5v to start. Then when something is displayed, fine tune it for best
contrast.

Quote:

Is there a way to load a string to memory/variable and then extract one
character at a time from that location/variable?

Use printf as shown near the beginning of the thread in the link below.
See how it's used to display a string from an array on the lcd:
http://www.ccsinfo.com/forum/viewtopic.php?t=45935
A string is an contiguous group of ASCII characters with a 0x00 byte at
the end of the group. The array must be at least be large enough to hold
all the characters and the string terminator byte of 0x00.
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

PostPosted: Sat Aug 27, 2011 11:44 pm     Reply with quote

I have used both the LCD.C and the Flex with similar results from both. I am also trying to stick with passing bytes instead of nibbles and it seems like both default to nibbles...still only 8 characters and my status LEDs stop and so does the LCD.

Contrast is poor when using the inits from both the LCD.c and Flex, but if I initialize it with general I/O commands per the LCD data sheet...very crisp once on I adjusted my pot that I have connected to the contrast pin...not really sure why the inits from LCD and Flex would cause that.

I have tried the printf(lcd_putc...) and it works great up to eight characters...I even tested sending like 2 characters with one line of code and then another 8 or more from another line of code...but still after 8 characters...everything stops...no more status/debug LEDs changing, nor do I get any progress on my LCD. However, if I use general I/O lines of code I can write perfectly to the whole display and without any contrast problems...hence my desire to abandon both the LCD and Flex files and go about it a different way if that is at all possible.
temtronic



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

View user's profile Send private message

PostPosted: Sun Aug 28, 2011 5:19 am     Reply with quote

Sorry to hear about the problem! I've used the flexLCD driver for years without problems. Can you supply the LCD model# to link to it's datasheet? Could be a silly 'timing'or setup problem. What pins are you using for the driver as well. Also be sure to have a good ground (though if it works in 8 bit mode...sigh)
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

PostPosted: Sun Aug 28, 2011 5:36 pm     Reply with quote

I am using a Newhaven Display NHD-C0216AZ-FSW-GBW which has a built in Novatek driver (NT7605). I have the data pins 0-7 wired to port b 0-7. I have RS connected to C0, RW to C1, and Enable on C3...C2 is used to drive a transitor connected to the backlight. Oh and the contrast pin is connected to a resistor and a pot that I have adjusted for best visual results...and my ground is good clear on back to the incoming supply from my Microchip PICKit2.

If you can let me know where I went wrong, or make any suggestions on how I might get the FlexLCD to work...that would be sooo awesome! I'm not really one for reinventing the wheel and I'd really like to get past this speed bump and on to other projects. Also, if you can let me know what LCDs you have found to work well with PICs and C that would also be very helpful...I'd much rather buy LCDs that are known to work well instead of be someones fieldtester.

Thanks in advance for yout time and effort temtronic.
temtronic



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

View user's profile Send private message

PostPosted: Sun Aug 28, 2011 6:20 pm     Reply with quote

I've looked at the datasheet and it seems like a 'generic' LCD.
If you open up the flex_lcd driver at the top you have to change the #defines to whatever pins you've wired up the LCD to PIC pins. I do NOT use the R/W pin (my LCDs are used as Write Only). There's a line near there to uncomment to change that use I believe.

It's best to open up the driver, save AS 'myLCDdriver.c' and make the appropriate changes there NOT the original.

I've used 3 or 4 different LCDs and never had a problem..hopefully you'll get it going soon !
Ttelmah



Joined: 11 Mar 2010
Posts: 19337

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 2:12 am     Reply with quote

It is also perhaps worth understanding 'why' nibble mode is the commonest format.
Transferring the data using this, with even a reasonably slow PIC, only takes a couple of uSec. The fastest LCD commands take 40uSec to complete, so the time penalty from nibble mode is negligible. However four pins is a big saving. The controllers also wake up in nibble mode.
Now, there is nothing normally in the LCD driver, that can affect contrast, _except_ setting the unit up for the wrong number of lines/columns. My guess is that perhaps in trying to change the driver to use byte mode, these values have got set wrongly.
Realistically, much simpler, to just use nibble mode, and the driver 'as is', just with the bit definitions changed to match your board, and I suspect you will find everything then works.

Best Wishes
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

PostPosted: Mon Sep 05, 2011 10:23 pm     Reply with quote

Alright, I have been trying all of your suggestion with no improvements on my situation. I have tried several times and even restarted from scratch again...only to arrive at the same aggrivating destination...the PIC freezes up. I used the " printf(lcd_putc,"\fCurrent Temp 75deg")", but all I get is a very crisp and clear "Current " with a blinking cursor afer the space at the end and then my status LEDs no longer change state. I can only get 8 characters to display using the fancy LCD.c and similar results when I have tried the FlexLCD.c on my 16 character 2 line LCD. I'd like to be able to use the quick drivers like everybody else. I'm certain I keep making the same novice error...maybe someone can look over this code and give me some pointers please?

Code:


#include <16F887.h>             // header file for the PIC16F887
                                // includes built-in functions and constants
                                // for arguments/returns.



//RS = Pin_C0
//RW = Pin_C1
//Back Light = Pin_C2
//Enable = Pin_C3
//Data 0-7 = Port B Pin 0-7


// FUSES sets the PIC16F887 Configuration Words.  See top of the header file
// 16F887.h for fuse option constants.
#FUSES INTRC,NOWDT,NOPUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP

#use fast_io(B)

#use delay(clock=4000000)

#include "My_LCD.c"


void main(void)
 {

  int16 shift = 100;      //delay between letters
  int Disp1 = 0x0f;       //used to store characters from LcD
  int8 Disp2 = 0xf0;    //used to store characters from LcD
  int16 time = 1000;   //delay variable

  output_d(Disp1);   //status LEDs
  output_high(pin_c2);
   delay_ms(time);
  output_d(Disp2);     //status LEDs
   delay_ms(time);


 lcd_init();
   output_d(0xaa);
    delay_ms(time);
 lcd_putc("\f");
   output_d(0x55);
    delay_ms(time);
 printf(lcd_putc,"\fCurrent Temp 75deg");
    delay_ms(time);

 top:
   output_d(Disp1);
    delay_ms(time);
   output_d(Disp2);
    delay_ms(time);
 goto top;

 }


Last edited by dale.grand on Tue Sep 06, 2011 7:32 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19337

View user's profile Send private message

PostPosted: Tue Sep 06, 2011 2:23 am     Reply with quote

Remove the LCD.c, from the post. Read it's header, and understand that you are in breach of copyright....
Just post your changes.

One thing leaps out though. LCD.c _requires_ the pin order to be enable, rs, RW, working up from the bottom of the port. To change this, you need to modify LCD_PIN_MAP.
Flex_lcd does not have this limitation and should work with just:
Code:


#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_E     PIN_C3
#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1

#define USE_LCD_RW   1


Best Wishes
temtronic



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

View user's profile Send private message

PostPosted: Tue Sep 06, 2011 5:22 am     Reply with quote

Couple of quick comments...
re...
#use fast_io(B)

I'd get rid of the use fast_io(..) line because if you don't configure the TRIS registers correctly it'll come back to bite you ! Let the compiler handle it automatically (one of the joys of the CCS C compiler!!).99.9999999% of the programs presented on this forum do NOT need the minor speed increase that set_tris(...) gives but ALL can be 'sunk' by incorrect coding.Yes, I was one of them, once).

Also, I'm using the flex_lcd.c driver, NO problems, easy to setup, understand,modify. I use 4 or 5 different PICs and have NEVER had any LCD issues (timing or bad data).
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 06, 2011 12:53 pm     Reply with quote

Quote:

New Haven Display LCD (16x2)

1. Post the full part number of your LCD.

2. Post a list of the physical connections to your LCD. Look at the LCD
on the board, and post the connections that you have to each pin.
Don't post a list of #defines. Look at the actual, real, wire connections
to the LCD and post what you see.
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

PostPosted: Tue Sep 06, 2011 10:50 pm     Reply with quote

Ok, I just tried the flex_lcd driver with only making/confirming that the pin map mods as suggested...I remembered right away why I abandoned this one. I just got a blank screen...not even a cursor. Do I need to modify the LCD_Init string too?

@PCM Programmer:
I am using a Newhaven Display NHD-C0216AZ-FSW-GBW which has a built in Novatek driver (NT7605). I have pins connected as follows:

LCD Pin 1(GND)...GND
LCD Pin 2(Contrast V+)...Pot Pin 2
LCD Pin 3(V+)...VDD
LCD Pin 4(RS)...PIN_C0
LCD Pin 5(RW)...PIN_C1
LCD Pin 6(Enable)...PIN_C3
LCD Pin 7(DB0)...PIN_B0
LCD Pin 8(DB1)...PIN_B1
LCD Pin 9(DB2)...PIN_B2
LCD Pin 10(DB3)...PIN_B3
LCD Pin 11(DB4)...PIN_B4
LCD Pin 12(DB5)...PIN_B5
LCD Pin 13(DB6)...PIN_B6
LCD Pin 14(DB7)...PIN_B7



I have used long code as below to send and read characters across the entire display to test all of my connections and LCD functionality so I am certain of my pin out and connections. Only trouble that I have encountered is reading some certain characters gives different characters, but I'm assuming that has something to do with signed and unsigned characters...

Some of the code in my long hand test program
Code:

//set to 8-bit operation and select 2-line display and character font
  output_low(pin_c0);
  output_low(pin_c1);
  Output_b(0x38);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0x0f);   //status LEDs
   delay_ms(1000);

//Display on and cursor on and blinking (0e=no blinking and 0f=blinking)
  output_low(pin_c0);
  output_low(pin_c1);
  Output_b(0x0f);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0xf0);   //status LEDs
   delay_ms(1000);

//increase address by one...shift the cursor to the right when writing to the DDRAM/CGRAM...
//now the display has no shift.
  output_low(pin_c0);
  output_low(pin_c1);
  Output_b(0x06);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0x0f);   //status LEDs
   delay_ms(1000);

//clear display
  output_low(pin_c0);
  output_low(pin_c1);
  Output_b(0x01);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0x0f);   //status LEDs
   delay_ms(3000);

//write "W" and increment the cursor to the right one space.
  output_high(pin_c0);
  output_low(pin_c1);
  Output_b(temp);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(temp);   //status LEDs
   delay_ms(3000);

//write "e"...
  output_high(pin_c0);
  output_low(pin_c1);
  Output_b(0x65);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0xf0);   //status LEDs
   delay_ms(shift);
.
.
.
//the cursor is moved to the beginning of the second line
  output_low(pin_c0);
  output_low(pin_c1);
  Output_b(0xc0);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0x0f);   //status LEDs
   delay_ms(shift);

//write "Y"...
  output_high(pin_c0);
  output_low(pin_c1);
  Output_b(0x59);
   delay_cycles(1);
  output_high(pin_c3);
   delay_cycles(1);
  output_low(pin_c3);
  output_d(0xf0);   //status LEDs
   delay_ms(shift);
.
.
.

Ttelmah



Joined: 11 Mar 2010
Posts: 19337

View user's profile Send private message

PostPosted: Wed Sep 07, 2011 8:14 am     Reply with quote

The one line this does not test, is the LCD R/W line, with you simply delaying, rather than reading data back from the LCD.
So try the flex driver with:
Code:

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_E     PIN_C3
#define LCD_RS    PIN_C0
#define LCD_RW    PIN_C1

#define USE_LCD_RW   0

and add "output_low(PIN_C1);" before calling the driver.

Sequence needed is:
Code:

#include <16F887.h>             // header file for the PIC16F887
#FUSES INTRC,NOWDT,NOPUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP

#use delay(clock=4000000)

#include flex_lcd.h //With the pin section changed as above

void main(void) {
    int8 ctr=0;
    output_low(PIN_C1); //Turn off reading from LCD
    output_high(PIN_C2); Turn on your backlight
    delay_ms(100); //Some LCD's are slow to wake up
    lcd_init();
    printf(lcd_putc,"\fLCD Live");
    do {
       lcd_gotoxy(1,2);
       printf(lcd_putc,"Count %d  ",ctr++);
       delay_ms(1000);
    } while(TRUE);
}


Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 07, 2011 1:23 pm     Reply with quote

Quote:
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7

#define LCD_E PIN_C3
#define LCD_RS PIN_C0
#define LCD_RW PIN_C1

// #define USE_LCD_RW 1


and add "output_low(PIN_C1);" before calling the driver.

To disable use of the R/W pin by the flex driver, you need to comment
out the line in bold. But as Ttlemah says, if you have the lcd's R/W line
connected to your PIC, then you will need to set that PIC pin to a low-
level with a line of code.

And get rid of all the #use fast_io() statements. The flex driver doesn't
use fast i/o.
dale.grand



Joined: 26 Aug 2011
Posts: 7

View user's profile Send private message

PostPosted: Wed Sep 07, 2011 11:25 pm     Reply with quote

Ok, I tried your suggestions with the flex_lcd driver, but I still came up with a blank display. I even tried pasting your code with the "LCD Live" and Counter...after adding the "//" before the second "Turn" and compiled it...still no display. I even adjusted my potentiometer for the contrast up and down 5 complete turns. Something just isn't jiving. My next move is to create and debug some 4-bit operation long hand code...considering all the drivers seem to resort to that operation anyway. Then once I work through that and learn a few lessons along the way, I will have a better understanding what I need the drivers to do...or what I need to do to better use the drivers. Thanks for your help and I will post any updates.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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