Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
thodoris46
PostPosted: Mar 22, 2011 - 10:39 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Koshchi wrote:
Quote:
You still haven't inserted the
Code:
while(1);//loop (for as long as power on)
{
}
Yes he has, under the guise of a for( ; ; ).
Code:
  PORTB=ADCW/4;      //take result from conversion
 if (~ADCSRA&(1<<ADSC));   //check the conversion
  {
  ADCSRA|=(1<<ADSC)|(1<<ADEN); //start a new one   
  }
Why are you getting the result before you checked to see that the conversion is complete? Since you have a 50ms delay just before, it likely is, but as soon as you take out that delay your code will fail.


by putting the delay i am making sure that the conversion is complete because a conversion needs max 15 clock cycles,i put a 50ms delay to be sure.
Although you are right i dont think it's a problem..
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 10:45 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Code:
#include<avr/io.h>
#include<stdlib.h>


int main(void)
{

 DDRA=0xFE;                  //set A0 input
 DDRB=0xFF;                 //set B output
 ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);

//enable and prescale

 ADMUX=(1<<REFS0)|(1<<ADLAR);
 
//use A0 input,Vcc at Aref pin,left adj.result

 ADCSRA=(1<<ADSC);           //start conversion     
for(;;)            //do forever
{
  PORTA^=(1<<0);             //toggle input
 
 if (!(ADCSRA&(1<<ADSC)))   //check the conversion
  {
  PORTB=ADCH;      //take result from conversion
  ADCSRA|=(1<<ADSC)|(1<<ADEN); //start a new one   
  }
 }
return 0;
}


Last edited by thodoris46 on Mar 24, 2011 - 03:51 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 22, 2011 - 10:54 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

if (~ADCSRA&(1<<ADSC));

That is utter nonsense.

1) What is that bitwise complement ~ doing in there?
2) With no parentheses, do you have the C operator precedence table memorized?
3) Tell us more about what happens with the semi-colon ; at the end of that line.
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Mar 22, 2011 - 10:56 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21257
Location: Orlando Florida

My opinion, based on several decades of experience writing programs that get sold in gizmos, is make a subroutine/function to read an a/d channel, return the value. Write a subroutine to check for keyboard hit and return a boolean. Write a subroutine to get the char from the uart and return it. Write a subroutine to send a char to the uart. None of this inline stuff in main. One might consider that main is a loop of subroutine calls. Check for char waiting. If true, get the char. If its an X call function y.

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
skeeve
PostPosted: Mar 22, 2011 - 11:38 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2648


bobgardner wrote:
On a microcontroller with no operating system, the bit about load the program and call it doesnt happen, so there isnt really a call, so main shouldnt return. No where to return to. But Richard Stallman wrote the free c compiler that everyone and his uncle tries to shoehorn into every new computer and microcontroller, so you have to sort of know how the compiler expects things to be.
To me, it seems a wonder of the world.
I'm amazed that it exists at all.

Actually, main is not required to return an int.
IIRC main is not required at all in a
freestanding environment, e.g. an AVR.
We don't use --freestanding because it removes
much knowledge of the C library from the compiler.
IIRC it would not be allowed to replace
an memcpy( ) with equivalent inline code.

To me, the rule seems overly strict.
Why not let the compiler assume that anything
declared in a system header file having the same name
as a standard C function is a standard C function?

That said, I think one could compile the file with
main with --freestanding and compile the rest hosted.

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 23, 2011 - 11:54 AM
Rookie


Joined: Mar 02, 2011
Posts: 23


theusch wrote:
Quote:

if (~ADCSRA&(1<<ADSC));

That is utter nonsense.

1) What is that bitwise complement ~ doing in there?
2) With no parentheses, do you have the C operator precedence table memorized?
3) Tell us more about what happens with the semi-colon ; at the end of that line.


sorry i'be more careful next time,i had many mistakes in my code..

i changed it to
if (!(ADCSRA&(1<<ADSC)))
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 23, 2011 - 12:25 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62281
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

if (!(ADCSRA&(1<<ADSC)))

Are you sure you want to do that. The more usual sequence is:
Code:
// wait for ADSC bit to go from 1 to 0 to show end of conversion
while(ADCSRA&(1<<ADSC));

Also if you are going to throw away two bits with "ADCW/4" then why not simply use ADLAR ?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 23, 2011 - 01:33 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Quote:


Also if you are going to throw away two bits with "ADCW/4" then why not simply use ADLAR ?


I'm not throing them away i'm prescaling the value to 8 bit.
like if we had
1100001111=783 10 bit
783/4=195,75=11000011 8bit
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 23, 2011 - 02:03 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

My opinion, based on several decades of experience writing programs that get sold in gizmos, is make a subroutine/function to ...

And the smallest AVR you've ever seen Twisted Evil is a Mega32. That's hardly even a >>micro<< controller. (Macro-controller?)

But as you know I'm a heretic on this. Yes, I use functions when I feel they are useful. But not just for the sake of keeping the main loop small--mine is huge in my biggest apps, mostly because of an extensive menu system and display panel build with lots of states.

Anyway, a real app will have interrupt-driven USART for sure. And probably ADC and timers. So my getchar() really peeks into a buffer; I don't have my AVR sit there tapping its toe waiting for an ADC conversion to start and complete.

With the above, I feel I pack a lot into a Mega48. My suspicion is that my program ends up tighter than the full modular approach but I've got no hard data on that.

As the app gets larger, into that Mega32 class, I indeed will build in a lot more structure from the beginning, in that my head can't hold all the details of the whole app anymore.
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 23, 2011 - 03:49 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13834
Location: Vancouver, BC

Quote:
1) What is that bitwise complement ~ doing in there?
2) With no parentheses, do you have the C operator precedence table memorized?
The following two "if" statements are equivalent:
Code:
if (~ADCSRA & (1 << ADSC))
...
if (!(ADCSRA & (1 << ADSC))
The "~" and the"&" have the same precedence, so the "~" will be done first.
Quote:
Are you sure you want to do that.
Once the errant semicolon was removed and the read of ADCW was moved to inside the "if", there is really nothing wrong with the code since the "if" is wrapped in an infinite loop. The "if" will be continually be evaluated. Any time the "if" evaluates to true, the value will be read and the next conversion started. It even has the advantage over "the more usual sequence" in that it does not block and allows other code to be run during the conversion.

Just because the solution is different from the norm doesn't make it "utter nonsense" or wrong (though obviously the semicolon was incorrect).

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 23, 2011 - 03:54 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13834
Location: Vancouver, BC

Quote:
I'm not throing them away i'm prescaling the value to 8 bit.
Since after the pre-scale you no longer have the two bits, you are, in fact, throwing them away (and no, you don't get 195.75, you get 195). And the easiest way to pre-scale/throw away those bits is to use the ADLAR bit as Cliff suggested.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 23, 2011 - 04:04 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

The "~" and the"&" have the same precedence, so the "~" will be done first.

??? http://www.difranco.net/cop2220/op-prec.htm And different associativity as well.

I knew/know that ~ has high precedence, but the way OP is whacking at these expressions I'd feel better seeing parentheses (and get in the habit).

(BTW my compiler generates better code for the ! version than the ~ version, both with ADCSRA low and high addresses.)
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 23, 2011 - 07:06 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13834
Location: Vancouver, BC

The fact remains that the code is perfectly correct.
Quote:
(BTW my compiler generates better code for the ! version than the ~ version, both with ADCSRA low and high addresses.)
Irrelevant.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 23, 2011 - 07:32 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

The fact remains that the code is perfectly correct.

The fact remains that the operators do not have the same precedence or associativity. Wink

The fact remains that while I'm a veteran C coder and "pretty much" know the precedence, without the parens I had to pull up a table and work through it. I don't want to do that on a daily basis, so I order parens in bulk quantity.
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 24, 2011 - 03:47 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Koshchi wrote:
Quote:
I'm not throing them away i'm prescaling the value to 8 bit.
Since after the pre-scale you no longer have the two bits, you are, in fact, throwing them away (and no, you don't get 195.75, you get 195). And the easiest way to pre-scale/throw away those bits is to use the ADLAR bit as Cliff suggested.



Maybe there's something i'm not getting but the manual says:By default, the result is presented right adjusted, but can optionally be presented left adjusted by setting the ADLAR bit in ADMUX.If the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read ADCH.

so if we adjust the ADLAR the first 8 bits go to the ADCH the other 2 to ADCL which we ignore.And it has the same result by dividing the number by 4.You are right guys i did the math jusy now...
Thanks guys,i'll change it
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Mar 24, 2011 - 04:06 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21257
Location: Orlando Florida

Doing an 8 bit conversion takes 2 a/d clks less than a 10 bit conversion, which usually takes 13 clks at 200kHz (5usec per bit 65usec per sample). The 8 bit conversion should take 55usec. Use that extra 10usec wisely! (15.3kHz sample rate vs 18.2kHz)

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
theusch
PostPosted: Mar 24, 2011 - 04:08 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

Doing an 8 bit conversion takes 2 a/d clks less than a 10 bit conversion,

OK, Bob--tell me how to do an "8 bit conversion" on an AVR8? [Hint: there is no such thing, and there are no saved ADC clock cycles.]
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Mar 24, 2011 - 04:10 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21257
Location: Orlando Florida

Huh? Doesnt setting the ADLAR short cycle the successive approximation at 8 bits?

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
theusch
PostPosted: Mar 24, 2011 - 04:18 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25904
Location: Wisconsin USA

Quote:

Huh? Doesnt setting the ADLAR short cycle the successive approximation at 8 bits?


No, Bob. It is just as it says, and was also said earlier in this thread. "LAR" is "left-adjusted result".
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Mar 24, 2011 - 04:26 PM
10k+ Postman


Joined: Sep 04, 2002
Posts: 21257
Location: Orlando Florida

OK, I guess the converter is always going to try for 10 bits, but in the example calc I gave (65usec for 10bit, 55usec for 8bit), you could start conv, read after 55usec, then restart conv, and be confident you were getting an 8 bit result. I think.

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits