Hi *, ich glaub ich bin zu doof, mir ein PWM Ambilight zu bauen. Code anbei, ist für die Hardware des STK-600 geschrieben (man kan also einfach die beigelegten Kabel stecken auf PortD und ein zweipoliges für USART).
1 | #define F_CPU 7373742 |
2 | #define MAX_CHANNELS 9 |
3 | #include <avr/io.h> |
4 | #include <avr/interrupt.h> |
5 | #include <util/delay.h> |
6 | |
7 | const unsigned int gamma22[256] = { 0, 564, 1125, 1684, 2240, 2794, 3345, 3893, 4438, 4981, 5521, 6059, 6594, 7126, 7656, 8183, 8707, 9229, 9748, 10265, 10779, 11290, 11799, 12305, 12808, 13309, 13807, 14303, 14796, 15286, 15774, 16260, 16742, 17222, 17700, 18175, 18647, 19117, 19584, 20048, 20510, 20970, 21427, 21881, 22333, 22782, 23229, 23673, 24114, 24553, 24989, 25423, 25855, 26283, 26710, 27133, 27554, 27973, 28389, 28803, 29214, 29622, 30028, 30432, 30833, 31231, 31627, 32021, 32411, 32800, 33186, 33569, 33950, 34329, 34705, 35078, 35449, 35818, 36184, 36547, 36908, 37267, 37623, 37977, 38328, 38677, 39023, 39367, 39709, 40048, 40384, 40718, 41050, 41379, 41706, 42031, 42353, 42672, 42989, 43304, 43616, 43926, 44234, 44539, 44841, 45142, 45440, 45735, 46028, 46319, 46607, 46893, 47177, 47458, 47737, 48014, 48288, 48560, 48829, 49096, 49361, 49623, 49883, 50141, 50397, 50650, 50900, 51149, 51395, 51639, 51880, 52119, 52356, 52591, 52823, 53053, 53281, 53506, 53729, 53950, 54169, 54385, 54599, 54811, 55020, 55228, 55433, 55635, 55836, 56034, 56230, 56424, 56616, 56805, 56992, 57177, 57360, 57541, 57719, 57895, 58069, 58241, 58411, 58578, 58743, 58906, 59067, 59226, 59383, 59537, 59690, 59840, 59988, 60134, 60278, 60420, 60559, 60697, 60832, 60965, 61097, 61226, 61353, 61478, 61601, 61722, 61841, 61957, 62072, 62185, 62295, 62404, 62511, 62615, 62718, 62818, 62917, 63014, 63108, 63201, 63292, 63380, 63467, 63552, 63635, 63716, 63795, 63872, 63948, 64021, 64092, 64162, 64230, 64296, 64360, 64422, 64482, 64540, 64597, 64652, 64705, 64756, 64806, 64854, 64900, 64944, 64986, 65027, 65066, 65103, 65139, 65173, 65205, 65236, 65265, 65293, 65319, 65343, 65366, 65387, 65406, 65424, 65441, 65456, 65470, 65482, 65493, 65503, 65511, 65518, 65524, 65528, 65531, 65533, 65535, 65535 }; |
8 | unsigned char volatile currentChannelNumber = 255; |
9 | unsigned char volatile channelValues[MAX_CHANNELS] = {0,0,0,0,0,0,0,0,0}; |
10 | |
11 | |
12 | ISR(USARTC1_RXC_vect) { |
13 | unsigned char data; |
14 | |
15 | data = USARTC1.DATA; |
16 | |
17 | if (currentChannelNumber == 0) { PORTD.OUT &= 0x7F; } |
18 | |
19 | channelValues[currentChannelNumber] = data; |
20 | |
21 | if (currentChannelNumber == 8) { |
22 | PORTD.OUT |= 0x80; |
23 | TCD0.CCA = gamma22[channelValues[0]]; |
24 | TCD0.CCB = gamma22[channelValues[1]]; |
25 | TCD0.CCC = gamma22[channelValues[2]]; |
26 | TCD0.CCD = gamma22[channelValues[3]]; |
27 | TCD1.CCA = gamma22[channelValues[4]]; |
28 | TCD1.CCB = gamma22[channelValues[5]]; |
29 | } |
30 | currentChannelNumber++; |
31 | |
32 | if (currentChannelNumber==9) { currentChannelNumber=0; } |
33 | |
34 | } |
35 | |
36 | int main() { |
37 | |
38 | PORTD.DIR = 0xFF; |
39 | PORTD.OUT = 0b11111111; |
40 | |
41 | |
42 | OSC.CTRL = OSC_RC32MEN_bm | OSC_XOSCEN_bm; //enable 32MHz oscillator and external OSC |
43 | |
44 | while(!(OSC.STATUS & OSC_RC32MRDY_bm)); //wait for stability for 32MHz |
45 | |
46 | |
47 | while(!(OSC.STATUS & OSC_XOSCRDY_bm)); //wait for stability for External Clock Source |
48 | |
49 | CCP = CCP_IOREG_gc; // Conf.Änderung erlauben |
50 | CLK.CTRL = 0x03; // CSource Clock Extern |
51 | CCP = CCP_IOREG_gc; // Conf.Änderung erlauben |
52 | CLK.PSCTRL = 0x00; // Prescaler 0 (Teiler) |
53 | |
54 | |
55 | //USART INIT |
56 | PORTC.DIR &= 0b10111111; // RX Bit (6) als Eingang |
57 | PORTC.DIR |= 0b10000000; // TX Bit (7) als Ausgang |
58 | USARTC1.CTRLA = 0b00010000; // Interrupt-Level: RX High, alles andere Off |
59 | USARTC1.CTRLC = 0b00000011; // Async, NoPar, 1SBit, 8Bit Wortgröße |
60 | |
61 | USARTC1.BAUDCTRLA = 0b00010111; // 23 = 19k2 |
62 | USARTC1.BAUDCTRLB = 0b00000000; //BSCALe=3x0, 23 hat keine high bits, daher auch 0 |
63 | |
64 | USARTC1.CTRLB = 0b00011000; // 000, RX ein, TX ein, Single-Speed, No-Multi, 2xDontCare |
65 | |
66 | //TIMER PORTD_0 INIT |
67 | TCD0.CTRLA = 0x01; // divide clock by 0, enable Timers |
68 | TCD0.PER = 0xFFFF; // set resolution to 16Bit |
69 | TCD0.CTRLB = 0xF3; // enable frequency generation for all 4 Channels |
70 | |
71 | //TIMER PORTD_1 INIT |
72 | TCD1.CTRLA = 0x01; |
73 | TCD1.PER = 0xFFFF; |
74 | TCD1.CTRLB = 0xF3; // Es scheint nichts zu machen, wenn mann Bits für |
75 | // Output-Compare setzt, die nicht vorhanden sind. |
76 | // Manual schweigt sich darüber aus. |
77 | |
78 | CCP = CCP_IOREG_gc; // Conf.Änderung erlauben |
79 | PMIC.CTRL = 0b00000111; // EN hi mi und lo level interrupts |
80 | |
81 | sei(); |
82 | |
83 | TCD0.CCA = 0xFFFF; |
84 | TCD0.CCB = 0xFFFF; |
85 | TCD0.CCC = 0xFFFF; |
86 | TCD0.CCD = 0xFFFF; |
87 | TCD1.CCA = 0xFFFF; |
88 | TCD1.CCB = 0xFFFF; |
89 | |
90 | while (1) { } |
91 | |
92 | } |
Ich möchte einfach nur, dass die LEDs entsprechend hell oder dunkler werden, die Software auf dem PC ist boblight 1.3; das Protokoll momo (also einfach 9 Bytes für R1-3,G1-3,B1-4); es funktioniert auch soweit ganz gut, nur flackern die LEDs reproduzierbar sporadisch auf. Habe Single-Slope, DualS und Freq-Modi der Timer probiert. Ich hatte zunächst auf ein Indexproblem mit der Channelnumber getippt, aber wie ich's auch drehe und wende, das glaub ich ist es nicht. Es scheint eine Art Konflikt zwischen USART Interrupt und Timer Interrupt zu sein, denn wenn ich Code zum ändern der Helligkeit ohne USART schreibe funktioniert alles einwandfrei. Könnte das vielleicht jemand auf einem STK600 nachvollziehen oder hätte sonst jemand einen Tip? Danke, Christoph