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

LCD on Port A problem

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



Joined: 27 Jan 2006
Posts: 69
Location: Manchester, England

View user's profile Send private message

LCD on Port A problem
PostPosted: Mon Oct 27, 2008 11:14 pm     Reply with quote

I have a Hitachi type LCD I am trying to get to work on port A of a PIC18F4520. I have no problem with any other port, but nothing appears on the screen when using port A. I know the screen works and I have also had identical trouble while simulating it in ISIS.

I am using a 20x4 LCD which I got the code of this forum somewhere and have had great success with.

my pin configuration is listed in the code below, the RW pin is taken to 0v, which is a normal configuration I use the LCDs in.

I have all the analogues turned off but still no avail.

anyone have any ideas?

lcd driver code (this is known to work):
Code:

////////////////////////////////////////////////////////////////////////////
////                             LCD_4b.C                               ////
////            Driver for common 4x20 LCD modules                      ////
////                                                                    ////
////  lcd_init()   Must be called before any other function.            ////
////                                                                    ////
////  lcd_putc(c)  Will display c on the next position of the LCD.      ////
////                     The following have special meaning:            ////
////                      \f  Clear display                             ////
////                      \n  Go to start of second line                ////
////                      \b  Move back one position                    ////
////                                                                    ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)     ////
////                                                                    ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD          ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
// lcd4.c

// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54

// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/


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

#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)

//#define LCD_CGRAM_ADDR 0x40           // Set the CGRAM address
//#define LCD_DDRAM_ADDR 0x80           // Set the DDRAM address
#define LCD_CGRAM_ADDR 0x40           // Set the CGRAM address
#define LCD_DDRAM_ADDR 0x80           // Set the DDRAM address


int8 lcd_line;


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2),  // Set mode: 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_RW_PIN
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_us(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);
delay_us(1);
   
return(retval);   
}   
#endif

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

#ifdef USE_RW_PIN
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_RW_PIN
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_RW_PIN
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;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E);

// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);         

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 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

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

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


switch(y)
  {
   case 1:
     address = LCD_LINE_1_ADDRESS;
     break;

   case 2:
     address = LCD_LINE_2_ADDRESS;
     break;

   case 3:
     address = LCD_LINE_3_ADDRESS;
     break;

   case 4:
     address = LCD_LINE_4_ADDRESS;
     break;

   default:
     address = LCD_LINE_1_ADDRESS;
     break;
     
  }

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

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

    default:
       lcd_send_byte(1,c);
       break;
   }
   if (lcd_line>4)
     {
       lcd_line=1;
     }
}

//------------------------------
#ifdef USE_RW_PIN
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


And the basic parts of my main code:

Code:

#include <18F4520.h>
#device adc=8
#FUSES NOWDT, WDT128, HS, NOPROTECT, BROWNOUT, BORV20, PUT, NOCPD, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, IESO, FCMEN, NOPBADEN, NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, LPT1OSC, MCLR, NOXINST
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,restart_wdt,errors)
#USE FAST_IO(A)
#define LCD_RS       PIN_A0
#define LCD_E        PIN_A1
#define LCD_DB4      PIN_A2
#define LCD_DB5      PIN_A3
#define LCD_DB6      PIN_A4
#define LCD_DB7      PIN_A5

#include "drivers\lcd_20x4.c"      // LCD driver

void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   lcd_init();

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   printf(lcd_putc,"\fThis is a test\n");
   printf(lcd_putc,"This is a test\n");
   printf("\fThis is a test\n");

   while(true)
   {
     process_tasks();
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 27, 2008 11:30 pm     Reply with quote

Quote:
#USE FAST_IO(A)

The Flex drivers don't work with Fast i/o enabled. It says that in the
instructions in the Code Library. You need to delete that line.

Thinking about it some more, since you're not using the R/W pin
all pins are write-only. You could use fast i/o mode in that case
but you need to set the TRIS on pins A0-A5 to be all outputs.
You could try it by adding this line to main(). Put it after all the
Wizard code:
Code:
set_tris_a(0xC0);


Quote:
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

You don't have an #int_rda interrupt service routine. If you receive
a character, the PIC will jump to address 0x0008, except there will
be nothing there and your program will crash. Delete those lines.
ratgod



Joined: 27 Jan 2006
Posts: 69
Location: Manchester, England

View user's profile Send private message

PostPosted: Tue Oct 28, 2008 7:25 am     Reply with quote

unfortunately it didn't do anything extra.
But a work colleague suggested putting pull up resistors and it worked a treat.

the INT_RDA is already in my code, I just removed it for the posting.

many thanks for your suggestions
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