Electronic Projects, forums and more.

Go Back   Electronic Circuits Projects Diagrams Free > Electronics Categories > Micro Controllers


Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc.

Reply
 
Tools
Old 10th July 2009, 06:12 PM   #76
Default

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 by be80be; 10th July 2009 at 06:26 PM.
be80be is offline  
Old 11th August 2009, 07:19 AM   #77
Default 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:

Quote:
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

PIC C18 Compiler Issues: Pointers, Function Prototypes

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.
__________________
Syed

Last edited by Wond3rboy; 11th August 2009 at 07:29 AM.
Wond3rboy is offline  
Old 11th August 2009, 03:48 PM   #78
Default

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.
Pommie is online now  
Old 11th August 2009, 05:16 PM   #79
Default

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.
__________________
Syed
Wond3rboy is offline  
Old 12th August 2009, 01:13 AM   #80
Default

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.
Pommie is online now  
Old 12th August 2009, 07:25 AM   #81
Default

Code:
#include<p18f1320.h>
char * data=00;// Initiazlizes it to zero so the array is saved on 
			   // first location and one can retrieve it.

void main(void)
{
rom near char * pname;
static rom near char name[]="Hi";
pname=name;//pointer points to first element of name
*data++=*pname++;
*data ++=*pname++;
data=data+20;;
pname=name;
*data++=*pname++;
*data ++=*pname++;
while(1);
}


//void main(void)
//{
////static rom near char name[]="Hi";
//*data++=name[];
//*data ++=pname[];
//while(1);
//}
Hi I was doing little code examples and creating a little pointer flash card like thing for my self in the process.The code in the comments works fine.As you can see that one can initialize a pointer at a specific location but what the problem is that cant seem to reinitialize it with the statement:

data=0x20;

It says wrong assignment.But the addition thing works fine.

I want to first store it from ram location 00 and then be able to access it using the pointer.Also & is illegal in C18.
__________________
Syed

Last edited by Wond3rboy; 12th August 2009 at 07:49 AM.
Wond3rboy is offline  
Old 12th August 2009, 09:43 AM   #82
Default

When you are working in C, you can't just write to any memory. The C compiler will allocate memory and if you need a block for yourself then you should allocate it as an array. You can do malloc in BoostC but I'm not sure in C18.

Why do you say & is illegal? You can do,
Code:
#include<p18f1320.h>

char chrArray[40];
char * data=chrArray;

void main(void)
{
rom near char * pname;
static rom near char name[]="Hi";
    pname=&name[0]      ;//pointer points to first element of name
    *data++=*pname++;
    *data ++=*pname++;
    data=data+20;       //will point to chrArray+22 (20+2 increments)
    pname=name;
    *data++=*pname++;
    *data ++=*pname++;
    while(1);
}
After running the above, chrArray[0] will contain H and charArray[22] will also contain H.

Mike.
Pommie is online now  
Old 12th August 2009, 10:20 AM   #83
Default

Quote:
Originally Posted by Wond3rboy
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...)
Yes. Just add the .c source file to you project. Note that this does not move a copy of the file to your project director it just includes the file from where it is at.

You can also link in compiled objects by adding .o files to the objects list.

3v0
__________________
Please post questions to the forums. PM's are for personal communication.

BCHS/3v0's Tutorials
Junebug USB PIC programmer kit., USB Bit Whacker,
The 15 Minute Printed Circuit Board! (+drill time)

Last edited by 3v0; 12th August 2009 at 10:20 AM.
3v0 is online now  
Old 12th August 2009, 11:30 AM   #84
Default

Just to make this clear as possible

Bit Manipulation:
PORTAbits.RA1 - Use this to read a bit/pin value (can be used like LATA also)
LATAbits.LATA1 - Use this to set a pin High or Low
TRISAbits.TRISA - Use this to set a pin input or output

Byte(whole port) Manipulation:
PORTA - Modifying this will alter every pin on PORTA/LATA register. Reading it will result in all PORTA pins data.
LATA - Modifying this will alter every pin on LATA/PORTA register
TRISA - Modifying this will alter every pin in TRISA register
AtomSoft is offline  
Old 12th August 2009, 02:17 PM   #85
Default

Thanks for your replies all.

Quote:
Originally Posted by 3v0 View Post
Yes. Just add the .c source file to you project. Note that this does not move a copy of the file to your project director it just includes the file from where it is at.

You can also link in compiled objects by adding .o files to the objects list.

3v0
Thanks had posted a question here but worked it all out.In order to use multiple source files in our project, we need to have one file with main and all that stuff and others which simply define functions and their respective variables.And arguments to functions need not be declared as global variables.
__________________
Syed

Last edited by Wond3rboy; 12th August 2009 at 02:37 PM.
Wond3rboy is offline  
Old 12th August 2009, 02:27 PM   #86
Default

you have to include the PICs header. Or the generic which is p18cxxx.h.

When you include that it will have all the definitions for the selected device in MPLAB.
Meaning it looks for your device setting in mplab and uses the appropriate header..

So if 18f1320 is selected in MPLAB it will use.... p18f1320.h

Which includes the definitions and info for every register on that pic.

EDIT:
Reuse is up to how you code it. If you use definitions in your code then its easy to move over to other PICs and even to AVRs and ARMs.

I have taken most of my PIC code and turned it into ARM in minutes. Its easy! as long as you code it right.

Instead of straight calling like

LATAbits.LATA1 = 0;

Define it :

#define LED_Ready LATAbits.LATA1

and in your code use

LED_Ready = 0;

This way when you move it over you can alter just the definition and the rest of the code follows

Last edited by AtomSoft; 12th August 2009 at 02:30 PM.
AtomSoft is offline  
Old 12th August 2009, 02:38 PM   #87
Default

Thanks for the pointer Atomsoft.I was editing my previuos query.
__________________
Syed

Last edited by Wond3rboy; 12th August 2009 at 02:38 PM.
Wond3rboy is offline  
Old 12th August 2009, 03:00 PM   #88
Default

heh ok just noticed it above
AtomSoft is offline  
Old 16th August 2009, 01:55 PM   #89
Default Thanks for the thread 3V0!

Hi, i wanted a bit to be used for indication but found out that C18 doesnt support the bit data type.

Secondly, a question regarding multiple source files.Is there some way one can have variables that are accessible in both files?
__________________
Syed
Wond3rboy is offline  
Old 16th August 2009, 02:15 PM   #90
Default

Quote:
Originally Posted by Wond3rboy View Post
Hi, i wanted a bit to be used for indication but found out that C18 doesnt support the bit data type.

Secondly, a question regarding multiple source files.Is there some way one can have variables that are accessible in both files?
The extern variable qualifer tells the compiler what the variable looks like but does not allocate any storage. You can declare the same variable in as many files as you like but make it extern in all but one.
shareStuff.h
Code:
extern int shareVar;
shareStuff.c
Code:
int shareVar;
All files that use shareVar must include shareStuff.h and shareStuff.c must be in the source file list.
Maybe if you give a bit more detail on what you mean by indication we can help you on your bit problem.

3v0
__________________
Please post questions to the forums. PM's are for personal communication.

BCHS/3v0's Tutorials
Junebug USB PIC programmer kit., USB Bit Whacker,
The 15 Minute Printed Circuit Board! (+drill time)

Last edited by 3v0; 16th August 2009 at 02:24 PM.
3v0 is online now  
Reply

Tags
c18, questions

Thread Tools
Display Modes


Similar
Title Starter Forum Replies Latest
A few questions erosennin Feedback/Comments 24 29th November 2007 12:08 AM
2 questions juan123 Electronic Projects Design/Ideas/Reviews 5 27th September 2007 03:46 AM
A few questions. Marks256 General Electronics Chat 55 5th August 2006 11:49 PM
few questions Victor Frankenstein General Electronics Chat 13 5th July 2005 07:29 PM
Questions? Philipc Electronic Projects Design/Ideas/Reviews 4 7th August 2003 07:18 PM



All times are GMT. The time now is 06:34 AM.


Electronic Circuits  |  Learning Electronics
eXTReMe Tracker