papunblg
Advanced Member level 3
- Joined
- Oct 22, 2010
- Messages
- 716
- Helped
- 172
- Reputation
- 344
- Reaction score
- 165
- Trophy points
- 1,343
- Location
- Kolkata India
- Activity points
- 6,421
I have attached a schematic. I have not shown the schematics of MAX 232.For a stable 5 Volt supply, voltage =1023.(Full scale). Use Send_Value () to send the content of voltage variable to Hyperterminal and check what is getting printed. If it is different (it should be 1023) Check the voltage of Vref+ pin(pin 5). How the Vref+ is connected. Publish the Schematic.
Refresh my memory. What compiler are you using, Microchip C18 or HiTech PICC18?
Is this your last code revision?
Post #40
BigDog
Mr. Paritosh Giri,
I will request you once again to run the code using
void main(void)
{
ADCON0 = 0b00000001;
ADCON1 = 0;
ADCON2 = 0b10111110;
TRISA = 0b00000001;
TXSTA = 0b10100010;
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
Delay10KTCYx(5);
ADCON0bits.GO=1;
while(ADCON0bits.GO); //dont forget the ; here
Read_ADC();
Send_Value();
Delay10KTCYx(240); //Delay 200 ms
Delay10KTCYx(240); //Delay 200 ms
}
}
---------- Post added at 16:06 ---------- Previous post was at 15:41 ----------
with the above main change this function also
void Read_ADC (void)
{
voltage = 0; //globally defined as unsigned long
//wait for EOC
voltage = (ADRESH << 8) | ADRESL; //combines two bytes into a long int
result = (float)(voltage * 5)/1023;
adc = result * 1000;
}
#include <p18f4550.h>
#include <delays.h>
#include <stdlib.h>
void Read_ADC(void);
void Send_Value (void);
unsigned long adc;
unsigned float result;
unsigned long voltage;
void main(void)
{
TRISA = 0b00000001;
ADCON0 = 0b00000001;
// A/D is ON
ADCON1 = 0;
// 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)
{
Delay10KTCYx(5);
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.GO);
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
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;
}
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 (TXSTA.TRMT == 0);
Read_ADC();
Send_Value();
Delay_ms(500);
}
}
void Read_ADC (void)
{
voltage = 0;
ADCON0.GO = 1;
while (ADCON0.DONE == 1);
voltage = (ADRESH << 8) | ADRESL;
voltage = voltage * 5000;
voltage = voltage / 1023;
}
void Send_Value (void)
{
char ch;
ch = (voltage/1000) % 10;
ch = ch + 48;
while (TXSTA.TRMT == 0);
TXREG = ch;
while (TXSTA.TRMT == 0);
TXREG = '.';
ch = (voltage/100) % 10;
ch = ch + 48;
while (TXSTA.TRMT == 0);
TXREG = ch;
ch = (voltage/10) % 10;
ch = ch + 48;
while (TXSTA.TRMT == 0);
TXREG = ch;
ch = voltage % 10;
ch = ch + 48;
while (TXSTA.TRMT == 0);
TXREG = ch;
while (TXSTA.TRMT == 0);
TXREG = 0x0D;
}
For some reason, testing the PIR1.TXIF bit makes one byte vanish. Testing the TXSTA.TRMT bit, however, works well.
I've tested once again the code on my dev board with P18F2420 @ 20MHz.
This is the working code for MikroC:
Only difference in the code is that I used SPBRG=207 for 20MHz Fosc.Code: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 (TXSTA.TRMT == 0); Read_ADC(); Send_Value(); Delay_ms(500); } } void Read_ADC (void) { voltage = 0; ADCON0.GO = 1; while (ADCON0.DONE == 1); voltage = (ADRESH << 8) | ADRESL; voltage = voltage * 5000; voltage = voltage / 1023; } void Send_Value (void) { char ch; ch = (voltage/1000) % 10; ch = ch + 48; while (TXSTA.TRMT == 0); TXREG = ch; while (TXSTA.TRMT == 0); TXREG = '.'; ch = (voltage/100) % 10; ch = ch + 48; while (TXSTA.TRMT == 0); TXREG = ch; ch = (voltage/10) % 10; ch = ch + 48; while (TXSTA.TRMT == 0); TXREG = ch; ch = voltage % 10; ch = ch + 48; while (TXSTA.TRMT == 0); TXREG = ch; while (TXSTA.TRMT == 0); TXREG = 0x0D; }
Voltage sweep from 0V - 5V and back
View attachment 66699
I've tried to compile the code for your P18F4550 Hotfile: ADC.hex
Check the settings used if I hit it right.
View attachment 66700
result = (float)(voltage * 5)/1023;
adc = result * 1000;
I have no idea why WinPic behaves the way you described. It should load the settings from hex file when loaded. I've never used it, sorry. I only used MPLAB for assembly years ago, and after that I switched to MikroC, mainly because I bought their dev board.
I thought your code might have some bugs, so I thought I better just send you the code that works for me so you can compare...
For example, as I remember C does not have an unsigned float (maybe microchip changed it in their implementation).
This part didn't work for me.
Code:result = (float)(voltage * 5)/1023; adc = result * 1000;
I don't know if it is because of the (float) modifier, or because of the unsigned float type, but I got 0.000 output with this conversion.
Anyway, it is always the best practice to multiply to the highest result, than divide. Of course, within sanity.
Here, it is the better choice since we multiply by a constant and we can anticipate the outcome.
Doing division early causes loss of precision due to round off of the result, and if you than multiply, you increase the error.
unsigned long adc;
[B]unsigned float result;[/B]
unsigned int voltage;
Mr. bjuric,
I was telling Mr. paritosh Giri.
voltage = (ADRESH << 8) | ADRESL;
4. In an assignment statement, the final result of the calculations is converted to the type of
the variable being assigned a value. This process can result in promotion, as described in
Rule 1, or demotion, in which a value is converted to a lower ranking type.
voltage = ((unsigned int)ADRESH << 8) | ADRESL;
voltage = ADRESH;
voltage <<= 8;
voltage |= ADRESL;
#include <p18f4550.h>
#include <delays.h>
void Read_ADC(void);
void Send_Value (void);
unsigned int 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 = 0b10111111;
// right justify
// Acq time 20TAD
// clk Frc
TXSTA = 0b10100010;
// 8-bit
// async
// low speed (BRGH=0)
RCSTA = 0b10010000;
SPBRG = 77;
while (1)
{
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
Delay10TCYx(24); // Delay for 240TCY allow sampling cap to charge
ADCON0bits.GO = 1; //start converting
while (ADCON0bits.DONE == 1); //wait for EOC
voltage = ((unsigned int)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 = '\n';
while (PIR1bits.TXIF == 0);
TXREG = '\r';
while (PIR1bits.TXIF == 0);
}
According to this, char (which is unsigned short) will be promoted to int.4. In an assignment statement, is converted to the type of the variable being assigned a value. Tis process can result in promotion, as described in Rule 1, or demotion, in which a value is converted to a lower ranking type.
union {
unsigned long value;
struct {
unsigned short lo;
unsigned short hi;
};
} voltage;
.......
.......
.......
voltage.lo = ADRESL;
voltage.hi = ADRESH;
voltage.value = current.value * 5000;
voltage.value = current.value / 1023;
According to this, char (which is unsigned short) will be promoted to int.
According to MikroC reference:
short → int, long, float, or double
char → int, long, float, or double
int → long, float, or double
long → float or double
4. In an assignment statement, the final result of the calculations is converted to the type of
the variable being assigned a value. This process can result in promotion, as described in
Rule 1, or demotion, in which a value is converted to a lower ranking type.
Never had that kind of problem so I never got into the problematics of that. Thanks for the explanation.RHS was fully evaluated and THEN the result was implicitly cast by assignment from an unsigned char to a unsigned integer.
I never implied that.These are the ANSI Standard C Rules, not rules of my own creation.
Never had that kind of problem so I never got into the problematics of that. Thanks for the explanation.
Btw. where the hell have you been man all this thread, you could save us all this trouble ;-)
I never implied that.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?