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.

C18 Questions

Status
Not open for further replies.
thanks, that made some progress, and got rid of the error, but um...

Code:
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:22:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:27:Error [1105] symbol 'TRISC' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:27:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:30:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:31:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:33:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:34:Warning [2066] type qualifier mismatch in assignment
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:36:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:37:Warning [2066] type qualifier mismatch in assignment
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:40:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\main.h:41:Warning [2058] call of function without prototype
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\LCD.h:65:Error [1109] type mismatch in redeclaration of 'send_cmd'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\LCD.h:66:Error [1109] type mismatch in redeclaration of 'send_data'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\LCD.h:67:Error [1109] type mismatch in redeclaration of 'set_cursor'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\LCD.h:71:Error [1109] type mismatch in redeclaration of 'sc_r'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\LCD.h:75:Error [1109] type mismatch in redeclaration of 'lcd_init'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\delay.h:12:Error [1109] type mismatch in redeclaration of 'delay250ms'
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:6:Error [1105] symbol 'PORTCbits' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:6:Error [1151] struct or union object designator expected
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:6:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:8:Error [1105] symbol 'PORTCbits' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:8:Error [1151] struct or union object designator expected
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:8:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:13:Error [1105] symbol 'PORTC' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:13:Error [1105] symbol 'PORTC' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:13:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:23:Error [1105] symbol 'PORTCbits' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:23:Error [1151] struct or union object designator expected
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:23:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:29:Error [1105] symbol 'PORTCbits' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:29:Error [1151] struct or union object designator expected
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:29:Error [1101] lvalue required
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:122:Error [1105] symbol 'PORTCbits' has not been defined
C:\Documents and Settings\Paul Sisneros\My Documents\pic project\LCD\lcd.c:122:Error [1151] struct or union object designator expected

this is going to take a while
 
It looks like you have things a bit tangled up to put it nicely.

Manyof the undefined symbols should have been defined in the processor header file which is obtained via

#include <p18cxxx.h>

Then there is this sort of error
:65:Error [1109] type mismatch in redeclaration of 'send_cmd'

It looks like you have an improperly setup project.
Others may disagree but I suggest you zip up the entire project and include it as an attachment. That way we can try to build the project and see where you have gone wrong.

3v0
 
Thanks. I think I'll try to untangle it a bit myself before I do that though. I haven't actually spent that much time on it. I only get about an hour a night I can work on this stuff, and thats not uninterupted, so its slow going for my projects. I'm sure I did setup the project wrong. The blog I got it from didnt really say how to set it up. Though I guess if I was expierienced with C18, it would probably be pretty obvious.
 
Triode if you put all the file in one folder and add just the .h files it should work. From what you
posted it's adding the wrong ones.
And LCD.c and delay.c
C18 has a lcd.h and delay.h of it's own I would bet it using them.
 
Last edited:
sorry, im a little confused by what you wrote at the end. What did you mean by "And LCD.c and delay.c " was that in addition to the things I should put in the folder, or the wrong ones?
 
Now that I can see the source it is clear I suggested a different definition for byte

Change
#define byte unsigned char;
to
typedef unsigned char byte; // no # char

That may fix the
Error [1109] type mismatch in redeclaration of 'send_cmd'
sort of errors.

To fix the undefined symbols try replacing
#include <p18cxxx.h>
with an include of the exact file you need.
If you chip were a 18F1320 you would use
#include <p18F1320.h>
Just adjust the number to fit you chip.
See how far that gets you.

3v0
 
Last edited:
Just had a play with this and I had to make a few changes to main.c to get it to compile.
Code:
#include <p18cxxx.h>
#include <stdio.h>
#include <delays.h>
#include "delay.h"              [COLOR="Red"]//added[/COLOR]
#include "LCD.h"

#pragma config OSC = INTIO67    //Internal oscillator
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BOREN = OFF
#pragma config WDT = OFF
#pragma config MCLRE = OFF     //MCLR is disabled
#pragma config LVP = OFF

/*                              [COLOR="red"]//removed[/COLOR]
void delay1s() {
    Delay10KTCYx(200);
}*/         

//User defined putc for user defined output stream
void _user_putc(unsigned char c) {
    send_data(c); //Send character to LCD
}

void main() {
    OSCCON = 0b01110010; //8 MHz
    TRISC = 0x00; //PORTC is all output
    stdout = _H_USER; //Set to user-defined output stream via _user_putc

    lcd_init(); //Initialize the LCD
    send_cmd(0x0C); //Turn off cursor

    set_cursor(1, 1); //Set cursor to row 1, column 1
    printf((far rom char*)"Hello!"); //Print "Hello!" to the LCD    [COLOR="red"]<---changed[/COLOR]

    set_cursor(2, 1); //Set cursor to row 2, column 1
    printf((far rom char*)"HD44780");                 // [COLOR="red"]changed[/COLOR]

    while(1) {
        delay250ms(); //Scroll the display 1 character right every 250 ms
        sc_r();
    }
}

Mike.
 
what is

#pragma config OSC = INTIO67

My spec sheet for 18F1320 doesnt show there being a 67. Just 1 and 2

Thanks for the suggestions, It may be a while before I can implement them since when I get home tonight I'm going to start moving, haha. It may be monday evening before I get to work on my hobby any more. Oh well, thats life when you have to work isn't it?
 
I set MPLAB to use an 18F2620 so I didn't have to go through the code and change PORTC to PORTB. The config labels vary between chips and the 2620 uses INTIO67.

Mike.
 
Yeah, I noticed that I will need to change that too. I'm doing this all on a junebug for now, So idealy I'll be setting it to ports that are easily accessable on the pin strip also.
 
Here the whole thing I think it will run on the junebug it built all right and I change it to use PORTB on a 18f1320 I didn't try it but it looked good
Mike I'm getting better now I know I need some of these {} LOL
I lied I will run on PORTB of a 18f1320 you'll have to do some more adjusting for the junebug
 

Attachments

  • lcdjune.zip
    41.7 KB · Views: 117
Last edited:
How would you do a low order on PORTA you RA1 to RA4 for data
and RB1 could be Enable, RB3 could be Read/write, and RB4 could be Register select
But I don't see how you could do the low order with out RA0
You change this but how I don't no
Code:
void send_nibble(byte b) {
	LCD_PORT = (LCD_PORT & 0x0F) | (b & 0xF0);
	strobe();
 
Last edited:
Maybe this would work Mike or 3v0 maybe let us no
Code:
void send_nibble(byte b) {
	LCD_PORT = (LCD_PORT & 0x1E) | (b & 0x1E);
	strobe();
It'S in the LCD.c
 
Close,

LCD_PORT = (LCD_PORT & 0xE1) | ((b & 0x0f)<<1);

Note, E1 - not 1E.

Mike.
 
So it would be this maybe
Code:
void send_nibble(byte b) {
	LCD_PORT = (LCD_PORT & 0xE1) | ((b & 0x0f)<<1);
	strobe();
Your shifting 1 with the((b & 0x0f)<<1); I see that now
and the E1 makes it use the lower PORTA
LCD.h should look like this
Code:
/*
 * PIC 16F886 HD44780 LCD Driver
 * Author:    solarwind
 * Date:      2009-01-31
 * Email:     x.solarwind.x@gmail.com
 * Compiler:  Microchip C18 (v3.22)
 * 
 * Pin Configuration:
 * 		The LCD's data 4 - 7 pins should be connected to bits 4 - 7,
 * 		respectively, of any port you wish to use on your PIC.
 * 
 * 		The E, R/W and RS pins can be connected to any unused port at
 * 		any pin.
 * 
 * 		My configuration is as follows:
 * 		LCD        PIC
 * 		16 BK-
 * 		15 BK+
 * 		14 D7   -> RA4
 * 		13 D6   -> RA3
 * 		12 D5   -> RA2
 * 		11 D4   -> RA1
 * 		10 D3
 * 		9  D2
 * 		8  D1
 * 		7  D0
 * 		6  E    -> RB1
 * 		5  R/W  -> RB3
 * 		4  RS   -> RB4
 * 		3  VO
 * 		2  VDD
 * 		1  VSS
 * 
 * Note:
 * 		This driver is designed to work with almost any PIC 18. Be sure to
 * 		correctly initialize your PIC, correctly connect your LCD and
 * 		define your connections below.
 * 
 * Note:
 * 		DDRAM Addresses are as follows on 16 x 4 displays:
 * 
 * 		Line 1:  0x00 -> 0x0F
 * 		Line 2:  0x40 -> 0x4F
 * 		Line 3:  0x10 -> 0x1F
 * 		Line 4:  0x50 -> 0x5F
 * 
 */

#ifndef LCD_H_
#define LCD_H_

#include "main.h"

//Define your LCD's data PORT here:
#define LCD_PORT PORTA

//Define your LCD's control pins here:
#define LCD_E  PORTBbits.RB1 //Enable
#define LCD_RW PORTBbits.RB3 //Read/write
#define LCD_RS PORTBbits.RB4 //Register select

void strobe(void);                      //Strobes the enable pin of the LCD
void send_nibble(byte b);               //Send high nibble of byte b to LCD
void send_byte(byte b);                 //Send entire byte b to LCD via 4 bit interface
void send_cmd(byte b);                  //Send command to LCD
void send_data(byte b);                 //Send data to LCD
void set_cursor(byte row, byte col);    //Set cursor position at (row, col)
void cursor_on(void);                   //Turn on cursor
void cursor_off(void);                  //Turn off cursor
void cls(void);                         //Clear screen
void sc_r(void);                        //Scroll all lines one character right
void sc_l(void);                        //Scroll all lines one character left
void home(void);                        //Send cursor to top-left position
byte b2hc(byte data);                   //Convert lower nibble of byte data to an ascii character
void lcd_init(void);                    //Initialize LCD

#endif /*LCD_H_*/
And the the LCD.c should look like this I think
Code:
#include "LCD.h"
#include "delay.h"

void strobe() {
	LCD_E = 1;
	Nop();
	LCD_E = 0;
	Nop();
}

void send_nibble(byte b) {
	LCD_PORT = (LCD_PORT & 0xE1) | ((b & 0x0f)<<1); // changed this to use low pins porta
	strobe();
}

void send_byte(byte b) {
	send_nibble(b); //Send high nibble
	send_nibble(b << 4); //Send low nibble
}

void send_cmd(byte b) {
	LCD_RS = 0; //Command mode
	send_byte(b);
	delay5ms();
}

void send_data(byte b) {
	LCD_RS = 1; //Data mode
	send_byte(b);
	delay100us();
}

void set_cursor(byte row, byte col) {
	byte command = 0x80;
	switch(row) {
	case 1:
		command += col - 1;
		break;
	case 2:
		command += 0x40 + col - 1;
		break;
	case 3:
		command += 0x10 + col - 1;
		break;
	case 4:
		command += 0x50 + col - 1;
		break;
	default:
		command += col - 1;
		break;
	}
	send_cmd(command);
}

void cursor_on() {
	send_cmd(0x0E);
}

void cursor_off() {
	send_cmd(0x0C);
}

void cls() {
	send_cmd(0x01);
}

void sc_r() {
	send_cmd(0x1E);
}

void sc_l() {
	send_cmd(0x18);
}

void home() {
	send_cmd(0x02);
}

byte b2hc(byte data) {	
	switch(data & 0x0F) {
	case 0:
		return '0';
	case 1:
		return '1';
	case 2:
		return '2';
	case 3:
		return '3';
	case 4:
		return '4';
	case 5:
		return '5';
	case 6:
		return '6';
	case 7:
		return '7';
	case 8:
		return '8';
	case 9:
		return '9';
	case 10:
		return 'A';
	case 11:
		return 'B';
	case 12:
		return 'C';
	case 13:
		return 'D';
	case 14:
		return 'E';
	case 15:
		return 'F';
	}
	return 0;
}


void lcd_init() {
	delay100us(); //Delay for LCD to start itself up
	
	LCD_E = 0;
	LCD_RW = 0;
	LCD_RS = 0;
	
	//Start initializing the LCD
	send_nibble(0x30);
	delay5ms();
	send_nibble(0x30);
	delay5ms();	
	send_nibble(0x30);
	delay100us();
	send_nibble(0x20); //4 bit interface
	delay100us();
	
	send_cmd(0b00101000); //Function set: 4 bit interface
	send_cmd(0b00001110); //Display on/off: display on, cursor on, blink off
	send_cmd(0b00000110); //Entry mode: increment, no shift
	send_cmd(0b00000010); //Cursor home
	send_cmd(0b00000001); //Clear DDRAM/LCD
	delay5ms();	
}
 
Last edited:
Multiple source codes in C18

Hi i do have another thread going on but since i found this one so i will go ahead and post my questions here k.

1)Can we have multiple source codes(not included as functions in header files) in a C18 project.This will help if one is working on multiple devices and rather then going through the process of putting the code in to one file(a huge head ache) one can just add them and link them.If so then how?(sorry my C has just dried up...)

2) A question about pointers, by looking at some code (thanks to Mike @ Pommie) i did get some idea of how a pointer can be used. The transfer was understandable and i post my question in the code given below:

ram char dataArray[20]="Test Data";
ram char *pData;

//copy string from rom to ram.
void SetString(ram char* RamString,rom char* RomString){
do{
*RamString++=*RomString;
}while(*RomString++!=0);
}

//in main you can then have,
static rom char HW[]="Hello world";

//You can then do,
SetString(dataArray,(rom char*) "Hello World");
//or
SetString(dataArray,HW);

//you can also do,
pData=dataArray;
chr=*pData;
SetString(pData,(rom char*) "Somert else.");

Courtesy of this thread

https://www.electro-tech-online.com...er-issues-pointers-function-prototypes.37945/

I understand the transfer but then if i want to access the first character of our transferred string then this

char *dstring;
*dstring++=*pdata++;// may be wrong!

Isnt *pdata now pointing to the last element? if i want to access the first element then will have to initialize it at a known location using pragma?

Also i dont get the difference between using and not using *, what does it mean...in Simple C its & so its very clear.
 
Last edited:
To access the first character of the transferred string you would use dataArray[0].

If you have a pointer p then you can set it to point to a variable by doing p=&Var. That is that you set it to the address of Var and so p contains an address. To find out what is contained in Var we have to tell the compiler that we want the value of the location at address p. We do this by using * before the pointer. So, if Var is a char at address 0x23 and we do Var=0x45 then p=&Var will set p to 0x23 and the value of *p will be 0x45.

I don't think I explained that very well.:(

Mike.
 
You did fine,thank you.This is like simple C, i can use this in C18?What does this imply then

pData=dataArray;

It does not specify whether you are using it for addressing or data.Thats what got me confused.

Thanks for your reply.
 
It is a rather confusing way to write it. You need to know the data types of the two variables to know what it is doing. A less confusing way would be,

pData=&dataArray[0];

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top