/* * Lab 6 - Servo Control * * This program demonstrates how to use the keyboard connected to a PC * running HyperTerminal can communicate with the ATmega16 on the STK500 * to manipulate the position of a servo. * * Last modified 2010-10-04 20:50 (ebw) */ #include #include #include #include "uart.h" #define T ((double)16.384e-3) #define OCR0_MIN 0 #define OCR0_MAX 255 /* * The ISR() function below is what's called an interrupt handler. * You don't need to worry about it too much right now as the concept of * interrupts will be covered in future labs and lectures. * * For now all you need to know is that interrupt handlers are functions that * are called when a particular event happens "out of nowhere", as opposed to * functions that are called under direct control of your program. * * This particular interrupt handler gets called every time the UART in the * microcontroller receives a character over the serial link, i.e. when a key * is pressed on the keyboard on the PC in HyperTerminal. * * When either 'a' or 'z' are received as input, we increment or decrement * OCR0 to effect a change in the duty cycle for the PWM signal driving the * servo. We ensure that OCR0 doesn't exceed its lower and upper boundaries. */ ISR(USART_RXC_vect) { uint8_t input = UDR; if ((input == 'a') && (OCR0 != OCR0_MAX)) OCR0++; else if ((input =='z') && (OCR0 != OCR0_MIN)) OCR0--; } /* * This initialization function just sets-up Timer0 for: * - phase Correct PWM * - clearing OC0 on up-count * - prescaled by 256 * and remembering to enable the output pin (PB3) driven by the timer. */ void init() { TCCR0 = _BV(WGM00) | _BV(COM01) | _BV(CS02); DDRB = _BV(PB3); uart_init(); } int main() { init(); printf("ME106 Servo Demonstration Program\r\n"); printf("Press \'a\' to increase the period, \'z\' to decrease.\r\n"); while (1) { uint8_t ocr0 = OCR0; printf("Period: %f/%f\tOCR0: %u/255\r\n", T*ocr0/255, T, ocr0); } return 0; // ain't never gonna happen }