

























Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
this doc will help you to understand what are the interrupts and how to use them
Typology: Lecture notes
1 / 33
This page cannot be seen from the preview
Don't miss anything!


























Arduino, AVR, and deep dark programming secrets
! Like a phone call in the middle of a conversation ! Stop what you are doing, deal with the interruption, then continue where you left off
! Or that need to occur at regular intervals ! Or that need to run automatically without the programmer keeping track
! How to check for an infrequent condition?
! Busy-Wait ! Stand by the curb waiting for the mail ! while (mail-not-here){}; ! Can’t do anything else while you’re waiting…
! Polling ! Like going to the mailbox every 10 min to see if the mail has arrived yet ! Check every time through the “loop” function ! Simple, but time consuming
! Interrupt ! Like getting a phone call when the mail has arrived ! Set up an “interrupt service routine” on the condition you’re waiting for ! You can ignore it and do other things until you get the call
! A phone rings
! Stop your conversation and check which phone is ringing
! Answer the phone and handle the call
! Hang up and resume your previous conversation
! Why not just check for a new character in a loop? ! How frequently would you have to check? ! How much processor time would be spend checking?
! Each bit is sent at 9.6 kHz (close to 10kHz) ! Each bit takes around 100usec ! Around 10 bits required for each character ! So, one character every 1msec or so ! If the USART is buffered, you have about 1msec to get a character before it’s overwritten by the next one
! If your main loop is not doing anything else, you can do this, but if you’re doing other things, or communicating at faster speeds, it gets ugly fast
! The USART will cause an interrupt each time it receives a complete character ! The Interrupt Service Routine (ISR) for this USART- receive event will be called ! The ISR will take the character from the USART and put it in a buffer for your program to use ! You never have to check the USART directly, characters just show up in your program’s buffer as they arrive
! External : A signal outside the chip (connected to a pin) ! Timer : Internal to the chip, like an alarm clock ! Device : One of the AVR devices (USART, SPI, ADC, EEPROM) signals that it needs attention
// Interrupt-Driver Bumper Example for a robot // A bumper switch on the front of the robot should be tied to digital pin 2 and ground
#include <avr/interrupt.h> // Some important interrupt-related definitions (needed?)
volatile int bumper; // Indicator to the main code have we hit something
void setup(){ pinMode(2, INPUT); // Make digital 2 an input (for the bumper switch) digitalWrite(2, HIGH); // Enable pull up resistor (bumper switch pulls low)
// attach our interrupt pin (pin 2) to its ISR attachInterrupt(0, bumperISR, FALLING);
interrupts(); // interrupts are enabled by default, but this doesn’t hurt
// start moving bumper = 0; DriveForward(); }
! But, that requires a little deep dark secret AVR-hacking ! So, unless you need it, don’t worry about it ! If you do need it – Look at the PC Int code on the Arduino site ! Magic code that allows triggering an interrupt from any pin on the Arduino… ! I’ll put a link on the class web site
! External : A signal outside the chip (connected to a pin) ! Timer : Internal to the chip, like an alarm clock ! Device : One of the AVR devices (USART, SPI, ADC, EEPROM) signals that it needs attention
! Problem – Arduino is just wasting time during the delay. It can’t be used for anything else.
int ledPin = 13; // LED connected to digital pin 13
void setup() { pinMode(ledPin, OUTPUT); // initialize the digital pin as an output: }
void loop() { digitalWrite(ledPin, HIGH); // set the LED on delay(1000); // wait for a second digitalWrite(ledPin, LOW); // set the LED off delay(1000); // wait for a second }
! Non-delay version – use a timer to see if it’s time to blink ! Can use the Arduino for other things in the meantime ! But, the programmer has to manage this activity
! Instead, there is a millis(); function that returns the current number of milliseconds since the last system reset ! Based on internal timers! ! Use that to check occasionally if enough time has passed that you should flip the LED again ! You can do other things between checking
! What are they? ! How to read/write timer values? ! How to configure them?
! Like an alarm clock ! When a timer alarm goes off, an ISR may be called
! They count (tick) once for each system clock tick ! 16MHz for Arduino ! Your program can check, and reset the count value ! You can also “prescale” the timer’s clock so that it’s counting more slowly than the 16MHz Arduino clock ! You can also have the timer set an alarm when the count gets to some particular value ! The alarm is an interrupt ! You can define the ISR for that timer alarm
! Timer0: an 8-bit timer (counts 0 to 255) ! Used for system timing, millis(); micros();, etc. ! and PWM on pins 5 and 6 ! Timer1: a 16-bit timer (counts 0 to 65,535) ! Used for PWM on pins 9 and 10 ! Timer 2: an 8-bit timer (counts 0 to 255) ! Used for PWM on pins 3 and 11
! 8bit timer TOP is 255 ! 16bit timer TOP is 65,
! A = TCNT2; // Read the value of timer 2 ! TCNT1 = 0; // Reset the value of timer 1 to 0
Prescale Value Tick Time OVF frequency
OVF Period
1 62.5nsec ~244.14Hz 4.096msec 8 500nsec ~30.52HZ 32.768msec 64 4usec ~3.815Hz 262.144msec 256 16usec ~0.954Hz ~1.05sec 1024 64usec ~0.238Hz ~4.19sec
16-bit counter at 16MHz system clock frequency (Timer1)
OVF = Overflow (time it takes to count from 0 to TOP)
TOP = 16,535 for a 16-bit counter
! Figure out what to count to to get to 1sec
timer_count = ((16,000,000/prescale)/target_freq) – 1
! Set up counter with the right prescaler, then check if the count is up to timer_count. ! Flash the LED and reset the timer to 0
! (16,000,000Hz/1024)/1Hz –1 = 15, (–1 because we count starting at 0!) ! So, if you count 0 to 15,624 at a 1024 prescale, that’s (15,625)x( 64usec)=1,000,000usec = 1sec
int LEDPin = 13; // Built-in LED pin
void setup () { pinMode(LEDPin, OUTPUT); // Make sure it’s an output
// set up timer1 (16-bit timer) in normal up-counting mode // set up timer1 (16-bit timer) for prescale of 1024 }
void loop (){ if (TCNT1 >= 15624) { // reached 1sec on timer digitalWrite(LEDPin, !digitalRead(LEDPin)); // toggle LEDPin TCNT1 = 0; // reset counter to 0 } }
digitalWrite(LEDPin, !digitalRead(LEDPin));
boolean FlipFlop = 0;
…
digitalWrite(LEDPin, FlipFlop); FlipFlop = !FlipFlop;
Detour: Setting bits inside bytes
! TCCR1B is an 8-bit byte ! Want to set bits 2 (CS12) and 0 (CS10) to 1, leave others 0 ! TCCR1B = B00000101; // overwrite whole byte ! TCCR1B = TCCR1B | B00000101; // leave other bits unchanged ! TCCR1B |= B00000101; // shorthand version of above ! CS12 = 2 and CS10 = 0 – these are magically set in an included header file ! bitSet(TCCR1B, CS12); // Arduino functions for setting an individual bit bitSet(TCCR1B, CS10); // There’s also bitClear(reg,bit); for clearing a bit… ! TCCR1B |= ((1<<CS10) | (1<< CS12)); // Register bits all have names ! TCCR1B |= _BV(CS10) | _BV(CS12); // _BV(bit) is another Arduino function ! TCCR1B |= bit(CS10) | bit(CS12); // Yet another Arduino function
! If there’s a 1 in A or B, there’s a 1 in C
! CS12 is defined to be 2 (in a secret included file) ! (1<<2) is 1 shifted two places to the left in the byte ! this is 00000100 ! CS10 = 0 ! So ((1<<CS12) | (1<<CS10)) = 00000100 | 00000001 ! This equals 00000101
int LEDPin = 13; // Built-in LED pin
void setup () { pinMode(LEDPin, OUTPUT); // Make sure it’s an output
// set up timer1 (16-bit timer) in normal up-counting mode // set up timer1 (16-bit timer) for prescale of 1024 }
void loop (){ if (TCNT1 >= 15624) { // reached 1sec on timer digitalWrite(LEDPin, !digitalRead(LEDPin)); // toggle LEDPin TCNT1 = 0; // reset counter to 0 } }