Skip to content

Instantly share code, notes, and snippets.

@ShawnHymel
Last active December 8, 2016 23:32
Show Gist options
  • Select an option

  • Save ShawnHymel/5ad94b4c55678275a52a004e55ba58b2 to your computer and use it in GitHub Desktop.

Select an option

Save ShawnHymel/5ad94b4c55678275a52a004e55ba58b2 to your computer and use it in GitHub Desktop.
Roshamglo Test - hardware PWM with TOV interrupts. Now it works.
// Set this to enable serial debugging
#define debug 1
// Only include SofwareSerial if we're debugging!
#if (debug > 0)
# include <SoftwareSerial.h>
#endif
#if (debug > 0)
SoftwareSerial softy(2, 1); // RX, TX
#endif
#define MOD_FREQUENCY 38000 // 38 kHz modulation frequency
#define MOD_COUNTER_VAL (F_CPU / MOD_FREQUENCY) - 1
// Pins
const int LED_R = 7;
const int LED_G = 8;
const int XMIT = 5; // OC1B
const int BTN_C = 3;
const int STATUS = LED_R;
// Global variables
int led = 0;
uint16_t cnt = 0;
void setup() {
// Begin debugging (if we need it)
#if (debug > 0)
softy.begin(9600);
#endif
// Set up pins
pinMode(STATUS, OUTPUT);
digitalWrite(STATUS, LOW);
pinMode(XMIT, OUTPUT);
pinMode(BTN_C, INPUT);
digitalWrite(BTN_C, HIGH);
// Use Timer 1 in Fast PWM mode, clear on match
TCCR1A = _BV(WGM11) | _BV(WGM10); //_BV(COM1B1) | _BV(WGM11) | _BV(WGM10);
// Reset timer on TOP (OCR1A), prescaler = 8
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);
// TOP (OCR1A) is modulation frequency. Timer 1 resets on this number.
OCR1A = MOD_COUNTER_VAL >> 3; // Account for prescaler of 8
// Set the PWM value to 50%
OCR1B = MOD_COUNTER_VAL >> 4; // #define won't divide nicely
// Enable Timer 1 overflow interrupt
TIMSK1 = _BV(TOIE1);
// Enable global interrupts
sei();
// Turn off transmitter
pulse(false);
#if (debug > 0)
softy.println(F("Setup complete"));
#endif
}
void loop() {
if ( digitalRead(BTN_C) == 0 ) {
pulse(true);
} else {
pulse(false);
}
}
void pulse(bool on)
{
if ( on ) {
#if defined(__AVR_ATmega328P__)
TCCR2A |= _BV(COM2B1);
#elif defined(__AVR_ATtiny84__)
TCCR1A |= _BV(COM1B1);
#elif defined(KINETISL)
*portConfigRegister(IR_LED_PIN) = PORT_PCR_MUX(4);
#endif
} else {
#if defined(__AVR_ATmega328P__)
TCCR2A &= ~(_BV(COM2B1));
#elif defined(__AVR_ATtiny84__)
TCCR1A &= ~(_BV(COM1B1));
#elif defined(KINETISL)
*portConfigRegister(IR_LED_PIN) = PORT_PCR_MUX(1);
#endif
}
}
// ISR - placeholder
ISR(TIM1_OVF_vect)
{
cnt++;
if ( cnt >= 38000 ) {
cnt = 0;
led ^= 1;
digitalWrite(STATUS, led);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment