Hallo zusammen, ich habe da einen schönen Kursus gefunden, den ich gerne durcharbeiten will. Allerdings tauchen natürlich immer Fragen auf, die ich mit anderen Interessierten besprechen möchte. Ich bin also noch ziemlich am Anfang ( Modul A ) und bei den Fragen zu A100 Seite 18 ( im Reader Seite 28 ) bin ich zu folgenden Schluß gekommen. A100 a) Der Adresszähler des ATmega32 beträgt 14-Bit und die höchste Flashadresse ist $3FFF ( FLASHEND ). b) Der Adresszähler des ATmega8 beträgt 12-Bit und die höchste Flashadresse ist $0FFF ( FLASHEND ). Das das für den ATmega32 stimmt, konnte ich an der Zeichung auf Seite 21 ( im Reader Seite 31 ) erkennen. Nun bin ich jedoch bei den Fragen zu A101 etwas verwirrt, da in der Zeichnung auf Seite 31 ( Ab nun werde ich immer die Acrobat Reader Seitenzahl nennen ) die RAMEND Adresse als $085F angegeben ist, ich jedoch folgendes denke : A101 a) Die RAMEND-Adresse des ATmega32 ist $07FF b) Die RAMEND-Adresse des ATmega8 ist $03FF Die Sachen sind hier zu finden : Mikrocontrollertechnik-Kursus MODUL_A http://www.weigu.lu/tutorials/avr_assembler/index.html Bernd_Stein
:
Gesperrt durch Moderator
Bernd Stein schrieb: > ich jedoch folgendes denke Das Master-Dokument, was einzig und alleine all solche Fragen beantworten kann, ist das Datenblatt zum jeweiligen Prozessor. Wenn du da noch nie reingeschaut hast, wird es jetzt allerhöchste Zeit. Da gibt es schöne Bilder, die zeigen, warum die Ramadressen sind, wie sie sind, und nicht so , wie du denkst. Bernd Stein schrieb: > die ich mit anderen > Interessierten besprechen möchte. Das könnte an einem Mangel an anderen Interessierten scheitern... Oliver
Hi >die RAMEND Adresse >als $085F angegeben ist, ich jedoch folgendes denke : >A101 >a) Die RAMEND-Adresse des ATmega32 ist $07FF >b) Die RAMEND-Adresse des ATmega8 ist $03FF Nein. RAMEND ist die Summe der Register r0...r31, der IO-Register und des RAMs. Also beim ATMega32 (0x20 + 0x40 + 0x800) -1 = 0x85F. MfG Spess
spess53 schrieb: > RAMEND ist die Summe der Register r0...r31, der IO-Register und > des RAMs. Also beim ATMega32 (0x20 + 0x40 + 0x800) -1 = 0x85F. > Ach so, ich dachte immer das Alles teilt sich den 1kByte SRAM. Danke. Oliver S. schrieb: > Das Master-Dokument, was einzig und alleine all solche Fragen > beantworten kann, ist das Datenblatt zum jeweiligen Prozessor. > Wenn du da noch nie reingeschaut hast, wird es jetzt allerhöchste Zeit. > Leider muss man sich die Fragen, dann immer noch selbst beantworten. Für mich mit meinem schlechten Englischverständnis wirft so etwas dann meistens mehr Fragen auf, als das ich mir damit beantworten konnte. Als Anfänger ist man immer etwas verwirrt, wenn man mit zu vielen Informationen auf einmal konfrontiert wird. Siehe z.B. Kreis im Anhang. Bernd_Stein
Bernd Stein schrieb: > Siehe z.B. Kreis im Anhang. Was genau verwirrt dich daran? Dass es zwei verschiedene Adressräume mit 20hex Unterschied zueinander gibt, man über diese jedoch auf den gleichen Bereich zugreifen kann? Das hat eher historische Ursachen: man hatte sich damals entschieden, die 32 CPU-Register in die unteren 32 Adressen des RAM-Adressraums abzubilden. (*) Damit blieb für die IO-Register der RAM-Bereich oberhalb 0x20 übrig. Zusätzlich hat man den IO-Registern für die Befehle IN, OUT, CBI und SBI jedoch noch einen eigenen (kleinen) Adressraum einräumen wollen, damit diese schneller und platzsparender abgearbeitet werden können. Der muss natürlich (wegen der Codierung im Befehlswort) wieder bei 0 beginnen, dadurch entsteht der Offset zwischen der Adressierung im IO space (IN/OUT) und im RAM-Bereich (LDS/STS). Ich hoffe, das ist jetzt irgendwie verständlicher geworden. ;-) (*) Warum auch immer, ein nur eher spärlich benutztes Feature, weshalb man das beim Xmega dann auch weggelassen hat. Dort gibt es diesen Offset 0x20 nicht mehr.
Bernd Stein schrieb: > spess53 schrieb: >> RAMEND ist die Summe der Register r0...r31, der IO-Register und >> des RAMs. Also beim ATMega32 (0x20 + 0x40 + 0x800) -1 = 0x85F. >> > Ach so, ich dachte immer das Alles teilt sich den 1kByte SRAM. > Danke. Es teilt sich denselben Adressraum! Das ist was anderes. Aber wenn im Datenblatt steht, ein bestimmter AVR hätte 1kB SRAM, dann hat er auch wirklich 1kB Speicherzellen im SRAM. Das ein I/O Register oder sonst irgendeine Konfigurationsregister nichts mit dem SRAM zu tun haben kann, zeigt sich doch schon daran, dass diese Register ja alle irgendwelche Spezialfunktionen haben. Schreibst du was ins Port-Register, dann taucht das an den Ausgangspins auf. D.h. das kann gar kein SRAM sein, denn der Zweck des SRAM besteht ja einzig und alleine darin, Bytes zu speicher und das gespeicherte wieder von dort lesen zu können. Das SRAM hat keine Zusatzfunktion, es ist einfach nur Speicher und sonst nichts. > Für mich mit meinem schlechten Englischverständnis wirft so > etwas dann meistens mehr Fragen auf, als das ich mir damit > beantworten konnte. Da musst du durch. Die meisten Dinge sind sowieso viel einfacher, als die meisten Menschen glauben. So ein Computer ist vom Prinzip her viel einfacher als die meisten denken. Jetzt mal von technologischen Problemen abgesehen und auch von High-Tech Dingen wie Caches und Branch Predictions und dergleichen Schnickschnack abgesehen. Aber das ist das Problem der Ingenieure in den CPU Schmieden. Ohne Datenblatt kommst du nicht weit. Das Datenblatt zu verweigern ist nicht akzeptabel. Wenn Japaner und Chinesen das können, dann kannst du das auch. Deutsch ist schliesslich viel näher an Englisch drann als Japanisch oder Chinesisch. Und derartige Datenblätter sind auch keine literarischen Meisterwerke mit gefinkeltem Satzbau. Mit der Zeit kriegt man Übung, kennt die 2 Handvoll technischer Begriffe und dann liest sich das alles fast wie ein deutscher Text. Zumal vieles in immer gleicher Form immer wieder in den einzelnen Kapitel erneut auftaucht. Alle Timer sind sich ähnlich und unterscheiden sich nur in ihren Möglichkeiten. Aber die Grundfunktion und wie man sie konfiguriert ist immer gleich. Sobald man verstanden hat, was ein ADC eigentlich macht und wie er ins System eingebunden ist, erschliesst sich die Wirkungsweise der diversen Konfigurationsbits, selbst wenn man nicht jedes Wort im DB versteht. Der Interrupt Mechanismus funktioniert bei (fast) allen Teilmodulen immer gleich. etc. Das Datenblatt wirkt auch deswegen recht umfangreich, weil all diese immer gleichen Mechanismen bei jedem Teilmodul immer wieder neu beschrieben sind, damit man eben nicht das DB unbedingt chronologisch von vorne bis hinten lesen muss.
Karl Heinz schrieb: > Bernd Stein schrieb: >> spess53 schrieb: >>> RAMEND ist die Summe der Register r0...r31, der IO-Register und >>> des RAMs. Also beim ATMega32 (0x20 + 0x40 + 0x800) -1 = 0x85F. >>> >> Ach so, ich dachte immer das Alles teilt sich den 1kByte SRAM. >> Danke. > > Es teilt sich denselben Adressraum! Das ist was anderes. Situation Parkhaus. Im Parkhaus gibt es 2 Ebenen, 'unten' und 'oben' mit je 20 Stellplätzen. Du kannst jetzt jedem Parkplatz 2 Nummern zuordenen. Die eine ergibt sich daraus, dass du alle Parkplätze geschossübergreifend durchnummerierst. Die andere ist eine geschossweise Nummerierung. Jetzt reservierst du das untere Geschoss für die eigenen Leute. Das bedeutet aber nicht, dass du die geschossübergreifende Nummerierung verändern musst. Der Parkplatz 38 ist nach wie vor im oberen Geschoss der 18.te Stellplatz. Die breite Öffentlichkeit fragt sich vielleicht, warum die für sie zur Verfügung stehenden Parkplätze bei der Nummer 20 anfangen, aber das ist ja schliesslich nur eine Nummer. Für sie stehen 20 Parkplätze bereit und das es da 20 weitere gibt (die Nummern 0 bis 19), ist ein 'internes Detail' des Parkhauses. Die reservierten Parkplätze und die öffentlichen Parkplätze teilen sich denselben Adressraum (0 bis 39). Aber natürlich kann man auch sagen: Es gibt 20 öffentliche Parkplätze und für die mache ich eine zweite Nummerierung, die unter Nichtberücksichtigung der reservierten Parkplätze bei 0 beginnt. Dann hat halt jeder Parkplatz 2 Nummern. Die eine ist für die Hasutechnik interessant, die am Parkplatz 36 den defekten Besetzsensor tauschen soll, die andere ist für den Huber Sepp interessant, der den Parkplatz 16 sucht, weil dort sein Auto steht. Tatsächlich ist es aber immer derselbe Parkplatz.
:
Bearbeitet durch User
Karl Heinz schrieb: > Parkplätze bei 0 beginnt. Dann hat halt jeder Parkplatz 2 Nummern. Die > eine ist für die Hasutechnik interessant, die am Parkplatz 36 den > defekten Besetzsensor tauschen soll, die andere ist für den Huber Sepp > interessant, der den Parkplatz 16 sucht, weil dort sein Auto steht. Da kann er aber lange suchen. a) Er hat sein Auto auf 18 geparkt. b) Es ist gar nicht sein Auto, sondern von seiner Frau. c) Es wurde in der Zwischenzeit gestohlen.
Karl Heinz schrieb: > Situation Parkhaus. > Im Parkhaus gibt es 2 Ebenen..... Ich wollte, ich könnte so gut an anschaulichen Beispielen erklären... Hut ab. (Oh, lieber gleich wieder aufsetzen -es ist kalt an der Rübe) ;-) MfG Paul
Jörg Wunsch schrieb: > Bernd Stein schrieb: >> Siehe z.B. Kreis im Anhang. > > Was genau verwirrt dich daran? > Danke erstmal, aber ich denke das hebe ich mir für Später auf, falls dies ein Thema in dem Kursus wird. Nun zur nächsten Sache. *Das erste Programm (A303_dig_out_8bit.asm)* Das erste Programm soll acht LEDs gleichzeitig einschalten. Dazu sind acht LEDs (mit entsprechenden Vorwiderständen) mit den acht Pins von Port D zu verbinden. A301 *a)* Ermittle aus dem Datenblatt des ATmega32A wie hoch der vom Ausgang gelieferte Strom maximal sein darf? *b)* Berechne die Vorwiderstände für eine rote LED, eine gelbe LED und eine grüne LED (Datenblatt oder Produktkatalog!), wenn diese jeweils mit 15 mA betrieben werden sollen. Welche Spannung liefert der ATMega32A bei 15 mA (siehe Datenblatt)? *c)* Berechne den Vorwiderstand für eine rote "low current" LED, die nur 2 mA benötigt. Achte auf die Spannung (Datenblatt ATmega32A)! *Zu a)* Wenn Uvcc = 5,0V beträgt Aus dem Datenblatt : 4. Although each I/O port can source more than the test conditions (20 mA at Vcc = 5V, 10 mA at Vcc = 3V) under steady state conditions (non-transient), the following must be observed: PDIP Package: 1] The sum of all IOH, for all ports, should not exceed 200 mA. 2] The sum of all IOH, for port A0 - A7, should not exceed 100 mA. 3] The sum of all IOH, for ports B0 - B7,C0 - C7, D0 - D7 and XTAL2, should not exceed 100 mA. Da würde ich doch mal sagen unter 100mA bleiben für PortD. *Zu b)* rot = 1,6V, gelb = 2,2V, grün = 2,1V Aus dem Diagramm ( siehe Anhang ) würde ich die Ausgangsspannung ( VOH ) einfach bei 4,5V setzen. Somit Rrot = 193 Ohm (200R), Rgelb = 153 Ohm (160R), Rgrün = 160 Ohm (160R). *Zu c)* laut Diagramm ca. 4,9V bedeutet 1650 Ohm (1k6). Da jetzt aber 8-LEDs geschaltet werden sollen, dürfen natürlich nicht 15mA pro LED fließen sondern höchstens 12,5mA ( 100mA : 8 ). Sind meine Überlegungen soweit in Ordnung ? Bernd_Stein
Bernd Stein schrieb: > Da würde ich doch mal sagen unter 100mA bleiben für PortD. klingt vernünftig. > *Zu b)* rot = 1,6V, gelb = 2,2V, grün = 2,1V > Aus dem Diagramm ( siehe Anhang ) würde ich die Ausgangsspannung ( VOH ) > einfach bei 4,5V setzen. Somit Rrot = 193 Ohm (200R), Rgelb = 153 Ohm > (160R), Rgrün = 160 Ohm (160R). Du hast vergessen die Vorwärtsspannung der jeweiligen LED abzuziehen? > Da jetzt aber 8-LEDs geschaltet werden sollen, dürfen natürlich nicht > 15mA pro LED fließen sondern höchstens 12,5mA ( 100mA : 8 ). Geht in Ordnung. > Sind meine Überlegungen soweit in Ordnung ? grundsätzlich ja. Nur finde ich, dass im konkreten Fall AVR der Kursschreiber hier übertreibt. Denn selbst wenn du rechnerisch 153Ohm erhältst: diesen Widerstand kannst du nicht kaufen. Und wenn du ihn kaufen könntest, hätte der nicht 153Ohm - schliesslich gibt es ja auch noch zulässige Bauteiltoleranzen. Und auch die LED hat nicht 1.6V Vorwärtsspannug aus dem gleichen Grund: Bauteiltoleranz. Hier den Spannungsabfall an den Pins bei einem zulässigen Strom mit einzubeziehen ist Krümelkackerei, auch wenn es technisch korrekt ist. Wenn im Kuchenrezept 100g Zucker angegeben sind, wiegt das auch kein Mensch mit der Analysenwaage im voll klimatisierten Raum aufs Milligramm genau ab.
:
Bearbeitet durch User
Karl Heinz schrieb: >> *Zu b)* rot = 1,6V, gelb = 2,2V, grün = 2,1V >> Aus dem Diagramm ( siehe Anhang ) würde ich die Ausgangsspannung ( VOH ) >> einfach bei 4,5V setzen. Somit Rrot = 193 Ohm (200R), Rgelb = 153 Ohm >> (160R), Rgrün = 160 Ohm (160R). > > Du hast vergessen die Vorwärtsspannung der jeweiligen LED abzuziehen? Edit: Nö. Passt schon. Ich hatte mich am Taschenrechner vertippt.
Ist der Simulator vom AVR-Studio 4.19 Build 730 mal wieder Bugy, oder mach ich was falsch ? Also, bin jetzt bei der Aufgabe *A305*( Seite 56 ). Die Beschreibung und der PAP ist vorher angegeben ( Seite 54 ). Habe im Simulator auch für den nicht gedrückten Taster - PIND5 angeklickt, damit PIND auch den Wert *$20* bekommt. Aber egal ob ich diesen anklicke oder nicht, der Progammablauf ist immer der Gleiche. Das heißt die LED PIND6 wird nie eingeschaltet bzw. PIND6 gesetzt. Ich arbeite übrigens mit dem ATmega8 und nicht wie im Kursus angegeben mit dem ATmega32A. Ich hatte früher schonmal so ein Problem : Beitrag "Portpin wird automatisch gelöscht im AVR-Studio 4.10"
1 | ; |
2 | ;******************************************************************************* |
3 | ;* |
4 | ;*Titel: Mein erstes Programm (A303_dig_out_8bit_BS.asm) |
5 | ;*Datum: |
6 | ;*Autor: |
7 | ;* |
8 | ;*Informationen zur Beschaltung: |
9 | ;* |
10 | ;*Prozessor: ATmega8 Quarzfrequenz: |
11 | ;*Eingaenge: |
12 | ;*Ausgaenge: |
13 | ;* |
14 | ;*Informationen zur Funktionsweise: |
15 | ;* |
16 | ;* An PortD6 wird so lange eine LED eingeschaltet, wie an PortD5 der Taster |
17 | ;* gegen Masse schaltet. |
18 | ;* |
19 | ;******************************************************************************* |
20 | ; |
21 | |
22 | ; |
23 | ;Einbinden der Controllerspezifischen Definitionsdatei |
24 | ; |
25 | .NOLIST ;List-Output ausschalten |
26 | .INCLUDE "m8def.inc" ;AVR-Definitionsdatei einbinden |
27 | .LIST ;List-Output wieder einschalten |
28 | |
29 | ; |
30 | ;=============================================================================== |
31 | ;= Eigene Definitionen und Labelzuweisungen |
32 | ;=============================================================================== |
33 | ; |
34 | .DEF Zero = r15 ;Register 15 wird zum Rechnen benoetigt |
35 | .DEF A = r16 ;Register 16 dient als erster Zwischenspeicher |
36 | .DEF B = r17 ;Register 17 dient als zweiter Zwischenspeicher |
37 | .DEF S_sreg = r18 ;Register zum Sichern des Statusregisters |
38 | .DEF Cnt1 = r19 ;Register 18 dient als Zaehler |
39 | |
40 | .DEF Wl = r24 ;Register 24 und 25 dienen als universelles |
41 | .DEF Wh = r25 ;Doppelregister W |
42 | |
43 | |
44 | .EQU LED_PORT = PORTD ;PortD komplett fuer LED Ansteuerung |
45 | .EQU LED_DDR = DDRD ;Datenrichtungsregister fuer LED-Port |
46 | .EQU LED_PIN = 6 ;Pin an dem die LED angeschlossen ist |
47 | |
48 | .EQU TASTER_PORT = PORTD ;Port an dem der Taster angeschlossen ist |
49 | .EQU TASTER_DDR = DDRD ;Datenrichtungsregister fuer den Taster |
50 | .EQU TASTER_PIN = 5 ;Pin an dem der Taster angeschlossen ist |
51 | ; |
52 | ;Programmstart nach RESET ( Interuppt Vectoren Tabelle ) |
53 | ; |
54 | .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher |
55 | .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000 |
56 | |
57 | rjmp _reset ;RESET-Vector |
58 | |
59 | |
60 | |
61 | ;.ORG INT0addr ;interner Vektor fuer INT0 (alt.: .ORG 0x0002) |
62 | ; rjmp ISR_I0 ;Springe zur ISR von INT0 |
63 | |
64 | .ORG INT_VECTORS_SIZE ;Platz fuer nicht eingetragene ISR Vektoren lassen |
65 | |
66 | ; |
67 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
68 | ;I Erstinitialisierungen |
69 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
70 | ; |
71 | |
72 | ; |
73 | ;Stapelzeiger initialisieren (fuer Unterprogramme bzw. Interrupts) |
74 | ; |
75 | _reset: |
76 | ldi A,HIGH(RAMEND) ;RAMEND (SRAM) ist in der Definitions- |
77 | out SPH,A ;datei festgelegt |
78 | ldi A,LOW (RAMEND) |
79 | out SPL,A |
80 | |
81 | ; |
82 | ;Variablen initialisieren |
83 | ; |
84 | clr Zero ;Register mit Null belegt |
85 | |
86 | ; |
87 | ;Ports Erstkonfiguration |
88 | ; |
89 | ; |
90 | ; ldi A,$FF ;LED-Port komplett als Ausgang... |
91 | ; out LED_DDR,A ;...konfigurieren |
92 | ; sbi LED_DDR,5 ;Pin 5 als Ausgang |
93 | sbi LED_DDR,LED_PIN ;Portpin als Ausgang schalten |
94 | sbi TASTER_PORT,TASTER_PIN;Pullup fuer den Tasterpin einschalten |
95 | |
96 | ; |
97 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
98 | ;H Hauptprogramm |
99 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
100 | ; |
101 | _main: |
102 | ; ser A ;alle Bits auf Eins setzen und somit... |
103 | ; out LED_PORT,A ;..alle LEDs einschalten |
104 | ; sbi LED_PORT,5 ;LED an Pin 5 einschalten |
105 | sbis TASTER_PORT,TASTER_PIN |
106 | sbi LED_PORT,LED_PIN |
107 | sbic TASTER_PORT,TASTER_PIN |
108 | cbi LED_PORT,LED_PIN |
109 | |
110 | |
111 | rjmp _main ;Hauptprogrammschleife |
112 | |
113 | |
114 | _endlos: |
115 | rjmp _endlos ;Endlosschleife |
116 | |
117 | ; |
118 | ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU |
119 | ;U Unterprogramme und Interrupt-Behandlungsroutinen |
120 | ;UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU |
121 | ; |
122 | ;.INCLUDE "SR_TIME_16M_sample.asm" ;Zeitschleifenbibliothek einbinden |
123 | |
124 | ; |
125 | ;FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
126 | ;F Tabellen im Programmspeicher (Flash) |
127 | ;FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
128 | ;TAB: .DB "Hallo" |
129 | |
130 | ; |
131 | ;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD |
132 | ;D Organisation des Datenspeichers (SRAM) |
133 | ;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD |
134 | ; |
135 | .DSEG ;was ab hier folgt kommt in den SRAM-Speicher |
136 | ;TAB1: .BYTE 100 ;100 Byte grosse Tabelle im Datensegment |
137 | |
138 | .EXIT ;Ende des Quelltextes |
Bernd_Stein
:
Bearbeitet durch User
Hallo Bernd, Du solltest den Eingang abfragen und nicht den Pullup. Der Port wird mit PIND abgefragt, oder? Grüße Bernhard
Und die Pullups sind per Default aktiviert die musst du nicht mehr aktiviere . Falls du auch eine LED zum leuchten bringen willst sollte da irgendwo ein out portx, xyz auftauchen damit der entsprechende Port auch was ausgeben kann.
Paul Baumann schrieb: > Ich wollte, ich könnte so gut an anschaulichen Beispielen erklären... Und ich wollte, Karl-Heinz Buchegger schriebe endlich ein Buch über C-Programmierung und Atmel-Mikrocontroller. Was der in den letzten zehn Jahren hier alles im Forum geschrieben und erklärt hat, einfach unglaublich!
Thomas O. schrieb: > Und die Pullups sind per Default aktiviert die musst du nicht mehr > aktiviere . Nein. Die Pullups sind natürlich nicht aktiviert. mfg.
Thomas O. schrieb: > ... Falls du auch eine LED zum leuchten bringen willst sollte da > irgendwo ein out portx, xyz auftauchen damit der entsprechende Port auch > was ausgeben kann. Er hat doch SBI bzw. CBI für die LEDs verwendet. Blind oder keine Ahnung?
Bernhard Schröcker schrieb: > Du solltest den Eingang abfragen und nicht den Pullup. > Der Port wird mit PIND abgefragt, oder? > Danke. Genau das war es. Es wird wohl noch ein bischen dauern, bis ich dieses Wissen wirklich verinnerlicht habe, denn das ist nicht das erstemal mit diesem PIN vs. PORT. Thomas O. schrieb: > Und die Pullups sind per Default aktiviert die musst du nicht mehr > aktiviere . > Das stimmt nicht. Die Ports sind so ausgelegt, das alle nach einem Reset erstmal Hochohmige-Eingänge sind. Siehe Anhang. Um ein Pull-Up Widerstand zu aktivieren muss im Datenrichtungsregister DDR eine Null für Eingang sein und im Portregister PORT eine eins. > > Falls du auch eine LED zum leuchten bringen willst sollte da > irgendwo ein out portx, xyz auftauchen damit der entsprechende Port auch > was ausgeben kann. > Der Befehl SBI ( Set Bit im I/0-Register ) macht dies für ein einzelnes Bit. Bernd_Stein
Hallo Bernd, Du kannst Dir ja das IN in PIN als Input merken und das O in PORT als Output. Freut mich wenn's dann funktioniert. Schönen Abend. Bernhard...
hI >Ist der Simulator vom AVR-Studio 4.19 Build 730 mal wieder Bugy, ... Ja, ist er. Vor allem , was Hardware-Module angeht. Näheres dazu findest in der AVR-Hilfe unter 'Known Issues'. MfG Spess
Bernhard Schröcker schrieb: > Hallo Bernd, > > Du kannst Dir ja das IN in PIN als Input merken und das O in PORT als > Output. > > Freut mich wenn's dann funktioniert. > Schön, dann haben sich ja mindestens zwei gefreut :-)) So werde ich es wohl in Zukunft auch versuchen zu sehen. spess53 schrieb: > Ja, ist er. Vor allem , was Hardware-Module angeht. Näheres dazu findest > in der AVR-Hilfe unter 'Known Issues'. > Danke, habe da mal nur ganz ganz kurz hineingeschaut. Gut zu wissen, wenn es mal wirklich Probleme damit gibt. Dies mal war mein Denken ja das Problem. Ich wollte mal zeigen mit welchen einfachen Mitteln ich diesen Kurs bis jetzt bewerkstellige. Die Grundschaltung für den ATmega8(L) wird wohl immer die Basis bleiben. Der Quarz mit seinen Ziehkondensatoren haben noch keine Verbindung zum µC, da der interne Takt bisher ausreicht. Da jeder µC-Pin über die Präzisionskontakte herausgeführt ist, können daran beliebige weitere Module angeschlossen werden. Links befindet sich ein Taster und rechts ein Drehencoder mit Taster. Oben rechts ist die 10-Polige ISP, sowie senkrecht darunter 6x Buchsen die mit GND verbunden sind. Ein Pol der Taster ist schon mit GND verbunden. Eingespeist wird mit einem Stecker-Schaltnetzteil das wenig belastet 5,17V bringt, deshalb auch die Shottky-Diode (1N5819), die dann auch noch wunderbar als Verpolungsschutz arbeitet und dadurch der µC 4,92V erhält. Vorher hatte ich eine 1N400x drin, was jedoch nur eine Versorgungsspannung von 4,49V für den µC brachte. Unterhalb des + Anschlusses befinden sich 7x Vcc-Buchsen. Die Steckverbinder ( z.B. Lila Leitung ) sind aus 0,14qmm flexibler Litze und 0,6mm Silberdraht mit Schrumpfschlauch erstellt worden. Werde hoffentlich morgen mal einen Warenkorb für die Sachen erstellen. Bernd_Stein
Hallo zusammen, habe nun mal einen Warenkorb bei Reichelt erstellt, der die Bauteile für die Basisschaltung enthält, sowie für eine 8-Fach LED-Erweiterung mit Treiber, 6x 7-Segmentanzeigen mit Treiber und einem 2x16 LCD ( HD44780 kompatibel ). Wie immer beim Warenkorb überlegen ob man alle Teile braucht, nur ein Teil, Sachen zusätzlich und auf die jeweilige Menge achten. Das Material für die nötigen Steckbrücken ist auch enthalten, dazu ist das 3m Kabel abzuisolieren und die einzelnen Adern zu verwenden. Als einzige nicht passende Farbe ist hier rosa als Ersatz für Orange zu sehen. Beim Schrumpfschlauch wäre es schön gewesen, wenn es den auch in den 10-Widerstand-Codefarben gegeben hätte. In der Box-Version ( 15m bzw. 20m ) sind alle Farben bis auf Violett vorhanden, dann könnte man die einzelnen Adern des Flachbandkabels damit Farbcodieren. Habe Reichelt diesbezüglich eine eMail geschrieben. http://www.reichelt.de/Schrumpfschlauch-Boxen/2/index.html?&ACTION=2&LA=2&GROUPID=5721;SID=11VHiK7X8AAAIAABu-i0s19520ddde944b9b8ed360250f607a696 Bei dem Detailfoto ist noch zu sehen, das erstmal der Quarz mit seinen Ziehkondensatoren nicht verlötet ist, was aber durch drei einfache Lötzinnbrücken zu erreichen ist. Es gibt auch noch EAGLE-Dateien zur Basisschaltung ( siehe Anhang ). Aber hier nun der Warenkorb : http://www.reichelt.de/?ACTION=20;AWKID=993859;PROVID=2084 Bernd_Stein
Hallo zusammen, wer nicht die Lösung mit den Krokoklemmen oder Klemmhaken hat, kann auch mit der im Foto arbeiten. Schön sieht es aus, wenn das Plastik ganz weg ist ( siehe Pfeil ). Da der Preis für den 1. Warenkorb ziemlich hoch für einen Einstieg ist, habe ich mir gedacht, ich mache noch mal einen der die *Basisschaltung + LEDs* enthält. Hiermit kann man für den Anfang schon ziemlich viel mit machen. Wie immer selber überlegen was man braucht. Habe z.B. noch eine 3-Pin DUO-LED hinzugefügt und bei der Spannungsversorgungsbuchse muss man selber entscheiden, ob man wirklich die Printlösung braucht oder gar keine von beiden. D.h. den Hohlstecker abschneidet und die Strippen so anlötet. Außer Lötkolben und Lötzinn ist also nichts weiter nötig. Sehr hilfreich finde ich die sogenannte " dritte Hand ", die ich nicht mehr missen möchte. http://www.reichelt.de/HALTER-ZD-10D/3/index.html?&ACTION=3&LA=446&ARTICLE=90934&artnr=HALTER+ZD-10D&SEARCH=dritte+hand Und hier nun der preisfreundlichere Einsteiger Warenkorb : http://www.reichelt.de/?ACTION=20;AWKID=994332;PROVID=2084 Bernd_Stein
Hi, ich bin nun bei der Aufgabe A307 angekommen.
1 | ; |
2 | .include "Header_A307_BS.h" ;Label und Werte Zuweisungen |
3 | .include "Hardware_A307_BS.h" ;Hardware Label Zuweisungen |
4 | ; |
5 | ;Einbinden der Controllerspezifischen Definitionsdatei |
6 | ; |
7 | .NOLIST ;List-Output ausschalten |
8 | .INCLUDE "m8def.inc" ;AVR-Definitionsdatei einbinden |
9 | .LIST ;List-Output wieder einschalten |
10 | |
11 | ; |
12 | ;Programmstart nach RESET ( Interuppt Vectoren Tabelle ) |
13 | ; |
14 | .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher |
15 | .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000 |
16 | |
17 | rjmp _reset ;RESET-Vector |
18 | |
19 | .include "IRQm8_A307_BS.inc" ;Interuppt Vectortabelle |
20 | |
21 | .ORG INT_VECTORS_SIZE ;Programmadresse nach den IRQ-Vectoren |
22 | |
23 | ; |
24 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
25 | ;I Erstinitialisierungen |
26 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
27 | ; |
28 | |
29 | ; |
30 | ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) |
31 | ; |
32 | _reset: |
33 | ldi A,HIGH(RAMEND) ;RAMEND (SRAM) ist in der Definitions- |
34 | out SPH,A ;datei festgelegt |
35 | ldi A,LOW (RAMEND) |
36 | out SPL,A |
37 | |
38 | ; |
39 | ;Variablen initialisieren |
40 | ; |
41 | ldi B,1<<LED_BIT ;Maske fuer LED-Toggeln |
42 | |
43 | ; |
44 | ;Ports Erstkonfiguration |
45 | ; |
46 | ; |
47 | sbi LED_DDR,LED_BIT ;Portpin als Ausgang schalten |
48 | sbi TASTER_PORT,TASTER_BIT;Pullup fuer den Tasterpin einschalten |
49 | |
50 | ; |
51 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
52 | ;H Hauptprogrammschleife |
53 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
54 | ; |
55 | _main: |
56 | in A,TASTER_PORT ;Pul-Up Widerstand Konfiguration laden |
57 | sbis TASTER_PIN,TASTER_BIT ;Taster nicht betaetigt => ueberspringen |
58 | eor A,B ;LED_Bit Toggeln |
59 | sbic TASTER_PIN,TASTER_BIT ;Taster betaetigt => ueberspringen |
60 | in A,LED_PIN ;LED-Zustand einlesen |
61 | out LED_PORT,A ;LED-Zustand ueberschreiben |
62 | |
63 | rjmp _main ;Hauptprogrammschleife |
64 | |
65 | |
66 | .EXIT ;Ende des Quelltextes |
Im Simulator funktioniert alles super. Nur in der Realität gibt es nun mal das Tasterprellen. Ich finde mitunter das Erste was Anfänger lernen sollten ist die Interrupt-Programmierung. Damit kann man schön Dinge miteinander Kombinieren und ausbauen. Eine sogenannte *P*rogramm*L*auf*A*nzeige ( PLA ), die im bestimmten Rhytmus eine LED blinken läßt ist schon mal ein guter Anfang für so etwas. Dies ist mir eingefallen, als das Programm von A306 machmal nach längerer Nichtbenutzung ( manchmal ein paar Tage, da ich das Stecker-Schaltnetzteil drin lies ) nicht funktionierte und nur durch einen Power On Reset ( POR ) wieder zum Leben zu erwecken war. Zumdem ist es dann gut möglich PeDas Entprellroutine mit einzufügen, was dann auch keine Probleme mit dem Tasterprellen beim Programm von A307 ergibt. Werde da mal was ausarbeiten, das die beiden Programmbeispiele mit Interruptverarbeitung umsetzt. Auf hilfreiche Verbesserungen bin ich danach schon gespannt. Außerdem möchte ich die Praxistips von PeDa gerne umsetzen und habe mal damit angefangen die ganzen Definitionsdateien seperat einzubinden, um die Programme nicht so aufzublähen und natürlich leichter Anpassbar zu machen. Beitrag "Zeit + Temperatur auf LCD mit AVR" Bernd_Stein
Hallo, habe da nun ein Problem mit einer Fehlermeldung vom AVR-Studio ( siehe Pfeil ). Was mache ich falsch ?
1 | ; |
2 | .include "Header_A310_BS.h" ;Label und Werte Zuweisungen |
3 | .include "Hardware_A310_BS.h" ;Hardware Label Zuweisungen |
4 | ; |
5 | ;Einbinden der Controllerspezifischen Definitionsdatei |
6 | ; |
7 | .NOLIST ;List-Output ausschalten |
8 | .INCLUDE "m8def.inc" ;AVR-Definitionsdatei einbinden |
9 | .LIST ;List-Output wieder einschalten |
10 | |
11 | ; |
12 | ;Programmstart nach RESET ( Interuppt Vectoren Tabelle ) |
13 | ; |
14 | .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher |
15 | .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000 |
16 | |
17 | rjmp _reset ;RESET-Vector |
18 | |
19 | .include "IRQm8_A310_BS.inc" ;Interuppt Vectortabelle |
20 | |
21 | .ORG INT_VECTORS_SIZE ;Programmadresse nach den IRQ-Vectoren |
22 | |
23 | ; |
24 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
25 | ;I Erstinitialisierungen |
26 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
27 | ; |
28 | |
29 | ; |
30 | ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) |
31 | ; |
32 | _reset: |
33 | ldi A,High(RAMEND) ;RAMEND (SRAM) ist in der Definitions- |
34 | out SPH,A ;datei festgelegt |
35 | ldi A,Low (RAMEND) |
36 | out SPL,A |
37 | |
38 | ; |
39 | ;Variablen initialisieren |
40 | ; |
41 | ldi B,1<<LED_BIT ;Maske fuer LED-Toggeln |
42 | clr Timer0 ;Zaehler fuer Timer0 Overflow Zeitbasis |
43 | ; |
44 | ;Ports Erstkonfiguration |
45 | ; |
46 | ; |
47 | sbi LED_DDR,LED_BIT ;Portpin als Ausgang schalten |
48 | sbi TASTER_PORT,TASTER_BIT;Pullup fuer den Tasterpin einschalten |
49 | |
50 | ; |
51 | ;Timer0 Overflow Interrupt initialisieren ( Vorteiler auf 1024 ) |
52 | ; |
53 | ldi A,1<<CS02|1<<CS00 ;Timer/Counter0 Clock Select auf 1024 stellen... |
54 | out TCCR0,A ;...und ins Timer/Counter0 Control Register |
55 | sbi TIMSK,TOIE0 ;Timer/Counter0 Overflow Interrupt freigeben |
56 | |
57 | sei ;Globale Interrupt Freigabe ( I-Bit im Statusreg ) |
58 | |
59 | ; |
60 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
61 | ;H Hauptprogrammschleife |
62 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
63 | ; |
64 | _main: |
65 | |
66 | sbrs Flag_Byte,LED_PLA ;Falls Flag Programmlaufanzeige gesetzt ist... |
67 | cbi LED_PORT,LED_PLA ;...LED aus ueberspringen... |
68 | sbrc Flag_Byte,LED_PLA ;Falls Flag Programmlaufanzeige geloescht ist... |
69 | sbi LED_PORT,LED_PLA ;...LED an ueberspringen |
70 | rjmp _main ;Zum Anfang der Hauptprogrammschleife |
71 | |
72 | ; |
73 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
74 | ;I Timer0 Overflow ISR ( Interrupt Service Routine ) |
75 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
76 | ; |
77 | OVF0addr: |
78 | in S_Sreg,SREG ;Statusregister sichern |
79 | dec Timer0 ;Verzoegerungszaehler um 1 vermindern... |
80 | breq _PLA ;...Falls 0 Flag Programmlaufanzeige setzen |
81 | rjmp _exit_OVF0addr ;Timer0 Overflow ISR verlassen |
82 | _PLA: |
83 | eor Flag_Byte,Iwl ;Flag fuer Programmlaufanzeige toggeln |
84 | _exit_OVF0addr: |
85 | out SREG,S_Sreg ;Gesichertes Statusregister zurueck schreiben |
86 | reti ;Rueckspung aus der Timer0 Overflow ISR |
87 | |
88 | .EXIT ;Ende des Quelltextes |
Bernd_Stein
Der Name 'OVF0addr' ist bereits "belegt". Wenn mich mein Gedächtnis nicht trügt, dann steht dieses Label für die Adresse an der der Interrupt Vektor für den Timer 0 Overflow stehen muss. Also die Adresse, wo dann normalerweise der rjmp zu deiner ISR-Behanldungsroutine zu stehen kommt. Benutze einen anderen Namen und alles ist gut.
Karl Heinz schrieb: > muss. Also die Adresse, wo dann normalerweise der rjmp zu deiner > ISR-Behanldungsroutine zu stehen kommt. Sieh dir das mal am Beispiel des Mega8 an AVR-Tutorial: Interrupts: Aufbau der Interruptvektortabelle
:
Bearbeitet durch User
Hi,
>Benutze einen anderen Namen und alles ist gut.
schlage OVF0_ISR vor. Dann steht bei
OVF0addr: rjmp OVF0_ISR ;Vector bei OVF0 springt weiter nach
ISR
OVF0_ISR: mach was Zeitabhängiges ;aber halte dich kurz
reti
Viel Erfolg, Uwe
Karl Heinz schrieb: > Sieh dir das mal am Beispiel des Mega8 an > > AVR-Tutorial: Interrupts: Aufbau der Interruptvektortabelle > Vielen Dank. Da habe ich mich wieder mal selbst verar... Hatte die Vektor-Tabelle ( IRQm8_A... ) nämlich aus der m8def.inc kopiert und ein wenig verändert ( reti eingefügt usw. ) und gar nicht mehr bedacht, das diesen Labels dort ( m8def.inc ) ja Adressen zugewiesen waren bzw. sind. Also bei jedem IRQ-Label einfach addr entfernt und gut ist. Lese mir jetzt erstmal genauer Deinen Link durch. Und danach sind noch weitere Fehler in meinem Programm auszumerzen. Bis dann Bernd_Stein
So, habe jetzt mal eine Programmlaufanzeige ( PLA ) mittels Interruptverarbeitung programmiert. Die LED ist über einen 270 Ohm Widerstand an PortD6 ( Pin 12 vom ATmega8 )angeschlossen. Dies dient auch wunderbar dazu um einmal zu testen, ob mit dem µC usw. alles in Ordung ist. Einfach die *.Hex* in den µC flashen und sehen ob die LED ca. im 1Hz-Takt blinkt. Dazu habe ich den Timer/Counter0 Overflow Interrupt benutzt. Der Vorteiler des Timer0 wird auf 8 gesetzt, womit der interne RC-Takt von ca. 1Mhz mit ca. 125kHz auf den Timer0 einwirkt. Der Overflow entsteht wenn das 8-Bit große TCNT0-Register wieder bei $00 anfängt ( $00 - $FF - $00 ). Also ca. alle 2ms gibt es einen Timer/Counter0 Overflow Interrupt. In der Interrupt-Service-Routine ( ISR ), wird ein Register als Verzögerungszähler ( Timer0 ) heruntergezählt. Somit wird ca. alle 0,5 Sekunden in der ISR ein Bit geprüft, ob die Mainschleife noch durchlaufen wird, da in der Mainschleife gegen Ende dieses Bit gelöscht wird. Am Ende der Mainschleife wird, wenn die ISR funktioniert - also dieses Bit auf 1 gesetzt hatte, jenes genutzt um die PLA-LED zu toggeln, was auch im 0,5 Sekundentakt passiert, wenn alles in Ordnung ist. Dadurch ergibt sich, das die PLA-LED mit ca. 1Hz blinkt. Hat jemand eine andere Idee wie man so eine gegenseitige ( Main & ISR ) optische Programmlaufkontrolle durchführen kann oder zumindest, ob die Mainschleife abgearbeitet wird ?
1 | ; |
2 | .include "Header_A310_BS.h" ;Label und Werte Zuweisungen |
3 | .include "Hardware_A310_BS.h" ;Hardware Label Zuweisungen |
4 | ; |
5 | ;Einbinden der Controllerspezifischen Definitionsdatei |
6 | ; |
7 | .NOLIST ;List-Output ausschalten |
8 | .INCLUDE "m8def.inc" ;AVR-Definitionsdatei einbinden |
9 | .LIST ;List-Output wieder einschalten |
10 | |
11 | ; |
12 | ;Programmstart nach RESET ( Interrupt Vektoren Tabelle ) |
13 | ; |
14 | .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher |
15 | .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000 |
16 | |
17 | rjmp _reset ;RESET-Vector |
18 | |
19 | .include "IRQm8_A310_BS.inc";Interrupt Vektortabelle |
20 | |
21 | .ORG INT_VECTORS_SIZE ;Programmadresse nach den ganzen IRQ-Vektoren |
22 | |
23 | ; |
24 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
25 | ;I Erstinitialisierungen |
26 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
27 | ; |
28 | |
29 | ; |
30 | ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) |
31 | ; |
32 | _reset: |
33 | ldi A,High(RAMEND) ;RAMEND (SRAM) ist in der Definitions- |
34 | out SPH,A ;datei festgelegt |
35 | ldi A,Low (RAMEND) |
36 | out SPL,A |
37 | |
38 | ; |
39 | ;Variablen initialisieren ( r0-r31 haben unbestimmten Inhalt ) |
40 | ; |
41 | ldi B,1<<LED_PLA ;Maske fuer LED-Toggeln |
42 | clr Timer0 ;Zaehler fuer Timer0 Overflow Zeitverlaengerung |
43 | clr Flag_Byte ;Enthaelt unterschiedliche Flags ( Signalbits ) |
44 | ; |
45 | ;Ports Erstkonfiguration |
46 | ; |
47 | ; |
48 | sbi LED_DDR,LED_PLA ;Portpin als Ausgang konfigurieren |
49 | |
50 | ; |
51 | ;Timer0 Overflow Interrupt initialisieren ( Vorteiler auf 8 ) |
52 | ; |
53 | ldi A,1<<CS01 ;Timer/Counter0 Clock Select auf 8 stellen... |
54 | out TCCR0,A ;...und ins Timer/Counter0 Control Register |
55 | ldi A,1<<TOIE0 ;Timer/Counter0 Overflow Interrupt Enable Bit... |
56 | out TIMSK,A ;...setzen und somit diesen IRQ freigeben |
57 | |
58 | sei ;Globale Interrupt Freigabe ( I-Bit im Statusreg ) |
59 | |
60 | ; |
61 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
62 | ;H Hauptprogrammschleife |
63 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
64 | ; |
65 | _main: |
66 | nop ;Symbolisch fuer weitere Programmzeilen |
67 | ; |
68 | ;ProgrammLaufAnzeige ( PLA ) durch Blinken einer LED anzeigen. |
69 | ;Mit gegenseitiger Ueberwachung durch Bit ( Main und Timer0 Overflow ISR ) |
70 | ; |
71 | sbrc Flag_Byte,LED_PLA ;ISR_PLA abgearbeitet = nicht ueberspringen |
72 | rjmp _pla_service ;Programmlaufanzeige bedienen |
73 | rjmp _loop ;Weitere Programmteile bearbeiten |
74 | _pla_service: |
75 | in A,LED_PORT ;LED Port-Zustand einlesen |
76 | eor A,B ;PLA-Bit toggeln |
77 | out LED_PORT,A ;PLA-LED toggeln |
78 | cbr Flag_Byte,1<<LED_PLA ;Flag fuer Programmlaufanzeige Ok ruecksetzen |
79 | _loop: |
80 | rjmp _main ;Zum Anfang der Hauptprogrammschleife |
81 | |
82 | ; |
83 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
84 | ;I Timer0 Overflow ISR ( Interrupt Service Routine ) |
85 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
86 | ; |
87 | OVF0: |
88 | in S_Sreg,SREG ;Statusregister sichern |
89 | dec Timer0 ;Verzoegerungszaehler um 1 vermindern... |
90 | breq _PLA ;...Falls 0 Programmlaufanzeige bearbeiten |
91 | rjmp _exit_OVF0 ;Timer0 Overflow ISR verlassen |
92 | _PLA: |
93 | sbrs Flag_Byte,LED_PLA ;Mainprogramm abgearbeitet = nicht ueberspringen |
94 | sbr Flag_Byte,1<<LED_PLA ;Flag fuer Programmlaufanzeige Ok setzen |
95 | _exit_OVF0: |
96 | out SREG,S_Sreg ;Gesichertes Statusregister zurueck schreiben |
97 | reti ;Rueckspung aus der Timer0 Overflow ISR |
98 | |
99 | .EXIT ;Ende des Quelltextes |
Bernd_Stein
Hier noch ein paar Informationen zum Timer und zu Interrupts : https://www.youtube.com/watch?v=Zr0842FEC5Qhttps://www.youtube.com/watch?v=Zr0842FEC5Q https://www.youtube.com/watch?v=kAnp2n2o60Y&list=UU6_3ViPBhXh2abpxJoSKtVw http://modelleisenbahn-steuern.de/controller/atmega8/10-8-bit-timer-counter-0.htm https://www.youtube.com/watch?v=UpxemFUVnFI&list=UU6_3ViPBhXh2abpxJoSKtVw&index=11 http://modelleisenbahn-steuern.de/controller/atmega8/7-interrupts.htm Bernd_Stein
Hallo Assembler-Freaks, alles sehr interessant...was man da so liest! Teils übersteigt es etwas mein Wissen, aber einiges baut meine Erkenntnisse auf. Karl Heinz Buchegger hat mir vor Jahren viel Now how beigebracht. Eine Modelleisenbahn (Spur H0) läuft mit einem Drehkran der Marke Märklin, und Container-Kran der Marke Brawa mit einem Tiny2313. Weiter so...bin gespannt, was da noch so ankommt! Grüße Rolf aus Quickborn bei Hmb. im hohen Alter Ach ja..9 St. Tiny13 laufen als Ortungspieper in Modellflugzeugen.
Rolf H. schrieb: > Hallo Assembler-Freaks, > alles sehr interessant...was man da so liest! > ... > Weiter so...bin gespannt, was da noch so ankommt! > Danke. Das hat mich angespornt weiter zu machen. Denn oberflächlich sah es bisher so aus, als ob dies niemand wirklich interessieren würde. Also wie bisher angemerkt, stört es mich, das es zu Anfang nicht vermittelt wird, wie man richtig programmiert. Bei der Aufgabe A305 geht es zum Beispiel darum, das eine LED so lange leuchten soll, wie der Taster betätigt ist. Hierbei ist das in der Praxis immer vorkommende Tasterprellen nicht zu bemerken. Jedoch gleich in der übernächsten Aufgabe A307 wird sehr deutlich, das diese Programmierstrategie nicht zu gebrauchen ist, da sich hier das Tasterprellen bemerkbar macht ( Bei jedem erneuten Tastendruck soll der LED-Zustand verändert, also getoggelt bzw. invertiert werden ). Ich weiß, es kommt immer darauf an. Aber wer nur so programmieren gelernt hat, weil es relativ kompakt und schön zu erklären ist, der wundert sich dann evtl. ein paar Tage lang warum seine Schaltung nicht das tut was er möchte und erfährt dann in einem der so vielen Threads, das das Tasterprellen wahrscheinlich die Ursache ist. Hat leider jedoch nie gelernt wie so etwas Softwaretechnisch sehr elegant gelöst werden kann und steht dann auf dem Schlauch. PeDa ( Peter Dannegger ) hat da eine sehr effiziente, aber auch sehr schwer zu verstehende Strategie ausgeklügelt die jedoch das Tasterprellen und überhaupt verschiedene Tastenfunktionen " Kugelsicher " ermöglicht. Beitrag "Tasten entprellen - Bulletproof" Dies habe ich bezogen auf eine Einzeltasterlösung mit in dem Programm aufgenommen. Werde hoffentlich morgen dazu kommen das Programm genauer zu erklären. Beitrag "Einzelnen Taster entprellen ASM" Habe beim Herumspielen bermerkt, das es nicht möglich ist einen von beiden Tastern der Basisplatine so zu betätigen, das dieser vor dem Klickgeräusch schaltet. Jedoch umgekehrt, das dieser bei leichtem lösen des Drucks öffnet bevor das Klickgeräusch kommt. Fazit : Ein unbeabsichtigtes " Einschalten " ist unwahrscheinlicher als ein unbeabsichtigtes " Ausschalten " mit evtl. unbemerkten " Wiedereinschalten " usw. Schade das PeDa jetzt fast ausschließlich in C zu lesen ist ;-) Hannes Lux schreibt auch sehr " assemblernah ". Habe schon so manches von Ihm gelernt, so hoffe ich. Hoffe noch mehr deutschsprachige " Assemblerfreaks " kennen lernen zu können. Rolf H. schrieb: > Rolf aus Quickborn bei Hmb. im hohen Alter > Ach ja - bist Du schon über 90ig oder was ? ;-)) Bernd_Stein
:
Bearbeitet durch User
Ich habe mir angewöhnt, bei Assembler Programme einfach immer gleich die komplette IRQ Vektortabelle auf einen 'Stub' zu leiten:
1 | ; ************** MAIN PROGRAM STARTS HERE ************************* |
2 | .CSEG |
3 | ; header for ATTiny 25/45/85 |
4 | .ORG 0x0 |
5 | rjmp RESET ; Reset Handler |
6 | rjmp EXT_INT0 ; IRQ0 Handler |
7 | rjmp PC_INT0 ; PCINT0 Handler |
8 | rjmp TIM1_COMPA ; Timer 1 compare match A |
9 | rjmp TIM1_OVF ; timer 1 overflow |
10 | rjmp TIM0_OVF ; Timer0 Overflow Handler |
11 | rjmp EE_RDY ; EEPROM Ready Handler |
12 | rjmp ANA_COMP ; Analog Comparator Handler |
13 | rjmp ADC_INT ; ADC Conversion Handler |
14 | rjmp TIM1_COMPB ; timer 1 compare match B |
15 | rjmp TIM0_COMPA ; Timer0 CompareA Handler |
16 | rjmp TIM0_COMPB ; Timer0 CompareB Handler |
17 | rjmp WATCHDOG ; Watchdog Interrupt Handler |
18 | rjmp USI_START ; usi start condition |
19 | rjmp USI_OVF ; usi overflow |
20 | ;
|
21 | ; stubs |
22 | EXT_INT0: |
23 | PC_INT0: |
24 | TIM1_COMPA: |
25 | TIM1_OVF: |
26 | TIM0_OVF: |
27 | EE_RDY: |
28 | ANA_COMP: |
29 | ADC_INT: |
30 | TIM1_COMPB: |
31 | TIM0_COMPA: |
32 | TIM0_COMPB: |
33 | WATCHDOG: |
34 | USI_START: |
35 | USI_OVF: reti |
36 | ; Und hier der Reset Einsprung |
37 | RESET: |
Je nach benutzten Interrupts 'löse' ich dann die benutzten aus dem Stub aus und schreibe die Routine. Das hat den Vorteil, das versehentlich freigegebene IRQ nicht gleich Amok laufen. Viel Spass weiterhin :-)
:
Bearbeitet durch User
mh...komisch, hatte gar keine Benachrichtigung bekommen, daß zwei Antworten da sind! Hallo Bernd Stein, ja das mit den Tastenprellen ist schon so ein Problem. Das tritt bei mir mit den Märklinkrahn auf, wenn er gegen einen Endlagenschalter läuft. Ich glaube aber, der ist nicht der Auslöser, sondern die nachfolgende Klappertechnik...sprich Relais. Die Ansteuerung vom Tiny2313 läuft über ULN2003 (ist Dir bestimmt bekannt). Von da geht's zur Klappertechnik zu den beiden Motoren, die potenzial- mäßig angesteuert werden. Habe eine "Entprellroutiene in den Proceduren eingefügt...Verbesserung ist spürbar, aber ab und zu spielt das mal verrückt. Also schnell die Reset- Taste. Nun habe ich die Backen voll und baue das ohne Klappertechnik neu auf. Habe eine xx.asm Datei erstellt über Entprellen. Wenn es interessiert, kann ich versuchen diese einzustellen. Mein Alter....im Januar 2015 = 80 Jahre und fliege noch große Modellhubis mit FBL. Grüße Rolf Vermerk: im Thread beobachten habe ich jetzt einen Haken gesetzt!
Hallo Bernd, Wennst noch einen ASM Freak brauchst, kann ich dir noch den André Menzel empfehlen. Schaust mal unter "Stammtisch Nähe München" Grüße Bernhard
Rolf H. schrieb: > ja das mit den Tastenprellen ist schon so ein Problem. > Das tritt bei mir mit den Märklinkrahn auf, wenn er gegen einen > Endlagenschalter läuft. > Ich werde ja versuchen PeDas Entprellroutine für einen einzelnen Taster zu erklären. Für Deine Endlagenschalter könnte dies evtl. ein Problem ergeben, da betätigte Kontakte ( Über Pull-Up gegen Masse ) nach einem Reset oder Wiederkehr der Spannungsversorgung ( POR = Power On Reset ) nicht direkt erkannt werden. > > Die Ansteuerung vom Tiny2313 läuft über ULN2003 (ist Dir bestimmt > bekannt). > Nur so aus dem Gedächnis, der ULN2803 sollte das Selbe können hat aber einen Treiber mehr, also acht. > > Mein Alter....im Januar 2015 = 80 Jahre und fliege noch große > Modellhubis mit FBL. > So etwas lese ich doch immer gerne, dann hab ich ja noch ein wenig Zeit mich weiter mit der µC-Materie zu befassen. Bernhard Schröcker schrieb: > Wennst noch einen ASM Freak brauchst, kann ich dir noch den André Menzel > empfehlen. Schaust mal unter "Stammtisch Nähe München" > Hatte bisher dort nicht gelesen, weil zu weit vom Ruhrgebiet entfernt. Aber ich muß ja nicht hinfahren ;-). In diesen Thread ist er ja schon mal nicht auf das Stichwort " Assembler " angesprungen - denke ich. Bernd_Stein
ich werde mal versuchen, wie ich ein Teil meines Quelltextes (Thema "Kran02") hierher exportiere. Ist schon lange her, daß mir das gelungen ist..mal sehen! Als Dateianhang wollte ich es nicht machen. entprellen: ;Prescale steht auf 1024 ldi temp18,0xFF ;r18=FF wait1: ldi temp19,0xFF ;r19=FF wait2: dec temp19 ;dekrement r19 brne wait2 ;Verzweig. wenn Z=0 (Z=1 wenn r19=0) dec temp18 ;dekrement r18 brne wait1 ;Verzweig. wenn Z=0 (Z=1 wenn r18=0) ret Und nun konnte man das noch irgendwie dunkel hervor heben. Wie ich schon schrieb hat die rcall Routiene was gebracht. Grüße Rolf Es giebt einen neuen Treiber: TPL 7407L (7 St. im Chip / Uout max. 40V= / Iout max. 600mA)
:
Bearbeitet durch User
Rolf H. schrieb: > ich werde mal versuchen, wie ich ein Teil meines Quelltextes > (Thema "Kran02") hierher exportiere. >
1 | > entprellen: ;Prescale steht auf 1024 |
2 | > ldi temp18,0xFF ;r18=FF |
3 | > wait1: |
4 | > ldi temp19,0xFF ;r19=FF |
5 | > wait2: |
6 | > dec temp19 ;dekrement r19 |
7 | > brne wait2 ;Verzweig. wenn Z=0 (Z=1 wenn r19=0) |
8 | > dec temp18 ;dekrement r18 |
9 | > brne wait1 ;Verzweig. wenn Z=0 (Z=1 wenn r18=0) |
10 | > ret |
Diese Art zu programmieren ist auch etwas, was ich meine das uns Anfängern falsch beigebracht wurde. So ein Stil macht einen wesentlichen Vorteil der Assemblersprache, nämlich seine Möglichkeit unübertroffen schnell zu sein zu nichte. Die Zeit zu vertrödeln, um auf etwas zu warten, ist bei der Nutzung einer Zeitbasis wie z.B. die des Timer0 Überlaufs nicht nötig. Deinen Code habe ich mit der Formatierungsfunktion
1 | AVR-Assembler-Code |
eingebettet ( [avrasmAVR-Assembler-Code/avrasm] ). Siehe Formatierung wenn Du eine Antwort schreibst. Dazu markiere und kopiere ich immer diese Zeile und füge sie am Anfang und am Ende des Codes an. Danach lösche ich den nicht benötigten Teil. Am Anfang des Codes steht also in den eckigen Klammern avrasm und am Ende in eckigen Klammern /avrasm ( Schrägstrich beachten ). Rolf H. schrieb: > Ich glaube aber, der ist nicht der Auslöser, sondern die nachfolgende > Klappertechnik...sprich Relais. > Dies solltest Du lieber in einem gesonderten Thread weiterführen, da es nicht mehr zu Threadüberschrift passt. Das Selbe tue ich jetzt auch mit der Erklärung zu " Einzelnen Taster " entprellen. Beitrag "Einzelnen Taster entprellen ASM" Bernd_Stein
Hallo, hier nun eine verbesserte Version der Aufgabe A307, wo bei jedem erneuten Tastendruck eine LED getoggelt ( invertiert ) werden soll, was ja wegen des Tastenprellens nicht zufriedenstellend war. Hier gilt es zu beachten das die PLA-LED nun an PortD7 ( Pin13 ) angeschlossen ist und die LED die vom Taster getoggelt wird an PortD6 ( Pin12 ) und der Taster weiterhin an PinD5 ( Pin11 ). Das Ganze basiert auf PeDas Entprellroutine für einen einzelnen Taster.
1 | ; |
2 | .include "Header_A312_BS.h" ;Label und Werte Zuweisungen |
3 | .include "Hardware_A312_BS.h" ;Hardware Label Zuweisungen |
4 | ; |
5 | ;Einbinden der Controllerspezifischen Definitionsdatei |
6 | ; |
7 | .NOLIST ;List-Output ausschalten |
8 | .INCLUDE "m8def.inc" ;AVR-Definitionsdatei einbinden |
9 | .LIST ;List-Output wieder einschalten |
10 | |
11 | ; |
12 | ;Programmstart nach RESET ( Interrupt Vektoren Tabelle ) |
13 | ; |
14 | .CSEG ;Was ab hier folgt kommt in den FLASH-Speicher |
15 | .ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000 |
16 | |
17 | rjmp _reset ;RESET-Vector |
18 | |
19 | .include "IRQm8_A312_BS.inc";Interrupt Vektortabelle |
20 | |
21 | .ORG INT_VECTORS_SIZE ;Programmadresse nach den ganzen IRQ-Vektoren |
22 | |
23 | ; |
24 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
25 | ;I Erstinitialisierungen |
26 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
27 | ; |
28 | |
29 | ; |
30 | ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) |
31 | ; |
32 | _reset: |
33 | ldi a,High(RAMEND) ;RAMEND (SRAM) ist in der Definitions- |
34 | out SPH,a ;datei festgelegt |
35 | ldi a,Low (RAMEND) |
36 | out SPL,a |
37 | |
38 | ; |
39 | ;Variablen initialisieren ( r0-r31 haben unbestimmten Inhalt ) |
40 | ; |
41 | ldi b,1<<LED_PLA ;Programmlaufanzeige LED selektieren |
42 | clr timer0 ;Zaehler fuer Timer0 Overflow Zeitverlaengerung |
43 | clr flag_byte ;Byte mit verschiedenen Flags ( Signalbits ) |
44 | clr key_reg ;Fuer Tasterentprellung |
45 | ldi a,1<<LED_BIT ;LED-Bit selektieren und... |
46 | mov led_msk,a ;...in ein unteres Register kopieren |
47 | |
48 | ; |
49 | ;Ports Erstkonfiguration |
50 | ; |
51 | ; |
52 | ldi a,1<<LED_PLA | 1<<LED_BIT; Portpins auswahlen und als... |
53 | out Led_Ddr,a ;...Ausgang konfigurieren |
54 | |
55 | sbi Taster_Port,TASTER_BIT;Pull-up Widerstand fuer den Taster aktivieren |
56 | ; |
57 | ;Timer0 Overflow Interrupt initialisieren ( Vorteiler auf 8 ) |
58 | ; |
59 | ldi a,1<<CS01 ;Timer/Counter0 Clock Select auf 8 stellen... |
60 | out Tccr0,a ;...und ins Timer/Counter0 Control Register |
61 | ldi a,1<<TOIE0 ;Timer/Counter0 Overflow Interrupt Enable Bit... |
62 | out Timsk,a ;...setzen und somit diesen IRQ freigeben |
63 | |
64 | sei ;Globale Interrupt Freigabe ( I-Bit im Statusreg ) |
65 | |
66 | ; |
67 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
68 | ;H Hauptprogrammschleife |
69 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
70 | ; |
71 | _main: |
72 | nop ;Symbolisch fuer weitere Programmzeilen |
73 | ; |
74 | ;Taster bearbeiten |
75 | ; |
76 | sbrs key_reg,KEY_FON ;Ueberspringen falls Flanke Taster betaetigt |
77 | rjmp _pla ;Zur Programmlaufanzeige springen |
78 | in a,Led_Port ;Zustand LED-Port in Arbeitsregister kopieren |
79 | eor a,led_msk ;Maskierte LED invertieren und neuen.... |
80 | out Led_Port,a ;...LED-Zustand ausgeben |
81 | cbr key_reg,1<<KEY_FON ;Flanke Taster betaetigt quitieren |
82 | |
83 | ; |
84 | ;ProgrammLaufAnzeige ( PLA ) durch Blinken einer LED anzeigen. |
85 | ;Mit gegenseitiger Ueberwachung durch Bit ( Main und Timer0 Overflow ISR ) |
86 | ; |
87 | _pla: |
88 | sbrc flag_byte,LED_PLA ;ISR_PLA abgearbeitet = nicht ueberspringen |
89 | rjmp _pla_service ;Programmlaufanzeige bedienen |
90 | rjmp _loop ;Weitere Programmteile bearbeiten |
91 | _pla_service: |
92 | in a,Led_Port ;LED Port-Zustand einlesen |
93 | eor a,b ;PLA-Bit toggeln |
94 | out Led_Port,a ;PLA-LED toggeln |
95 | cbr flag_byte,1<<LED_PLA ;Flag fuer Programmlaufanzeige Ok ruecksetzen |
96 | _loop: |
97 | rjmp _main ;Zum Anfang der Hauptprogrammschleife |
98 | |
99 | ; |
100 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
101 | ;I Timer0 Overflow ISR ( Interrupt Service Routine ) |
102 | ;IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
103 | ; |
104 | OVF0: |
105 | in s_sreg,Sreg ;Statusregister sichern |
106 | ; |
107 | ;Taster entprellen |
108 | ; |
109 | bst key_reg,KEY_DEB ;1= Anzeigen das das Signal als entprellt gilt |
110 | sbis Taster_Pin,TASTER_BIT ;Ueberspringen falls Taster nicht betaetigt |
111 | rjmp _on_OVF0 ;Sprung zu Taster wurde betaetigt |
112 | brts _clr_OVF0 ;Zaehlerbits loeschen ( ruecksetzen ) |
113 | rjmp _test_OVF0 ;Taster betaetigt entprellt pruefen |
114 | _on_OVF0: |
115 | brts _test_OVF0 ;Taster betaetigt entprellt pruefen |
116 | _clr_OVF0: |
117 | cbr key_reg,$03 ;Prellzaehler ruecksetzen |
118 | _test_OVF0: |
119 | sbrs key_reg,KEY_FON ;Falls Taster betaetigt entprellt ueberspringen |
120 | inc key_reg ;Kombiniertes Register incrementieren |
121 | |
122 | ; |
123 | ;Programmlaufanzeige ( PLA ) mittels Verzoegerungszaehler erzeugen |
124 | ; |
125 | dec timer0 ;Verzoegerungszaehler um 1 vermindern... |
126 | breq _pla_OVF0 ;...Falls 0 Programmlaufanzeige bearbeiten |
127 | rjmp _exit_OVF0 ;Timer0 Overflow ISR verlassen |
128 | _pla_OVF0: |
129 | sbrs flag_byte,LED_PLA ;Mainprogramm abgearbeitet = nicht ueberspringen |
130 | sbr flag_byte,1<<LED_PLA ;Flag fuer Programmlaufanzeige Ok setzen |
131 | _exit_OVF0: |
132 | out Sreg,s_sreg ;Gesichertes Statusregister zurueck schreiben |
133 | reti ;Rueckspung aus der Timer0 Overflow ISR |
134 | |
135 | .EXIT ;Ende des Quelltextes |
Und hier noch eine Quelle zum Tasterprellen in Assembler : http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten Bernd_Stein
:
Bearbeitet durch User
Ich war verwundert über das Ergebnis der Aufgabe A400, als nach dem ORI-Befehl das Sign-Flag im Statusregister gesetzt wurde. c) In welchem Register steht jeweils das Resultat? d) Betrachte das Statusregister (Flagregister) SREG und die Resultate der Berechnungen im "I/OView"Fenster und interpretiere die Ergebnisse. Zu c) würde ich sagen immer im Arbeitsregister Tmp1 bzw. bei mir im Arbeitsregister a. Zu d) Würde ich erstens empfehlen das " Processor " Fenster zu nehmen wie im Anhang zu sehen. Und nun zum Interpretieren : LDI verändert keine Flags im Statusregister. ANDI bringt als Ergebnis Null, weshalb das Z-Flag gesetz wird. ORI setzt das N-Flag weil Bit7 gestezt wird, was einer Negativen Zahl gleichgesetzt werden kann. Zusätzlich wird das S-Flag gesetzt, da ja der Befehl das V-Flag auf Null setzt und das N-Flag gesetzt ist ( XOR N V ). Bitte berichtigt mich, falls ich mir die Dinge gerade falsch erkläre. Bernd_Stein
Hallo, da auf mein vorheriges Posting nicht eingegangen wurde, denke ich mal das alles so richtig ist. Denn meistens wird man ja korrigiert. Also weiter im Text. Bin jetzt bei A401 und finde das hier schon viel zu heftig und zu oberflächlich auf die Flags im Statusregister eingegangen wird. Die Sache mit dem CPI-Befehl habe ich noch nicht gemacht, da ich schon das Setzen des Half-Carry Flags ( H ) nicht interpretieren kann.
1 | ; |
2 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
3 | ;H Hauptprogrammschleife |
4 | ;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH |
5 | ; |
6 | _main: |
7 | ldi a,100 |
8 | subi a,50 |
9 | |
10 | ldi a,100 |
11 | subi a,100 |
12 | |
13 | |
14 | ldi a,100 |
15 | subi a,200 |
16 | |
17 | rjmp _main |
18 | |
19 | .EXIT ;Ende des Quelltextes |
So ein µC kennt ja nur die Addition. Und die Subtraktion baut auf einer Addition mit dem Zweierkomplement auf. ( Zweierkomplement = invertieren und 1 hinzu addieren ) Zur ersten Sache : 100-50 = 50
1 | Zweierkomplementbildung |
2 | 0110 0100 $64 = 100 0011 0010 $32 = 50 |
3 | +1100 1110 $CE = -50 |
4 | ---------- 1100 1101 $CD = 50 invertiert = 205 |
5 | C0011H0010 $32 = 50 +0000 0001 $01 = 1 addieren |
6 | ---------- |
7 | 1100 1110 $CE = -50 |
Wenn man es schriftlich addiert kommt es beim Half-Carry ( H ) sowie beim Carry ( C ) zum Überlauf. Nach dem ich mir die AVR-Instruction-Set zum SUBI Befehl angeschaut habe, ist mir klar geworden das das C-Flag schon mal nicht gesetzt wird ( Set if the absolute value of K is larger than the absolute value of Rd; cleared otherwiese. ) Es findet ja auch kein Unterlauf bzw. Borgen statt, da ja Subrahiert wird und der Subtrahend ( 50 ) kleiner ist als der Minuend ( 100 ). Also korrekt das das C-Flag nicht gesetzt wird. Für das Half-Carry-Flag steht ( H ):
1 | Set if there was a borrow from bit 3; cleared otherwise |
2 | /Rd3 und K3 *oder* K3 und R3 *oder* R3 und /Rd3 |
Den ersten Ausdruck ( /Rd3 und K3 ) verstehe ich noch, aber bei den anderen weiß ich es nicht, da ich mir die Entstehung von R3 nicht erklären kann. Da dies aber identisch mit der " Algebra " vom C-Flag ist - anstatt 7 hier 3 - kann man dies dann nicht so betrachten, das das H-Flag nur dann gesetzt wird wenn das Low-Nibble größer ist als das H-Nibble ? Bernd_Stein
:
Bearbeitet durch User
Hi >Den ersten Ausdruck ( /Rd3 und K3 ) verstehe ich noch, >aber bei den anderen weiß ich es nicht, da ich mir die Entstehung von >R3 nicht erklären kann. Instruction Set: R: Result after instruction is executed MfG Spess
@ Bernd Stein (bernd_stein) Mein Gott, du mit deinem UNSCHLAGBAR schnellen Assembler murkst hier an Trivialitäten rum, die man in C schon längt fertig hätte. Naja, jedem das Seine.
Falk Brunner schrieb: > Mein Gott, du mit deinem UNSCHLAGBAR schnellen Assembler murkst hier an > Trivialitäten rum, die man in C schon längt fertig hätte. Quatsch. Einer der größten Nachteile von C ist ja gerade, daß man keinen direkten Zugriff auf die MCU-Flags hat und deswegen bei vielen Algorithmen auf Gedeih und Verderb der Qualität des Codegenerators des Compilers ausgeliefert ist. Ein sehr klares Zeichen für die Wichtigkeit und potentielle Überlegenheit von Assembler ist doch allein schon, daß praktisch kein C-Programm ohne Asm-Einschübe oder Asm-Routinen in den plattformspezifischen Libs auskommt, um auch nur einigermaßen effizenten Code zu erzeugen. Wenn C wirklich so toll und universell wäre, wie die C-Apologeten ständig gebetsmühlenartig wiederholen, dann sollte es ohne Anleihen bei einer fremden Sprache auskommen können. Tut es aber offensichtlich nicht. q.e.d.
Hi, setze fuer X und Y Werte ein, damit das gewuenschte Ergebnis entsteht.
1 | /Rd3 und K3: |
2 | |
3 | Rd3 : .... 0... |
4 | K3 : .... 1... |
5 | Borrow : ...1 X... |
6 | ------------------- |
7 | R3 : .... Y... |
8 | |
9 | K3 und R3: |
10 | |
11 | Rd3 : .... X... |
12 | K3 : .... 1... |
13 | Borrow : ...1 Y... |
14 | ------------------- |
15 | R3 : .... 1... |
16 | |
17 | R3 und /Rd3: |
18 | |
19 | Rd3 : .... 0... |
20 | K3 : .... X... |
21 | Borrow : ...1 Y... |
22 | ------------------- |
23 | R3 : .... 1... |
Gruss
:
Bearbeitet durch User
c-hater schrieb: > Ein sehr klares Zeichen für die Wichtigkeit und potentielle > Überlegenheit von Assembler ist doch allein schon, daß praktisch kein > C-Programm ohne Asm-Einschübe oder Asm-Routinen in den > plattformspezifischen Libs auskommt, um auch nur einigermaßen effizenten > Code zu erzeugen. Da würden mich mal ein paar reale Beispiele interessieren. Ich denke, daß ist in Wirklichkeit nur warme Luft MfG Klaus
spess53 schrieb: > R: Result after instruction is executed > Hmm. SUBI Rd,K ( Rd-K => Rd ). Wenn ich das Obige so stehen lassen würde, wäre uns beiden wahrscheinlich nicht geholfen. Also - mir steht ja das Ergebnis dieser Operation nur im Rd-Register ( d = Destination => Ziel ) zur Verfügung, auf dieses ominöse R-Register kann ich ja nicht zugreifen, also ist für mich eigentlich ( Result after instruction is executed ) das Rd-Register das Ergebnisregister. Bernd Stein schrieb: > Da dies aber identisch mit der " Algebra " vom C-Flag ist - anstatt 7 > hier 3 - kann man dies dann nicht so betrachten, das das H-Flag nur dann > gesetzt wird wenn das Low-Nibble größer ist als das H-Nibble ? > > _*H-Flag*_ : > /Rd3 und K3 oder K3 und R3 oder R3 und /Rd3 > Set if there was a borrow from bit 3; cleared otherwise. > > _*C-Flag*_ : >/Rd7 und K7 oder K7 und R7 oder R7 und /Rd7 > Set if the absolute value of K is > larger than the absolute value of Rd; cleared otherwiese. > Da bisher keine Antwort mit Erklärung auf meine Frage gekommen ist, überlege ich gerade evtl. ein Programm zu schreiben das meine Überlegung durchspielt und ich anhand des H-Flags überprüfen muss ob sie stimmt. Dabei besteht jedoch immer das Problem mich selbst zu verarschen. Josef schrieb: > Hi, > > setze fuer X und Y Werte ein, damit das gewuenschte Ergebnis entsteht. > > /Rd3 und K3: > > Rd3 : .... 0... > K3 : .... 1... > Borrow : ...1 X... X = 0 => 0 AND 1 = 0 > ------------------- > R3 : .... Y... Y = 0 => 0 AND 1 = 0 + Borrow ( X ) > Ehrlich gesagt weiß ich nicht wie ich bei R3 ( Y ) vorgehen muß. Muß ich Borrow, also das vorherige Verknüpfungsergebnis ( X ), addieren, subtrahieren, wieder mit K3 oder Rd3 AND-Verknüpfen ? Das gewünschte Ergebnis wäre ja, das das H-Flag gesetzt wird, was ja für mich immer gegeben ist, wenn K3 > Rd3 ist. ( Bei einer Subtraktion betrachtet ), aber hier wird ja eine AND-Verknüpfung durchgeführt. Jetzt brauch ich eine Pausse, das verwirrt mich nämlich alles. > > K3 und R3: > > Rd3 : .... X... > K3 : .... 1... > Borrow : ...1 Y... > ------------------- > R3 : .... 1... > > R3 und /Rd3: > > Rd3 : .... 0... > K3 : .... X... > Borrow : ...1 Y... > ------------------- > R3 : .... 1... > Bernd_Stein
@ c-hater (Gast) >Quatsch. Einer der größten Nachteile von C ist ja gerade, daß man keinen >direkten Zugriff auf die MCU-Flags hat Die braucht man in C in den allerwenigsten Fällen. Jenseits der Mikrocontroller extakt NIE! >und deswegen bei vielen >Algorithmen auf Gedeih und Verderb der Qualität des Codegenerators des >Compilers ausgeliefert ist. Der ist oft besser als die C-Programmierer es je sein werden ;-) >Ein sehr klares Zeichen für die Wichtigkeit und potentielle >Überlegenheit Aha. "potentielle Überlegenheit". Klingt so wie ein verkanntes Genie. Also DU! ;-) > von Assembler ist doch allein schon, daß praktisch kein >C-Programm ohne Asm-Einschübe oder Asm-Routinen in den >plattformspezifischen Libs auskommt, um auch nur einigermaßen effizenten >Code zu erzeugen. Viel schlimmer! Jeder C-Compiler erzeugt ASM-Code!!! >Wenn C wirklich so toll und universell wäre, wie die C-Apologeten >ständig gebetsmühlenartig wiederholen, dann sollte es ohne Anleihen bei >einer fremden Sprache auskommen können. [ ] Du hast verstanden, wie ein Compiler funktioniert und welche Vorteile er bietet. Ach, was wäre diese Forum ohne die ewig gleichen, sinnfreien Diskussionen.
Hi >Also - mir steht ja das Ergebnis dieser >Operation nur im Rd-Register ( d = Destination => Ziel ) zur Verfügung, >auf dieses ominöse R-Register kann ich ja nicht zugreifen, also ist für >mich eigentlich ( Result after instruction is executed ) das Rd-Register >das Ergebnisregister. Selbstverständlich ist in diesem Fall das Rd-Register das Ergebnisregister. Aber in den Formeln beschreibt Rd den Inhalt dieses Register vor der Ausführung und R den Inhalt nach der Ausführung der Operation. MfG Spess
Hi, ich finde es sehr löblich vom TO dass er sich zuerst einmal mit den Grundlagen (sprich ASM und Operationen auf CPU/MPU Ebene) beschäftigt. Nicht zuletzt erarbeitet er sich doch hier Grundlagen der Informatik. Das hilft für das spätere Verständnis von Hochsprachen wie C ebenso wie beim Debugging. Ich erlebe im Beruf als Informatiker immer wieder Leute die sich im Extremfall virtuelle Instanzen bei AWS zusammenklicken können, aber keinen Plan haben was Hexzahlen sind, geschweige denn auch nur Shellskripte verfassen können. Von Netzwerkgrundlagen will ich garnicht mehr sprechen. Es ist eine zunehmende "Krankheit", dass die Leute sich immer weniger mit den Grundlagen beschäftigen (wollen). Alles muss schnell schnell gehen, irgendwie hinwurschteln, Hauptsache es funktioniert (erstmal!). Aber wenn es mal nicht funktioniert sind sie hilflos. Neustart wird schon helfen. Oder ein anderes Tool/Plattform/Ansatz verwenden. Nur nicht zuviel Zeit vergeuden (sic!) um ins Detail zu gehen. Bernd: Beschäftige Dich ruhig mit den Grundlagen. ABER Du solltest überlegen ob Du ab einem gewissen Punkt wo Deine Projekte einen gewissen Umfang erreichen nicht doch lieber in eine höhere Sprache, z.B. C, wechseln willst. Du kannst auch C und ASM mischen (entweder inline oder auf Modulebene) um zeitkritische Sachen in ASM zu programmieren und den Rest in C. Ciao... Markus
toll von Markus formuliert! Alles muss schnell schnell gehen, irgendwie hinwurschteln, Hauptsache es funktioniert (erstmal!). Aber wenn es mal nicht funktioniert sind sie hilflos. Neustart wird schon helfen. Ich bin aus dem Schmunzeln nicht heraus gekommen. Mein logisches Denkvermögen (als Anfänger) wird vom Assembler ganz schön aufgeheizt. Grüße Rolf
Ok, das war etwas zu kompakt. Das wesentliche hast du ja schon verstanden, naemlich das ein Uebertrag stattfindet wenn die 2. Zahl "groesser" ist als die erste. Also K3>Rd3. Da das aber nur Nullen und Einsen sein koennen ist das K3=1 > Rd3=0. Oder logisch ( /Rd3 AND K3 ). Jetzt spielt aber noch der Uebertrag von der vorigen Stelle mit. Um das zu beruecksichtigen sind die anderen beiden Faelle (K3 AND R3) und (/Rd3 AND R3). Die folgende Tabelle zeigt alle moeglichen 8 Faelle fuer R3 = Rd3 - K3 - B3 mit dem entstehenden H-Flag. In jeder Spalte steht eine Addition fuer das 3. Bit. (eine Zeile ist also nicht wie oben ein ganzes Register und die Zahlen sind nicht im 2er-Komplement). Rd3 : 0 1 0 1 0 1 0 1 -K3 : 0 0 1 1 0 0 1 1 -B3 : 0 0 0 0 1 1 1 1 ------------------------------ R3 : 0 1 1 0 1 0 0 1 H : 0 0 1 0 1 0 1 1 *-----------*-------> /Rd3 AND K3 *--------------*----> K3 AND R3 *-----*-------------> /Rd3 AND R3 Ich hoffe das ist etwas verstaendlicher. Und ja, das ist genau dasselbe wie auch beim Carry Bit. Gruss
spess53 schrieb: > Aber in den Formeln beschreibt Rd den Inhalt dieses > Register vor der Ausführung und R den Inhalt nach der Ausführung der > Operation. > Ich nehme jetzt einfach mal an, das dieses ominöse R-Register einfach nur dazu dient, die Logikschaltung zu beschreiben. Habe mich noch mal mit der Leseprobe von Seite 13 ( Rechenwerk und Registersatz ) aus dem Buch von Günter Schmitt " Mikrocomputertechnik mit Controllern der Atmel AVR-RISC- Familie " beschäftigt und bin auf folgende mögliche Logikschaltung gekommen, die den Sachverhalt mit dem R-Register, dem H-Flag und der " Algebra bzw. Formel " als Logikplan veranschaulichen soll. K3 Rd3 Rd3 1100 | | XOR K3 1010 |---| | ------------- | [ XOR ] R 0110 | | AND K3 1010 |-| |_______ R ------------- | | H 0010 | | [ AND ] | H = /Rd3&K3 + K3&R3 + /Rd3&R3 | H + = ODER Josef schrieb: > Jetzt spielt aber noch der Uebertrag von der vorigen Stelle mit. > Um das zu beruecksichtigen sind die anderen beiden Faelle (K3 AND R3) > und (/Rd3 AND R3). > > Die folgende Tabelle zeigt alle moeglichen 8 Faelle fuer > R3 = Rd3 - K3 - B3 > > Vielen Dank, das hat mich erheblich im Verständnis weitergebracht, das ich mal behaupten möchte, das Du schon den SBCI-Befehl ( Subtract Immediate with Carry ) beschrieben hattest und das das hier " eher " den SUBI-Befehl. R3 = Rd3 - K3 Rd3 : 0 1 0 1 K3 : 0 0 1 1 ------------------ R3 : 0 1 1 0 H : 0 0 1 0 *------> /Rd3 AND K3 *------> K3 AND R3 *------> /Rd3 AND R3 Danke nochmals, das Ihr mich einen Schritt weiter gebracht habt. http://books.google.de/books?id=AI_HVUE0xYEC&pg=PA404&lpg=PA404&dq=at90s2313+sbi&source=bl&ots=Q_OQlfAY2Z&sig=MNcHMHf-7HfdceEva8SQDzgTzEw&hl=de&ei=vT7mSeK2GtfisAbc59GjCw&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q=rechenwerk&f=false Bernd_Stein
:
Bearbeitet durch User
Bernd Stein schrieb: > Da dies aber identisch mit der " Algebra " vom C-Flag ist - anstatt 7 > hier 3 - kann man dies dann nicht so betrachten, das das H-Flag nur dann > gesetzt wird wenn das Low-Nibble größer ist als das H-Nibble ? > *Nein, kann man nicht.* Das folgende Programm richtet sein Augenmerk auf den Zeitpunkt, an dem das H-Flag bei einer Subtraktion nicht gesetzt ist - also gelöscht. Da dies weniger oft vorkommt und bei der hexadezimalen Schreibweise auffällig bei $00; $10; $20; $30; $40; $50; $60; $70; $80; $90; $A0; $B0; $C0; $D0; $E0; $F0 geschieht. Man könnte also sagen, wenn das Low-Nibble nach einer Subtraktion Null ist, ist auch das H-Flag gelöscht. Das finde ich ist eine gute Eselsbrücke für das H-Flag bei der Subtraktion, da dies einfacher zu erkennen ist, als wann ein Borgen von Bit3 nicht erfolgte. In allen anderen Fällen erfolgte halt das Borgen von Bit3 und somit das setzen des H-Flags. Bernd_Stein
Bernd Stein schrieb: > Man könnte also sagen, wenn das Low-Nibble nach einer Subtraktion Null > ist, ist auch das H-Flag gelöscht. Das finde ich ist eine gute > Eselsbrücke für das H-Flag bei der Subtraktion, da dies einfacher zu > erkennen ist, als wann ein Borgen von Bit3 nicht erfolgte. > > In allen anderen Fällen erfolgte halt das Borgen von Bit3 und somit das > setzen des H-Flags. > Ich hatte es doch geahnt, das ich mich selbst verarschen werde. Da ich bei meinen Programmsimulationen bemerkt habe, das SUBI b,-1 nicht wirklich der Addition ADD b,a ( a = 1 ) entspricht, da die Flags unterschiedlich beeinflusst werden, habe ich auch bemerkt das meine Eselsbrücke nicht stimmt. Wenn man nämlich z.B. 2 subtrahiert, dann stimmt die Eselsbrücke nicht mehr. Bei der " wirklichen " Addition, also nicht wenn man mit SUBI und dem Zweierkomplement arbeitet, würde ich sagen wird das H-Flag immer dann gesetzt, wenn ein Übertrag an das High-Nibble erfolgt, also ein Überlauf des Low-Nibble. Bei der Subtraktion ist es wahrscheinlich so, das das H-Flag immmer dann gesetzt wird, wenn ein Borgen vom High-Nibble erfolgt, also ein Unterlauf des Low-Nibble. Aber auch das ohne Gewähr ;-) Bernd_Stein
@ Bernd Stein (bernd_stein) >Zweierkomplement arbeitet, würde ich sagen wird das H-Flag immer dann >gesetzt, wenn ein Übertrag an das High-Nibble erfolgt, also ein Überlauf >des Low-Nibble. Du hast es erfasst. Es heißt ja nicht umsonst "H"alf carry Flag. Dein Interesse für die Grundlagen in allen Ehren, aber gerade da H-Flag ist der Blinddarm des AVRs. Das habe ich in den letzten 15 Jahren AVR(Assembler) noch NIE gebraucht oder vermisst. Es gibt auch genügend CPUs, die haben gerade mal ein Z und C Flag, fertig. Und damit kann man problemmos auskommen. Ich vermute mal, dass selbst der avr gcc Compiler dieses Flag nie irgendwie nutzt.
Bernd Stein schrieb: > Bei der Subtraktion ist es wahrscheinlich so, das das H-Flag immmer dann > gesetzt wird, wenn ein Borgen vom High-Nibble erfolgt, also ein > Unterlauf des Low-Nibble. Falk Brunner schrieb: > Dein Interesse für die Grundlagen in allen Ehren, aber gerade da H-Flag > ist der Blinddarm des AVRs. Das habe ich in den letzten 15 Jahren > AVR(Assembler) noch NIE gebraucht oder vermisst. Ich denke ein Stichwort für den Sinn des H-Flags ist BCD-Arithmetik. Aus http://www.elektronik-bastelkeller.de/atmega8_sreg.html "H - Half Carry Flag Dieses Flag zeigt einen Half-Carry-Überlauf an, also einen Überlauf über 4-Bit hinaus. Es wird hauptsächlich für BCD-Verarbeitung benutzt." Zu BCD siehe z.B. http://de.wikipedia.org/wiki/BCD-Code
@ Alexander S. (alesi) >Ich denke ein Stichwort für den Sinn des H-Flags ist BCD-Arithmetik. >Aus http://www.elektronik-bastelkeller.de/atmega8_sreg.html Jo. Wobei die Frage ist, ob es von einem Compiler oder sonstwem (Libs) verwendet wird. Und wieviel schneller/kompakter wird der Code, wenn er das H-Flag benutzt anstatt der normalen Flags bzw. Befehle.
Alexander S. schrieb: > Ich denke ein Stichwort für den Sinn des H-Flags ist BCD-Arithmetik. > > Aus http://www.elektronik-bastelkeller.de/atmega8_sreg.html > > "H - Half Carry Flag > Dieses Flag zeigt einen Half-Carry-Überlauf an, also einen Überlauf über > 4-Bit hinaus. Es wird hauptsächlich für BCD-Verarbeitung benutzt." > Ich denke das trifft die Sache nicht richtig. Z.b. addiert man zu 16 eine 1 hinzu, dann kommt man über die 4-Bit ( 0-15 ) hinaus, aber das Half-Carry-Flag wird nicht gesetzt. Nur bei einem Übertrag von Bit 3 auf Bit 4 bei einer Addition wird das H-Flag gesetzt. Das trifft die Sache besser : http://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche#Half_Carry_.28H.29 Für die Subtraktion werde ich mir das so merken, das dies sich invertiert zur Addition verhält. Beim addieren komme ich mit dem H-Flag irgendwie besser zu recht. Die Einsatzgebiete für das H-Flag scheinen wirklich sehr eingeschränkt zu sein. Mir fällt zusätzlich eingentlich nur ein Zähler bis 16 ein. Bernd_Stein
Bernd Stein schrieb: >> Aus http://www.elektronik-bastelkeller.de/atmega8_sreg.html >> >> "H - Half Carry Flag >> Dieses Flag zeigt einen Half-Carry-Überlauf an, also einen Überlauf über >> 4-Bit hinaus. Es wird hauptsächlich für BCD-Verarbeitung benutzt." >> > Ich denke das trifft die Sache nicht richtig. > Z.b. addiert man zu 16 eine 1 hinzu, dann kommt man über die 4-Bit > ( 0-15 ) hinaus Nein, natürlich nicht. Denn schon die 16 ist ja in vier Bit überhaupt nicht darstellbar, sondern wird bestenfalls zu Null gewrapped. Und null plus ins ist natürlich eins. Kein Übertrag nötig.
Hi >Z.b. addiert man zu 16 eine 1 hinzu, dann kommt man über die 4-Bit >( 0-15 ) hinaus, aber das Half-Carry-Flag wird nicht gesetzt. Da ist ja auch kein Übertrag. Versuch mal 15 + 1. MfG Spess
spess53 schrieb: > Da ist ja auch kein Übertrag. Versuch mal 15 + 1. > Habe ich Dich jetzt auch schon total verwirrt ? Es geht um das Half-Carry-Flag und einer wirklichen addition und nicht um dieses SUBI a,-1 Konstrukt, das ja in Wirklichkeit eine Subtraktion ist, auch wenn sich das Ergebnis um eins erhöht. Im weiter oben genannten Buch von Günter Schmitt ist auf den Seiten 14 ( Paralleladdierer ) und Seite 15 ( add und sub => Ca = 0 ) gut zu erkennen wie die Addition und Subtraktion auf das Carry-Flag-Neu ( Cn ) und das Carry-Flag einer vorhergehenden Aktion ( Ca = Carry-Alt ) in Verbindung mit dem S steht. S => 0 bedeutet addieren, S => 1 bedeutet subtrahieren, dabei auch berücksichtigen das der Subtrahend dabei invertiert bzw. negiert wird. Leider ist das Half-Carry-Flag hierbei nicht dargestellt, aber es wird wohl genauso wie das Carry-Flag ( Cn ) vorher durch das S und und ein XOR beeinflusst. Bernd_Stein
HI >Habe ich Dich jetzt auch schon total verwirrt ? Wieso? Das H-Flag wird gesetzt wenn ein Übertrag vom unteren .auf das obere Nibble stattfindet. >Es geht um das Half-Carry-Flag und einer wirklichen addition und nicht >um dieses SUBI a,-1 Konstrukt, das ja in Wirklichkeit eine Subtraktion >ist, Ich auch. Teste mal einfach diesen Code:
1 | ldi r16, 14 |
2 | ldi r17,1 |
3 | |
4 | add r16,r17 |
5 | add r16,r17 ; nach diesem Befehl H-Flag gesetzt |
6 | add r16,r17 |
MfG Spess
spess53 schrieb:
1 | ldi r16, 14 |
2 | ldi r17,1 |
3 | |
4 | add r16,r17 |
5 | add r16,r17 ; nach diesem Befehl H-Flag gesetzt |
6 | add r16,r17 |
Das ist aber 14 + 1 + 1 + 1 und nicht 15 + 1 !!! Alexander S. schrieb: > "H - Half Carry Flag > Dieses Flag zeigt einen Half-Carry-Überlauf an, also einen Überlauf über > 4-Bit hinaus. Es wird hauptsächlich für BCD-Verarbeitung benutzt." > Ich meinte das man das evtl. so verstehen könnte, das alles was über 4-Bit ( 0-15 ) groß ist das H-Flag setzt. Aber es kommt eben nur darauf an, ob es zu einen Übertrag von Bit3 zu Bit4 kam und nicht das der Wert > 15 ist. Weil 17 ist > als 15, aber 16 + 1 setzt halt nicht mehr das H-Flag. Nicht wie bei dem N-Flag, das solange gesetzt ist wie die Zahl > ist als 127, also bei 128, 129, 130 usw. bis 255. Hoffe mich hiermit besser verständlich gemacht zu haben. Bernd_Stein
@ Bernd Stein (bernd_stein) >Das ist aber 14 + 1 + 1 + 1 und nicht 15 + 1 !!! Mensch Bernd, halt mal die Bälle flach! Ersten kannst du getrost davon ausgegehen, dass der spess53 schon weiß, was er da schreibt. Und Zweitens wollte er dir ein gutes Beispiel geben, an dem man sieht, wo sich das H-Flag NICHT ändert (nach dem 1. add) und wann es sich ändert ( nach dem 2. add) und wann es sich nicht mehr ändert (nach dem 3. add). Aber das scheint bei dir nicht angekommen zu sein. naja. >Nicht wie bei dem N-Flag, das solange gesetzt ist wie die Zahl > ist als >127, also bei 128, 129, 130 usw. bis 255. Hoffe mich hiermit besser >verständlich gemacht zu haben. Bernd, UNS musst das H-Flag und auch alle anderen kaum erklären . . .
Alexander S. schrieb: > Ich denke ein Stichwort für den Sinn des H-Flags ist BCD-Arithmetik. Diese Mühe macht sich aber heutzutage (fast) keiner mehr. Man läßt die CPU binär rechnen, weil sie das am besten kann (schneller und kompakter Code). Und nur zur Ausgabe für den Menschen macht man die Umwandlung nach dezimal. Die ganzen Math-Libs rechnen nur binär bzw. bei float nach IEEE 754.
Frohes Neues, ich hoffe Ihr könnt jetzt schon wieder klar denken. Das Statusregister bzw. die Flags machen mich wahnsinnig. Bin jetzt bei der Aufgabe A402. Ich hatte die Sache früher immer verdrängt, da ich immer Fehler gemacht hatte beim Auswerten der Flags H, S, und V. Da ich ja jetzt hoffentlich mit dem H-Flag zurecht komme, bleiben noch das S-Flag und das V-Flag übrig. Durch mehrmaliges durchdenken der Abläufe bei der Simulation der Aufgabe A402, dachte ich auch diese verstanden zu haben, aber bei der letzten Rechnung scheitere ich immer wieder.
1 | ldi a,190 |
2 | subi a,-90 |
Um wieder bei der Arbeitsweise eines µC zu bleiben, führe ich natürlich eine Addition mit dem Zweierkomplement durch.
1 | 1011 1110 $BE 190dez |
2 | +0101 1010 $5A 90dez |
3 | ---------- |
4 | C0001H1000 $18 24dez |
Das V-Flag wird ja gesetz wenn der Wertebreich 255 bis 128 ( $FF bis $80 ) unterschritten ( Bereich negativer Zahlen ) oder der Bereich 0 bis 127 ( $00 bis $7F ) überschritten ( Bereich positiber Zahlen ) wird. Also praktisch, wenn sich das N-Flag geändert hat. Warum wird dann hier nicht das V-Flag gesetzt ? Bernd_Stein
:
Bearbeitet durch User
mmhhh weiß nicht obs hilft. Das H-Flag wird ja von Prinzip her auch im dezimalen System gesetzt (borgen wie es ja schon gezeigt wurde) und zwar immer dann wenn die EINER-Stellen in die ZEHNER-Stellen wechseln. *EINER ~ 16er ' 8bitter #ZEHNER + 256er ^ 4bitter DEZ HEX BIN H-Flag #* +~ ' ' ' ' ^^^ 00 00 0000 0000 0 01 01 0000 0001 0 02 02 0000 0010 0 03 03 0000 0011 0 04 04 0000 0100 0 05 05 0000 0101 0 06 06 0000 0110 0 07 07 0000 0111 0 08 08 0000 1000 0 09 09 0000 1001 0 10 0A 0000 1010 0 1!! 11 0B 0000 1011 0 12 0C 0000 1100 0 13 0D 0000 1101 0 14 0E 0000 1110 0 15 0F 0000 1111 0 16 10 0001 0000 1 2!! 17 11 0001 0001 0 18 12 0001 0010 0 19 13 0001 0011 0 20 14 0001 0100 0 3!! 1!! dort würde der Mensch das FLAG setzen 2!! wird im BIN/Hex Zahlensystemen das FLAG gesetzt 3!! hier wie 1!! Bedenke das 8Bit erstmal erarbeitet werden musste vorher gab es nur 4bit-Rechner. Mehr Verständniss gibs im Net unter Halb/Volladdierer. selbst alte Milttärtechnik nutzt teilweise 3bit-Rechner... Bernd Stein schrieb: > kann man dies dann nicht so betrachten, das das H-Flag nur dann > gesetzt wird wenn das Low-Nibble größer ist als das H-Nibble ? NEIN das Low-Nibble kann niemals höher sein als das High-Nibble schaue er auf die Tabelle mit * und # . um es jetzt mal total zu übetreiben im DEZ einer, hunderter, tausender, zehentausender usw im HEX 16er, 256er, 4096er, 65536er usw im BIN 4bitter, 8bitter, 12bitter, 16bitter, usw
Markus M. schrieb: > Alles muss > schnell schnell gehen, irgendwie hinwurschteln, Hauptsache es > funktioniert (erstmal!). Solch eine Herangehensweise ist nicht unbedingt verkehrt, wenn man dann anfängt das aufzuarbeiten und sich anhand des funktionierenden Beispiels in die Materie einarbeitet. Gerade bei Mikrocontrollern und auch mit der damit verbundenen Elektronik, ist der weg weit und steinig. Wenn man dann nur ewig drüber liest und nichts wirklich sieht, verliert man schnell die Lust und erlernt man auch nicht die kleinen Stolperfallen, die aus schlechten Verbindungen kommen können. Ich hatte im Anfang mal eine Platine gebaut, nachdem ich schon einiges gemacht hatte, aber der Quarz wollte nicht schwingen. Alles ausprobiert, einen ganzen Tag lang, erst am nächsten Tag sah ich, dass ich 100nF am Quarz hatte. So was passiert mir sicher nicht wieder. Das ewige lernen von Grundlagen bring keinen am Anfang weiter. Erst die Kombination aus lernen und probieren bringt den Erfolg. Das ist jedenfalls meine Meinung. Ohne Arduino hätte ich den ganzen Mist in die Ecke geworfen. Jetzt habe ich gerade begonnen Assembler zu lernen.
F. Fo schrieb: > Jetzt habe > ich gerade begonnen Assembler zu lernen. > Hast Du da vielleicht ein paar Links in denen das mit den Flags geübt werden kann. Das heißt Aufgaben die dann auch erklärt werden ? Ich habe im Netz entweder immer nur eine kurze Beschreibung zu den Flags gefunden, oder gleich hammer Berechnungen mit Zeilenweise ASM-Befehlen. In dem Kurs geht es jetzt nämlich mit den Adressierungsarten weiter und ich denke ich brauch noch ein wenig Übung mit den Flags. Bernd_Stein
wie groß kann der wert in einem R denn werden ????? 255 ist max die dargestellt werden können.. was du machst ist ja eine addition über subtraktion das Problem ist dein Ergebniss ist halb richtig/falsch 190 + 90 = 280 $BE -(-$5a) = $118 das Problem ist das hier das CARRY nicht gesetzt wird..... Bernd Stein schrieb: > ich denke ich brauch noch ein wenig Übung mit den Flags. Mal dumm gefragt wie stellst du dir denn den Ablauf im CTRL, wie Flags gesetzt werden, vor? Also wie das erledigt wird ? http://de.wikipedia.org/wiki/Volladdierer http://www.emu-online.de/imd3kap2-1.pdf http://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche
chris schrieb: > Mal dumm gefragt wie stellst du dir denn den Ablauf im CTRL, wie Flags > gesetzt werden, vor? Also wie das erledigt wird ? > Was meinst Du mit CTRL ? Wahrscheinlich etwas mit " Control ". Es wäre schön wenn wenigstens zu Anfang einmal Abkürzungen erkläutert würden. Da halte ich mich ganz an dem Buch von Günter Schmitt Seite 20. http://books.google.de/books?id=AI_HVUE0xYEC&pg=PA404&lpg=PA404&dq=at90s2313+sbi&source=bl&ots=Q_OQlfAY2Z&sig=MNcHMHf-7HfdceEva8SQDzgTzEw&hl=de&ei=vT7mSeK2GtfisAbc59GjCw&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q=verschiebewert&f=false > > 190 + 90 = 280 > $BE -(-$5a) = $118 > > das Problem ist das hier das CARRY nicht gesetzt wird..... > Und was hat das jetzt mit dem V-Flag zu tun ? Ich habe da was zum V-Flag im Buch " AVR-RISC Mikrocontroller " von Wolfgang Trampert auf Seite 192 ganz unten gefunden : " Haben beide Operatoren verschiedene Vorzeichen ..., so kommt ein Überlauf nicht vor und das V-Flag wird rückgesetzt. Das erklärt warum das V-Flag nicht gesetzt ist, aber verstehen tue ich es noch nicht. Bernd_Stein
Bernd Stein schrieb: > verstanden zu haben, aber bei der letzten Rechnung scheitere ich immer > wieder. > > ldi a,190 > subi a,-90 > > Um wieder bei der Arbeitsweise eines µC zu bleiben, führe ich natürlich > eine Addition mit dem Zweierkomplement durch. > > 1011 1110 $BE 190dez > +0101 1010 $5A 90dez > ---------- > C0001H1000 $18 24dez > Die Rechnung für das V-Flag heißt nicht 190dez -(-90dez). 190dez ist für die Berechnung des V-Flags eine negative Zahl (Bit 7 gesetzt) Die Rechnung wäre also (-66dez)-(-90dez) = 24dez. Da das Ergebnis in 8 Bit paßt (Carry Flag=0) und auch kein Übertrag in das Bit7 stattgefunden hat (24dez paßt in 7 Bits, Bit 0 .. Bit 6) ist auch das V-Flag = 0. http://sandbox.mc.edu/~bennet/cs110/tc/orules.html
Bernd Stein schrieb: > Was meinst Du mit CTRL ? Controller Bernd Stein schrieb: >> 190 + 90 = 280 >> $BE -(-$5a) = $118 >> >> das Problem ist das hier das CARRY nicht gesetzt wird..... >> > Und was hat das jetzt mit dem V-Flag zu tun ? man man mal wieder richtig ins boxhorn jagen lassen... In diesen Fall leider nix weil ich anders gedacht habe... aber mit der Vorgabe hier kein Wunder. Bernd Stein schrieb: > ldi a,190 > subi a,-90 S-Flag, V-Flag.... du möchtest die Flags verstehn dann verstehe den digitalen Addierer. > " Haben beide Operatoren verschiedene Vorzeichen ..., so kommt ein > Überlauf nicht vor und das V-Flag wird rückgesetzt. > > Das erklärt warum das V-Flag nicht gesetzt ist, aber verstehen tue ich > es noch nicht. ob ich nun 1,2 + 1,2Ohm rechne oder 1,2Kohm + 1,2Kohm der Wert wird in beiden Bereichen der gleiche bleiben 2,4. Das selbe mit dem Minus wenn du weißt das du zwei negative Werte verarbeitest -90 - -9 = -81 kann man sich das minus sparen denn 90 - 9 = 81 unter der Beachtung das der Wert negativ bleibt Bernd Stein schrieb: > Ich habe da was zum V-Flag im Buch " AVR-RISC Mikrocontroller " von > Wolfgang Trampert auf Seite 192 ganz unten gefunden : kann keiner lesen ausser man ist angemeldet... So jetzt mal aber wie is denn dein Fortschritt, ohne Feedback kann keiner folgen, ausser es ist gewollt.
Bernd Stein schrieb: > Hast Du da vielleicht ein paar Links in denen das mit den Flags geübt > werden kann. Das heißt Aufgaben die dann auch erklärt werden ? Leider nicht, Bernd. Ich habe auch gerade erst begonnen. Die Bücher von Schwabl-Schmidt halte ich für ganz gut. Ich glaube der ist in seinen Büchern, über alle Bücher, bis in die tiefsten Tiefen gegangen.
:
Bearbeitet durch User
mh....das Buch "AVR-RISC Mikrocontroller von Wolfgang Trampert (Assembler) habe ich hier vor mir liegen. Ich wollte es für 17.-€ wieder los werden...keiner will es haben. Warum? Es ist für mich zu hoch geschrieben, also für jemand, der die Atmels nur für Steuerungszwecke benötigt..schade nichts für meine Anwendungen, auch auf der CD nichts! Dagegen mein dickes Buch von über 500 Seiten von Günter Schmitt (Oldenburg)verstehe ich sehr gut. Grüße Rolf
Hi, wie MaSehn bereits erklaert hat bedeutet 190dez fuer die ALU -66dez. Das MSB ist gesetzt -> negative Zahl -> steht im Register als 2er-Komplement. ---------------------------- Mein Tip: Mut zur Luecke. Wenn etwas einfach (auch nach einiger Muehe) nicht in den Kopf will, sollte man es einfach fuer einige Wochen beiseite legen. Man kann ein Buch/Skript auch erst einmal schlampig lesen und sich einen Ueberlick verschaffen und dann bei Bedarf in die Details gehen. Ich wuerde jetzt einfach weitermachen. Die Anwendung der Flags bei Addressierung / Jumps wird sich in Wohlgefallen aufloesen. Gruss
Josef schrieb: > Mein Tip: Mut zur Luecke. > Wenn etwas einfach (auch nach einiger Muehe) nicht in den Kopf will, > sollte man es einfach fuer einige Wochen beiseite legen. > So habe ich es ja bisher immer gemacht. Nur gehen dann leider Monate bis Jahre ins Land. Aber ich merke, das das wieder nicht in meinen Kopf mit dem V-Flag und dem S-Flag will. Es bleibt mir leider wieder nichts anderes übrig, als zu hoffen, das es beim Nächstenmal klappt. In der Praxis ist es auch noch nicht bei mir vorgekommen, das ich mit negativen Zahlen arbeiten musste. Auch das half leider nichts : http://rn-wissen.de/wiki/index.php/Assembler_Einf%C3%BChrung_f%C3%BCr_Bascom-User#.22S.22_und_.22V.22_Bit Immerhin scheine ich ja jetzt wenigstens das mit dem H-Flag begriffen zu haben. F. Fo schrieb: > Die Bücher von Schwabl-Schmidt halte ich für ganz gut. > Leider kann man nicht auszugsweise darin lesen und eine Büchersammlung über die AVR-µC wollte ich mir auch nicht zulegen. @Rolf H. Behalt es lieber, so schlecht ist es nämlich gar nicht. Es sei denn Du meinst das " Messen, Steuern und Regeln mit AVR-Mikrocontrollern " Buch von ihm, das finde ich nämlich auch viel zu Hoch. Falls Du doch mal unerwarterter Weise ein paar Fragen zum Buch von Günter Schmitt hast, kannst Du es ja hier posten : Beitrag "Buch AVR von Günter Schmitt durcharbeiten" Bernd_Stein
:
Bearbeitet durch User
@ Bernd Stein (bernd_stein) >> Wenn etwas einfach (auch nach einiger Muehe) nicht in den Kopf will, >> sollte man es einfach fuer einige Wochen beiseite legen. >So habe ich es ja bisher immer gemacht. Nur gehen dann leider Monate bis >Jahre ins Land. Aber ich merke, das das wieder nicht in meinen Kopf mit >dem V-Flag und dem S-Flag will. Es bleibt mir leider wieder nichts >anderes übrig, als zu hoffen, das es beim Nächstenmal klappt. Dann ist Programmieren vielleicht nicht das passende Hobby für dich. Oder ASM. Man kann auch mit BASCOM, C oder anderen Programmierspachen glücklich werden. >Immerhin scheine ich ja jetzt wenigstens das mit dem H-Flag begriffen zu >haben. Ein Phyrussieg. MfG Falk
Falk Brunner schrieb: > Dann ist Programmieren vielleicht nicht das passende Hobby für dich. Man, man, Falk! Auch wenn dieser Ron ein blö*** Pi**** ist, aber so langsam ist das aber nicht mehr so schön. So kenne ich dein Schreiben gar nicht. Was ist denn los? Wenn jemand das als Hobby erlernen will, da ist es doch scheiß egal, ob er sich schwer tut oder Koryphäe wird. Vielleicht wird er das sogar noch. Manch einer tut sich eben etwas schwerer, dem anderen fällt es leichter. Na und? Du bist bestimmt ein schlaues Kerlchen, das konnte ich in vielen Beiträgen von dir schon raus lesen, aber es gibt immer irgendein Gebiet, sei es in der Wildnis überleben müssen, in der dir ein anderer überlegen ist und du der depperte bist. Komm mal runter von dem hohen Roß! Du bist doch eigentlich ein netter Kerl.
@ F. Fo (foldi) >> Dann ist Programmieren vielleicht nicht das passende Hobby für dich. >Wenn jemand das als Hobby erlernen will, da ist es doch scheiß egal, ob >er sich schwer tut oder Koryphäe wird. Er muss kein Koryphäse sein oder werden, aber wenn das WIRKLICH so ist wie es geschrieben steht, >> Wenn etwas einfach (auch nach einiger Muehe) nicht in den Kopf will, >> sollte man es einfach fuer einige Wochen beiseite legen. >So habe ich es ja bisher immer gemacht. Nur gehen dann leider Monate bis >Jahre ins Land. Aber ich merke, das das wieder nicht in meinen Kopf mit >dem V-Flag und dem S-Flag will." Dann IST das schlicht eine sachliche Schlußfolgerung, ohne Anspruch auf Richtigkeit. Ich schrieb ja "vielleicht". Ist kein Anpissen oder sonstwas, nur eine nüchterne Einschätzung. Es gibt hier noch ein paar andere Leute, die ich ebenso einschätzen würde. Sie friemeln zwar immer wieder an Sachen rum, kommen aber scheinbar in ihrer Entwicklung der Programmierkenntnisse kaum vorran. Dinge, die sie eigentlich vor wochen schonmal halbwegs drauf hatten scheinen plötzlich wieder weg zu sein. Ist genauso wie wenn ich plötzlich die Liebe zum Eiskunstlaufen entdecken würde . . . > Vielleicht wird er das sogar noch. Der Text deutet etwas anderes an. > Manch einer tut sich eben etwas schwerer, dem anderen fällt es >leichter. Na und? Kein Thema. Siehe oben. >Du bist bestimmt ein schlaues Kerlchen, das konnte ich in vielen >Beiträgen von dir schon raus lesen, aber es gibt immer irgendein Gebiet, >sei es in der Wildnis überleben müssen, in der dir ein anderer überlegen >ist und du der depperte bist. Das sind gefühlt 99% aller Tätigkeiten dieser Welt. Nicht nur Eiskunstlauf ;-) >Komm mal runter von dem hohen Roß! Darum geht es gar nicht! Siehe oben! > Du bist doch eigentlich ein netter Kerl. Danke.
Falk Brunner schrieb: > Dinge, die sie eigentlich vor wochen schonmal halbwegs drauf hatten > scheinen plötzlich wieder weg zu sein. Falk, das kann ich erklären. Mir geht es auch oft so. Da ich nur wenig Zeit habe, auch nicht immer den Drive abends noch zu lernen, dann andere Sachen dazwischen kommen oder der Kopf einfach leer ist. Letzteres war bei mir durch äußere Einflüsse erst der Fall. Mein Sohn hatte einen sehr schweren Verkehrsunfall und mein Vater starb in dieser Zeit. Da ist einfach erstmal viel weg und nur noch Matsche im Kopf. Wenn ich jetzt anfange, dann fast wieder bei Null. Der Unterschied bei mir ist sicher der, dass ich mich dann eigentlich allein "durch beiße". Muss ja nicht Eiskunstlaufen sein, aber beim Schlittschuhlaufen kann ich dir gern behilflich sein und sollte noch mal ein Krieg kommen, stell dich hinter mich. :-)
Bernd Stein schrieb: > So habe ich es ja bisher immer gemacht. Nur gehen dann leider Monate bis > Jahre ins Land. Aber ich merke, das das wieder nicht in meinen Kopf mit > dem V-Flag und dem S-Flag will. Ich denke dein Hauptproblem ist, dass du da zu viel hineinliest. Grundsätzlich hast du bei einem add oder sub 2 Möglichkeiten entweder du fasst alles ohne Vorzeichen auf. D.h. die 8 Bit in einem Register kennzeichnen ausschliesslich positive Werte von 0 bis 255. Oder du fasst die 8 Bit in einem Register als Werte im 2-er Komplement auf. Dann hast du Zahlen zwischen -128 und +127. Ein und dasselbe Bitmuster kann also 2 verschiedene Zahlen darstellen. Welches davon gilt, entscheidest du, in dem du die Entscheidung triffst, ob das jetzt eine stink normale 8 Bit Zahl ohne Vorzeichen sein soll, oder ob die Regeln des 2-er Komplements anzuwenden sind und ein Bitmuster mit auf 1 gesetztem MSB als eine negative Zahl anzusehen ist. Der springende Punkt ist: Dem µC ist das Wurscht, wie du die Zahlen auffassen willst! Ob mit oder ohne Vorzeichen. Das geniale am 2-er Komplement ist, dass man es bei Addition und/oder Subtraktion nicht berücksichtigen muss, solange man einfach nur die Bits addiert/subtrahiert. Daraus folgt aber auch, dass man dazu keine eigenen Befehle braucht. Ein und derselbe ADD bzw. SUB Befehl kann sowohl als auch. Das einzige was unterschiedlich ist, ist die Art und Weise wie man die diversen Überläufe/Unterläufe feststellt. Solange du unsigned rechnest (also ohne Vorzeichen - 8 Bit in einem Byte - alle Bits für den numerischen Wert), ist das Carry Flag dafür zuständig, dir einen Überlauf/Unterlauf anzuzeigen. Das kann aber logischerweise bei einer Auffassung als 2-er Komplement Rechnung nicht mehr funktionieren. In dem Fall ist das V-Flag dafür zuständig. Und das S-Flag ist ganz einfach nur eine Kopie des MSB des Ergebnisses, zeigt also an ob das Ergebnis positiv oder negativ war - unter *der* Voraussetzung, das du überhaupt gewillt bist das ganze im Rahmen von 2-er Komplement als ein mit einem Vorzeichen behaftetes Ergebnis ansehen zu wollen. Ob du das Carry brauchst oder das Overflow-V-Flag hängt nur davon ab, ob du die Rechnung als mit oder ohne Vorzeichen ansehen willst.
:
Bearbeitet durch User
Karl Heinz schrieb: > Ein und dasselbe Bitmuster kann also 2 verschiedene Zahlen darstellen. > Danke erstmal, das Du Dir wieder einmal so viel Mühe gibst mir diese Dinge begreiflich zu machen. Und den Anderen möchte ich hiermit auch noch mal dafür danken. Ich habe den Thread noch mal ab da nachgelesen, wo es schon mit den logischen Verknüpfungen dazu kam, das das S-Flag gesetzt wurde. Beitrag "Re: AVR-Mikrocontrollertechnik-Kursus in Assembler besprechung" Und die Fragen werden immer mehr, um so mehr ich darüber nachdenke. Warum wird bei einer logischen Verknüpfung ein Flag gesetzt, das eigentlich für Rechenaufgaben mit negativen Zahlen gedacht ist ? Ich verstehe halt die ganzen Zusammenhänge nicht, die ich begreifen möchte. Klar kann ich mir " Formeln " merken wie z.B. S = N xor V, aber es ist mir nicht verständlich wie man darauf kommt. Oder wird eine positive und eine negative Zahl addiert, wird das V-Flag nie gesetzt. Oder wenn zwei positive Zahlen addiert werden und das Ergebnis größer +127 wird, ist das V-Flag geseztzt. Oder wenn zwei negative Zahlen addiert werden und das Ergebnis " kleiner " wird als -128 dann ebenfalls. Auch das man bei der Subtraktion der genannten Sachen einfach die Addition mit dem 2er-Komplement anwendet und dann einfach die Flags H, C invertiert. Wie das dann bei dem V-Flag und S-Flag zu handhaben ist, weiß ich nicht, vielleicht stimmt es auch schon nicht für das H und C-Flag, weil es nur zufälliger Weise bisher bei den Übungen hinhaute. Ich denke sowas wird im Normalfall auch nicht vermittelt, sondern immer nur das Endresultat und nicht der Weg wie es dazu kommt. Ich war nämlich schon sehr erstaunt, das das Addieren auf einer AND und XOR aufbaut. Ich denke es ist wirklich wieder einmal der Punkt gekommen, wo mein Gehirn erst die Zusammenhänge nach und nach Verknüpfen kann und zu viele neue Sachen einfach ausblendet. Also lass ich es beim " hoffentlich " verstandenem zu Stande kommen des H-Flags beruhen. Ich hoffe dieses Begreifen der Zusammenhänge kommt mit der Zeit. Bis zum nächsten Problem Bernd_Stein
Karl H. schrieb: > Das ein I/O Register oder sonst irgendeine Konfigurationsregister nichts > mit dem SRAM zu tun haben kann, zeigt sich doch schon daran, dass diese > Register ja alle irgendwelche Spezialfunktionen haben. > Ich sehe das zur Zeit etwas anders. Ich vermute das, das SRAM teilweise als Dual Port SRAM ausgeführt ist. Adressbereich $00-$1F. Es wäre schön, wenn mal jemand das Testprogramm auf einen ATMEL AVR µC debuggen könnte, ob wirklich die GPRs und I/O-Register manipuliert werden. Der ATmega8 hat leider keine Debug-Schnittstelle. Ich bin darauf gekommen, weil im Datenblatt des ATmega8 im Blockdiagramm zu sehen ist, das das SRAM einmal über diesen breiten Doppelpfeil und intern ( AVR CPU )die Verbindung zum INSTUCTION REGISTER hat. Und Dieses auch auf die GPRs und den INSTRUCTION DECODER.
1 | ; |
2 | ;Der Simulator legt nahe, das das SRAM teilweise als |
3 | ;Dual Port SRAM ausgefuehrt ist ( $0000-$001F ), wo die GPR |
4 | ;( General Purpose Register ) bzw. das Register File und die I/O-Register |
5 | ;auch ueber den " Haupt-Adressbus " angesprochen werden können. Dafuer spricht, |
6 | ;das die I/O-Register nach druecken des Reset-Buttons des Simulators auf ihre |
7 | ;Initaleinstellungen springen, die GPR aber ihren Wert behalten. Zum Beispiel |
8 | ;ist beim ATmega8 nach einem Reset das I/O-Register an Adresse $0020 |
9 | ;( TWBR = TWI Bit Rate Register ) komplett rueckgesetzt. Im I/O-Register an |
10 | ;Adresse $000B ( UCSRA = USART Control and Status Register) ist das Bit5 UCSRA |
11 | ;( UDRE = USART Data Register Empty ) jedoch gesetzt. Dies spricht dafuer das |
12 | ;das SRAM Teilweise mit zwei verschiedenen Adressbussen angesprochen wird. |
13 | ;Das sich die GPR und I/O-Register im unteren Adressbereich befinden, hat |
14 | ;wohl den Sinn des schnelleren und ein Byte einsparenden Vorteils, da die |
15 | ;Adressen von $00-FF nur ein Byte benötigen. Der Befehl STS ( Store direkt |
16 | ;to SRAM bzw. Data Space ) benoetigt zwei Takte ( Clocks ) und zwei Words und |
17 | ;macht hier sts $001F,r16 das gleiche wie ser r31 mit einem Takt und einem Word. |
18 | ;Der SER-Befehl ( Set all Bit in Register ) scheint auf einen anderen Adressbus |
19 | ;zuzugreifen, der nur 5 Bit fuer die Addressierung benoetigt bzw. 5 Adressbits |
20 | ;zur Verfuegung stellt ( SBI = Set Bit in I/O-Register ) Adressbreich $00-1F. |
21 | ; |
22 | _START: |
23 | ser r16 ;Alle Bits im GPR R16 setzen |
24 | sts $0000,r16 ;R16 in Adresse $0000 schreiben = GPR R0 |
25 | clr r0 ;Alle Bits im GPR R0 ruecksetzen ( loeschen ) |
26 | mov r0,r16 ;Alle Bits im GPR R0 wieder setzen ( SER und ... |
27 | ;LDI gehen nur ab R16 aufwaerts ) |
28 | sts $001F,r16 ;R16 in Adresse $001F schreiben = GPR R31 |
29 | clr r31 ;Alle Bits im GPR R31 ruecksetzen ( loeschen ) |
30 | ser r31 ;Alle Bits im GPR R31 wieder setzen |
31 | sts $0020,r16 ;Alle Bits im I/O-Register TWBR setzen |
32 | in r16,UCSRA ;Inhalt des I/O Registers UCSRA... |
33 | ;...USART Control and Status Register A... |
34 | ;...nach GPR R16 kopieren |
35 | cbi UCSRA,UDRE ;Dient hier nur der Verdeutlichung der I/O-Initalisierung |
36 | nop ;No OPeration, aber ein Taktzyklus |
37 | ; rjmp _START ; Relativer Sprung zum Anfang |
38 | ; |
Quelle Dual Port SRAM : http://www.idt.com/sites/default/files/709079%20-%201%20-%20Block%20Diagram.png Bernd_Stein
Bernd S. schrieb: > Ich vermute das, das SRAM teilweise als Dual Port SRAM ausgeführt ist. CPU-Register sind CPU-Register, kein SRAM, auch nicht Dualport. Dass man sie auch in den RAM-Adressbereich mappt (genauso wie die IO-Register) war einfach mal 'ne Schnapsidee damals. Hat sich offenbar nicht ernsthaft bewährt, kaum einer benutzt das Feature, sodass man es beim Xmega dann auch wieder rausgeworfen hat. Daher sind beim Xmega die IO-Adressen und die RAM-Adressen der IO-Register gleich. Mit der Initialisierung hat das rein gar nichts zu tun. IO-Register muss man halt zwingend beim Reset initialisieren, denn die Peripherie muss sich in einem reproduzierbaren Zustand befinden. Solch eine Initialisierung kostet in der Hardware Aufwand, daher macht man das nur, wo es nötig ist. Bei CPU-Registern und SRAM ist es nicht nötig. Dualport-SRAM gibt's beispielsweise bei den USB-AVRs, der kann sowohl von der CPU als auch vom USB-PHY aus zugegriffen werden.
Bernd S. schrieb: > Ich sehe das zur Zeit etwas anders. Wieso holst Du diesen angemoderten Thread wieder hoch? Das hast Du bereits am 30.01. dieses Jahres (erfolglos) probiert. Warum jetzt wieder? Fakten ändern sich nicht dadurch, dass Du irgendwas von Zeit zu Zeit anders siehst.
Jörg W. schrieb: > war einfach mal 'ne Schnapsidee damals Ich denke, das haben sie sich vom MCS51 rübergeholt. Da fand ich es ab und zu sehr praktisch, z.B. in Registerbank 2 schon mal einen Wert zu schreiben, mit dem die IRQ Routine, die diese Bank nutzte, dann rumwurschteln konnte. Da aber diese Bankumschaltung beim AVR nie realisiert wurde, braucht mans da eigentlich nicht.
Jörg W. schrieb: > CPU-Register sind CPU-Register, kein SRAM, auch nicht Dualport. > > Dass man sie auch in den RAM-Adressbereich mappt (genauso wie die > IO-Register) war einfach mal 'ne Schnapsidee damals. Hat sich offenbar > nicht ernsthaft bewährt, kaum einer benutzt das Feature, sodass man es > beim Xmega dann auch wieder rausgeworfen hat. Daher sind beim Xmega > die IO-Adressen und die RAM-Adressen der IO-Register gleich. > Aus dem Datenblatt des ATmega8(L) auf der Seite 12, wird sich zu dem General Purpose Register File schon mal so geäussert : " As shown in Figure 3, each register is also assigned a Data memory address, mapping them directly into the first 32 locations of the user Data Space. Although not being physically implemented as SRAM locations, this memory organization provides great flexibility in access of the registers, as the X-pointer, Y-pointer, and Z-pointer Registers can be set to index any register in the file. " Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Aus dem Datenblatt [...] Zugreifbarkeit über einen Adressraum impliziert keineswegs irgendein Design wie Dualport-RAM, ob du das nun wahrhaben willst oder nicht. Gegenbeispiel: die IO-Register sind auch alle über den RAM-Adressraum zugreifbar (die höheren ohnehin nur darüber), trotzdem wirst du vermutlich nicht auf die Idee kommen, dass bspw. das UART-Datenregister eine Dualport-RAM-Zelle wäre. Noch ein Gegenbeispiel: beim Xmega lässt sich auch der EEPROM über den RAM-Adressraum zugreifen. Ist er deswegen etwa Dualport-SRAM? Oder bei der Tiny-Architektur (ATtiny10 & Co.) lässt sich der Flash über den RAM-Adressraum zugreifen. Dualport-SRAM? Können wir den Uralt-Thread damit wieder in der Kiste versenken?
Jörg W. schrieb: > Können wir den Uralt-Thread damit wieder in der Kiste versenken? > Nein, der wird ja fortgeführt und steht praktisch erst am Anfang. Oder liebt ihr Moderatoren Datenmüll ? Ich habe schon so viele Threads gelesen, die von ein und dem selben Thema handelten, aber nie ein " sinnvolles " Ende zeigten. Bernd S. schrieb: > Aus dem Datenblatt des ATmega8(L) auf der Seite 12, wird sich zu dem > General Purpose Register File schon mal so geäussert : > Ich denke dieses " schon mal so geäussert " ist falsch verstanden bzw. von mir zu diesem Zeitpunkt verkehrt eingesetzt. Es zeigt eigentlich nur, das du in bezug auf CPU-Register recht hast. Aber ATMEL schreibt ja, das sie das Register File deshalb in den SRAM gespiegelt haben, damit auch diese über alle Adressierungsarten angesprochen werden können. Dieses " schon mal " sollte andeuten, das ich noch herausfinden will, warum auch die I/O-Register ins SRAM gespiegelt wurden. Wahrscheinlich aus dem selben Grund, aber dafür finde ich halt nichts schriftliches. Bernd_Stein
Bernd S. schrieb: > warum auch die I/O-Register ins SRAM gespiegelt wurden Weil man nur so alle Adressierungsarten zur Verfügung hat, bspw. über berechnete Zeiger. Der IO-Adressbereich kennt nur direkt im Opcode angegebene Adressen, daher ist er ja auch so klein (aber eben auch schnell). Später kam hinzu, dass mit wachsender Zahl von IO-Registern gar nicht mehr alle im separaten IO-Adressbereich unterzubringen waren.
Frank M. schrieb: > Wieso holst Du diesen angemoderten Thread wieder hoch? Jörg W. schrieb: > Können wir den Uralt-Thread damit wieder in der Kiste versenken? Habt Ihr keine anderen Probleme ??? Lasst doch die Leute hier diskutieren. Nix wird allein dadurch obsolet wenn mal eine zeitlang nichts zu einem Thema geschrieben wurde!
Rolf schrieb: > Habt Ihr keine anderen Probleme ??? Das Problem ist folgendes: Immer, wenn ein alter Thread aus der Versenkung geholt wird, dann beginnen die Leute, auf die ersten Beiträge des Threads zu antworten, ohne zu bemerken, dass gerade die ersten Beiträge längst obsolet sind. Dann werden teilweise ellenlange Beiträge mit Themen verfasst, die längst nicht mehr zur Debatte stehen. Die aktuell Antwortenden bemerken erst viel zu spät, dass sie sich die Arbeit umsonst gemacht haben, weil die ursprünglichen Verfasser längst nicht mehr mitlesen. Aber nicht nur hier wird Energie verschwendet: Wir Moderatoren müssen meist auch noch hinter den Schreibenden aufräumen, um den Thread letztendlich wieder in die richtige Bahn zu bekommen. Das ist einfach Arbeit. Daher mögen wir es nicht so besonders, wenn alte Threads wiederbelebt werden. Glücklicherweise ist dies wegen geringem Interesse hier in diesem Thread noch nicht passiert. Aber wenn es einmal losgeht, dann wirds richtig anstrengend. Stattdessen sollte der Verfasser besser einen neuen Thread aufmachen - evtl. mit einem Link zum alten Thread. Schau Dir einfach mal die ersten Beiträge und die letzten an. Die haben so gut wie nichts mehr miteinander gemein. Deshalb ist es im Zweifel immer besser, einen neuen Thread zu eröffnen.
:
Bearbeitet durch Moderator
Jörg W. schrieb: > Bernd S. schrieb: >> warum auch die I/O-Register ins SRAM gespiegelt wurden > > Weil man nur so alle Adressierungsarten zur Verfügung hat, bspw. > über berechnete Zeiger. Der IO-Adressbereich kennt nur direkt im > Opcode angegebene Adressen, daher ist er ja auch so klein (aber eben > auch schnell). > > Später kam hinzu, dass mit wachsender Zahl von IO-Registern gar nicht > mehr alle im separaten IO-Adressbereich unterzubringen waren. > Also aus dem selben Grund der für die GPR ( General Purpose Register bzw. Register File bzw. GPWR General Purpose Working Register ) angegeben wurde. Ich lasse es hiermit mal dabei beruhen, da ich nur etwas ähnliches gefunden habe, was aber auch keine befriedigende Antwort für mich darstellt, da es wohl auf den Prozessor eines IBM-PCs zugeschnitten ist. Hier unter I/O-Mapped nachzulesen : http://www.bjoern-koester.de/iogrundlagen/ Da ich ja nun mit dem ATMEL Studio 7.0.1188 arbeite, würde ich gerne mal wissen, wo ich die AVR-Definitionsdateien dort finde ( z.B. m8def.inc ) ? Frank M. schrieb: > Immer, wenn ein alter Thread aus der Versenkung geholt wird, dann > beginnen die Leute, auf die ersten Beiträge des Threads zu antworten, > ohne zu bemerken, dass gerade die ersten Beiträge längst obsolet sind. > Tja, dann sollten diese Leute lernen, wie im wirklichen Leben, erst den anderen aussprechen zu lassen, bevor sie ihm ins Wort fallen. Und ja, ich habe mir den ersten und alle weiteren Beiträge hier durchgelesen, weil ich diesen Kursus gerade nochmal von vorn beginne. Für mich ist dieser Thread somit schonmal wunderbar dafür geeignet zu sehen, was wirklich hängen geblieben, richtig verstanden worden ist und wo ich noch mal nachhaken sollte. Und Obsolet finde ich hier gar nichts, denn der ATmega8 bzw. mega32 ist nicht abgekündigt und auch die Programmiersprache Assembler wird noch genutzt. Ich finde es auch nicht schön, wenn die ursprünglichen Verfasser sich nicht mehr melden und somit der Thread zur Datenleiche gemacht wird. Gut, ich habe mich eine wirklich lange Zeit hier nicht zu Wort gemeldet, dennoch finde ich diesen Thread eine Bereicherung für Assembleranfänger. Eure Aufräumarbeit in diesem Thread finde ich nicht schlecht, aber warum lasst ihr so etwas übrig : Beitrag "Re: AVR-Mikrocontrollertechnik-Kursus in Assembler besprechung" Bernd_Stein
Bernd S. schrieb: > Da ich ja nun mit dem ATMEL Studio 7.0.1188 arbeite, würde ich gerne mal > wissen, wo ich die AVR-Definitionsdateien dort finde ( z.B. m8def.inc ) Ist abhängig von deinem Installationsverzeichnis. Gibt es auf deinem Rechner keine Suchfunktion für Dateien? Da müßtest du nur den Namen der Datei eingeben und suchen lassen.
Also, ich mache das bei Win7 Home Premium so : Linksklick auf das Windowslogo, dann in dem Feld "Programme/Dateien durchsuchen" schreibe ich " .inc ", aber keine AVR-Definitionsdateien werden gefunden. Bernd_Stein
Dann wühl dich da mal durch. https://www.windowspro.de/wolfgang-sommergut/keine-dateien-gefunden-suche-windows-7-richtig-konfigurieren
Bernd S. schrieb: > Also, ich mache das bei Win7 Home Premium so : > > Linksklick auf das Windowslogo, dann in dem Feld "Programme/Dateien > durchsuchen" schreibe ich " .inc ", aber keine AVR-Definitionsdateien > werden gefunden. Also bei mir liefert schon die ganz normale, nicht weiter konfigurierte Suche von Windows7 nach "*.inc" ca. 6000 Hits und natürlich sind da auch alle diese AVR-Asm-Includes dabei... Allerdings: Wenn ich wirklich mal was suchen muss (was eher selten vorkommt), dann würde ich wohl niemals diese unsägliche Windows-Suche benutzen... Die wurde von MS bis zur praktischen Unbenutzbarkeit massakriert. Du findest nur das, was Microsoft meint, das du finden solltest. Man will ja keinen DAU überfordern. Der könnte ja durch die Menge der Suchtreffer in den Suizid getrieben werden...
Bezug nehmend auf die letzten Postings: Die kastrierte Windows-Suchfunktion hat mich schon vor einiger Zeit genötigt, Fremdprogramme einzusetzen, als da wären z.B. "SearchMyFiles".
wühlmaus schrieb: > Dann wühl dich da mal durch. > > https://www.windowspro.de/wolfgang-sommergut/keine-dateien-gefunden-suche-windows-7-richtig-konfigurieren > Danke Wühlmaus, habs geschafft. Bernd_Stein EDIT: Im Beitrag "Weigu AVR-Assemblerkurs Modul A" gehts weiter
:
Bearbeitet durch Moderator