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

PIC16F628A with PICDEM4 LCD problem - help needed
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
petur



Joined: 26 Mar 2010
Posts: 5

View user's profile Send private message

PIC16F628A with PICDEM4 LCD problem - help needed
PostPosted: Mon Apr 12, 2010 10:39 am     Reply with quote

Hy everybody,

I need your help. I'm a newbie in programming microcontrollers.
I am using PICDEM 4 DEMO Board with a PIC16F628A mCtrl.
I want to display something on the LCD and to send the message through RS232 .. but it's not working, and I don't know why. Only the led on PIN_A0 is shining ... that's all

-- I'm not using the right pins, fuses ... or what is the problem ? Please help me.

Here is my code
Code:

#include "only_lcd.h"


#define LCD_ENABLE_PIN PIN_B4
#define LCD_RS_PIN PIN_B6
#define LCD_RW_PIN PIN_B5
#define LCD_TYPE 2
#include <lcd.c>
void main()
{
output_high(PIN_A0);
   lcd_init();

   lcd_putc("\fReady...\n");

   lcd_putc('a');
 

   // TODO: USER CODE!!

}

The content of lcd.h
Code:

#include <16F628A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC                    //Internal RC Osc
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=2000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8)



The LCD.C provided by CCS
Code:

///////////////////////////////////////////////////////////////////////////
////                             LCDD.C                                ////
////                 Driver for common 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         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     D0  enable
//     D1  rs
//     D2  rw
//     D4  D4
//     D5  D5
//     D6  D6
//     D7  D7
//
//   LCD pins D0-D3 are not used and PIC D3 is not used.

// Un-comment the following define to use port B



struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;

#define use_portb_lcd TRUE
#if defined use_portb_lcd
   #locate lcd = getenv("sfr:PORTB")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #locate lcd = getenv("sfr:PORTD")    // This puts the entire structure over the port
   #define set_tris_lcd(x) set_tris_d(x)
#endif

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


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
  for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]); 
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE 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;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 12, 2010 11:44 am     Reply with quote

Quote:

#include <16F628A.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=2000000)
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8)

In your code above, you are attempting to configure the program
to run with a 2 MHz internal oscillator.

Download the 16F628A data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

Look in the "Special Features" section of the data sheet. It explains
the internal oscillator options. It runs at 4 MHz, not 2 MHz:
Quote:

14.2.4 PRECISION INTERNAL 4 MHZ OSCILLATOR


Also, I downloaded the PicDem4 User's guide:
http://ww1.microchip.com/downloads/en/DeviceDoc/51337b.pdf
The LCD on this board is not connected directly to the PIC. It goes
through an "i/o expander" chip. This means that all the normal LCD
drivers (including the one from CCS) won't work on this board.
Quote:

A.14 LCD DISPLAY
The LCD display has two lines with 16 characters per line. It is connected
to the I/O expander (U3) which can be driven by all three device sockets.


To make the LCD on this board work with CCS, you would have to
download the "PICDEMâ„¢ 4 Software and Demo Files" from this page:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010054
Inside the Zip file, there is an ASM source file called 16IoExpLcd.asm.
It shows how to talk to the I/O Expander chip. This ASM code would
have to be translated to CCS. Or at least, the protocol would have to
be analyzed and understood. Then a CCS program could be written that
would let you use the LCD.
petur



Joined: 26 Mar 2010
Posts: 5

View user's profile Send private message

PostPosted: Mon Apr 12, 2010 4:35 pm     Reply with quote

Thanks for the reply ... I've just modified the address of the lines based on the ASM examples, but I don't think is enough. Can you help me with an example ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 12, 2010 4:50 pm     Reply with quote

Just changing the address somewhere won't do anything.

If you take the time to look at the ASM source files in this Zip file
from the Microchip page that I linked earlier,
Quote:
PICDEMâ„¢ 4 Software and Demo Files

you will see that the Microchip PicDem 4 LCD driver is built around this low level routine:
Quote:

; Function: SPImbbWrite1Byte
;
; PreCondition: SPImbbInit must have already been invoked.
;
; Overview:
; This routine is used to transmit 1 byte through SPI,
; Bit-Banged Mode

It's in this file in the Zip package:
Quote:
\picdem 4 demo code\picdem 4 16f demo\16spimb.asm


All the routines in all the LCD files would have to be translated to CCS.
The whole job must be done.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 18, 2010 4:17 pm     Reply with quote

Here is a test program and an LCD driver for the PicDem 4 board.
I don't have a PicDem 4 board to test this code on. But I compiled
their MPASM firmware and programmed it into a 16F628, and then
I looked at the I/O Expander signals with a logic analyzer. The
signals produced by the code below look very similar to the Microchip
firmware. So I think it has a good chance to work. I did this with
vs. 4.106 of the CCS compiler.

Many of the delays used in the LCD driver are very long. I think
they are much longer than is really needed. But, the Microchip
firmware has these long delays in it, so I kept them the same
in the code below. Also, I kept the init values exactly the same.

Here's the test program. It should be saved as "PicDem4_Test.c".
It's the main source program for the project.
Code:

#include <16F628.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
// We can't use the hardware UART at the same time as the LCD
// because they share pin B1.
//#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, ERRORS)

#include "PicDem4_lcd.c"  // This is the PicDem 4 LCD driver

#define PICDEM4_PERIPH_CS  PIN_B3

// The RS-232 level converter chips, LIN bus transceiver,
// and Motor Driver chip  on the PicDem4 board are all
// enabled or disabled by one PIC pin (Pin B3).
#define disable_peripherals()  output_low(PICDEM4_PERIPH_CS)
#define enable_peripherals()  output_high(PICDEM4_PERIPH_CS)

//==========================
void main()
{
disable_peripherals(); 

delay_ms(1000);  // Start-up delay for i/o expander

lcd_init();     // Always call this first.

printf(lcd_putc,"Hello World\n");
printf(lcd_putc,"This is line 2");

delay_ms(2000);

printf(lcd_putc,"\fHi There\n");
printf(lcd_putc,"PicDem4 LCD");

while(1);
}


This is the LCD driver. It should be saved as "PicDem4_lcd.c".
Code:

// This is a PicDem4 LCD driver for the CCS compiler.
// This driver writes to the LCD by writing to the
// I/O Expander on the PicdDem4 board, using SPI.
// The LCD is connected to the I/O Expander.

#define SDO  PIN_B1   // SPI data
#define SCK  PIN_B4   // SPI clock

#define LCD_E_BITMASK  0x10
#define LCD_RS_BITMASK 0x40

#define LCD_LINE2_ADDRESS  0x40 

// The value is transmitted MSB first, in SPI Mode 2,
// to the I/O Expander chip on the PicDem4 board.
void spi_write_byte(int8 value)
{
int8 i;

for(i = 0; i < 8; i++)
   {
    output_low(SDO);
    output_high(SCK);

    if(bit_test(value, 7))
       output_high(SDO);
    else
       output_low(SDO);

    value <<= 1;
    delay_us(4);

    output_low(SCK);
    delay_us(6);
   }

output_low(SDO);
}

//----------------------------------------------
void lcd_send_nibble(int8 address, int8 value)
{
value &= 0x0F; 

if(address)
  {
   value |= LCD_RS_BITMASK;
  }

SPI_write_byte(value);
delay_us(5);
SPI_write_byte(value | LCD_E_BITMASK);
delay_us(5);
SPI_write_byte(value);
delay_us(5);

}

//----------------------------------------------
// Send one byte to the LCD via the I/O expander.
void lcd_send_byte(int8 address, int8 value)
{
delay_ms(40);  // Possibly this delay can be reduced
lcd_send_nibble(address, value >> 4);  // Send high nibble first
lcd_send_nibble(address, value & 0x0F);
}


//--------------------------------
void lcd_init(void)
{
output_low(SCK);
output_low(SDO);
delay_ms(1);

spi_write_byte(0x00);   // Init I/O Expander

delay_ms(150);

lcd_send_nibble(0, 3);
delay_ms(40);
lcd_send_nibble(0, 3);
delay_ms(1);
lcd_send_nibble(0, 3);
delay_ms(1);

lcd_send_nibble(0, 2);
delay_ms(40);

lcd_send_byte(0, 0x28);   // Function set
lcd_send_byte(0, 0x0D);   // Display = ON
lcd_send_byte(0, 0x01);   // Display clear
lcd_send_byte(0, 0x06);   // Entry Mode
lcd_send_byte(0, 0x80);   // DDRAM address 0
}

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

if(y != 1)
   address = LCD_LINE2_ADDRESS;
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;
   }
}
bmmribeiro



Joined: 12 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Sat May 12, 2012 5:01 pm     Reply with quote

That code really works?

I want to program PICDEM4 in C (obviously sending messages to the LCD display) but using HI-TECH PICC instead CCS compiler.

Anybody can help me?...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 12, 2012 5:04 pm     Reply with quote

You need to ask questions on the Hi-Tech forums. We can't help you
on this forum. Here are the links:
http://forum.htsoft.com/all/categories.php
http://www.microchip.com/forums/f231.aspx
bmmribeiro



Joined: 12 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Sat May 12, 2012 5:25 pm     Reply with quote

Thanks for your reply.

However, is there any feedback about the correct functionality of your code above in CCS?

If it works, I can try to translate the code to be understandable for other compiler...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 12, 2012 5:54 pm     Reply with quote

If there was feedback, it would be posted in this thread.
bmmribeiro



Joined: 12 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Sun May 13, 2012 4:10 am     Reply with quote

You are right.

I'm using PIC18f1320 (18pin). I don't understand how my PIC can comunicate with the PIC16F72 (20pin-QFN) embedded in I/O expander block, so that to send messages to LCD display.

Sorry my english (I'm portuguese) and forgive my insistence but I really need some help...


Thanks in advance.
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun May 13, 2012 5:24 am     Reply with quote

As was stated earlier, go to the Hi-Tech forum. If you can't get the kind of
help available here then maybe you shouldn't be using Hi-tech. This
forum is one of the advantages of using CCS C. However. we are not a
beginner's teaching forum either and won't write your code or test it for you.
That's your job. The moderator needs to lock this thread.
_________________
Google and Forum Search are some of your best tools!!!!
bmmribeiro



Joined: 12 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Sun May 13, 2012 8:00 am     Reply with quote

Please forget HI-TECH.

I saw the code above and I would to know if is possible to explain it better.

Programming it's not the problem, the problem is to understand the logic about the communication between 16F628 (or 18F1320) and I/O expander block.

Sorry any inconvenience...
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun May 13, 2012 9:35 am     Reply with quote

OK, forget about Hitech.

PCM did not post the code two years ago to have someone question his
work. He is one of the top programmers on this forum and you can be
assured what he wrote is good code.

Instead of a blanket "explain your code". Ask specific questions about
certain lines and you might get an answer from someone here.

If you don't know the CCS compiler you need to learn the fundamentals of
that first before you start asking questions about how CCS code works. If
you don't know the compiler how can you understand CCS code?
_________________
Google and Forum Search are some of your best tools!!!!
bmmribeiro



Joined: 12 May 2012
Posts: 5

View user's profile Send private message

PostPosted: Tue May 15, 2012 2:01 pm     Reply with quote

Code:
#define SDO  PIN_B1   // SPI data
#define SCK  PIN_B4   // SPI clock


PIN_B1 means RB1 and PIN_B4 means RB4?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 15, 2012 2:05 pm     Reply with quote

Yes it does.

Please go to a Hi-Tech forum and copy the code into a new post on
the Hi-Tech forum. Ask them to translate it to Hi-Tech for you.
Anything that we can tell you about the program, they should also
be able to explain to you.

Here are the Hi-Tech forums:
http://forum.htsoft.com/all/categories.php
http://www.microchip.com/forums/f231.aspx
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