Skip to content

Instantly share code, notes, and snippets.

@z3t0
Created August 13, 2015 18:30
Show Gist options
  • Select an option

  • Save z3t0/0e7b74bff5cb4e1c494e to your computer and use it in GitHub Desktop.

Select an option

Save z3t0/0e7b74bff5cb4e1c494e to your computer and use it in GitHub Desktop.
/* Blinker Demo */
// ------- Preamble -------- //
#include <avr/io.h> /* Defines pins, ports, etc */
#include <util/delay.h> /* Functions to waste time */
#define F_CPU 8000000
#define SYSCLOCK F_CPU
# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
# define IR_USE_TIMER1 // tx = pin 9
# define ENABLE_OUTPUT (DDRB |= (1 << PB1))
#define IR
void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz);
int main(void) {
int khz=38;
unsigned int rawData[5] = {796, 180,45, 12,0};
// -------- Inits --------- //
ENABLE_OUTPUT;
// ------ Event loop ------ //
while (1) {
sendRaw(rawData, sizeof(rawData) / sizeof(int), khz);
} /* End event loop */
return (0); /* This line is never reached */
}
#ifdef IR
//---------------------------------------------------------
// Timer1 (16 bits)
//
#elif defined(IR_USE_TIMER1)
#define TIMER_RESET
#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
//-----------------
# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A))
# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A))
//-----------------
#define TIMER_INTR_NAME TIMER1_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \
const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
TCCR1A = _BV(WGM11); \
TCCR1B = _BV(WGM13) | _BV(CS10); \
ICR1 = pwmval; \
OCR1A = pwmval / 3; \
})
#define TIMER_CONFIG_NORMAL() ({ \
TCCR1A = 0; \
TCCR1B = _BV(WGM12) | _BV(CS10); \
OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
TCNT1 = 0; \
})
//-----------------
//
void delayMicroseconds(int time){
_delay_ms(time);
}
void sendRaw (unsigned int buf[], unsigned char len, unsigned char hz)
{
// Set IR carrier frequency
enableIROut(hz);
for (unsigned char i = 0; i < len; i++) {
if (i & 1) space(buf[i]) ;
else mark (buf[i]) ;
}
space(0); // Always end with the LED off
}
void enableIROut (int khz)
{
// Disable the Timer2 Interrupt (which is used for receiving IR)
TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
ENABLE_OUTPUT; // Enable output on PWM PIN
PORTB = 0b00000000; /* Turn off all B pins, including LED */
// When not sending PWM, we want it low
// COM2A = 00: disconnect OC2A
// COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
// WGM2 = 101: phase-correct PWM with OCRA as top
// CS2 = 000: no prescaling
// The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A.
TIMER_CONFIG_KHZ(khz);
}
//+=============================================================================
// Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency.
//
void mark (int time)
{
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
if (time > 0) delayMicroseconds(time);
}
//+=============================================================================
// Leave pin off for time (given in microseconds)
// Sends an IR space for the specified number of microseconds.
// A space is no output, so the PWM output is disabled.
//
void space (int time)
{
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
if (time > 0) delayMicroseconds(time);
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment