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 21, 2011 - 02:45 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Hi guys!
I have a problem with the A/D.I wrote a program that takes an input 0-5v and gives out a PWM 10%-90% duty cycle.The result where the led was shining with a cerain brightness thought i was adjusting the input voltage with a pontesiometer.So i took the progam piece by piece.
I wrote a simple program for the A/D and the outout response(PB3,ADCH,ADCL) was zero,nothing.
The code is here with comments if anyone can see any mistakes please let me know..

etc:i'm using AVR studio 4 and AVR mega 16

thanks




Code:

#include<avr/io.h>
#include<stdlib.h>
int main(void)
{
int i;
 DDRA=0xFE;                  //set A0 input
 DDRB|=_BV(PB3);             //set B3 output
 ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);

//enableand prescaleprescale

 ADMUX=0x40;          //use A0 input AVcc at Aref pin
 ADCSRA=(1<<ADSC);           //start conversion     
for(i=1;i<20;i++)            //do 19 times
{
  PORTA^=(1<<0);             //toggle input
 if (~ADCSRA&(1<<ADSC));   //check the conversion
  {
  ADCSRA=(1<<ADSC)|(1<<ADEN); //start a new one   
  }
 } 
return 0;
}
 
 View user's profile Send private message  
Reply with quote Back to top
dksmall
PostPosted: Mar 21, 2011 - 02:50 PM
Raving lunatic


Joined: Apr 16, 2001
Posts: 3522
Location: Phoenix, Arizona

Where in this code are you reading back ADCH/ADCL?
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 21, 2011 - 03:14 PM
10k+ Postman


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

Quote:

return 0;

Where do you think you are returning to?
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 21, 2011 - 03:23 PM
10k+ Postman


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

Quote:
//do 19 times
And ONLY 19 times. After that your program ends.
Code:
ADCSRA=(1<<ADSC)|(1<<ADEN); //start a new one
But also overwrite your ADPSx bits so that the conversion becomes faster than the ADC can handle.
Quote:
//use A0 input AVcc at Aref pin
Not sure what this comment means. You can set AVCC as the reference, or AREF as the reference. There is no option to set AVCC at the AREF pin.

_________________
Regards,
Steve A.

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


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

Code:
  ADCSRA=(1<<ADSC)|(1<<ADEN); //start a new one   
//++ and lose previous setting of ADPS bits !!

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
katochd46
PostPosted: Mar 22, 2011 - 06:39 AM
Hangaround


Joined: Aug 29, 2010
Posts: 291
Location: Dharamshala, India

[url]I wrote a simple program for the A/D and the outout response(PB3,ADCH,ADCL) was zero,nothing. [/url]put the code where are you taking the response. I cannot see you reading ADC --- 10 bit value.

Also check your circuit connection.

Put an while(1) at the end of the programe.
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:09 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


dksmall wrote:
Where in this code are you reading back ADCH/ADCL?


so i have to store it somewhere like this:

DDRB=0xFF;
value=ADCW;
PORTB=value/4; //1024/4=256 10bit to 8 bit

//or

PORTB=ADCW/4;[code]
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:11 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


theusch wrote:
Quote:

return 0;

Where do you think you are returning to?



most of the examples i've seen have return 0;
so i thought it was standard procedure,thanks i'll look in to it
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:18 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Koshchi wrote:
Quote:
//do 19 times
And ONLY 19 times. After that your program ends.
Code:
ADCSRA=(1<<ADSC)|(1<<ADEN); //start a new one
But also overwrite your ADPSx bits so that the conversion becomes faster than the ADC can handle.
Quote:
//use A0 input AVcc at Aref pin
Not sure what this comment means. You can set AVCC as the reference, or AREF as the reference. There is no option to set AVCC at the AREF pin.


with this command i dont overwrite gotcha.
ADCSRA|=(1<<ADSC)|(1<<ADEN);

sorry there i mean Vcc at the A/D refrence voltage (5v)

thanks for the reply
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:23 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


katochd46 wrote:
[url]I wrote a simple program for the A/D and the outout response(PB3,ADCH,ADCL) was zero,nothing. [/url]put the code where are you taking the response. I cannot see you reading ADC --- 10 bit value.

Also check your circuit connection.

Put an while(1) at the end of the programe.


I'll check it tomorow because my teacher has the board
thanks for reply
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:26 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


thanks guys for the replys,i'll get it working and post it.(i did it 19 times because i wanted to test the program from the AVR studio)
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 01:47 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Code:
#include<avr/io.h>
#include<stdlib.h>
#include<util/delay.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=0x40;          //use A0 input,Vcc at Aref pin
 ADCSRA=(1<<ADSC);           //start conversion     
for(;;)            //do forever
{
  PORTA^=(1<<0);             //toggle input
 _delay_ms(50);
  PORTB=ADCW/4;      //take result from conversion
 if (~ADCSRA&(1<<ADSC));   //check the conversion
  {
  ADCSRA|=(1<<ADSC)|(1<<ADEN); //start a new one   
  }
 }

}



Is this correct?
sorry for asking because i can't test it untill tomorow


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


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

Quote:

Is this correct?

Quote:

I cannot see you reading ADC --- 10 bit value.
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 02:21 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


sorry i forgot to put it
 
 View user's profile Send private message  
Reply with quote Back to top
bobgardner
PostPosted: Mar 22, 2011 - 02:56 PM
10k+ Postman


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

A c program running on a computer with an operating system like linux or windows loads the binary from disk to ram, then 'calls' it like a subroutine, and when it returns, there is a returned value 'ok' or 'error' or something. This is why main is supposed to return an int, and why there should be a return 0 or something at the end of main. 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.

_________________
Imagecraft compiler user
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
geoglobe12
PostPosted: Mar 22, 2011 - 03:04 PM
Rookie


Joined: Mar 09, 2011
Posts: 44


bobgardner wrote:
A c program running on a computer with an operating system like linux or windows loads the binary from disk to ram, then 'calls' it like a subroutine, and when it returns, there is a returned value 'ok' or 'error' or something. This is why main is supposed to return an int, and why there should be a return 0 or something at the end of main. 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.


Thanks for this comment! Now I understand what it means return 0 or more.
 
 View user's profile Send private message  
Reply with quote Back to top
geoglobe12
PostPosted: Mar 22, 2011 - 03:08 PM
Rookie


Joined: Mar 09, 2011
Posts: 44


thodoris46 wrote:
katochd46 wrote:
[url]I wrote a simple program for the A/D and the outout response(PB3,ADCH,ADCL) was zero,nothing. [/url]put the code where are you taking the response. I cannot see you reading ADC --- 10 bit value.

Also check your circuit connection.

Put an while(1) at the end of the programe.


I'll check it tomorow because my teacher has the board
thanks for reply


You still haven't inserted the
Code:
while(1);//loop (for as long as power on)
{
}



can you please post the final working code for the sake of spreading information and ideas. I learn from them.
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 22, 2011 - 03:34 PM
10k+ Postman


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

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.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
geoglobe12
PostPosted: Mar 22, 2011 - 04:39 PM
Rookie


Joined: Mar 09, 2011
Posts: 44


[quote="Koshchi"]
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( ; ; ).


sorry I overlooked it.
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 22, 2011 - 10:32 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


bobgardner wrote:
A c program running on a computer with an operating system like linux or windows loads the binary from disk to ram, then 'calls' it like a subroutine, and when it returns, there is a returned value 'ok' or 'error' or something. This is why main is supposed to return an int, and why there should be a return 0 or something at the end of main. 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.


very good comment thank you
 
 View user's profile Send private message  
Reply with quote Back to top
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: 25891
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: 21251
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: 2640


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: 62230
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: 25891
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: 13820
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: 13820
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: 25891
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: 13820
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: 25891
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: 21251
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: 25891
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: 21251
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: 25891
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: 21251
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
clawson
PostPosted: Mar 24, 2011 - 04:32 PM
10k+ Postman


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

Quote:

then restart conv

How do you do that? You set ADSC and it remains set until a conversion completes. Setting it to 1 again part way through is not going to have any effect? I guess your best hope is to pick F_CPU and the ADPS bits so that the ADC clock runs at 10/8 * 200kHz (ie just a bit too fast) then wait for a complete conversion but knowing the bottom two bits are inaccurate as they will be discarded by the ADLAR anyway.

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


Joined: Mar 02, 2011
Posts: 23


clawson wrote:
Quote:

then restart conv

How do you do that? You set ADSC and it remains set until a conversion completes. Setting it to 1 again part way through is not going to have any effect? I guess your best hope is to pick F_CPU and the ADPS bits so that the ADC clock runs at 10/8 * 200kHz (ie just a bit too fast) then wait for a complete conversion but knowing the bottom two bits are inaccurate as they will be discarded by the ADLAR anyway.


You're talking about the ADEN or ADSC.Because you have to set them again to star a new conversion it's not free running mode.(i'm not sure about the ADEN,but setting it again i guess it does no harm).
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 25, 2011 - 03:29 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


I wrote a program conecting the A/D and Timer 0.They both take clock source from CPU 1Mhz,the A/D prescales with 4 and timer0 prescales with 64 so the timing is:

F_A/D=250Khz T_A/D=4μsec T(conversion)=4*15=60μsec

F_timer=15,6Khz T_timer=64,1μsec

-4*15:are the clock cycles needed to do a conversion and prepare for a new one
-when a period of the timer is finished(64,1μsec)the A/D will have the value ready to place it in OCR0,the timer restarts counting it will output a pulse when compare match is made,in the same time a conversion starts because it's triggered by the previous overflow of the timer.and goes on...

here is the code:
Code:

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

int main(void)
{
 int value;
 DDRB=0xFF;    //outout
 DDRA=0xFE;    //input
 TCCR0=0x7B;   //Fast Pwm,inverting mode,prescale
 ADCSRA=(1<<ADEN)|(1<<ADPS1); //enable,prescale
 ADMUX=(1<<REFS0)|(1<<ADLAR); //refrence,left adj.
 ADCSRA=(1<<ADSC);     //do a dummy read out
 while(!(ADCSRA&0x01));  //wait for dummy
 SFIOR=(1<<ADTS2);  //trigger source(overflow)       

 ADCSRA|=(1<<ADATE);      //enable auto trigger
 
for(;;)
 {
 
 value=ADCH;
if((value<27)|(value>229))  //check for 10%~90%
 {
   //do nothing
else
 OCR0=value;
 }
}
return 0;
}

 

-i'm using mega 16,so the output bit for timer 0 is PB3
-i want the 10%~90% of the input.

please have a look and tell me what you think,thanks


Last edited by thodoris46 on Mar 25, 2011 - 05:47 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Mar 25, 2011 - 04:52 PM
10k+ Postman


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

Quote:

please have a look and tell me what you think,thanks

I'm losing track of the purpose of the whole exercise. Auto trigger seems like overkill for this simple app.

1) AFAIK the above won't work as expected. You have to clear the trigger interrupt flag before it will trigger again.
1a) A "normal" way do this is to watch for the A/D complete either with an ISR or the flag, and then clear the trigger flag and the ADC flag if needed.

2) Why have the auto trigger setup every time though the main loop?

3) ADATE is set before the SFIOR bit(s). So you have initiated an auto-trigger with an arbitrary trigger source. In that case, when does a new value written to SFIOR take effect? I don't really care to analyze this--it is easy enough to just do the operations in an order that does not raise the question.

4) You are grabbing a new value every time through the loop and applying it. There is only going to be a new reading like every 100 times through the loop. After going through all the timing calculations--what is the point? Perhaps you have a reason to do all this. Why not just start a conversion, wait for it to complete, and apply the new value?
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 25, 2011 - 05:43 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


theusch wrote:
Quote:

please have a look and tell me what you think,thanks

I'm losing track of the purpose of the whole exercise. Auto trigger seems like overkill for this simple app.

1) AFAIK the above won't work as expected. You have to clear the trigger interrupt flag before it will trigger again.
1a) A "normal" way do this is to watch for the A/D complete either with an ISR or the flag, and then clear the trigger flag and the ADC flag if needed.

2) Why have the auto trigger setup every time though the main loop?

3) ADATE is set before the SFIOR bit(s). So you have initiated an auto-trigger with an arbitrary trigger source. In that case, when does a new value written to SFIOR take effect? I don't really care to analyze this--it is easy enough to just do the operations in an order that does not raise the question.

4) You are grabbing a new value every time through the loop and applying it. There is only going to be a new reading like every 100 times through the loop. After going through all the timing calculations--what is the point? Perhaps you have a reason to do all this. Why not just start a conversion, wait for it to complete, and apply the new value?



1)I'll place the interupts tomorow,i didn't now it needed to clear the flag
2)I took it outside the loop
3)you're right i thought the order was defrent,fixed it
4)i'll replace the for loop with a while loop and put the interrupt flag check inside the while,so the loop runs when it has too

thank you,i'll fix it tomorow
 
 View user's profile Send private message  
Reply with quote Back to top
thodoris46
PostPosted: Mar 27, 2011 - 07:16 PM
Rookie


Joined: Mar 02, 2011
Posts: 23


Quote:


thank you,i'll fix it tomorow


Code:

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

int main(void)
{
 int value;


 DDRB=0xFF;    //outout
 DDRA=0xFE;    //input
 TCCR0=0x78;   //Fast Pwm,inverting mode
 ADCSRA=(1<<ADEN)|(1<<ADPS1); //enable,prescale
 ADMUX=(1<<REFS0)|(1<<ADLAR); //refrence,left adj.
 ADCSRA=(1<<ADSC);     //do a dummy read out
 while(!(ADCSRA&0x01));  //wait for dummy
 SFIOR=(1<<ADTS2);  //trigger source(overflow)       

 ADCSRA|=(1<<ADATE);      //enable auto trigger
 
 TCCR0|=(1<<CS01)|(1<<CS00); //prescale(timer on)

//when it overflows A/D is enabled things start to hapen

for(;;)
{
 while(ADCSRA&&(1<<ADIF));  //while flag is set(conversion complete)
{
 
 value=ADCH;

 ADCSRA|=!(1<<ADIF);    //clear flag
 
 
if((value<27)|(value>229))  //check for 10%~90%
 {
   //do nothing
else
{
 OCR0=value;
}
 
 }
}
}
return 0;
}


 


any comments are useful to me thanks![/code]


Last edited by thodoris46 on Mar 28, 2011 - 01:34 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 27, 2011 - 07:24 PM
10k+ Postman


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

Your indentation style makes that almost impossible to follow. The whole point is that each time you use { you indent and each time you use } you outdent so the start/end of any statement block can easily be seen. Others may find this easier to follow:
Code:
#include<stdlib.h>
#include<avr/io.h>
#include<avr/interrupt.h>

int main(void)
{
 int value;

//enable global interupts

 DDRB=0xFF;    //outout
 DDRA=0xFE;    //input
 TCCR0=0x78;   //Fast Pwm,inverting mode
 ADCSRA=(1<<ADEN)|(1<<ADPS1); //enable,prescale
 ADMUX=(1<<REFS0)|(1<<ADLAR); //refrence,left adj.
 ADCSRA=(1<<ADSC);     //do a dummy read out
 while(!(ADCSRA&0x01));  //wait for dummy
 SFIOR=(1<<ADTS2);  //trigger source(overflow)       

 ADCSRA|=(1<<ADATE);      //enable auto trigger
 
 TCCR0|=(1<<CS01)|(1<<CS00); //prescale(timer on)

 //when it overflows A/D is enabled things start to hapen

 for(;;)
 {
  while(ADCSRA&&(1<<ADIF));  //while flag is set(conversion complete)
  {
   value=ADCH;

   ADCSRA|=!(1<<ADIF);    //clear flag
 
   if((value<27)|(value>229))  //check for 10%~90%
   {
    //do nothing
    else
     OCR0=value;
 
   }
  }
 }
 return 0;
}

As I did that one of your problems became immediately obvious. You have an unbalanced "else" in the middle. I'm astonished your C compiler did not complain.

EDIT: thought as much - I lifted the unedited code from your post and passed it to avr-gcc. It said:
Code:
test.c: In function 'main':
test.c:39: error: expected '}' before 'else'
test.c: At top level:
test.c:45: error: expected identifier or '(' before 'return'
test.c:46: error: expected identifier or '(' before '}' token
make: *** [test.o] Error 1

So what's the point in asking for comments on code that won't even compile. I'd start by asking the C compiler if IT can see anything wrong first!

EDIT2: by the way I didn't read it in detail yet but this line is clearly wrong:
Code:
   ADCSRA|=!(1<<ADIF);    //clear flag

(I've never understood the attraction of using ADIF anyway, when ADSC does the job just as well and auto-clears)

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


Joined: Mar 02, 2011
Posts: 23


Quote:
(I've never understood the attraction of using ADIF anyway, when ADSC does the job just as well and auto-clears)




I used the ADSC to do a dummy read out(because 1st conversion needs 25 clock cycles)
I'm using auto trigger that's why i have to clear the flag.

You're right about compiling i have a problem intalling the program so i can't compile at home,i compile them when i go to my university lab..
 
 View user's profile Send private message  
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