Hallo Prorammierer, möchte mit AVR-Studio und STK500 Mega48 progen. Hier bleib ich schon hängen -------------------------- Reset: ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, temp ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse out SPH, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) out UBRR0L, temp ldi temp, HIGH(UBRRVAL) out UBRR0H, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB,TXEN ; TX aktivieren ------------------------------------------------------------------- bei Baudrate einstellen "out UBRR0L, temp" kommt eine Fehlermeldung "illegal Argument .." In den Unterlagen von ATMEL steht es aber auch so drinnen [UBRRnL]. Wer sagt mit wo's fehlt? Gruss Kurt
Man sieht ja leider nicht den Anfang aber hast Du die Datei "m48def.inc" eingebunden? MfG Andi
Sorry habs übersehen. hier der Anfang ------------------- .include "m48def.inc" .equ CLOCK = 1000000 .equ BAUD = 1200 .equ UBRRVAL = CLOCK/(BAUD*16)-1 ; Stackpointer initialisieren .def Temp = r16 ; ; Kurt
beim Mega48 liegt der UART außerhalb des mit IN/OUT Befehlen ansprechbaren Bereiches. Ist nur mit den entsprechenden Memory Befehlen LDS/STS usw. ansprechbar.
Auf UBRR0L und UBRR0H kann man beim Mega48 nicht über OUT zugreifen. Diese I/O Register sind Bestandteil des "Extended-I/O-Bereiches" und müssen mit STS (statt OUT) bzw. LDS (statt IN) benutzt werden. Steht auch so im Datenblatt: "For I/O Registers located in extended I/O map, IN, OUT, SBIS, SBIC, CBI, and SBI instructions must be replaced with instructions that allow access to extended I/O. Typically LDS and STS combined with SBRS, SBRC, SBR, and CBR."
Über diese Hürde bin ich drüber.
Danke.
nun steht er bei:
> ldi temp, (1<<URSEL)|(3<<UCSZ0)
out UCSRC, temp
sbi UCSRB,TXEN ; TX aktivieren
hier kommt Undef. Var-referenz
Was bedeutet das "(1<<URSEL)|(3<<UCSZ0)
sollte hier eine Auswahl getroffen werden ?
Kurt
@Kurt: Es scheint mir, dass Du den Code für einen falschen AVR verwendet hast. So kommst Du nicht weiter. Keine der drei Zeilen aus Deinem letzten Posting wird für den ATMega48 assembliert werden, geschweige denn richtig laufen. Bitte lies doch den Abschnitt zur USART im Datenblatt.
Leider hat Atmel beim Mega48/88/168 die UART Beispiele aus dem "alten" Mega8 übernommen. Man hofft wohl auf das der Anwender die Kompatibilitäts-Macros aus der App-Note benutzt. Die andere Frage dürfte wohl die ASM-Hilfe im AVR-Studio unter der Rubrik Expressions hinreichend beantworten.
so soweit läuft es ohne Errormeldung!! (Freude) ------------------------------------------------ Reset: ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, temp ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse out SPH, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) sts UBRR0L, temp ldi temp, HIGH(UBRRVAL) sts UBRR0H, temp ; Frame-Format: 8 Bit ; enable receiver und transmitter ldi temp, (1<<RXEN0) | (1<<TXEN0) sts UCSR0B, temp ; setze Framformat 8 dat 2 stop ldi temp , (1<<USBS0) | (3<<UCSZ00) sts UCSR0C, temp ----------------------------------------------- Im Datenblatt werden die Var mit "out" weggeschrieben ! Was ich nicht verstehe ist "(1<<USBS0) | (3<<UCSZ00)" das schaut nach "C" aus. Sind das ev. Schiebeoperationen in eine Byte-Var ? Kurt
"(1<<USBS0) | (3<<UCSZ00)" ist eine IMHO umständliche Art und Weise, drei Bits an der richtigen Stelle zu setzen. Angenommen, USBS0 sei 2 und UCSZ00 sei 4 (das sind völlig aus der Luft gegriffene Werte!), dann ist das Resultat (1 << 2) | (3 << 4) 0x04 | 0x30 also 0x34. Das ganze rührt wohl daher, daß viele Leute das manuelle Zusammensetzen von Bits für zu kompliziert und fehleranfällig halten. Warum das dann noch zusätzlich "elegant" gemacht werden muss durch Definition der Bit_nummer_ statt des Bitwertes hat sich mir noch nie eröffnet.
Das Verändern von Bits mit 'symbolischen Namen' hat schon seine Vorteile. Man erkennt im Code, was man damit bezweckt. Es sagt bedeutend mehr aus als das Arbeiten mit nichtssagenden Hexwerten oder Binärwerten. Es macht den Code daher lesbarer. Man muss nicht mehr jede Kleinigkeit im Datenblatt nachschlagen (welches Bit war das denn nun???). ...
Achso: ---->8---- Warum das dann noch zusätzlich "elegant" gemacht werden muss durch Definition der Bit_nummer_ statt des Bitwertes hat sich mir noch nie eröffnet. ----8<---- Nunja, die Bitnummer braucht man für sbi, cbi, sbic, sbis, sbrc, sbrs, die Bitmaske (Bitwert) für cbr und sbr. ...
irgendetwas schaff ich nicht. "USBS0 sei 2 und UCSZ00 sei 4 " USBS0 = 00000010 UCSZ00= 00000100 ------------------------- (1 << 2) | (3 << 4) 0x04 | 0x30 also 0x34. -------------------------- Teil1: (1 << 2) 0x04 an die "erste" Stelle kommt eine Zwei 00000100 * Zwei 0010 Teil2: | (3 << 4) | 0x30 an die "dritte" Stelle kommt eine Vier 00100000 * 0100 ergibt dann 00100100 = 0x44 wo kommt das 0x34 her? schaut mal
Ich schiebe zwar meist nur EINSen durch, aber: Wenn du eine 3 (DREI) durchschiebst (4 mal), dann bleiben schon die beiden Einsen, aus denen die 3 besteht, erhalten. Also 00000011 ist die 3, eine 1 in der Einer-Stelle, eine in der Zweier 00110000 ist 3<<4, nämlich 11 um 4 Stellen nach links geschubst 00000100 ist dann 1<<2, 00110100 wäre dann 1<<2 OR (|) 3<<4 Aber: Wenn ich das mache, um "sprechende Bitnamen" zu nutzen, dann schiebe ich keine Dreien sondern nur Einsen... ...
also: (1 << 2) | (3 << 4) 0x04 | 0x30 (1 << 2) = eine Eins 2 x nach links geschoben (3 << 4) = zwei Bits (3) 4 x nach links geschoben (16>>4 = Bit4(00010000) 4 x nach rechts geschoben = 00000001 (1 << 2) = 00000100 (3 << 4) = 00110000 ---------------------- 00110100 = 0x34 also sind das Schiebeinformationen (Zahl sooft Nach geschoben) Was passiert mit einem Überlauf: z.B. (4>>6) Stimmt das so?
Stimmt erstmal so. Bei Überlauf kommt es drauf an, was du mit der übergelaufenen Zahl anstellst. Weist du sie einem Register zu (ldi, cbr, sbr, andi, ori, cpi, subi) bzw. veränderst ein Register damit, dann wird der obere Teil abgeschnitten, bzw. geht ins Leere. Probiere es doch einfach mal aus, wozu gibt es denn im AVR-Studio den Simulator? ...
OK gut so, ; setze Framformat 8 dat 2 stop ldi temp , (1<<USBS0) | (3<<UCSZ00) sts UCSR0C, temp Dieses Zeichen dazwischen (|) muss also eine ODER-Verknüpfung darstellen ! Was mich noch verwirrt sind die Angaben (1<<USBS0) | (3<<UCSZ00) Es wird hier also beschrieben wie oft geschoben werden muss. (3<<UCSZ00) heisst also dass 2 Bit's um UCSZ00 x geschoben werden muss Falls ich euch auf die Nerven gehe ... Dann hat die Angabe UCSZ00 nichts mit realen Werten zu tun sondern es sind nur Typbezogene Angaben.
@Kurt: Du arbeitest doch sicher mit AVR-Studio. Das hat oben eine Menüleiste. Ganz rechts gibt es den Menüpunkt "Help". Wenn man den anklickt, bekommt man unter Tools, AVR-Assembler (oder so ähnlich) komplette Auflistungen der Direktiven, Operatoren und Befehle uns was sonst alles noch so wissenswert ist. Im Gegensatz zur allgemeinen Windows-Hilfe (die absoluter Schrott ist,) ist die Hilfe vom AVR-Studio sehr ergiebig. Du kannst also alles nachlesen und brauchst nicht zu spekulieren. Gruß... ...HanneS...
Hallo Leute, Danke für eure Hilfe. Das mit derHilfefunktion schaut ja sehr gut aus. Zeichen kann ich schon rausschicken. Aber mit der Pufferkontrolle klappt es nicht Ausgabe: ; Zeichen raussenden # sbis UCSR0A, UDRE0 RJMP Ausgabe out UDR0, temp ret Hier kommt eine Fehlermeldung. "sbis UCSR0A, UDRE0" ist aus Anleitung. so nun schalt ich ab. Grüsse an Alle Kurt
Hallo bin wieder QRV so nun mal Vergleichen. 32 Universalregister : (sind nahe an der CPU) 64 I/O Register : (hier ist die Verbindung zur Hardware) 160 erweiterte I/O Register : 512 Byte RAM Die 160 erw. I/O's liegen im Ram und sind daher nicht mit den "üblichen" I/O Befehlen erreichbar.? Darauf hin habe ich versucht diese Register (UCSR0A) "direkt" zu erreichen. Ging nicht" Wie es scheint sind "Berechnungen" wie Bit-nachschauen usw. nur in den Universalregistern möglich. --------------------------------------------------------- ; ----------------------------------------------------- Ausgabe: ; Zeichen ausgeben lds temp2, UCSR0A ; Zustandsregister (aus REM) in Universalregister bringen sbrs temp2,UDRE0 ; schauen ob Bit gesetzt ist rjmp Ausgabe ; zurück wenn noch nicht fertig sts UDR0, temp ; Zeichen in Ausgabe-Register bringen ret ------------------------------------------------------------- Damit werden Zeichn "gesittet" ausgegeben. Lieg ich soweit richtig? Gruss Kurt
Hallo Helfer, dank Euerer Hinweise komm ich nun zurecht. Im Simulator wurden die entsprechenden Register (SMCR + PRR) bei Änderung nicht bearbeitet. In den Unterlagen von Atmel sind die Adressen ja angegeben. Aber erst die Verwendung der in klammerstehenden Werte führten zum Erfolg. Ich möchte mich nochmal bei Allen bedanken die mitgewirkt haben. Kurt
@Kurt, schau dir bei solchen Problemen auch mal die dementsprechende Include-Datei an. Ich habe da irgendwo auch schon einen Unterschied zwischen der Bezeichnung im Datenblatt und in einer Include-Datei gesehen. Leider weiß ich jetzt nicht mehr, wo (bei welchem AVR) das war. ...
@Kurt... Mein Hinweis auf die Hilfe zum AVR-Studio heißt doch nicht, dass du keine Fragen stellen darfst. Ich wollte dir damit nur mitteilen, dass du wichtige Informationen bereits in deinem Rechner verfügbar hast und sich dadurch manche Frage erübrigt. Sicher kannst du weitere Fragen stellen. Schlimmstenfalls verweist man auf das Datenblatt oder die AVR-Studio-Hilfe. ...HanneS...
OK gut, Dann die nächste "Aktion" Mega 48 (der von Oben) 32768 Hz Quarz Interrupt alle Sekunden (also Teiler durch 32768) Welchen Timer/Counter soll ich nehmen? Kurt
Bei einem Sekunden-Takt ist das eigentlich egal! Timer 0: 8Bit-Counter, max. bis 256 Möglicher Prescaler z. B.1024 Möglicher Counter dann 32768 / 1024 = 32 (256 - 32 = 224 wegen Aufwärts-Counter). Genauso mit Timer 2. Timer 1 halte ich dann für verschwendung da 16 Bit und nicht nötig. Nim am beste Timer0. Wenn Du Sleep mit Power-Down machen willst, dann den Quarz an Timer2 (zusätzlich) anklemmen. Sollen die 32768KHz etwa der Haupttakt werden? MfG Andi
"Sollen die 32768KHz etwa der Haupttakt werden?" Bei dieser Anwendung Ja. Möchte aber auch mit höheren Frequenzen gleiches machen können. ( mit USART-Betrieb) Kurt
Wenn Du eine genaue Sekunde mit 32768Hz benötigst mach das dann doch am besten mit dem Quarz an T2 und nicht am System-Takt. Den AVR kannst Du dann mit dem internen Oscilator Rechnen lassen und wenn erforderlich kannst Du den per Software mit OSCCAL=0 bremsen. Timer2 wird von T2 mit 32768Hz getaktet. Wenn natürlich der AVR mit einer 3V-Batterie Wochenlang auskommen soll ist das natürlich was anderes. MfG Andi
Ja / es geht primär um den Stromverbrauch Dachte mir so: Der 32k macht die "Zeit" (Arbeitszyklen alle paar Sekunden) Und in der Arbeit der Interne RC die Taktung. Jedoch muss man den RC dann auf "Kurs" bringen, da sonst die Genauigkeit für USART nicht reicht. Kurt
Der interne RC läuft allerdings immer. Weiß nicht, ob der im Power-Down ruhig gestellt ist und ob der per Fuses auf weniger als 1MHz mit Kalibyte in OSCCAL einstellbar ist. Jedenfalls mußt Du da ein bißchen mit dem OSCCAL experimentieren, einen Takt an einem Pin erzeugen und messen wie schnell der dann läuft. Probier mal folgendes: ldi r16,0 ;oder andere Werte für den OSCCAL. out OSCCAL,r16 sbi DDRB,0 ;PortB.0 als Ausgang. in r16,PortB ;Port-Status einlesen. ldi r17,0b1 ;Bit 0 zum switchen. loop: eor r16,r17 ;PortB.0 umschalten. out PortB,r16 ;Und Ausgeben. rjmp loop Macht eine einfache Takterzeugung an PortB.0. An PinB.0 mißt Du die Frequenz und multiplizierst sie mit 4 (4 Takte je Schleife). Gruß Andi
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.