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
garnett
PostPosted: Nov 07, 2007 - 06:34 AM
Newbie


Joined: Aug 30, 2007
Posts: 6


Hi Dean,
thanks for ur advice..
We have declared our variables below:
Code:

unsigned volatile int verticalspeed=0;
int volatile reference=0;
int volatile altitudeR_int=0;

int main(void)
{
// initialise interrupt here
while(1)     
{
// at here the [b]altitudeR_int [/b] changes according to our sensor


printf("Pump ON \n" );
printf("Altitude= %d ft \n", altitudeR_int);
printf("reference= %d mb \n",reference);
printf("verticalspeed:%u ", verticalspeed);
}

}


ISR(TIMER1_COMPA_vect)
{
verticalspeed=((altitudeR_int-reference)*60);
      
reference = altitudeR_int;
     
}




Is this the correct way of using voletile global variables to return the verticalspeed into the main?

_________________
Location : Singapore
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Nov 07, 2007 - 06:51 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

That should be fine, however, there's one more thing you're not accounting for - atomic access of the variables.

It's possible for your COMPA interrupt to fire in between the reading of a multi-byte global variable, which results in corrupted data being used. The solution is to read the volatile value into a normal local variable while interrupts are disabled in your main code:

Code:
volatile unsigned int verticalspeed = 0;
volatile int reference=0;
volatile int altitudeR_int=0;

int main(void)
{
// initialise interrupt here
while(1)     
{
// at here the [b]altitudeR_int [/b] changes according to our sensor

cli(); // Read in the globals here with interrupts disabled to prevent the ISR from updating them while reading the values
unsigned int verticalspeed_LCL = verticalspeed;
int reference_LCL = reference;
int altitudeR_int_LCL = altitudeR_int;
sei();

printf("Pump ON \n" );
printf("Altitude= %d ft \n", altitudeR_int_LCL);
printf("reference= %d mb \n",reference_LCL);
printf("verticalspeed:%u ", verticalspeed_LCL);
}

}


ISR(TIMER1_COMPA_vect)
{
verticalspeed=((altitudeR_int-reference)*60);
     
reference = altitudeR_int;
     
}


The added benefit of this in your code, is that since all globals are cached locally with the interrupts disabled, you prevent the update from also occuring between the variable reads. Without this you might get the corrupt data as above, but also correct data, but with half the variables from one sample, and half from another.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Nov 07, 2007 - 01:35 PM
10k+ Postman


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

Dean,

Just to note that when you want to interrupt protect access to a variable you may not always know that the current interrupt state is SEI or CLI so rather than wrapping the access in a cli() before and an sei() afterwards it sometimes makes sense to define a 'uint8_t sreg_state' then do 'sreg_state = SREG; cli();' before the access and then 'SREG = sreg_state;' afterwards which recovers the pre-existing interrupt state rather than making the assumption that it was SEI.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Nov 07, 2007 - 09:47 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Right as always Cliff, I was oversimplifying for his example, which seemed to always need interrupts enabled. The "correct" way to do it is to save and restore SREG:

Code:
uint8_t SREG_Save = SREG;
cli();
// Atomic variable access here
SREG = SREG_Save;


Which I wrapped up into a handy macro and submitted to the avr-lib-c project, so it's going to be part of the library in the next avr-lib-c release or so.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
garnett
PostPosted: Nov 09, 2007 - 06:00 AM
Newbie


Joined: Aug 30, 2007
Posts: 6


hi Dean,
thanks for ur help ... we are not sure if we have disable our interrupt correctly...

Code:

int main (void)
{   
   TCCR1A= (1 << WGM12);             TCCR1B = 0x04;   // prescaler 256      
   TIMSK |= (0 << OCIE1A);    disable the interrupt            
   sei(); //  Enable global interrupts

function1(); //
function2(); // interrupt start and end here
funciotn3(); //
}

function2()
{

                TIMSK |= (1 << OCIE1A);
      OCR1A  = 625;     // we set the 20ms  interrupt here    
while(1)     
{
// at here the [b]altitudeR_int [/b] changes according to our sensor

cli(); // Read in the globals here with interrupts disabled to prevent the ISR from updating them while reading the values
unsigned int verticalspeed_LCL = verticalspeed;
int reference_LCL = reference;
int altitudeR_int_LCL = altitudeR_int;
sei();

printf("Pump ON \n" );
printf("Altitude= %d ft \n", altitudeR_int_LCL);
printf("reference= %d mb \n",reference_LCL);
printf("verticalspeed:%u ", verticalspeed_LCL);
}
   TIMSK |= (0 << OCIE1A);  // disable CTC interrupt 
}

ISR(TIMER1_COMPA_vect)
{
verticalspeed=((altitudeR_int-reference)*60);
     
reference = altitudeR_int;
     
}


is this a correct way to disable and enable the interrupt? and another problem is even we intend to set to 20ms interrupt but the program seem to perform one second interrupt? did we set the interrupt interval correctly ?

_________________
Location : Singapore
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Nov 09, 2007 - 06:15 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

That's correct for the atomic access, assuming that you want interrupts on at all times except for the global reads (otherwise you need to save and restore SREG as discussed above).

This line:
Code:
TIMSK |= (0 << OCIE1A);    disable the interrupt


Does nothing - I suggest you read the "Bit Manipulation" tutorial. The correct code is:

Code:
TIMSK &= ~(1 << OCIE1A);    disable the interrupt


Although since that bit is cleared when the AVR is reset, it *still* doesn't achieve anything.


What clock speed are you feeding into the AVR? It comes with it's internal 1MHz RC oscillator enabled by default, you need to change the fuses to use an external crystal/clock source.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
penquissciguy
PostPosted: Nov 13, 2007 - 04:32 PM
Newbie


Joined: Sep 09, 2006
Posts: 7
Location: Maine

Great tutorial! I successfully ran several of the code examples in this tutorial on an Olimex AVR MT 128 board (ATMega 128-based) after changing the timer prescale to 1/1024 to match a 16MHz system clock. I also changed the pin assignment to Port E Pin 2 because that pin on my board is adjacent to a ground pin. I'm just starting out with the AVR, and code from your tutorials is the first code I've successfully run on an AVR.

You write very well. You definitely have the right mindset when you write these tutorials - assume NOTHING of the reader. That's where many tutorials fall short. I teach for a living, and I've seen many "introductory" books in several different areas that miss this point. If you ever do get the time to write the book everyone is suggesting, I'll certainly buy it.

Ken
 
 View user's profile Send private message  
Reply with quote Back to top
tigge_nz
PostPosted: Nov 20, 2007 - 03:03 PM
Newbie


Joined: Jun 10, 2006
Posts: 14


Thanks for the great tutorial. Using your tutorial alone, I've just wrote my very first interrupt implementation, to drive a servo with PWM signal in software, on a atmega8. Loaded it up, and it worked first time. Great tutorial! I'm very impressed. You've taught me how periodic interrupts work.

Thank you.
 
 View user's profile Send private message  
Reply with quote Back to top
mcenhillk
PostPosted: Nov 24, 2007 - 08:18 PM
Wannabe


Joined: Jan 17, 2007
Posts: 91
Location: Bellevue, NE

FYI, the PDF of this tutorial is not in sync with the online version at the top of the thread. I just spent two hours chasing a mistake in the PDF that was fixed online a while ago. Once I figured out that the PDF was old, I fixed it in minutes. On the flip side, I have spent two hours reading the mega168 datasheet trying to figure this mess out Smile .

Dean, is there a plan to update the PDF? If not, it might be a good idea to either take it offline or add a disclaimer at the beginning that the document is not up to date.

The tutorial was great even though I had problems. Thanks for putting it together.

_________________
You can have my mac when you pry my cold dead fingers off of it.

Kevin McEnhill -- mcenhillk@gmail.com
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Nov 25, 2007 - 11:12 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Kevin,

Sorry about that, my fault. I'm going to remove the PDF version for the meantime, while I try to find an automated solution; maintaining two formats is a pain in the rear and I want to simplify things. Ideally I'd want to go from BBCode from the post straight to a formatted PDF, but that's a pipe-dream. I think the best I can hope for is a BBCode-HTML converter, then a HTML to PDF converter. I'll have a look around.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
abcminiuser
PostPosted: Nov 25, 2007 - 01:51 PM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Actually, I've been thinking today about the comments others have made about me writing a book. Books on AVR and the C language has been done, and I don't want to take away money from hungry mouths like Smokey (and that, as he will tell you, is a big mouth Laughing). However, I think that a book that is essentially a set of worked examples using the different AVR peripherals might fill a niche while not treading on any toes. A bit like a book of my tutorials, but ones that flow from one to the next. Thoughts?

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
mcenhillk
PostPosted: Nov 25, 2007 - 05:07 PM
Wannabe


Joined: Jan 17, 2007
Posts: 91
Location: Bellevue, NE

Well, speaking from my days of having to tackle that cursed Perl language, the Perl Cookbook was a lifesaver. The reference books (i.e. datasheets) are not a good place to learn the basics. The beginner books (i.e. turorials) are not much good once you have run through them once because the examples are too simple. Something like a cookbook that illustrates each function helps bridge the gap.

For example, as of right now, I would KILL for an example of a working input capture counter! I am not ready to give up and go to the AVR Forum yet but a cookbook would be high on my list to Santa right now.

_________________
You can have my mac when you pry my cold dead fingers off of it.

Kevin McEnhill -- mcenhillk@gmail.com
 
 View user's profile Send private message  
Reply with quote Back to top
ujrajani
PostPosted: Nov 26, 2007 - 05:17 AM
Newbie


Joined: Nov 19, 2007
Posts: 1


Hey All,

I have made a simple timer program that would toggle 3 LEDs after set time. I am using tiny13 uc. The program works perfect if I simulate it using AVR simulator or debug it using JTAGICE mk II but doesn't work at all if I flash program using ISP. All 3 LEDs stay ON instead of toggling after a set time.

I don't think there is an error with ISP. I have developed few other programs (not shown below) and they work fine when I flash them using ISP.

Any idea whats wrong ? I have tried playing with different clock prescales and different time delays (as explained using variable elapstedtimeseconds for longer time delays) but it didn't really help.

Below is program code :

Code:
Code:


#include <avr/io.h>
#include "fuelgauge.h"


void main(void)
{

  unsigned char counter;

  init();              // Initialize the controller

  TCCR0A |=  (1<< WGM01) | (0 << WGM00);

  OCR0A= 0xFF;
 
  TCCR0B |= ((0 << CS02) | (0 << CS01) | (1 << CS00)); // Set up timer at Fcpu/1024

 
  for (;;)
   {

   counter=TCNT0;


   if (TIFR0 & (1 << OCF0A))
      {
          PINB = 0x07; // Toggle the LED

          TIFR0 = (1 << OCF0A);

      }

   }

}

void init(void)
{

  CLKPR = (1 << CLKPCE);
  CLKPR = 0;


  DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB4) ;
  PORTB = (1<<PB0)|(1<<PB1)|(1<<PB2);
  PINB = 0x00;
}

Code:
Code:


Thanks for all your help !!!

- Umesh
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Nov 26, 2007 - 10:35 AM
10k+ Postman


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

Umesh,

If the LEDs appear to be on all the time it suggests that on/off toggling is simply happening too fast for you to see it (which is the difference between the simulator and real life - one is hundreds of times slower than the other). For one thing start by increasing the clock prescaler to the highest setting - you comment says "Fcpu/1024" but that's not what you are setting - I'll bet you speeded it up so you could see something happening in the simulator!

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
uzairsaeed
PostPosted: Dec 10, 2007 - 08:27 PM
Newbie


Joined: Dec 10, 2007
Posts: 1


hi
guys can any one tell me how do i start my AVR studies i m bit confused plz help me with this k where i should i start my AVR program......some of my frends said to start studies of AVR 4m ATMEGA8 datasheet....plz tell me or give any brief or supporting tutorial
thanx....
 
 View user's profile Send private message  
Reply with quote Back to top
WilburWright
PostPosted: Dec 10, 2007 - 08:35 PM
Wannabe


Joined: Oct 03, 2007
Posts: 55
Location: Kittyhawkistan

uzairsaeed wrote:
hi
guys can any one tell me how do i start my AVR studies i m bit confused plz help me with this k where i should i start my AVR program......some of my frends said to start studies of AVR 4m ATMEGA8 datasheet....plz tell me or give any brief or supporting tutorial
thanx....


FIRST READ: General Information about Posting in the AVR Forum
http://www.avrfreaks.net/index.php?name ... mp;t=18856

ESPECIALLY THE LINK:
http://www.catb.org/~esr/faqs/smart-questions.html

After reading those, then start a new thread in the AVR Forum, not the tutorials forum, and give it an informative title like: "How to start with AVR?"

Wilbur
 
 View user's profile Send private message  
Reply with quote Back to top
pedro_nf
PostPosted: Dec 11, 2007 - 04:36 PM
Newbie


Joined: Nov 02, 2007
Posts: 12


Very Happy
 
 View user's profile Send private message  
Reply with quote Back to top
bergere
PostPosted: Dec 20, 2007 - 05:44 PM
Newbie


Joined: Dec 20, 2007
Posts: 1


Hi,

I tried the short LED Toggling Programm on my CM-5 Atmega 128. But i donīt know which LED is mean with DDRG? Could i see this one on my CM-5 case?

Could you help me let my LEDīs on CM-5 like AUX/TXD blink? Smile
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Dec 31, 2007 - 12:14 AM
Moderator


Joined: Jan 23, 2004
Posts: 6964
Location: Melbourne, Victoria, Australia

Added part eight - "Overflow as CTC". Writing PWM section now, just need to figure out the best way to go about it.

- Dean Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
vicky3413
PostPosted: Jan 01, 2008 - 06:32 AM
Wannabe


Joined: Mar 12, 2007
Posts: 54


Thanks for the new year gift Dean.
Thanks a lot for ur dedicated work on even the new years eve.
i have a doubt.i simulated the code in part part five of ur tutorial in avrstudio.i am not able to see the counting in the tcnt registers.
is it so that the count is not visibile while using interrupts?
Code:
#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
   DDRB |= (1 << 0); // Set LED as output

   TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode

   TIMSK |= (1 << OCIE1A); // Enable CTC interrupt

   sei(); //  Enable global interrupts

   OCR1A   = 15625; // Set CTC compare value to 1Hz at 1MHz AVR clock, with a prescaler of 64

   TCCR1B |= ((1 << CS10) | (1 << CS11)); // Start timer at Fcpu/64

   for (;;)
   {

   }
}

ISR(TIMER1_COMPA_vect)
{
   PORTB ^= (1 << 0); // Toggle the LED
}
 
 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