|
|
Example 2.4 - Low resolution servo controller using PWM
Thing to learn: external interrupt (button press activates an interrupt so we can use it instead of polling the button all the time)
One more PWM example. This time a low resolution (only ~30 steps) servo controller.
Parts:- ATiny45
- 100 nF capacitor
- Push button
- 10k ohm resistor
- Standard R/C servo motor

Example 2.4

Example 2.4
/**
* MetkuMods - http://metku.net/
* How to get started with AVR microcontrollers, part 2
* Example 2.4 - Low resolution servo controller using PWM
*
* Author: Aki Korhonen
* Date: 2009-04-29
*/
// If clock speed isn't set in the project settings then it is set here
#ifndef F_CPU
#define F_CPU 1000000UL // 1 MHz
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <util/delay.h>
// Servo at PB0, OCR0A
#define SERVO_PIN 0
// Button at PB2, INT0
#define BTNPIN 2
// Predefined Servo position values for OCR0A
// You might want to fine tune these for your own servo
#define SERVO_LEFT 7
#define SERVO_CENTER 22
#define SERVO_RIGHT 35
uint8_t position = 1;
int main(void)
{
// PB2 input, others output
DDRB = 0b11011;
// Enable internal pull-up resistor on PB2 and set others low
PORTB = 0b00100;
// -------------------------
// Initialize external interrupt 0 (INT0)
// The falling edge of INT0 generates an interrupt request (hi -> low)
MCUCR |= (1<<ISC01);
// Enable INT0
GIMSK |= (1<<INT0);
// Enable global interrupts
sei();
// -------------------------
// Initialize PWM
// Fast PWM
TCCR0A |= (1<<WGM01) | (1<<WGM00);
// Clear OC0A/OC0B on Compare Match
// Set OC0A/OC0B at BOTTOM (non-inverting mode)
TCCR0A |= (1<<COM0A1);
// Set prescaler to 64
// 1 MHz / 64*256 = 61 Hz PWM frequency
TCCR0B |= (1<<CS01) | (1<<CS00);
// -------------------------
// Start with the servo in center position
OCR0A = SERVO_CENTER;
while(1)
{
// No need to poll the button here because the button
// press will be handled in the interrupt handler
}
return 0;
}
// Interrupt handler for INT0
// Cycles through the predefined servo positions
ISR(SIG_INTERRUPT0)
{
cli();
switch(position)
{
case 0:
OCR0A = SERVO_LEFT;
break;
case 1:
OCR0A = SERVO_CENTER;
break;
case 2:
OCR0A = SERVO_RIGHT;
break;
default:
break;
}
position++;
if(position == 3)
position = 0;
_delay_ms(300);
sei();
}
| | Pages: 1 2 3 4 5 6 | |


Content in english!
Sisältö suomeksi!






