Paritoshgiri
Member level 5
I still can't figure out the problem. When I change the input voltage, the characters in the hyperterminal changes, which means something is working. Might there be any problem with ASCII conversion? Please help....
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Thank u so much for your suggestion Bjuric. I tried the following code:
[CODE TXSTA = 0x20;
SPBRG = 77;
TXSTAbits.TXEN = 1;
RCSTAbits.SPEN = 1;
Send_Value();
SPBRG=77 will set the bud rate at 4006 bps
Then what value you are setting in Hyperterminal? In Hyperterminal , BPS values are available like 1200, 2400, 4800, 9600 etc. Also set the same bud rate for COM port of your PC
What frequency are you looking at?SPBRG=77 will set the bud rate at 4006 bps
Thank u so much for your help. I used SPBRG = 77; and the serial communication is up and running
I still can't figure out the problem. When I change the input voltage, the characters in the hyperterminal changes, which means something is working. Might there be any problem with ASCII conversion? Please help....
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
Thank u for the reply. For TXSTA I was using 0x20 before and was working well for serial communication. Do I need to change it?What frequency are you looking at?
You forgot to set the ADCON2 register.
Try this for main().
Code:TRISA = 0b00000001; ADCON0 = 0b00000001; // A/D is ON ADCON1 = 0b00001110; // Vref- set to Vss // Vref+ set to Vdd // AN0 is analog - others are digital ADCON2 = 0b10111110; // right justify // Acq time 20TAD // clk Fosc/64 TXSTA = 0b10100010; // 8-bit // async // low speed (BRGH=0) RCSTA = 0b10010000; SPBRG = 77;
I didn't test this.
void main
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
Read_ADC();
Send_Value(voltage);
}
No, it's OK. I just did it from scratch, but the result is the same.Thank u for the reply. For TXSTA I was using 0x20 before and was working well for serial communication. Do I need to change it?
Vref is set at RA3(AN3), so it would be the 5th pin.. Check the pinout for the MCU.And about the reference voltage, I was giving a 5V reference voltage to AN1 i.e. 3rd pin. Do I need to give it to the AN3 i.e. 5th pin?
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (unsigned char c);
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
Read_ADC();
Send_Value(voltage);
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023; //10 bit ADC
}
void Send_Value (unsigned char c)
{
char ch;
ch = (voltage/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (voltage/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = (voltage/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = voltage % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
}
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
Read_ADC();
Send_Value();
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023; //10 bit ADC
}
void Send_Value (void)
{
char ch;
ch = (voltage/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (voltage/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = (voltage/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = voltage % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
}
while (PIR1bits.TXIF == 0){ Nop(); }
main(void)
{
....
....
while(1)
{
Read_ADC();
Send_Value();
// call delay routine here
}
}
I think the last character does not show because TXREG gets filled, that is while() doesn't work properly. Try adding empty instruction cycle in while loop.
This should work in MPLAB.Code:while (PIR1bits.TXIF == 0){ Nop(); }
Try adding some delay between readings, do it like this in a while loop... just, I again don't know how to do a delay in MPLAB, you're on your own on that.
I also got the same weird output without the delay (mine was .50 ).
Code:main(void) { .... .... while(1) { Read_ADC(); Send_Value(); // call delay routine here } }
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
while (PIR1bits.TXIF == 0);
Nop();
Read_ADC();
Send_Value();
Delay10KTCYx(240); //Delay 200 ms
Delay10KTCYx(240); //Delay 200 ms
}
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023; //10 bit ADC
}
void Send_Value (void)
{
char ch;
ch = (voltage/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (voltage/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = (voltage/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = voltage % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
}
while (PIR1bits.TXIF == 0){ Nop(); }
while (PIR1bits.TXIF == 0) //semicolon removed from here
Nop();
Nop() is one empty cycle. It's used when you have to have a command in some place without actually doing anything.
Use the command as I posted:
Code:while (PIR1bits.TXIF == 0){ Nop(); }
I see you removed brackets, which is OK, but than you need to remove the semicolon at the end of the while statement
Code:while (PIR1bits.TXIF == 0) //semicolon removed from here Nop();
With that semicolon in place, you've got the same code as before, only one empty cycle after.
Without the semicolon, while statement will execute Nop() over and over again.
That's why I use brackets... removes this hard to spot mistakes.
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
while (PIR1bits.TXIF == 0)
{
Nop();
}
Read_ADC();
Send_Value();
Delay10KTCYx(240); //Delay 200 ms
Delay10KTCYx(240); //Delay 200 ms
}
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023; //10 bit ADC
}
void Send_Value (void)
{
char ch;
ch = (voltage/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (voltage/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = (voltage/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = voltage % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
}
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
while (PIR1bits.TXIF == 0);
Nop();
Read_ADC();
Send_Value();
Delay10KTCYx(240); //Delay 200 ms
Delay10KTCYx(240); //Delay 200 ms
}
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023; //10 bit ADC
}
void Send_Value (void)
{
char ch;
ch = (voltage/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
TXREG = 'T';
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (voltage/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = 'E';
ch = (voltage/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = 'S';
ch = voltage % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = 'T';
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
}
What will be stored in voltage? Think yourself.unsigned long voltage;
voltage = voltage * 5000; //Vref is in milliVolts
voltage = voltage/1023;
Supose u apply 2.5 volt to ADC
So it will conver it into binary (0111111111) or it will eqaul to 511 in decimal.
Voltage = 511 * 5 / 1023
or Voltage = 2.497 (It is not an integer)
So in your code,
What will be stored in voltage? Think yourself.
long adc;
int voltage;
float result;
result=(float)(voltage*5)/1023;
adc=result*1000;
Now send the digits of adc one by one (remember the decimal place)
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long adc;
unsigned float result;
unsigned int voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0b00001110;
// Vref- set to Vss
// Vref+ set to Vdd
// AN0 is analog - others are digital
ADCON2 = 0b10111110;
// right justify
// Acq time 20TAD
// clk Fosc/64
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
while (PIR1bits.TXIF == 0)
{
Nop();
}
Read_ADC();
Send_Value();
Delay10KTCYx(240); //Delay 200 ms
Delay10KTCYx(240); //Delay 200 ms
}
}
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
result = (float)(voltage * 5)/1023;
adc = result * 1000;
//voltage = voltage * 5000; //Vref is in milliVolts
//voltage = voltage/1023; //10 bit ADC
}
void Send_Value (void)
{
char ch;
ch = (adc/1000) % 10; //extract thousands digit
ch = ch + 48; // now it is in ASCII
while (PIR1bits.TXIF == 0);
{
TXREG = ch;
}
while (PIR1bits.TXIF == 0);
TXREG = '.'; //We need a decimal point
ch = (adc/100) % 10; //extract hundredth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = (adc/10) % 10; //extract tenth digit
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
ch = adc % 10;
ch = ch + 48;
while (PIR1bits.TXIF == 0);
TXREG = ch;
while (PIR1bits.TXIF == 0);
TXREG = 0x0D;
}