Guten abend zusammen, ich verwende einen AT898252 Controller und will per SPI am MOSI pin (P1.5) seriell daten ausgeben. zu testzwecken soll fortlaufend 10101101 seriall ausgeben werden. leider funktioniert das bei mir nicht was mache ich falsch? ist das unterprogramm senden richtig? danke für eure hilfe Stefan hier mein assemblerprogramm: $nomod51 #include <AT898252.H> org 0000h setb es ; für spi interrupt ;*****************************SPI am ATMEL initialisieren************************************** mov SPCR,#11001010b ;Initialisierung des SPI Port zur seriellen Übertragung ;********************** Senden ****************************************** loop: mov a,#10101101b ;diese 8 bit sollen fortlaufend an mosi ausgegeben werden lcall senden lcall loop ;********************** Unterprogramm Senden ****************************************** senden: mov spdr,a ;Akkuinhalt senden warteS: jnb 0x80 ,warteS clr 0x80 ;Sende-Flag löschen ret ;writing to the spi data register of the master cpu starts the spi clock generator, ;and the data written shifts out of the mosi pin ;0x80= spi interrupt flag ;spdr=spi data register end
Hi, 1. Das ORG 0000h... du weisst schon, dass bei Verwendung des seriellen Interrupts der Controller immer, wenn solch ein Interrupt auftritt, an eine bestimmte Adresse springt, an der er die Interrupt-Routine erwartet, oder? Das heisst, deine Software liegt höchstwahrscheinlich genau an dieser Adresse (ich glaube der serielle IR liegt an 000Bh, musst du nachschauen). Die erste Interrupt-Adresse (glaube Timer0) liegt an 0003h. Das bedeutet, wenn du mit Interrupts arbeiten willst, MUSS dein erster Befehl (0000h) ein JMP sein, der dafür sorgt, dass das eigentliche Programm angesprungen wird. 2. SETB ES bringt dir gar nix, wenn du nicht auch das globale Interrupt-Freigabe-Bit EA setzt. Falls du (wie ich vermute) das ganze NICHT interruptgesteuert machen willst, sondern per Polling, kannst du dir auch das SETB ES sparen. 3. Guckst du hier: http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3419 Da ist ein PDF sowohl mit C- als auch mit Assembler-Beispielen. Hoffe, ich konnte helfen. Gruß Ralf
;********************** Senden ****************************************** loop: mov a,#10101101b ;diese 8 bit sollen fortlaufend an mosi ausgegeben werden lcall senden lcall loop Rekursive Funktionen sind zwar nicht schön, aber erlaubt. Bloß du must dann auch eine Abbruchbedingung definieren, sonst ist irgendwann Dein SRAM dicht. Peter
Ich glaube, er ist noch am Üben, was µC und Assembler angeht. Die Sache mit dem lcall loop würde ich definitiv als FEHLER einstufen (war mein erster Fehler in der Lehre, als es an µC ging), das muss "jmp loop" heissen, sonst zerbröselt es ihm den Stack (so wie ich es sehe, zwar nicht in diesem Programm, aber wenn er sich erstmal dran gewöhnt hat, Schleifen so aufzurufen, wirds kritisch). Gruß Ralf
Hallo, erstmal vieln danbk für eure Hilfe, Ralf hat Recht, ich fange erst mit Controller an. Der Link auf die Atmelsite ist sehr interessant, Würde das ganze jedoch gerne ohne Interrupts machen, also per polling. Weiß jemand wo ein Programm zu finden ist, wo das ganze per polling funktioniert? gruß Stefan
Hi Stefan, Polling ist doch ganz einfach: 1. Interrupts deaktivieren, also ES = 0 2. Eine Polling-Routine könnte für den Empfang z.B. so aussehen: send_SPI:jnb Interrupt-Flag,$ clr Interrupt-Flag mov spi,a ret In Zeile 1 wird über das Interrupt-Flag abgefragt, ob das letzte Senden abgeschlossen wurde. Das Interrupt-Flag wird auch gesetzt, wenn der Interrupt selbst deaktiviert ist! JNB bedeutet, springe, wenn ein Bit nicht gesetzt ist, an eine bestimmte Stelle im Programm. Das $-Zeichen sagt dem Controller in diesem Fall, dass er wieder zum JNB-Befehl springen soll (für diesen Fall könntest du statt $ auch send_SPI eintragen). In Zeile 2 wird das Interrupt-Flag wieder gelöscht, damit das nächste Senden wieder in Angriff genommen werden (Der Controller setzt das IR-Flag nachdem er das letzte Bit rausgehauen hat). Zeile 3 und 4 brauch ich wohl nicht erklären, oder? Freilich musst du darauf achten, dass du die SPI-Schnittstelle vor der ersten Verwendung richtig initialisierst. Falls noch Fragen offen sind, einfach weiterfragen ;-) Gruß Ralf
nabend zusammen, versuche gerade das ganze mit data_polling zum laufen zu bringen. anbei mein assemblerprogramm. wenn ich das ganze im debugmodus laufen lasse, dann wird nie das spdr datenregister beschrieben, obwohl das spif flag gesetzt wird. was amche ich falsch? $nomod51 ;vorgegebene Includedatei wird abgeschaltet #include <AT898252.H> ;Includedatei fuer ATMEL 89S8252 aktiviert sie muss transmit_completed BIT SPIF_ /* SPI Interrupt Flag 0x80 */ data_to_send DATA 10111101b org 0000h clr transmit_completed clr WCOL_ /* SPI Write Collision Flag: 1=Collision 0x40 */ mov p1,00h ;*****************************SPI am ATMEL initialisieren****** mov SPCR,#01011011b ;Initialisierung des SPI Port zur seriellen Übertragung loop: mov spdr,data_to_send jnb transmit_completed,$ clr transmit_completed call loop ret end
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.