/*
* Filename: Timers_Exercise3
* Author: George Howard
* Date: 12/05/2024
* Description: PURPOSE
*/
// Task: Use the FastPWM Mode to produce a square wave with a duty cycle
// which is adjustable by using switches on the red shield.
// You can change only one switch to high and the rest to zero.
// For each case mention the duty cycle value and your calculations.
// Draw a timing diagram to explain how it works
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
// Workings:
void setupTimer() {
// Clear the Timer/Counter Control Registers
TCCR1A = 0;
TCCR1B = 0;
// Set the Waveform Generation Mode to Fast PWM, ICR1 as TOP (Mode 14)
TCCR1A |= (1 << WGM11); // Configure for non-inverting mode, set WGM11
TCCR1B |= (1 << WGM12) | (1 << WGM13); // Set WGM12 and WGM13 for Fast PWM
// Set the Compare Output Mode to non-inverting mode
TCCR1A |= (1 << COM1A1); // Set COM1A1 for non-inverting PWM on OC1A
// Set the Clock Select bits to define the prescaler
TCCR1B |= (1 << CS10); // Set CS10 for a prescaler of 1 (No prescaling)
// Set the TOP value for 16-bit resolution
ICR1 = 65535; // Define the top count for maximum 16-bit resolution
}
void dutyCycle(unsigned char switch_states) {
switch (switch_states) {
case 0x01:
OCR1A = 8192;
break;
case 0x02:
OCR1A = 16384;
break;
case 0x04:
OCR1A = 24576;
break;
case 0x08:
OCR1A = 32768;
break;
case 0x10:
OCR1A = 40960;
break;
case 0x20:
OCR1A = 49152;
break;
case 0x40:
OCR1A = 57344;
break;
case 0x80:
OCR1A = 65535;
break;
default:
OCR1A = 0;
break;
}
}
int main(void)
{
Serial.begin(9600);
cli();
DDRC = 0x00; // Port C pins configured as input
PORTC = 0xFF; // Enabling the pull-up resistors
DDRA = 0xFF; // Sets PORTA PIN7 as output
setupTimer();
sei(); // Enable interupts
while (1)
{
unsigned char switch_states = PINC;
dutyCycle(switch_states);
}
}