| Author |
Message |
|
|
Posted: Mar 24, 2011 - 04:32 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 25, 2011 - 02:28 PM |
|

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). |
|
|
| |
|
|
|
|
|
Posted: Mar 25, 2011 - 03:29 PM |
|

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
|
| |
|
|
|
|
|
Posted: Mar 25, 2011 - 04:52 PM |
|


Joined: Feb 19, 2001
Posts: 26115
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? |
|
|
| |
|
|
|
|
|
Posted: Mar 25, 2011 - 05:43 PM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Mar 27, 2011 - 07:16 PM |
|

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
|
| |
|
|
|
|
|
Posted: Mar 27, 2011 - 07:24 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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) |
_________________
|
| |
|
|
|
|
|
Posted: Mar 28, 2011 - 01:29 PM |
|

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.. |
|
|
| |
|
|
|
|
|