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 LEDs 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 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|