Der DMX-Bereich sollte in drei Felder aufgeteilt werden: Aus, normal, Einzelblitz
Zusätzlich wollen wir kein Blinken sondern ein kurzes Flashen.
Deshalb nehme ich das zweite Vergleichsregister (OCR1B) und nutze es, um kurz vor dem anderen Interrupt mit dem Blitz zu beginnen. Über das alte Vergleichsregister (OCR1A) wird dann der Blitz nur noch abgeschlossen.
C
/* DMX Stroboskop Interface
Version: 0.1
Datum: 21.06.09
Autor: H.Hölscher (www.hoelscher-hi.de)
Target: DMX Transceiver @8MHz
Lizenz: GPLv2
*/
#include "lib_dmx_in.h"
#include <avr/wdt.h>
#include <avr/pgmspace.h>
uint8_t DmxBuf;
const uint16_t FreqTable[] PROGMEM = {
29206, 27412, 25826, 24414, 23148, 22007, 20973, 20032, 19172, 18382, 17655, 16984, 16361, 15783, 15244,
14741, 14269, 13827, 13412, 13021, 12652, 12303, 11973, 11660, 11364, 11082, 10813, 10557, 10314, 10081,
9858, 9645, 9441, 9246, 9058, 8878, 8705, 8538, 8378, 8224, 8075, 7931, 7793, 7659, 7530, 7405, 7284,
7167, 7054, 6944, 6838, 6735, 6635, 6538, 6443, 6352, 6263, 6176, 6092, 6010, 5930, 5852, 5776, 5703,
5631, 5560, 5492, 5425, 5360, 5297, 5235, 5174, 5115, 5057, 5000, 4945, 4890, 4837, 4786, 4735, 4685,
4636, 4589, 4542, 4496, 4452, 4408, 4365, 4322, 4281, 4240, 4200, 4161, 4123, 4085, 4048, 4012, 3976,
3941, 3906, 3872, 3839, 3806, 3774, 3743, 3711, 3681, 3651, 3621, 3592, 3563, 3535, 3507, 3480, 3453,
3427, 3400, 3375, 3349, 3324, 3300, 3276, 3252, 3228, 3205, 3182, 3160, 3138, 3116, 3094, 3073, 3052,
3031, 3011, 2990, 2971, 2951, 2932, 2912, 2894, 2875, 2856, 2838, 2820, 2803, 2785, 2768, 2751, 2734,
2717, 2701, 2685, 2669, 2653, 2637, 2622, 2606, 2591, 2576, 2561, 2547, 2532, 2518, 2504, 2490, 2476,
2463, 2449, 2436, 2422, 2409, 2396, 2384, 2371, 2358, 2346, 2334, 2322, 2310, 2298, 2286, 2274, 2263,
2251, 2240, 2229, 2218, 2207, 2196, 2185, 2175, 2164, 2154, 2143, 2133, 2123, 2113, 2103, 2093, 2083
};
void init_system(void)
{
DDRA= 0xFF; //low outputs
PORTA= 0;
DDRD= 0b10000110; //DMX, spare, LED1
PORTD= 0b01111010;
DDRE= 0b001;
TCCR1B = (1<<CS12)|(1<<WGM12); //set T1 @clk/256, CTC mode
TIMSK = (1<<OCIE1A);
OCR1A = 5000;
init_DMX(); //initialisiere DMX-Empfang
}
int main(void)
{
cli();
init_system();
sei();
for(;;)
{
wdt_reset(); //reset watchdog (evtl durch Fuse Bits aktiv)
get_dips();
if (DmxRxField[0] != DmxBuf)
{
if (DmxRxField[0] < 11)
{
TIMSK &= ~(1<<OCIE1B); //disable firing ISR
}
else if (DmxRxField[0] < 211 )
{
uint16_t TimeBuf;
TimeBuf= pgm_read_word(&FreqTable[DmxRxField[0] -11]);
if (TCNT1 >= (TimeBuf -310)) TCNT1= TimeBuf -310;
cli();
OCR1A= TimeBuf; //set quench time
OCR1B= TimeBuf -300; //set time to start firing
sei();
if (!(TIMSK &(1<<OCIE1B)))
{
TIFR = (1<<OCF1B);
TIMSK |= (1<<OCIE1B); //enable firing ISR
TCNT1= 0;
}
}
else
{
if (DmxBuf < 211)
{
TIMSK &= ~(1<<OCIE1B); //disable firing ISR
TCNT1 = 0;
PORTD &= ~(1<<PD7); //enable strobe
PORTA |= (1<<PA0);
OCR1A = 300; //set on time
}
}
DmxBuf= DmxRxField[0];
}
}
}
ISR (TIMER1_COMPA_vect)
{
PORTD |= (1<<PD7); //disable strobe
PORTA &= ~(1<<PA0);
}
ISR (TIMER1_COMPB_vect)
{
PORTD &= ~(1<<PD7); //enable strobe
PORTA |= (1<<PA0);
}
Alles anzeigen