Need help programming MCU in Winavr

Status
Not open for further replies.

polashd

Member
I’m learning MCU programming with Atmega32 & winavr. I need to convert ADC value to something else (say voltage=5*ADCvalue/1023) which needs to deal with floating point/double. Then to display on LCD I need to convert the calculated value to string/array (eg. Sprintf(….)). Both these (floating point number & print function) consumes large memory/code area of the microcontroller (even with the small versions made for MCU).

Can any one please help me with any alternative way. I goggled a lot but failed to figure out solution specific to my case (I’m not an expert in programming/MCU).
*****
ISR(ADC_vect)
{
uint8_t thelow=ADCL;
uint16_t adc10bit=ADCH<<2 |thelow>>6;

float adcvolt=4.8*((adc10bit)/1023);
char adcvoltstr[10];
sprintf(adcvoltstr,"%.2f",adcvolt); //sprintf() may not be used
PrintValuetolcd(adcvolt,2,1); //display ADC value
PrintStringtolcd(adcvoltstr); //display volt

_delay_ms(50);
ADCSRA |=1<<ADSC; //start the next conversion
}
****
 
I program PIC's.. But they also have a problem with sprintf..


See if your compiler has an ftoa() function..

All else fails.... Swap to fixed point math..

ie.. 4.678 * 1000 = 4678.... then insert your own decimal point...
 
I program PIC's.. But they also have a problem with sprintf..


See if your compiler has an ftoa() function..

All else fails.... Swap to fixed point math..

ie.. 4.678 * 1000 = 4678.... then insert your own decimal point...

I tried with this solution. but its i get unexpected value . Is it because of data type.
If so, what variable type i should use?
---
uint8_t thelow=ADCL;
uint16_t adc10bit=ADCH<<2 |thelow>>6;

uint16_t adcvolt=5*((adc10bit*1000)/1023);


Printlcdval(adc10bit,1,1); //display the value
Sendastring(" "); //clear 0 of previous display
Printlcdval(adcvolt,2,1);
--
how to impliment fixed point math (sorry, I'm a newbie).
 
Just cast it after you have done the calculations..


Code:
float adcvolt=4.8*((adc10bit)/1023);
int16 FPM = (int16)adcvolt *1000;

Or you can miss out the floating part altogether.


Code:
int32 adcvolt=4800 *adc10bit /1023; //<-- see Romans article about  this

Then insert your own decimal point...
 
Sure... Heres a small routine that will yield a four digit number with a decimal in position 1 with negative sign

You need to pass a string pointer with room for 7 characters...

C:
#define  abs(x)   (((x) < 0) ? (-(x)) : (x)) 


void printFloat(char * flt, int value)
	{
	char sign = 32;				// space
	if(value < 0)
		{
		value = abs(value);		// just in case it goes negative
		sign = 45;			// minus
		}
	flt[0] = sign;
	flt[1] = value / 1000 + 48;		// thousands
	flt[2] = 46;				// decimal point
	flt[3] = ((value % 1000) / 100)+ 48;	// hundreds
	flt[4] = ((value % 100) / 10)+ 48;	// tens
	flt[5] = (value % 10) + 48;		// units
	flt[6] = 0;	
	}
You need to include the abs() definition ( pasted as well )
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…