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.

A simple C18 ?

Status
Not open for further replies.

AGCB

Member
Hi
I've not been on the forum for a while but lurked a little. I temporarily switched to "Propeller as a stepping stone to learning "C".

'I'm working on learning MC C18 and have compiled a few simple programs for blinking LEDs and using the delay tools in the library. Now I'm trying to get a LCD working with the XLCD library. I was able to display on the LCD but only using one line of code per character. EDIT (That was with a different program type) I would like to be able to include strings like I did in assembly with Mike McClaren's 'putstr' MACRO.
This program compiles without error but only shows black boxes on the LCD.
I'm hoping someone can spot an obvious mistake.

Thanks Aaron

Code:
//
  Program INFO  and what it does  //Display strings on LCD

//#includes                  
#include <p18F43K20.h>
#include <xlcd.h>
#include <delays.h>
      
//Processor configuration
#pragma config FOSC=INTIO67,BOREN=OFF,PWRT=ON,WDTEN=OFF,PBADEN=OFF,STVREN=OFF,LVP=OFF
#define  LEDPIN  PORTAbits.RA1

//Prototype declarations
void DelayFor18TCY (void);
void DelayXPORXLCD (void);    //Power on delay to get LCD going
void DelayXLCD (void);

void DelayFor18TCY (void)
{
    Delay10TCYx(2);  //20 us delay
}
void DelayPORXLCD (void)
{
    Delay1KTCYx(15); //15ms delay
}
void DelayXLCD (void)
{
    Delay1KTCYx(5);  //5ms delay
}

///////////////// MAIN Funtion //////////////////////////////////////////////////
void main (void)
{
  OSCCON = 0xD0;            /* Set internal oscillator at 4 Mhz */
  ADCON0 = 0x00;             /* Disable internal ADC */

  TRISE=0;
  PORTEbits.RE2 = 1;      //turn on LCD power via MOSFET
  Delay1KTCYx(40);         //40 ms delay
  OpenXLCD(FOUR_BIT & LINES_5X7); 
  DelayPORXLCD;
   
  putsXLCD("Hello");
  
  while(1);

}
 
The custom delay functions that you have there.. useless. Why don't you just call the original delay functions..

And on top of that, you have the function call syntax wrong.
DelayPORXLCD;

that should be:
DelayPORXLCD();

Or even better if you call directly the delay function from your library:
Delay1KTCYx(15); /* 15ms delay */

EDIT: I did not check for logical errors etc. Just the obvious from the syntax.
 
Last edited:
The custom delay functions that you have there.. useless. Why don't you just call the original delay functions..
Or even better if you call directly the delay function from your library:
Delay1KTCYx(15); /* 15ms delay */

I'm all for simple. I was just trying to follow the tuts
 
I say this again because you did not comment on it, so I assume you did not correct it:

You have one line very wrong in your code:
DelayPORXLCD;

that should be:
DelayPORXLCD();

Notice the parenthesis that denotes a function call. Without the parenthesis there is no function call. I don't know how serious mistake that is. Potentially a very serious programming mistake.
 
Last edited:
I say this again because you did not comment on it, so I assume you did not correct it:

You have one line very wrong in your code:
DelayPORXLCD;

that should be:
DelayPORXLCD();

Notice the parenthesis that denotes a function call. Without the parenthesis there is no function call. I don't know how serious mistake that is. Potentially a very serious programming mistake.

Thanks Mr T
I will reload it in the morning and then get back. I'm getting late for a meeting right now. Aaron
 
This is the latest code . I also tried Delay1KTCYx() of various values in place of DelayPORXLCD()

Code:
//   Program INFO  and what it does
 
//#includes                   
#include <p18F43K20.h>
#include <xlcd.h>
#include <delays.h>
       
//Processor configuration
#pragma config FOSC=INTIO67,BOREN=OFF,PWRT=ON,WDTEN=OFF,PBADEN=OFF,STVREN=OFF,LVP=OFF
#define  LEDPIN  PORTAbits.RA1
 
void DelayPORXLCD (void)
{
    Delay1KTCYx(10);
}
void DelayFor18TCY (void)
{
    Delay1KTCYx(20);
}
void DelayXLCD (void)
{
    Delay1KTCYx(6);
}
   
///////////////// MAIN Funtion //////////////////////////////////////////////////
void main (void)
{
  OSCCON = 0xD0;            /* Set internal oscillator at 4 Mhz */
  ADCON0 = 0x00;             /* Disable internal ADC */
 
  TRISE=0;
  PORTEbits.RE2 = 1;      //turn on LCD power
  Delay1KTCYx(100);         //100 ms delay
 
  OpenXLCD(FOUR_BIT & LINES_5X7);
   
  DelayPORXLCD();    
  putrsXLCD("Hello");
   
  while(1);
 
}
 
This is how the XLCD.h was modified

Code:
#ifndef __XLCD_H
#define __XLCD_H
#include "p18cxxx.h"
/* PIC18 XLCD peripheral routines.
*
*   Notes:
*      - These libraries routines are written to support the
*        Hitachi HD44780 LCD controller.
*      - The user must define the following items:
*          - The LCD interface type (4- or 8-bits)
*          - If 4-bit mode
*              - whether using the upper or lower nibble
*          - The data port
*              - The tris register for data port
*              - The control signal ports and pins
*              - The control signal port tris and pins
*          - The user must provide three delay routines:
*              - DelayFor18TCY() provides a 18 Tcy delay
*              - DelayPORXLCD() provides at least 15ms delay
*              - DelayXLCD() provides at least 5ms delay
*/
 
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
/* #define BIT8 */
 
/* When in 4-bit interface define if the data is in the upper
* or lower nibble.  For lower nibble, comment the #define UPPER
*/
/* #define UPPER */
 
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT              PORTD
#define TRIS_DATA_PORT         TRISD
 
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN   LATDbits.LATD6           /* PORT for RW */
#define TRIS_RW  TRISDbits.TRISD6       /* TRIS for RW */
 
#define RS_PIN   LATDbits.LATD4           /* PORT for RS */
#define TRIS_RS  TRISDbits.TRISD4        /* TRIS for RS */
 
#define E_PIN    LATDbits.LATD7          /* PORT for E  */
#define TRIS_E   TRISDbits.TRISD7        /* TRIS for E  */
 
I write my own libraries.... The trouble with inbuilt libraries is they have to cater for every chip! To many ifelse defines!!!

Ian
Would you if possible give me an example of a LCD library that you wrote. I will modify for the chips I use.
Or if not a lcd then some other commonly used code. Just something to get me going doing my own.

Thanks
Aaron
 
Thanks Ian
I took a quick look at those and they look like just what I need to help me get learning.
I will be using C18, so, is there a great deal of difference in the code or very little? I don't know if I have the Hi-Tech
on my machine.
Aaron

EDIT: The reason I can't tell right is that the computer that I use for 'play' is in the basement and not connected to the internet
 
Still fighting with this one! Latest code (today) attached. I can get the single 'S' to print on line 1 and then some other letter prints and fills the LCD screen, sometimes WWWWWW or DDDDDD or ZZZZZZ.
on both lines.

One other (of several) question I have is, Can the clock setting go somehow in an earlier part of the code befor the main?

One more! I'm using LATE to turn on power to the LCD via a MOSFET. If I do TRISEbits.TRISE2=0 and then LATEbits.LATE2=1 it will not compile. But if I just do the TRIS part the power is on and it compiles. I don't get it!

Main questions are where the ????????????????? are on the right side.

Thanks Aaron

Code:
/////////////////////////////More LCD ///////////////////////////////////////
                                //Sat AM Feb 22 added Line and Column GOTO
#include <p18F43k20.h>
 
#pragma config FOSC=INTIO67,BOREN=OFF,PWRT=ON,WDTEN=OFF,PBADEN=OFF,STVREN=OFF,LVP=OFF
 
//////////// Defines ////////////////////////////////////////////////////////
// The lower 4 bits of this port will be used
#define LCD_DATA        LATD
#define LCD_EN             LATDbits.LATD7
#define LCD_RS             LATDbits.LATD4
#define TRIS_LCD_DATA    TRISD
#define TRIS_LCD_EN     TRISDbits.TRISD7
#define TRIS_LCD_RS     TRISDbits.TRISD4
#define TRIS_LCD_PWR    TRISEbits.TRISE2    //RE2 is for LCD power control through MOSFET
 
// Commands for Hitachi LCD
#define CLEAR_DISPLAY    0x01
#define FOUR_BIT       0b00101111  /* 4-bit Interface               */
#define EIGHT_BIT      0b00111111  /* 8-bit Interface               */
#define LINE_5X7       0b00110011  /* 5x7 characters, single line   */
#define LINE_5X10      0b00110111  /* 5x10 characters               */
#define LINES_5X7      0b00111011  /* 5x7 characters, multiple line */
 
#define DISPLAY_ON  0b00001111  /* Display on      */
#define DISPLAY_OFF 0b00001011  /* Display off     */
#define CURSOR_ON   0b00001111  /* Cursor on       */
#define CURSOR_OFF  0b00001101  /* Cursor off      */
#define BLINK_ON    0b00001111  /* Cursor Blink    */
#define BLINK_OFF   0b00001110  /* Cursor No Blink */
#define UNDERLINE_ON    0b00001111
#define UNDERLINE_OFF   0b00001101
 
#define INCREMENT    0b00000111    /* Entry mode increment */
#define DECREMENT    0b00000101    /* Entry mode decrement */
#define SHIFT_ON    0b00000111    /* Display shift on        */
#define SHIFT_OFF    0b00000110    /* Display shift off    */
 
#define PulseEnable { LCD_EN = 1; Nop(); LCD_EN = 0; }
 
                   // Required prototypes.. each function needs to be declared
                // if called BEFORE definition.
void LCDInit(void);
void LCDCmd(unsigned char);  //RS is 0 for commands
void LCDChar(unsigned char);  //RS is 1 for characters
void LCD_GOTO(unsigned char,unsigned char);  //Sets position, line and column
void Delay5ms(void);
void Delay15ms(void);
void Delay100ms(void);  //100 ms delay
 
  unsigned char text1[] = {"Hello"};                                                     ?????????????????
 
//////////////////////////// MAIN funtion ////////////////////////////////////
 
void main (void)
{
  int index = 0;
OSCCON = 0xD0;            /* Set internal oscillator at 4 Mhz */
  ADCON0 = 0x00;             /* Disable internal ADC */
 
  TRISEbits.RE2 = 0;  //turns on power to LCD via MOSFET                                 ????????????????
  TRISD = 0;    //Make all bits on the Port B (LCD) output bits.
 
  PORTD = 0;    //Reset the LCD bits to 0 
  Delay15ms();
 
    LCDInit();
    LCDChar('S');  //display a S on 1st line
    LCD_GOTO(2,0);
   
    while*text1[index] != 0)        // while text1[index] is'nt zero        ?????????????????
{
    while(text1[index] != 0)        // while text1[index] is'nt zero        ?????????????????
    LCDChhar(text1[index++]);    // write message 1   
    Delay5ms;   
   
     }
   
//    while(1);
    }
 
void Delay5ms(void) {
    Delay1KTCYx(10); // Delay of 5ms
    // Cycles = (TimeDelay * Fosc) / 4
    // Cycles = (5ms * 8MHz) / 4
    // Cycles = 10,000
    return;
}
 
void Delay15ms(void) {
    Delay1KTCYx(30); // Delay of 15ms
    // Cycles = (TimeDelay * Fosc) / 4
    // Cycles = (15ms * 8MHz) / 4
    // Cycles = 30,000
    return;
}
 
void Delay100ms(void)
{
    Delay1KTCYx(100);  //delay 100 ms
}
 
void LCDInit(void) {
    PORTEbits.RE2 = 1;      //turn on LCD power
    Delay100ms();         //100 ms delay to power up LCD
   
    // Set port directions
    TRIS_LCD_DATA &= 0xf0;    // Clear lower 4 bits
    TRIS_LCD_EN = 0;
     TRIS_LCD_RS = 0;
 
    //LCDCmd(FOUR_BIT);            // Nigel's code sends this before the next command?
    LCDCmd(FOUR_BIT & LINES_5X7);
    LCDCmd(INCREMENT & SHIFT_OFF);
    LCDCmd(DISPLAY_ON & BLINK_OFF & UNDERLINE_OFF);
    LCDCmd(CLEAR_DISPLAY);
    Delay15ms();
}
void LCDCmd(unsigned char c) {
    LCD_RS = 0;
 
    LCD_DATA &= 0xf0;
    LCD_DATA |= (c >> 4);
    PulseEnable;
 
    LCD_DATA &= 0xf0;
    LCD_DATA |= (c & 0x0f);
    PulseEnable;
 
    Delay5ms();
}
 
void LCDChar(unsigned char c) {
    LCD_RS = 1;
 
    LCD_DATA &= 0xf0;
    LCD_DATA |= (c >> 4);
    PulseEnable;
 
    LCD_DATA &= 0xf0;
    LCD_DATA |= (c & 0x0f);
    PulseEnable;
 
    Delay5ms();
}
void LCD_GOTO(unsigned char line,unsigned char column)
{
    unsigned char data = 0x80;                // default to 1
    if(line == 2)data = 0xc0;                // change to 2
    data += column;                            // add in  column
    LCDCmd(data);
    Delay5ms();
    }
 
Ok! First off... You don't want this in your code.. "while*text1[index] != 0)"

Secondly... To print characters you'll need to specify the volatile keyword or the compiler will make "text" a constant.. I'm not sure how you are printing at the moment as one while statement is using a pointer.

Try this
C:
while(text[index]!=0)
   {
    LCDchar(text[index++]);
    Delay5ms();
   }
 
Status
Not open for further replies.

Latest threads

Back
Top