| Author |
Message |
|
|
Posted: Mar 22, 2011 - 10:39 PM |
|

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.. |
|
|
| |
|
|
|
|
|
Posted: Mar 22, 2011 - 10:45 PM |
|

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
|
| |
|
|
|
|
|
Posted: Mar 22, 2011 - 10:54 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 22, 2011 - 10:56 PM |
|


Joined: Sep 04, 2002
Posts: 21271
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
|
| |
|
|
|
|
|
Posted: Mar 22, 2011 - 11:38 PM |
|

Joined: Oct 29, 2006
Posts: 2652
|
|
|
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.
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 11:54 AM |
|

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))) |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 12:25 PM |
|


Joined: Jul 18, 2005
Posts: 62337
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 ? |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 01:33 PM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 02:03 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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 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. |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 03:49 PM |
|

Joined: Nov 17, 2004
Posts: 13847
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.
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 03:54 PM |
|

Joined: Nov 17, 2004
Posts: 13847
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.
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 04:04 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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.) |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 07:06 PM |
|

Joined: Nov 17, 2004
Posts: 13847
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.
|
| |
|
|
|
|
|
Posted: Mar 23, 2011 - 07:32 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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.
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 03:47 PM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 04:06 PM |
|


Joined: Sep 04, 2002
Posts: 21271
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
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 04:08 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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.] |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 04:10 PM |
|


Joined: Sep 04, 2002
Posts: 21271
Location: Orlando Florida
|
|
| Huh? Doesnt setting the ADLAR short cycle the successive approximation at 8 bits? |
_________________ Imagecraft compiler user
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 04:18 PM |
|


Joined: Feb 19, 2001
Posts: 25921
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". |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2011 - 04:26 PM |
|


Joined: Sep 04, 2002
Posts: 21271
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
|
| |
|
|
|
|
|