Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

passing decimal value to TXREG register in PIC16F877A.

Status
Not open for further replies.

dheeruparu

Newbie level 4
Joined
Jul 17, 2010
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,355
Hi,Iam a newbie to PICs.
My project uses PIC16F877A to monitor temperature and transmit it serially as wellas display it on LCD.
I have a problem while passing the value to TXREG register for serial transmission.

The value of temperature varies and is an integer value.While displaying the value on LCD,Proteus simulator displays the value perfectly!
But the TX pin data is scrambled as i just pass the value given to LCD directly to TXREG register.
I want to know if there is a way to convert this integer value to binary before passing it to TXREG register.

The code snippet is as follows:
TXSTA = 0b00100010;
RCSTA = 0b10010000;
SPBRG=25;
while(!TRMT);
TXREG=tr;

tr has the calculated decimal value as integer.

this is where my doubt arises.Is the output wrong because Iam passing the decimal value directly to TXREG or is it due to any error in program elsewhere?

Please help me as early as possible... :-(
 

Hi,
You can pass on any value (decimal, binary or hex) but it has to be 8-bit. Is integer in your compiler 8-bits? It is most likely due to an error in the program elsewhere.

Hope this helps.
Tahmid.
 
ok.I'll put the entire program here if u don't mind.Tell me where Iam wrong.


#include<pic.h>
#include<math.h>
#include"lcd.h"
#include"delay.h"


void disp(float); // prototype declaration of a function to display a float number
char lookup(int); //prototype declaration of a function to find ASCII code for digits
void main() // main program begins
{
lcd_init();
unsigned x,y,c=0x100,z;
float p,tmpr,f;
ADCON0=0; //ADC channel-1 (AN0) is selected,A/D clock=Fosc/4
TRISA=1;
ADCON1=0xCE; //RA0 configured as ananlog (AN0),A/D result Right justified,A/D clock=Fosc/4
ADCON0=ADCON0|1; //ADC is turned on
while(1) //infinite loop
{
ADCON0=ADCON0|4; //A/D conversion begins
while(1)
{
if(ADCON0==0x01)
break;
} //A/D conversion ends
x=ADRESH; //ADC result higher 2 bits
y=ADRESL; //ADC result lower 8 bits
PIR1=PIR1&~64; //ADC interrupt flag is cleared
z=x*c+y; //combined 10 bit number formation
f=z; //unsigned to float conversion
p=(f*5)/1023; //equivalent voltage calculation from ADC output
tmpr=p*100; //sensor output voltage to degree Celsius conversion
disp(tmpr); //call of disp(float) to display the temperature
}
} //main program ends

void disp(float num)
{
int x1,x2,x3,x4,n,temp,tr;
static float f1;
char ch1,ch2,ch3,ch4,dot='.';
n=num;
temp=num;
x1=n%10;
n=n/10;
x2=n%10;
n=n/10;
x3=n%10;
f1=num-temp;
x4=f1*10;
ch1=lookup(x3);
ch2=lookup(x2);
ch3=lookup(x1);
ch4=lookup(x4);
tr=(x3*100+x2*10+x1);
TXSTA = 0b00100010; // Initialize the TX
RCSTA = 0b10010000; // Initialize the RX
SPBRG=25;
while(!TRMT);
TXREG=0d(tr);
lcd_goto(0);
lcd_putch(ch1);
lcd_putch(ch2);
lcd_putch(ch3);
lcd_putch(dot);
lcd_putch(ch4);
lcd_puts(" deg cel");
}

char lookup(int no)
{
char cha;
switch(no)
{
case 0:
cha='0';
break;
case 1:
cha='1';
break;
case 2:
cha='2';
break;
case 3:
cha='3';
break;
case 4:
cha='4';
break;
case 5:
cha='5';
break;
case 6:
cha='6';
break;
case 7:
cha='7';
break;
case 8:
cha='8';
break;
case 9:
cha='9';
break;
}
return cha;
}

Thanx in advance. :)
 

You can't send a number containing 4 digits and a decimal point in one operation. You have three options, first is to send each digit individually to TXREG as you do to the LCD, second is to scale the result so it falls in the range 0 to 0xFF so it will fit in a single byte before sending it. Option 3 is to use the full value but split it's binary value (tr) into smaller sections. tr is an int so it uses 16 bits, if you use TXREG = (tr & 0xFF00) >> 8; it will send the top 8 bits then use TXREG = tr & 0xFF; it will send the lower 8 bits. You will have to check the transmit buffer is empty before loading TXREG in both cases.

Brian.
 
Iam not sending the last decimal bit at all.
x4 is the decimal point bit! Iam sending only x1,x2 and x3.So there is no problem of sending the last decimal point.
But your reply has given me another method as well.Thanks a lot.
Now without the decimal point is the program alright?

transmit buffer check is done by using this right?

while(!TRMT)
so,if i write
TXREG=(tr & 0xFF00)>>8;
while(!TRMT)
TXREG=tr & 0xFF;


Will it be right?
 

It should work as long as the while(!TRMT) really waits before moving on to the next instruction. some compilers may show an error because the while statement has no body. If it causes a problem place {} after it to make it think it has something to do. In particular, beware that some code optimizers may see it has no body and remove the instruction completely!

The way it works is this:
The value is stored as an integer so it has 16 bits. For this example I'm going to use the value 0xCC55:
CC55 in binary is 1100 1100 0101 0101
ANDing it with 0xFF00 gives 1100 1100 0000 0000
Shifting it 8 places to the right gives 1100 1100 so you have the high 8 bits moved to the low 8 bit positions ready to send
ANDing it with 0xFF removes the top 8 bits so you have 0101 0101 which is ready to send.

Brian.
 
Ok.Fine Thanks a lot.Will try it and see.

Another question:
My project involves me to receive this transmitted data on PC via USB and through LabVIEW software Iam trying to display this value on screen.
If i send higher 8 bits and then lower 8 bits then,how must I configure it in LabVIEW to display all bits together in analog form?

Btw,Iam using VISA in LabVIEW to input data from USB.I dunno much abt it,so it wud be helpful if u can tell me.

Thanx in advance.
 

Is there anyway of passing the value obtained in ADCON0 register directly to TXREG so that i can manipulate the analog values in LabVIEW??

I tried you method of separating the 8 bits from 16 bits but, it seems Iam not gerring what is expected.I'll post the output below.

Here's d new modified code:


#include<pic.h>
#include<math.h>
#include"lcd.h"
#include"delay.h"


void disp(float); // prototype declaration of a function to display a float number
char lookup(int); //prototype declaration of a function to find ASCII code for digits
void main() // main program begins
{
lcd_init();
unsigned x,y,c=0x100,z;
float p,tmpr,f;
ADCON0=0; //ADC channel-1 (AN0) is selected,A/D clock=Fosc/4
TRISA=1;
ADCON1=0xCE; //RA0 configured as ananlog (AN0),A/D result Right justified,A/D clock=Fosc/4
ADCON0=ADCON0|1; //ADC is turned on
while(1) //infinite loop
{
ADCON0=ADCON0|4; //A/D conversion begins
while(1)
{
if(ADCON0==0x01)
break;
} //A/D conversion ends
x=ADRESH; //ADC result higher 2 bits
y=ADRESL; //ADC result lower 8 bits
PIR1=PIR1&~64; //ADC interrupt flag is cleared
z=x*c+y; //combined 10 bit number formation
f=z; //unsigned to float conversion
p=(f*5)/1023; //equivalent voltage calculation from ADC output
tmpr=p*100; //sensor output voltage to degree Celsius conversion
disp(tmpr); //call of disp(float) to display the temperature
int tr=z;
TXSTA = 0b00100010; // Initialize the TX
RCSTA = 0b10010000; // Initialize the RX
SPBRG=25;
TXREG=((tr&0xFF00)>>8);

TXREG=(tr&0xFF);


}
} //main program ends

void disp(float num)
{
int x1,x2,x3,x4,n,temp,tr;
static float f1;
char ch1,ch2,ch3,ch4,dot='.';
n=num;
temp=num;
x1=n%10;
n=n/10;
x2=n%10;
n=n/10;
x3=n%10;
f1=num-temp;
x4=f1*10;
ch1=lookup(x3);
ch2=lookup(x2);
ch3=lookup(x1);
ch4=lookup(x4);
lcd_goto(0);
lcd_putch(ch1);
lcd_putch(ch2);
lcd_putch(ch3);
lcd_putch(dot);
lcd_putch(ch4);
lcd_puts(" deg cel");
}

char lookup(int no)
{
char cha;
switch(no)
{
case 0:
cha='0';
break;
case 1:
cha='1';
break;
case 2:
cha='2';
break;
case 3:
cha='3';
break;
case 4:
cha='4';
break;
case 5:
cha='5';
break;
case 6:
cha='6';
break;
case 7:
cha='7';
break;
case 8:
cha='8';
break;
case 9:
cha='9';
break;
}
return cha;
}

I'vew uploaded the image below.The sensor temp is at 100 degrees n LCD displays 100 as well.But the oscilloscope gives some absurd output!!!
Please help!

dheeraj.
83_1295445324.png
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top