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.

urgent help in Code!!!!

Status
Not open for further replies.
Works like a charm! Here's engkhlaif's cheat sheet :D
Code:
#include <pic.h>
#include <htc.h>
#include <stdlib.h>
#include <stdio.h>

__CONFIG(XT&WDTDIS&LVPDIS);

void lcd_line1(void);				//function prototypes
void lcd_line2(void);
void lcd_cmd(unsigned char);
void lcd_char(char);
void e_togg(void);
void lcd_init(void);
void lcd_string(char *);
void lcd_busy(void);
unsigned char read_a2d(void);
void delay(void);

#define	E		RD2
#define	RS		RD0
#define RW		RD1
#define	busyflag	RB3
#define RW_TrisBit	TRISD1
#define D7_TrisBit	TRISB3

char number[] = "                ";

int main(void)
{
	int voltage;
	unsigned char a;
	long fract;
	char fract1,fract2;
	ADCON1 = 0b00001110;
	ADCON0 = 0b10000000;
	ADON = 1;
	TRISB = TRISD = 0;
	RW = 0;					//set R/W low
	E = 0;					//set E low
	lcd_busy();				//wait for LCD to settle
	lcd_init();

	while(1)
	{
		a = read_a2d();
		lcd_line1();
		voltage = a;
		voltage*=5;
		fract=((((long)voltage*100)/255)%100);
		fract1=(fract/10)%10;
		fract2=(fract)%10;
		voltage/=255;
		sprintf(number,"A2d = %d.%d%d volts",voltage,fract1,fract2);
		lcd_string(number);
		delay();
	}
}

unsigned char read_a2d(void)
{
	ADGO=1;
	while(ADGO){}
	return(ADRESH);
}

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}	

void lcd_busy(void)
{
	RW_TrisBit = 1;					//make R/W input (read)
	D7_TrisBit = 1;					//make D7 input
	RS = 0;						//set RS low
	RW = 1;						//set R/W high
	E = 1;						//set E high
	while(busyflag);				//wait for busy flag to go low
	E = 0;						//set E low
	RW = 0;						//set R/W low
	TRISB = 0;					//make D7 output
	RW_TrisBit = 0;					//make R/W output (write)
}	
	
void lcd_line1(void)
{
	lcd_cmd(0x80);
}

void lcd_line2(void)
{
	lcd_cmd(0xc0);
}		

void lcd_cmd(unsigned char letter)
{
	lcd_busy();
	PORTB = letter;					//put char in PORTB
	PORTB = PORTB >> 4;				//shift over to output high 4 bits
	RS = 0;						//RS low
	e_togg();					//latch the data
	lcd_busy();
	PORTB = letter;
	RS = 0;						//RS low
	e_togg();					//latch it
}

void lcd_char(char letter)
{
	lcd_busy();
	PORTB = letter;					//put char in PORTB
	PORTB = PORTB >> 4;				//shift over to output high 4 bits
	RS = 1;						//RS high
	e_togg();					//latch the data
	lcd_busy();
	PORTB = letter;
	RS = 1;						//RS high
	e_togg();					//latch it
}

void lcd_init(void)
{
	PORTB = 0x03;					//send 3
	e_togg();
	lcd_busy();
	PORTB = 0x03;
	e_togg();
	lcd_busy();
	PORTB = 0x03;
	e_togg();
	lcd_busy();
	PORTB = 0x02;					//send 2 - set 4-bit mode
	e_togg();
	lcd_busy();
	lcd_cmd(0x28);					//set 4-bit mode and 2 lines
	lcd_busy();
	lcd_cmd(0x10);					//cursor move & shift left
	lcd_busy();
	lcd_cmd(0x06);					//entry mode = increment
	lcd_busy();
	lcd_cmd(0x0d);					//display on - cursor blink on
	lcd_busy();
	lcd_cmd(0x01);					//clear display
	lcd_busy();
}

void e_togg(void)
{
	E=1;
	E=0;
}

void delay(void)
{
	int x,y;
	for(x=0;x<1;x++)
	{
		for(y=0;y<10000;y++){}
	}
}
 
Last edited:
Here's a slightly more elegant solution using 16.16 fixed point maths. The FpToString function suppresses leading zeroes and returns a number of places after the decimal point defined by Digits.

Code:
int Voltage;
unsigned long Fixed;
char number[] = "                ";

    Voltage=104;
    Fixed=((long)Voltage)<<16;
    Fixed*=5;
    Fixed/=255;
    FpToString(number,Fixed,2);


void FpToString( char * String, unsigned long Number, char Digits){
unsigned long work;
int divider=10000;
char chr,i,poss=0;
char LeadingZero=1;    
    work=Number>>16;
    for(i=0;i<5;i++){
        chr=work / divider;
        work-=chr*(long)divider;
        if(chr!=0 || LeadingZero==0 || i==4){
            String[poss++]=chr+0x30;
            LeadingZero=0;
        }
        divider/=10;
    }
    String[poss++]='.';
    work=Number&0xffff;
    for(i=0;i<Digits;i++){
        work*=10;
        String[poss++]=(work>>16)+0x30;
        work&=0xffff;
    }
    if(work>0x8000 &&String[poss-1]!='9'){    //is remainder > 0.5?
        String[poss-1]++;           //round up last digit
    }
    String[poss]=0;
}

Mike.
 
Last edited:
Pommie said:
Here's a slightly more elegant solution using 16.16 fixed point maths. The FpToString function suppresses leading zeroes and returns a number of places after the decimal point defined by Digits.
Excellent! I'm sure I'll find a use for that. I'll test it out tomorrow. I'm going blind from too much time at the computers. :D

Installing LAMP and Joomla on another box right now. Gotta get a client's web-site set up the way he wants it so he'll get off my back. "When are ya gonna do it? When are ya gonna do it? When are ya gonna do it? Waaa! Waaaa! WAAA!" Sigh...
 
Pommie said:
Here's a slightly more elegant solution using 16.16 fixed point maths. The FpToString function suppresses leading zeroes and returns a number of places after the decimal point defined by Digits.


Mike.

dear,
what i want to say is that the reading that i want to get must be displayed on the LCD continuously as the object is moving in the line of sight for the sensor!!!!
so i need first to convert the voltage to digital and then into distance!!!
i try just to display the voltage using this piece of code
Code:
void init_a2d(void)
{
	ADCON0=0;	// select Fosc/2
	ADCON1=0;	// select left justify result. A/D port configuration 0
	ADON=1;		// turn on the A2D conversion module
}
unsigned char read_a2d(unsigned char channel)
{
	channel&=0x07;	// truncate channel to 3 bits
	ADCON0&=0xC5;	// clear current channel select
	ADCON0|=(channel<<3);	// apply the new channel select
	ADGO=1;	// initiate conversion on the selected channel
	while(ADGO)continue;
	return(ADRESH);	// return 8 MSB of the result
}



void main(void)
{
   unsigned char outString[20];
   float voltage;
   unsigned char x;
    init_a2d();	// initialise the A2D module
	GIE=0;

TRISE = 0;
TRISD = 0;
TRISB = 0;
TRISA  = 0x01;;
ADCON1 = 14;
RE2 = 0;
DelayMs(500);
lcd_init();

while(1) {
      lcd_clear();
      lcd_goto(0);
      lcd_puts("Damn!");
      x=read_a2d(0);      
      lcd_goto(40);
      //lcd_puts("Since I use LCDs :-)"); 
     voltage=(x/255.0)*(5.0);  // this equation must convert the reading into voltage
     sprintf(outString,"A2D = %d volts",voltage);    
      lcd_puts(outString);


   
DelayMs(3000);
  }

}
 
Use the code that Futz posted earlier. This will display the voltage to 2 decimal places.

Mike.
 
engkhlaif said:
is the code of Futz suitable for my purpose and i cant compile it using MPLAB !!!!
Hahahahahaha!!! :D :D We do the work for ya and you still can't figure it out? Hilarious! :p

Not only did you say before that you wanted to display voltage - not distance, but your code was trying to display voltage - not distance. Anyway, it's easy enough to convert.

What compiler do you use?
 
engkhlaif said:
is the code of Futz suitable for my purpose and i cant compile it using MPLAB !!!!

We're 5 pages into the thread and you state that you can't compile with MPLAB! I'm hoping it's a language thing. You now have working code, if you can't turn that into a usable project then you do not deserve to be given the title Electronic Engineer or any other such title. Just checked, there is no sad smilie.

Mike.
 
futz said:
Hahahahahaha!!! :D :D We do the work for ya and you still can't figure it out? Hilarious! :p

Not only did you say before that you wanted to display voltage - not distance, but your code was trying to display voltage - not distance. Anyway, it's easy enough to convert.

What compiler do you use?
fisrt of all it seem that my language is not enough to tell what iam exactly want
any way dear at first iam trying to display the voltage on an lCD and if i secced i think it is not a big problem to convert it into distance
but the main problem i faced is that when i compile the first code i posted it gives me an output voltage that is impossibe and here the code
Code:
while(1) {
      lcd_clear();
      lcd_goto(0);
      lcd_puts("Damn!");
      x=read_a2d(0);      
      // lcd_goto(40);
      //lcd_puts("Since I use LCDs :-)"); 
     voltage=(x/255.0)*(5.0);   
     sprintf(outString,"A2D = %d volts",voltage);    
      lcd_puts(outString);
DelayMs(3000);
  }

}
when i turn on and befor connect the sensor into the board i get the reading"A2D =17791 volts"
and i try what Pommie tell me to change ADCON1=7 to ADCON1=0 whith out any change
about ur last posted code i will try in the as iam working in the university lab
iam using PIC16F877A with c lanbuage MPLAB v7.31

iam very sory bcoz my thread was very long
 
Pommie said:
We're 5 pages into the thread and you state that you can't compile with MPLAB! I'm hoping it's a language thing. You now have working code, if you can't turn that into a usable project then you do not deserve to be given the title Electronic Engineer or any other such title. Just checked, there is no sad smilie.

Mike.
u misunderstand me!!!
i mean that when i compile the code it gives me an error: cannot include htc.h it seem that my MPLAB doent contain
any way iam very pleasure to thank u and to ur care
:(
 
Pommie said:
We're 5 pages into the thread and you state that you can't compile with MPLAB! I'm hoping it's a language thing. You now have working code, if you can't turn that into a usable project then you do not deserve to be given the title Electronic Engineer or any other such title. Just checked, there is no sad smilie.

Mike.
u misunderstand me!!!
i mean that when i compile the code it gives me an error: cannot include htc.h it seem that my MPLAB doesnt contain
any way iam very pleasure to thank u and to ur care
:(
 
engkhlaif said:
when i compile the first code i posted it gives me an output voltage that is impossibe and here the code
Code:
while(1) {
      lcd_clear();
      lcd_goto(0);
      lcd_puts("Damn!");
      x=read_a2d(0);      
      // lcd_goto(40);
      //lcd_puts("Since I use LCDs :-)"); 
     voltage=(x/255.0)*(5.0);   
     sprintf(outString,"A2D = %d volts",voltage);    
      lcd_puts(outString);
DelayMs(3000);
  }

}
Geesh engkhlaif, try to follow the conversation. Start reading this thread somewhere back on page 3. Read all the messages. You'll see that we went over this problem and found the probable cause (definite cause in my case) and a pretty good solution too.
 
engkhlaif said:
i mean that when i compile the code it gives me an error: cannot include htc.h it seem that my MPLAB doesnt contain
any way iam very pleasure to thank u and to ur care
:(
htc.h is a Hi-Tech PICC compiler thing. You're going to have to make some small changes to suit your compiler. :rolleyes: Compilers are NOT all the same. C code, especially when written for the same processor, is usually very portable though. But it won't port itself. You have to make some adjustments to suit compiler differences.

And MPLAB is NOT a compiler. It is an IDE, or Integrated Development Environment. You can use many different assemblers and compilers with MPLAB.
 
Last edited:
futz said:
And MPLAB is NOT a compiler. It is an IDE, or Integrated Development Environment. You can use many different assemblers and compilers with MPLAB.
ok i get it iam using PICC in MPLAB enviroment i will ry every thing you and pommie told me about and i hope that i will get results

thanx agian
 
Code:
#include <pic.h>
#include <htc.h>
#include <stdlib.h>
#include <stdio.h>

__CONFIG(XT&WDTDIS&LVPDIS);

void lcd_line1(void);				//function prototypes
void lcd_line2(void);
void lcd_cmd(unsigned char);
void lcd_char(char);
void e_togg(void);
void lcd_init(void);
void lcd_string(char *);
void lcd_busy(void);
unsigned char read_a2d(void);
void delay(void);

#define	E		RE2
#define	RS		RE0
#define RW		RE1
#define	busyflag	RB3
#define RW_TrisBit	TRISE1
#define D7_TrisBit	TRISB3

char number[] = "                ";

int main(void)
{
	int voltage;
	unsigned char a;
	long fract;
	char fract1,fract2;
	ADCON1 = 0b00001110;
	ADCON0 = 0b10000000;
	ADON = 1;
	TRISB = TRISE = 0;
	RW = 0;					//set R/W low
	E = 0;					//set E low
	lcd_busy();				//wait for LCD to settle
	lcd_init();

	while(1)
	{
		a = read_a2d();
		lcd_line1();
		voltage = a;
		voltage*=5;
		fract=((((long)voltage*100)/255)%100);
		fract1=(fract/10)%10;
		fract2=(fract)%10;
		voltage/=255;
		sprintf(number,"A2d = %d.%d%d volts",voltage,fract1,fract2);
		lcd_string(number);
		delay();
	}
}

unsigned char read_a2d(void)
{
	ADGO=1;
	while(ADGO){}
	return(ADRESH);
}

void lcd_string(char *senpoint)
{
	while(*senpoint != '\0')
	{
		lcd_char(*senpoint);
		senpoint++;
	}
}	

void lcd_busy(void)
{
	RW_TrisBit = 1;					//make R/W input (read)
	D7_TrisBit = 1;					//make D7 input
	RS = 0;						//set RS low
	RW = 1;						//set R/W high
	E = 1;						//set E high
	while(busyflag);				//wait for busy flag to go low
	E = 0;						//set E low
	RW = 0;						//set R/W low
	TRISB = 0;					//make D7 output
	RW_TrisBit = 0;					//make R/W output (write)
}	
	
void lcd_line1(void)
{
	lcd_cmd(0x80);
}

void lcd_line2(void)
{
	lcd_cmd(0xc0);
}		

void lcd_cmd(unsigned char letter)
{
	lcd_busy();
	PORTB = letter;					//put char in PORTB
	PORTB = PORTB >> 4;				//shift over to output high 4 bits
	RS = 0;						//RS low
	e_togg();					//latch the data
	lcd_busy();
	PORTB = letter;
	RS = 0;						//RS low
	e_togg();					//latch it
}

void lcd_char(char letter)
{
	lcd_busy();
	PORTB = letter;					//put char in PORTB
	PORTB = PORTB >> 4;				//shift over to output high 4 bits
	RS = 1;						//RS high
	e_togg();					//latch the data
	lcd_busy();
	PORTB = letter;
	RS = 1;						//RS high
	e_togg();					//latch it
}

void lcd_init(void)
{
	PORTB = 0x03;					//send 3
	e_togg();
	lcd_busy();
	PORTB = 0x03;
	e_togg();
	lcd_busy();
	PORTB = 0x03;
	e_togg();
	lcd_busy();
	PORTB = 0x02;					//send 2 - set 4-bit mode
	e_togg();
	lcd_busy();
	lcd_cmd(0x28);					//set 4-bit mode and 2 lines
	lcd_busy();
	lcd_cmd(0x10);					//cursor move & shift left
	lcd_busy();
	lcd_cmd(0x06);					//entry mode = increment
	lcd_busy();
	lcd_cmd(0x0d);					//display on - cursor blink on
	lcd_busy();
	lcd_cmd(0x01);					//clear display
	lcd_busy();
}

void e_togg(void)
{
	E=1;
	E=0;
}

void delay(void)
{
	int x,y;
	for(x=0;x<1;x++)
	{
		for(y=0;y<10000;y++){}
	}
}[CODE]

i have modifeid ur code to get the controls of LCD at pins 0,1,2 of PORTE 
as u see above 
but the problem that when i connect the power the LCD givesa ablank 
i connedt the output of LCD AS below:
LCD  PIC
11    RB4
12  RB5
13  RB6
14 RB7
 
Last edited:
engkhlaif said:
i have modifeid ur code to get the controls of LCD at pins 0,1,2 of PORTE as u see above but the problem that when i connect the power the LCD givesa a blank i connect the output of LCD AS below:
LCD PIC
11 RB4
12 RB5
13 RB6
14 RB7
First, when you use code tags, the end tag needs a / before the word code or you get the mess you see in your post. Always preview your post to see what it looks like before posting.

Second, you'll have to modify the functions lcd_init, lcd_cmd and lcd_char to suit where you connected your LCD data lines. It's not initializing properly, and even if it did it would never display anything, since you're putting the four bits of data in the wrong place in PortB. My code assumes RB0-RB3 for data. You've plugged your data lines into RB4-RB7. The LCD never gets any real data so it can never work. Modify those routines and it should work.

Now I'm starting to wonder... Your original code - did you write it? Or did you just download it from somewhere, and don't have any idea how it works? :p If this is all just magic to you and you don't actually know how to program, you're going to have a tough time with it.
 
Last edited:
first i will be very clear with u
the code i have posted i make a modification on it so that i can suit it with my purpose you know this is my lasy semester and iam registered to 20Hours (9 cources)
the original code i get it from the samples in the HI-TECH when i install the MPLAB
and about the LCD why i connedt it to the high (B4-B7) the code i poste it at the begenning of my posts requires to do that !!!
so is that to get a sample code and then modify it to suite ur ampition wrog thing!!! advice me
 
engkhlaif said:
first i will be very clear with u
the code i have posted i make a modification on it so that i can suit it with my purpose you know this is my lasy semester and iam registered to 20Hours (9 cources)
the original code i get it from the samples in the HI-TECH when i install the MPLAB
and about the LCD why i connedt it to the high (B4-B7) the code i poste it at the begenning of my posts requires to do that !!!
so is that to get a sample code and then modify it to suite ur ampition wrog thing!!! advice me
Nothing wrong with that. But you need to understand the code so you can modify it. You posted my code above with a couple minor mods, but you haven't made the most important modifications necessary. As posted it will NOT work as long as your LCD data lines are at RB4 to RB7.

You have to make the changes I told you about. Either change the code so it puts the data bits at RB4 to RB7, or leave the code as is and connect your LCD data lines to RB0 to RB3.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top