Reputation: 99
I am trying to create a digital voltmeter using the potenial divider on the dev board. It uses a 8051 chip. To convert it to volts we have to times the number from the pot by 5000/196. I have the following code which compiles but when I send it to the board I get
"Summary:
517 lines received
4694 bytes received
291 bytes written
Error:
4403 bytes unable to write"
I have no idea why it won't send but I am sure I am being silly somewhere in my code which is below.
#include<8051.h> //header file, containing information on 8051
#include<stdio.h> //standard input/output file
#include<math.h>
#define DAC 0x0600 //DAC address
float conv=5000/196;
unsigned char xdata * idata DPTR; //pointer declaration, made as external to main
unsigned int volt_in;
void delay();
void main()
{
unsigned char a; //variable to store signal value
DPTR=DAC; //pointer as a variable takes address of // DAC
while(1)
{
a=0;
*DPTR=a; //assign a to address in DPTR
while(P3_5!=0){
a++;
*DPTR=a;
}
a=(int) a*conv;
volt_in=a;
printf ("The voltage is %d Mv. \r" , volt_in);
a=~a;
P1=a;
//delay();
}
}
void putchar(char c)
{
while(!TI);
TI=0;
SBUF=c;
}
void delay()
{
unsigned int k;
for (k=0xFFFF;k>0;k--);
}
I am totally lost so any help would be great. Many thanks in advance
Upvotes: 1
Views: 1782
Reputation: 301
I am not sure how is this code supposed to work.
Your precompiled constant is 5000 / 196, which is 25. Why do you need your variable "conv" to be float? You are multiplying char "a" with float "conv", it will be upcasted to float, only to be casted to char "a" again within the same line of your code. Not exactly most efficient thing to do. And that char "a" could not store the result of your multiply operation. It should not work, whatever your intention was, unless you have some clever, optimized algorithm here beyond my understanding. But in this case it is a good idea to document it, as the programmer's intention was by no means obvious here, and would not be obvious to you neither after some time.
Anyway, you don't even need the fractional point representation, you are dealing with integers only here, and you display result as an integer. Why do you need float in the first place? Or am I missing something?
And yes, the 8051 floating point is a bit heavy lacking the HW support, it is probably not reentrant so you should take some measures not to used it from interrupts (without saving the FP stack), and the standard 8051 is limited to 4 KB ROM (use 8052 if you wanted this to fit as it is). Best to avoid floating point on 8051 or any small micro unless absolutely necessary, or you had a lot of space and instruction cycles to waste.
Upvotes: 0
Reputation: 3484
It sounds to me like your 8051 has very limited program memory (flash) and the floating point emulation library has bloated the image so it is much to large to fit. AFAIK, 8051s do not have floating point instructions so all operations must be emulated.
I'd suggest trying to use scaled integers instead of floats. In other words, use long integers representing, say, 1/100's of a millivolt and reformat the output in your printf's.
BTW, I'm assuming that "Mv" is supposed to represent millivolts. The correct abbreviation is "mv". "Mv" means Megavolt.
Upvotes: 1