Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PICKIT3 + MPLAB + Simple LCD driver = Problems

Status
Not open for further replies.

Spadez

New Member
Hi,

Im trying to program a PIC 16F88 with my PICKIT3. This is the CCS C code im using:

CCS :: View topic - Flexible LCD driver

My code is as such:

main.c
Code:
#include <16F88.H> 
#fuses NOMCLR, INTRC_IO, NOBROWNOUT, NOWDT, NOPROTECT, PUT, NOLVP 
#use delay(clock=8M)

#include "flex_lcd.c" 
    
//========================== 
void main() 
{ 
lcd_init();  // Always call this first. 

lcd_putc("\fHello World\n"); 
lcd_putc("Line Number 2"); 

while(1); 
}

flex_lcd.c
Code:
// flex_lcd.c 

// These pins are for the Microchip PicDem2-Plus board, 
// which is what I used to test the driver.  Change these 
// pins to fit your own board. 

#define LCD_DB4   PIN_A6 
#define LCD_DB5   PIN_A7 
#define LCD_DB6   PIN_A0 
#define LCD_DB7   PIN_A1 

#define LCD_E     PIN_A2 
#define LCD_RS    PIN_A3 
#define LCD_RW    PIN_A4 

// If you only want a 6-pin interface to your LCD, then 
// connect the R/W pin on the LCD to ground, and comment 
// out the following line. 

#define USE_LCD_RW   1      

//======================================== 

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines 
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line 


int8 const LCD_INIT_STRING[4] = 
{ 
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots 
 0xc,                    // Display on 
 1,                      // Clear display 
 6                       // Increment cursor 
 }; 
                              

//------------------------------------- 
void lcd_send_nibble(int8 nibble) 
{ 
// Note:  !! converts an integer expression 
// to a boolean (1 or 0). 
 output_bit(LCD_DB4, !!(nibble & 1)); 
 output_bit(LCD_DB5, !!(nibble & 2));  
 output_bit(LCD_DB6, !!(nibble & 4));    
 output_bit(LCD_DB7, !!(nibble & 8));    

 delay_cycles(1); 
 output_high(LCD_E); 
 delay_us(2); 
 output_low(LCD_E); 
} 

//----------------------------------- 
// This sub-routine is only called by lcd_read_byte(). 
// It's not a stand-alone routine.  For example, the 
// R/W signal is set high by lcd_read_byte() before 
// this routine is called.      

#ifdef USE_LCD_RW 
int8 lcd_read_nibble(void) 
{ 
int8 retval; 
// Create bit variables so that we can easily set 
// individual bits in the retval variable. 
#bit retval_0 = retval.0 
#bit retval_1 = retval.1 
#bit retval_2 = retval.2 
#bit retval_3 = retval.3 

retval = 0; 
    
output_high(LCD_E); 
delay_cycles(1); 

retval_0 = input(LCD_DB4); 
retval_1 = input(LCD_DB5); 
retval_2 = input(LCD_DB6); 
retval_3 = input(LCD_DB7); 
  
output_low(LCD_E); 
    
return(retval);    
}    
#endif 

//--------------------------------------- 
// Read a byte from the LCD and return it. 

#ifdef USE_LCD_RW 
int8 lcd_read_byte(void) 
{ 
int8 low; 
int8 high; 

output_high(LCD_RW); 
delay_cycles(1); 

high = lcd_read_nibble(); 

low = lcd_read_nibble(); 

return( (high<<4) | low); 
} 
#endif 

//---------------------------------------- 
// Send a byte to the LCD. 
void lcd_send_byte(int8 address, int8 n) 
{ 
output_low(LCD_RS); 

#ifdef USE_LCD_RW 
while(bit_test(lcd_read_byte(),7)) ; 
#else 
delay_us(60);  
#endif 

if(address) 
   output_high(LCD_RS); 
else 
   output_low(LCD_RS); 
      
 delay_cycles(1); 

#ifdef USE_LCD_RW 
output_low(LCD_RW); 
delay_cycles(1); 
#endif 

output_low(LCD_E); 

lcd_send_nibble(n >> 4); 
lcd_send_nibble(n & 0xf); 
} 

//---------------------------- 
void lcd_init(void) 
{ 
int8 i; 

output_low(LCD_RS); 

#ifdef USE_LCD_RW 
output_low(LCD_RW); 
#endif 

output_low(LCD_E); 

delay_ms(15); 

for(i=0 ;i < 3; i++) 
   { 
    lcd_send_nibble(0x03); 
    delay_ms(5); 
   } 

lcd_send_nibble(0x02); 

for(i=0; i < sizeof(LCD_INIT_STRING); i++) 
   { 
    lcd_send_byte(0, LCD_INIT_STRING[i]); 
    
    // If the R/W signal is not used, then 
    // the busy bit can't be polled.  One of 
    // the init commands takes longer than 
    // the hard-coded delay of 60 us, so in 
    // that case, lets just do a 5 ms delay 
    // after all four of them. 
    #ifndef USE_LCD_RW 
    delay_ms(5); 
    #endif 
   } 

} 

//---------------------------- 

void lcd_gotoxy(int8 x, int8 y) 
{ 
int8 address; 

if(y != 1) 
   address = lcd_line_two; 
else 
   address=0; 

address += x-1; 
lcd_send_byte(0, 0x80 | address); 
} 

//----------------------------- 
void lcd_putc(char c) 
{ 
 switch(c) 
   { 
    case '\f': 
      lcd_send_byte(0,1); 
      delay_ms(2); 
      break; 
    
    case '\n': 
       lcd_gotoxy(1,2); 
       break; 
    
    case '\b': 
       lcd_send_byte(0,0x10); 
       break; 
    
    default: 
       lcd_send_byte(1,c); 
       break; 
   } 
} 

//------------------------------ 
#ifdef USE_LCD_RW 
char lcd_getc(int8 x, int8 y) 
{ 
char value; 

lcd_gotoxy(x,y); 

// Wait until busy flag is low. 
while(bit_test(lcd_read_byte(),7));  

output_high(LCD_RS); 
value = lcd_read_byte(); 
output_low(lcd_RS); 

return(value); 
} 
#endif

All ive done on either code is modify it for 16F88 and adjust the pin numbers. When I try to program I get what you see in the attachment.

I said "ok" to this and it said it programmed ok, and it also verified ok, but the screen doesn't work, it has 16 solid black box's across the top.

Any suggestions on how I can move forward with this?

James
 

Attachments

  • picerror.jpg
    picerror.jpg
    211.6 KB · Views: 314
Update, I tried to change the main.c to this:

Code:
#include <16F88.H> 
[COLOR="red"][B]#fuses NOMCLR, INTRC_IO, NOBROWNOUT, NOWDT, NOPROTECT, PUT, NOLVP 
#use delay(clock=8M)[/B][/COLOR]

#include "flex_lcd.c" 
    
//========================== 
void main() 
{ 
lcd_init();  // Always call this first. 

lcd_putc("\fHello World\n"); 
lcd_putc("Line Number 2"); 

while(1); 
}

Same thing happens, same error and no display on my screen. Screen is brand new, pic is brand new.
 
Last edited:
The error seems like you have to enable MCLR and use external pullup if using a internal OSC

I assume you see nothing because its not running at all because of that error.

So turn on MCLR and then add a 10K PULLUP resistor to the PIC MCLR line and try it out
 
Last edited:
Hi.

Yes ive tried a few different resistors, 10Ohm etc, which is what I had before. The message should be printed on line two, and so far its still only solid blocks on the top line. It does the same thing when the screen is powered on with no DB / E / RS lines connected.
 
Is it that I have to enable, I thought it was that it should be disabled? The MCLR is also connected to the PICKIT3 so I assumed that would handle everything.
 
Have you tried this:

"So turn on MCLR in the fuse bits and then add a 10K PULLUP resistor to the PIC MCLR line and try it out "
 
Last edited:
An update, i got rid of the error that came up, when I was using the pullup I didnt realise there was still meant to be a connection to the PICKIT.

I still get the "internal MCLR" error, how should I set my fuse to do this to use external pullup on MCLR?
 
From what ive read, its about turning MCLR off, not on?

I tried exactly the same code on the university PICKIT2, same breadboard and same code, and it works fine there, but doesnt work on my PICKIT3.
 
I get an new error about device ID. I think the PICKIT3 needs to connect to MCLR from what ive read.
What is the error? It sounds to me like youve fixed the osc problem but you dont have power on the board (or an incorrect device is selected).

On the PICkit2 the power is auto-sensed and enabled if your board isnt powered. On the PICkit3 you have to do this manually.
 
Last edited:
Yes that error no longer shows up but there is still a host of problems. Sometimes I start up the program, compile and programming and it works beutifully. Then I change the code slightly (increase delay) and it just runs the old program again. I verify and it says "verified" but still the old program runs. Its extremely intermittent.

Ive tried powering using the PICKIT and an external supply. I get about 4.6V across the pic.
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top