Mikrocontroller und Digitale Elektronik
›
Thread
TLC5940 mit Xmega
Hallo,
ich möchte den TLC5940 in Betrieb nehmen und habe dazu das Datenblatt
und Demistifying gewältzt und versucht den Code mit einem Xmega
umzusetzen. In Demisitifying wird der Code in verschiedenen
Optimierungsstufen erstellt. Den ersten habe ich bei mir umgesetzt. Er
funktioniert auch. Wenn ich diesen jedoch durch Interrupts erweitere,
funktioniert er nicht. Die LED s leuchten nicht.
Könnt ihr mir weiterhelfen? Was habe ich vergessen?
Meine Unterschiede zum Original:
- Xmega anstatt Atmega
- 32Mhz interner Takt anstatt 16Mhz
Code 1, der funktioniert: 1 #define F_CPU 2e6
2
3 #include <asf.h>
4 #include <avr/io.h>
5 #include <stdint.h>
6 #include <util/delay.h>
7
8 #define GSCLK_PORT PORTC
9 #define GSCLK_PIN 4
10 #define SIN_PORT PORTC
11 #define SIN_PIN 5
12 #define SCLK_PORT PORTC
13 #define SCLK_PIN 3
14 #define BLANK_PORT PORTC
15 #define BLANK_PIN 2
16 #define DCPRG_PORT PORTC
17 #define DCPRG_PIN 6
18 #define VPRG_PORT PORTC
19 #define VPRG_PIN 7
20 #define XLAT_PORT PORTC
21 #define XLAT_PIN 1
22
23 #define TLC5940_N 1
24
25 uint8_t dcData [ 96 * TLC5940_N ] = {
26 //MSB LSB
27 1 , 1 , 1 , 1 , 1 , 1 , // Channel 15
28 1 , 1 , 1 , 1 , 1 , 1 , // Channel 14
29 1 , 1 , 1 , 1 , 1 , 1 , // Channel 13
30 1 , 1 , 1 , 1 , 1 , 1 , // Channel 12
31 1 , 1 , 1 , 1 , 1 , 1 , // Channel 11
32 1 , 1 , 1 , 1 , 1 , 1 , // Channel 10
33 1 , 1 , 1 , 1 , 1 , 1 , // Channel 9
34 1 , 1 , 1 , 1 , 1 , 1 , // Channel 8
35 1 , 1 , 1 , 1 , 1 , 1 , // Channel 7
36 1 , 1 , 1 , 1 , 1 , 1 , // Channel 6
37 1 , 1 , 1 , 1 , 1 , 1 , // Channel 5
38 1 , 1 , 1 , 1 , 1 , 1 , // Channel 4
39 1 , 1 , 1 , 1 , 1 , 1 , // Channel 3
40 1 , 1 , 1 , 1 , 1 , 1 , // Channel 2
41 1 , 1 , 1 , 1 , 1 , 1 , // Channel 1
42 1 , 1 , 1 , 1 , 1 , 1 , // Channel 0
43 };
44
45 uint8_t gsData [ 192 * TLC5940_N ] = {
46 //MSB LSB
47 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 15
48 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 14
49 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 13
50 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , // Channel 12
51 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , // Channel 11
52 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , // Channel 10
53 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , // Channel 9
54 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , // Channel 8
55 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , // Channel 7
56 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 6
57 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 5
58 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 4
59 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 3
60 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 2
61 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 1
62 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // Channel 0
63 };
64
65 #define setOutput(ddr,pin) (ddr |= (1<<pin))
66 #define setHigh(port,pin) (port |= (1<<pin))
67 #define setLow(port,pin) (port &= ~(1<<pin))
68 #define outputState(port,pin) ((port) & (1<<(pin)))
69
70 #define pulse(port,pin) do { \
71 setHigh((port),(pin)); \
72 setLow((port),(pin)); \
73 } while (0);
74
75 void TLC5940_Init ( void );
76 void TLC5940_ClockInDC ( void );
77 void TLC5940_SetGS_And_GS_PWM ( void );
78
79
80 int main ( void )
81 {
82
83 //Oszillator auf 32Mhz stellen
84 OSC . CTRL |= OSC_RC32MEN_bm ;
85 // Warten bis der Oszillator bereit ist
86 while ( ! ( OSC . STATUS & OSC_RC32MRDY_bm ));
87 //Schützt I/O Register, Interrupts werden ignoriert
88 CCP = CCP_IOREG_gc ;
89 //aktiviert den internen Oszillator
90 CLK . CTRL = CLK_SCLKSEL_RC32M_gc ;
91
92 TLC5940_Init ();
93 TLC5940_ClockInDC ();
94
95 for (;;) {
96 TLC5940_SetGS_And_GS_PWM ();
97 }
98
99 return 0 ;
100 }
101
102 void TLC5940_Init ( void )
103 {
104 setOutput ( GSCLK_PORT . DIR , GSCLK_PIN );
105 setOutput ( SCLK_PORT . DIR , SCLK_PIN );
106 setOutput ( DCPRG_PORT . DIR , DCPRG_PIN );
107 setOutput ( VPRG_PORT . DIR , VPRG_PIN );
108 setOutput ( XLAT_PORT . DIR , XLAT_PIN );
109 setOutput ( BLANK_PORT . DIR , BLANK_PIN );
110 setOutput ( SIN_PORT . DIR , SIN_PIN );
111
112 setLow ( GSCLK_PORT . OUT , GSCLK_PIN );
113 setLow ( SCLK_PORT . OUT , SCLK_PIN );
114 setLow ( DCPRG_PORT . OUT , DCPRG_PIN );
115 setHigh ( VPRG_PORT . OUT , VPRG_PIN );
116 setLow ( XLAT_PORT . OUT , XLAT_PIN );
117 setHigh ( BLANK_PORT . OUT , BLANK_PIN );
118
119 }
120
121 void TLC5940_ClockInDC ( void ) {
122 setHigh ( DCPRG_PORT . OUT , DCPRG_PIN );
123 setHigh ( VPRG_PORT . OUT , VPRG_PIN );
124
125 uint8_t Counter = 0 ;
126
127 for (;;) {
128 if ( Counter > TLC5940_N * 96 - 1 ) {
129 pulse ( XLAT_PORT . OUT , XLAT_PIN );
130 break ;
131 } else {
132 if ( dcData [ Counter ])
133 setHigh ( SIN_PORT . OUT , SIN_PIN );
134 else
135 setLow ( SIN_PORT . OUT , SIN_PIN );
136 pulse ( SCLK_PORT . OUT , SCLK_PIN );
137 Counter ++ ;
138 }
139 }
140 }
141
142 void TLC5940_SetGS_And_GS_PWM ( void ) {
143 uint8_t firstCycleFlag = 0 ;
144
145 if ( outputState ( VPRG_PORT . OUT , VPRG_PIN )) {
146 setLow ( VPRG_PORT . OUT , VPRG_PIN );
147 firstCycleFlag = 1 ;
148 }
149
150 uint16_t GSCLK_Counter = 0 ;
151 uint8_t Data_Counter = 0 ;
152
153 setLow ( BLANK_PORT . OUT , BLANK_PIN );
154 for (;;) {
155 if ( GSCLK_Counter > 4095 ) {
156 setHigh ( BLANK_PORT . OUT , BLANK_PIN );
157 pulse ( XLAT_PORT . OUT , XLAT_PIN );
158 if ( firstCycleFlag ) {
159 pulse ( SCLK_PORT . OUT , SCLK_PIN );
160 firstCycleFlag = 0 ;
161 }
162 break ;
163 } else {
164 if ( ! ( Data_Counter > TLC5940_N * 192 - 1 )) {
165 if ( gsData [ Data_Counter ])
166 setHigh ( SIN_PORT . OUT , SIN_PIN );
167 else
168 setLow ( SIN_PORT . OUT , SIN_PIN );
169 pulse ( SCLK_PORT . OUT , SCLK_PIN );
170 Data_Counter ++ ;
171 }
172 }
173 pulse ( GSCLK_PORT . OUT , GSCLK_PIN );
174 GSCLK_Counter ++ ;
175 }
176 }
Code 2 - funktioniert nicht 1 #define F_CPU 2e6
2
3 #include <asf.h>
4 #include <avr/io.h>
5 #include <stdint.h>
6 #include <util/delay.h>
7 #include <avr/interrupt.h>
8
9 #define GSCLK_PORT PORTC
10 #define GSCLK_PIN 4
11 #define SIN_PORT PORTC
12 #define SIN_PIN 5
13 #define SCLK_PORT PORTC
14 #define SCLK_PIN 3
15 #define BLANK_PORT PORTC
16 #define BLANK_PIN 2
17 #define DCPRG_PORT PORTC
18 #define DCPRG_PIN 6
19 #define VPRG_PORT PORTC
20 #define VPRG_PIN 7
21 #define XLAT_PORT PORTC
22 #define XLAT_PIN 1
23
24 #define TLC5940_N 1
25
26 uint8_t dcData [ 96 * TLC5940_N ] = {
27 //MSB LSB
28 1 , 1 , 1 , 1 , 1 , 1 , // Channel 15
29 1 , 1 , 1 , 1 , 1 , 1 , // Channel 14
30 1 , 1 , 1 , 1 , 1 , 1 , // Channel 13
31 1 , 1 , 1 , 1 , 1 , 1 , // Channel 12
32 1 , 1 , 1 , 1 , 1 , 1 , // Channel 11
33 1 , 1 , 1 , 1 , 1 , 1 , // Channel 10
34 1 , 1 , 1 , 1 , 1 , 1 , // Channel 9
35 1 , 1 , 1 , 1 , 1 , 1 , // Channel 8
36 1 , 1 , 1 , 1 , 1 , 1 , // Channel 7
37 1 , 1 , 1 , 1 , 1 , 1 , // Channel 6
38 1 , 1 , 1 , 1 , 1 , 1 , // Channel 5
39 1 , 1 , 1 , 1 , 1 , 1 , // Channel 4
40 1 , 1 , 1 , 1 , 1 , 1 , // Channel 3
41 1 , 1 , 1 , 1 , 1 , 1 , // Channel 2
42 1 , 1 , 1 , 1 , 1 , 1 , // Channel 1
43 1 , 1 , 1 , 1 , 1 , 1 , // Channel 0
44 };
45
46 uint8_t gsData [ 192 * TLC5940_N ] = {
47 //MSB LSB
48 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 15
49 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 14
50 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 13
51 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , // Channel 12
52 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , // Channel 11
53 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , // Channel 10
54 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , // Channel 9
55 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , // Channel 8
56 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , // Channel 7
57 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 6
58 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 5
59 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 4
60 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 3
61 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 2
62 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // Channel 1
63 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // Channel 0
64 };
65
66 #define setOutput(ddr,pin) (ddr |= (1<<pin))
67 #define setHigh(port,pin) (port |= (1<<pin))
68 #define setLow(port,pin) (port &= ~(1<<pin))
69 #define outputState(port,pin) ((port) & (1<<(pin)))
70
71 #define pulse(port,pin) do { \
72 setHigh((port),(pin)); \
73 setLow((port),(pin)); \
74 } while (0);
75
76
77
78 void TLC5940_Init ( void );
79 void TLC5940_ClockInDC ( void );
80
81 int main ( void )
82 {
83 //Oszillator auf 32Mhz stellen
84 OSC . CTRL |= OSC_RC32MEN_bm ;
85 // Warten bis der Oszillator bereit ist
86 while ( ! ( OSC . STATUS & OSC_RC32MRDY_bm ));
87 //Schützt I/O Register, Interrupts werden ignoriert
88 CCP = CCP_IOREG_gc ;
89 //aktiviert den internen Oszillator
90 CLK . CTRL = CLK_SCLKSEL_RC32M_gc ;
91
92 TLC5940_Init ();
93 TLC5940_ClockInDC ();
94
95 PORTR . DIR = 1 ; // Nur zum Test
96 PORTR . OUT = 1 ; // Nur zum Test
97
98
99 PMIC . CTRL |= PMIC_HILVLEN_bm | PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm ;
100
101 TCD1 . CTRLA = TC_CLKSEL_DIV1024_gc ; //1024 Vorteiler
102 TCD1 . CTRLB = 0x00 ;
103 TCD1 . INTCTRLA = 0x03 ;
104 TCD1 . PER = 6 ; // Wert zu dem gezählt wird
105
106 sei ();
107
108 for (;;) {
109
110 }
111
112 return 0 ;
113 }
114
115 ISR ( TCD1_OVF_vect ) {
116 PORTR . OUTTGL = 1 ; // Nur zum Test
117
118 uint8_t firstCycleFlag = 0 ;
119 static uint8_t xlatNeedsPulse = 0 ;
120
121 setHigh ( BLANK_PORT . OUT , BLANK_PIN );
122
123 if ( outputState ( VPRG_PORT . OUT , VPRG_PIN )) {
124 setLow ( VPRG_PORT . OUT , VPRG_PIN );
125 firstCycleFlag = 1 ;
126 }
127
128 if ( xlatNeedsPulse ) {
129 pulse ( XLAT_PORT . OUT , XLAT_PIN );
130 xlatNeedsPulse = 0 ;
131 }
132
133 if ( firstCycleFlag )
134 pulse ( SCLK_PORT . OUT , SCLK_PIN );
135
136 setLow ( BLANK_PORT . OUT , BLANK_PIN );
137
138 uint8_t Data_Counter = 0 ;
139 for (;;) {
140 if ( ! ( Data_Counter > TLC5940_N * 192 - 1 )) {
141 if ( gsData [ Data_Counter ])
142 setHigh ( SIN_PORT . OUT , SIN_PIN );
143 else
144 setLow ( SIN_PORT . OUT , SIN_PIN );
145 pulse ( SCLK_PORT . OUT , SCLK_PIN );
146 Data_Counter ++ ;
147 } else {
148 xlatNeedsPulse = 1 ;
149 break ;
150 }
151 }
152
153 }
154
155
156 void TLC5940_Init ( void )
157 {
158 setOutput ( GSCLK_PORT . DIR , GSCLK_PIN );
159 setOutput ( SCLK_PORT . DIR , SCLK_PIN );
160 setOutput ( DCPRG_PORT . DIR , DCPRG_PIN );
161 setOutput ( VPRG_PORT . DIR , VPRG_PIN );
162 setOutput ( XLAT_PORT . DIR , XLAT_PIN );
163 setOutput ( BLANK_PORT . DIR , BLANK_PIN );
164 setOutput ( SIN_PORT . DIR , SIN_PIN );
165
166 setLow ( GSCLK_PORT . OUT , GSCLK_PIN );
167 setLow ( SCLK_PORT . OUT , SCLK_PIN );
168 setLow ( DCPRG_PORT . OUT , DCPRG_PIN );
169 setHigh ( VPRG_PORT . OUT , VPRG_PIN );
170 setLow ( XLAT_PORT . OUT , XLAT_PIN );
171 setHigh ( BLANK_PORT . OUT , BLANK_PIN );
172
173 }
174
175 void TLC5940_ClockInDC ( void ) {
176 setHigh ( DCPRG_PORT . OUT , DCPRG_PIN );
177 setHigh ( VPRG_PORT . OUT , VPRG_PIN );
178
179 uint8_t Counter = 0 ;
180
181 for (;;) {
182 if ( Counter > TLC5940_N * 96 - 1 ) {
183 pulse ( XLAT_PORT . OUT , XLAT_PIN );
184 break ;
185 } else {
186 if ( dcData [ Counter ])
187 setHigh ( SIN_PORT . OUT , SIN_PIN );
188 else
189 setLow ( SIN_PORT . OUT , SIN_PIN );
190 pulse ( SCLK_PORT . OUT , SCLK_PIN );
191 Counter ++ ;
192 }
193 }
194 }
Ich habe den Fehler gefunden. Er ist im Demistifying drin gewesen.
Im Interrupt hat noch ein 1 pulse ( GSCLK_PORT . OUT , GSCLK_PIN )
weiter hinten gefehlt.
Die ISR lautet somit wiefolgt: 1 ISR ( TCD1_OVF_vect ) {
2 PORTR . OUTTGL = 1 ; // Nur zum Test
3
4 uint8_t firstCycleFlag = 0 ;
5 static uint8_t xlatNeedsPulse = 0 ;
6
7 setHigh ( BLANK_PORT . OUT , BLANK_PIN );
8
9 if ( outputState ( VPRG_PORT . OUT , VPRG_PIN )) {
10 setLow ( VPRG_PORT . OUT , VPRG_PIN );
11 firstCycleFlag = 1 ;
12 }
13
14 if ( xlatNeedsPulse ) {
15 pulse ( XLAT_PORT . OUT , XLAT_PIN );
16 xlatNeedsPulse = 0 ;
17 }
18
19 if ( firstCycleFlag )
20 pulse ( SCLK_PORT . OUT , SCLK_PIN );
21
22 setLow ( BLANK_PORT . OUT , BLANK_PIN );
23
24 uint8_t Data_Counter = 0 ;
25 for (;;) {
26 if ( ! ( Data_Counter > TLC5940_N * 192 - 1 )) {
27 if ( gsData [ Data_Counter ])
28 setHigh ( SIN_PORT . OUT , SIN_PIN );
29 else
30 setLow ( SIN_PORT . OUT , SIN_PIN );
31 pulse ( SCLK_PORT . OUT , SCLK_PIN );
32 pulse ( GSCLK_PORT . OUT , GSCLK_PIN ); // MaWa
33 Data_Counter ++ ;
34 } else {
35 xlatNeedsPulse = 1 ;
36 break ;
37 }
38 }
39
40 }
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren