Guten Tag,
heute macht meine Schaltung, was ich nicht verstehe. Genau:
AT Mega 324 PA. Über SPI sollten in MAX7219 jeweils 2 Bytes übertragen
werden. Wie auch immer: ~CS, Addr, Data, CS.
Wenn ich schrittweise mit JTAG in AVR Studio 4.19 gehe, wird alles OK.
Wenn ich versuche, Abschnitt schnell durch zu machen, bekommt MAX7219
die Daten nicht.
Ich habe versucht, zwischen ~CS, Addr, Data und CS Verzögerungen
eizubauen - bringt nichts.
Wenn ich in Assembler Schritte gehe, dann funktioniert alles nur, wenn
irgendwo (egal wo genau!) zwischen ~CS und CS ein Halt mit JTAG wird.
Auf einem Stück bekommt MAX7219 nichts.
In der Schaltung stehen zwei MAX7219, mit beiden ist das Gleiche.
Es gibt keine Kurzschließungen. Abblockkondensatoren gint es mehr als
genug.
Relevante Teil der Schaltung ist auf dem Bild. Zwei freie Ventile von
HC132 werden benutzt, um SPI intern und extern sicher zu trennen (falls
SPI extern mal in Slave-Modus läuft).
Was passiert bei dem Austausch mit JTAG, was auf SPI oder ~CS-Leitung
wirken könnte? Weil Verhalten sich nur unterscheidet je nachdem
dazwischen Austausch mit JTAG ist oder nicht.
Auch Testprogrammabschnitt: 1 | const volatile __flash u8 barwert[13] = {0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff};
| 2 |
| 3 | #define MYDEL() do{ asm volatile("nop");\
| 4 | asm volatile("nop");}while(0);
| 5 |
| 6 | void MYDEL_1(void){
| 7 | asm volatile("nop");
| 8 | }
| 9 |
| 10 | #define SEND(x,y) do{ PORTC &= ~(1<<PC6);\
| 11 | MYDEL()\
| 12 | SPDR = x;\
| 13 | while(!(SPSR & (1<<SPIF)));\
| 14 | SPDR = y;\
| 15 | while(!(SPSR & (1<<SPIF)));\
| 16 | MYDEL_1();\
| 17 | PORTC |= (1<<PC6);\
| 18 | MYDEL();}while(0);
| 19 |
| 20 | int main(void){
| 21 |
| 22 | spi_intern_init();
| 23 |
| 24 | spi_intern_outadr(BAR_ADR);
| 25 |
| 26 | // Dienstbyte
| 27 |
| 28 | SEND(0x0c,1); // normal operation
| 29 | SEND(0x09,0x00); // no decode
| 30 | SEND(0x0a,0x0f); // max hell
| 31 | SEND(0x0b,7); // scan limit
| 32 | SEND(0x0f,1); // Test
| 33 | SEND(0x0f,0); // no Test
| 34 | SEND(1,0);
| 35 | SEND(2,0);
| 36 | SEND(3,0);
| 37 | SEND(4,0);
| 38 | SEND(5,0);
| 39 | SEND(6,0);
| 40 |
| 41 | while(1){
| 42 |
| 43 | for(u8 i=0;i<9;i++){
| 44 |
| 45 | SEND(1,barwert[i]);
| 46 |
| 47 | SEND(2,barwert[i+1]);
| 48 |
| 49 | SEND(3,barwert[i+2]);
| 50 |
| 51 | SEND(4,barwert[i+3]);
| 52 |
| 53 | SEND(5,barwert[i+4]);
| 54 |
| 55 | }
| 56 | }
| 57 | return 0;
| 58 | }
|
Vielen Dank für eine Erklärung im voraus!
SPDR wird nicht gelesen. Dadurch wird SPIF ebenfalls nicht gelöscht
IMHO, der Code rennt durch den SPI Teil ohne Bremse durch.
Abhilfe: Jeweils ein Dummy read auf SPDR nach dem Warten aufs SPIF.
Ach so!!!
Das war meine Dummheit: ich wollte 2 bytes Code sparen :)
Half leider nicht...
Jetzt sieht die Funktion so aus: 1 | // spi.h
| 2 | static inline u8 spi_master_transmit(u8 data)
| 3 | {
| 4 | /* Start transmission */
| 5 | SPDR = data;
| 6 | /* Wait for transmission complete */
| 7 | while(!(SPSR & (1<<SPIF)));
| 8 | return SPDR;
| 9 | }
| 10 |
| 11 | static inline void spi_write_2byte(volatile u8 *csreg, u8 csbit, u8 data0, u8 data1)
| 12 |
| 13 | {
| 14 | *csreg &= ~(1<<csbit);
| 15 | spi_master_transmit(data0);
| 16 | spi_master_transmit(data1);
| 17 | *csreg |= (1<<csbit);
| 18 | }
|
1 | // spi_intern.h
| 2 | static inline void spi_intern_write_2byte(u8 data0, u8 data1)
| 3 |
| 4 | {
| 5 | spi_write_2byte(&SPI_INTERN_E_PORT,SPI_INTERN_E,data0,data1);
| 6 | }
|
1 | // main.c
| 2 | spi_intern_write_2byte(0x0c,1); // normal operation
| 3 | ...
|
Effekt bleibt, leider
Das Problem habe ich gelöst: es half Oszilloskop.
MOSI ist mit Widerstand 47k an Vcc angeschlossen (um in dem hochohmigen
Zustand Stromverbrauch zu reduzieren).
Mit Programm-SPI ist es gelungen, normale Datenübertragung auf etwa 20
kHz zu schaffen. Oszilloskop zeigt langsame steigende SIgnalflanke. JTAG
zeigt DDR-bit = 1.
Also, defekte Mikrocontroller. P-Transistor sollte kaputt sein.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|