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


Joined: Jul 18, 2005
Posts: 62337
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: 25921
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: 62337
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