Hi,
ich versuche die SPI-Schnittstelle des AT89C51AC3 anzusprechen, es kommt
aber nicht einmal der SPI-clock heraus. Da muss ich wohl noch etwas
wissen, oder? Die application note von Atmel führt bei mir nicht zum
Erfolg. Der µC läuft mit 29,4912 Mhz im X2 mode. DAC_CS ist das Chip
enable
signal für den DAC, das geht wenigstens.
Hier mein Code für die hoffentlich Wissenden:
SS bzw. CS für den Peripheriebaustein einfach über einen Portpin auf
low.
Richtig sind die Adressen: SPCON 0xD4, SPSCR 0xD5 und SPDAT 0xD6.
"using 1" nutzt Registerbank 1 - muss nicht sein.
Bye
Rabis
R. B. schrieb:> void SPI_ISR (void) interrupt SPI_VECTOR using 1 { // SPI_VECTOR = 0x0053 !
Hallo, ich habe gerade genau das gleiche Problem wie du, als du damals
mit dem AT89C51AC3 gearbeitet hast. Aus dem Datenblatt ist mir nicht
ganz klar, welche Interruptnummer der SPI-Interrupt hat. Daher würde ich
dich gerne fragen wie du die Variable SPI_VECTOR belegt hast.
Getestet habe ich es mal mit SPI_VECTOR=0x53 jedoch will er einfach
nicht in die ISR rein springen.
Würde mich freuen, wenn du mir hier einen kleinen Tipp geben könntest.
Danke!
Grüßle
Die ISR-Einsprungadresse ist lt. DB tatsächlich 0x0053, das passt. Die
IRQ-Nummer bzw. dessen Definition, die dein nicht näher genannter
Compiler verwendet, auf 0x0053 zu setzen ist definitiv falsch. Die
Definition müsste eigentlich bereits im Header-File definiert sein,
schau dort mal nach.
Ralf
Nachtrag:
> Die IRQ-Nummer bzw. dessen Definition, die dein nicht näher genannter> Compiler verwendet, auf 0x0053 zu setzen ist definitiv falsch...
... es sei denn, der Compiler erwartet dort tatsächlich die IRQ-Adresse,
sorry. Der Keil will ne Nummer haben und berechnet die Adresse anhand
der Nummer.
Ralf
Als Compiler kommt der sdcc zum Einsatz. Habe gleich mal einen Blick in
mein Headerfile geworfen...konnte aber nichts finden. Habe das File mal
angehängt.
> Als Compiler kommt der sdcc zum Einsatz. Habe gleich mal einen Blick in> mein Headerfile geworfen...konnte aber nichts finden. Habe das File mal> angehängt.
Stimmt, da ist nix drin bzgl. der ISR-Vektoren.
> Hier mal noch mein bisheriger Code.
Du hast Unterschiede zwischen ISR-Prototyp und -Funktion (braucht der
SDCC denn einen ISR-Prototyp?).
Der Rest sieht auf einen schnellen Blick stimmig aus, wobei ich
mindestens das transmit_completed-Flag als volatile deklarieren würde.
> jedoch will er einfach nicht in die ISR rein springen.
Wie hast du das geprüft? Kommt denn überhaupt n SPI-Clock oder so raus?
Dann weisst du das wenigstens das SPI-Interface wirklich an ist.
Und ob der Interrupt wirklich ausgelöst werden kann, kannst du prüfen,
indem du testweise einfach mal das SPIF-Flag setzt, dann muss er den IRQ
ausführen.
Ralf
Ralf schrieb:> Du hast Unterschiede zwischen ISR-Prototyp und -Funktion (braucht der
Ja, das sehe ich gerade auch :-) muss dann wohl beim rumprobieren
passiert sein. Aber ich kann versichern, dass ich die genannte
Problematik auch schon hatte, als ISR-Prototyp und -Funktion den
gleichen Kopf hatten.
>> jedoch will er einfach nicht in die ISR rein springen.> Wie hast du das geprüft? Kommt denn überhaupt n SPI-Clock oder so raus?> Dann weisst du das wenigstens das SPI-Interface wirklich an ist.> Und ob der Interrupt wirklich ausgelöst werden kann, kannst du prüfen,> indem du testweise einfach mal das SPIF-Flag setzt, dann muss er den IRQ> ausführen.
SPI-Clock und MOSI Signal sind da. Habe ich mit Oszi geprüft.
SPI_send_byte(0x11); führt er noch aus. Konnte auf dem Oszi die Bitfolge
00010001 also dezimal 17 erkennen. Aber danach kommt nichts mehr. Obwohl
ja noch einige Bytes im Buffer sind.
Über das schalten einer LED am Pin P1.0 konnte herausfinden wo genau er
hängen bleibt. Habe dazu in die obigen Funktionen das Setzen des Ports
auf Null eingebaut:
1
voidSPI_send_byte(charbyte)
2
{
3
SPDAT=byte;/* send an example data */
4
while(!transmit_completed)/* wait end of transmition */
5
{
6
P1_0=0;
7
}
8
P1_0=1;
9
transmit_completed=0;/* clear software transfert flag */
10
}
Hier ging die LED an P1.0 dann an und blieb an! Das heißt für mich er
klemmt in der While-Schleife fest.
Dann habe ich die beiden Zeilen mit P1_0 wieder auskommentiert und dafür
das nachfolgende getestet.
1
voidSPI_interrupt(void)__interrupt(9)__using(1)
2
{
3
P1_0=0;
4
switch(SPSCR)/* read and clear spi status register */
5
{
6
case0x80:
7
serial_data=SPDAT;/* read receive data */
8
transmit_completed=1;/* set software flag */
9
break;
10
11
case0x10:
12
/* put here for mode fault tasking */
13
break;
14
15
case0x40:
16
/* put here for overrun tasking */
17
break;
18
}
19
}
Der Pin wird hier ja eigentlich gleich zu Beginn der ISR gesetzt. Doch
die LED bleibt aus. Daher kam ich zu dem Schluss, dass er nicht in die
ISR springt.
Die Interrupt-Nummer bei 8051-Kompatiblen errechnet sich eigentlich aus
( Einsprungadresse - 3 ) / 8
Bei 0x53 müsste daher eigenlich die Interrupt-Nummer 10 sein... In
meinem (funktionierenden Code für den AT89C5131 habe ich
Interrupt-Nummer 9 mit Adresse 0x4B drinstehen...
Hallo Markus,
> ESPI = 1; /* enable spi interrupt */
Das hier kommt kam mir gerade komisch vor. Beim 5131 ist das obere
Freigaberegister nicht bitadressierbar, bei Deinem Typ ist es auf einer
bitadressierbaren Adresse, sollte also in Ordnung sein.
Da hat Atmel doch einige Unterschiede zwischen den Derivaten eingebaut!
tschuessle
Bernhard
Bernhard Spitzer schrieb:> Die Interrupt-Nummer bei 8051-Kompatiblen errechnet sich eigentlich aus> ( Einsprungadresse - 3 ) / 8> Bei 0x53 müsste daher eigenlich die Interrupt-Nummer 10 sein...
Hallo Bernhard...danke dir, das war der entscheidende Hinweis. Mit
Interrupt Nummer 10 geht es jetzt auch bei mir. :-)
Grüße
Hallo ,
ich möchte gerne mit einem 89c51cc03 ein ediptft43 von Elektronik
Assembly mit dem spi-bus verbinden und dem display etwas senden bwz ich
habe auf dem Display Instrumenten von denen ich den Zeiger bewegen
möchte leider habe ich in C keinen Plan.
Über hilfe freue ich mich sehr.
Grüße Robin
Robin schrieb:> Hallo ,>> ich möchte gerne mit einem 89c51cc03 ein ediptft43 von Elektronik> Assembly mit dem spi-bus verbinden und dem display etwas senden bwz ich> habe auf dem Display Instrumenten von denen ich den Zeiger bewegen> möchte leider habe ich in C keinen Plan.> Über hilfe freue ich mich sehr.>> Grüße Robin
So leid es mir tut, aber da wirst du nicht umhin kommen, dich erstmal in
C einzuarbeiten. Es sei denn, du kannst Assembler. Aber da kann ich dir
dann aich nicht mehr Helfen.
Eine eigene Frage?
Dieser Thread ist über 16 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.