Warum schreibt man z.B. LCD_PORT &= ~(1<<LCD_RS) und nicht LCD_PORT &= (0<<LCD_RS) Ich bin übrigens sehr froh, dass ich vorher in Assembler unterwegs war, da z.B. in den lcd_routines.c oder .h oft das pinning des Displays am µC versteckt ist. LG Rudi
Wenn du Assemblererfahrung hast, dann weisst du doch welcher binäre (oder hex) Wert du möchtest. Schreib dir doch mal auf welcher Wert in das Register soll und was bei den Varianten rauskommt: ~(1<<LCD_RS) (0<<LCD_RS) Dann siehst du selbst was richtig ist und warum. Nimm Papier und Bleistift und gehs durch, so wie Karl Heinz das immer propagiert, da ist der Lerneffekt am nachhaltigsten
Hallo Mal dir das ganze doch mal auf, was da passiert. Dann fällts dir wie Schuppen aus den Haaren. Gruß Joachim
Hallo, tolle Antworten bis jetzt... Du musst Schritt für Schritt vorgehen: 1. (1<<LCD_RS) wird bearbeitet: "Die 1 um LDC_RS Stellen nach links schieben" Beispiel: aus 1 wird 00100 wenn LDC_RS = 2 ist. 2. Das ganze wird durch die Tilde bitweise negiert. Aus 00100 wird z.B. 11011 Wenn Du unter 1. eine 0 nach links verschiebst, kommt eben auch 0 raus. Viele Grüße
Antworter schrieb: > Hallo, > > tolle Antworten bis jetzt... > > Du musst Schritt für Schritt vorgehen: > 1. (1<<LCD_RS) wird bearbeitet: "Die 1 um LDC_RS Stellen nach links > schieben" > Beispiel: aus 1 wird 00100 wenn LDC_RS = 2 ist. > 2. Das ganze wird durch die Tilde bitweise negiert. Aus 00100 wird z.B. > 11011 > > Wenn Du unter 1. eine 0 nach links verschiebst, kommt eben auch 0 raus. Und genau darauf wäre er auch gekommen, wenn er das selber mit Papier und Bleistift durchgespielt hätte. Nur mit einem Unterscheid: Er hätte es nie wieder vergessen, weil er selber drauf gekommen ist. Einziger Nachteil: Es hätte 3 Minuten länger gedauert, bis er begriffen hat, dass er das Bitmuster 0000 0000 so oft er will um x Stellen nach links verschieben kann und sich nichts ändert.
Hallo, @Karl Heinz Buchegger: Ich gehe schon davon aus, dass hier nicht jeder aus jux und tollerei Fragen stellt. Wenn er dann seine Frage vernünftig formuliert hat, finde ich es gelinde gesagt albern, ihm keine vernünftige Antwort zu geben. Das kann jeder sehen wie er will. Eine ordentliche Antwort muss man dann auch nicht unbedingt noch kommentieren. Man kann seine persönliche Meinung auch für sich behalten... Fazit: Wer gut fragt bekommt auch gute Antworten. Viele Grüße
Rudi D. schrieb: > Ich bin übrigens sehr froh, dass ich vorher in Assembler unterwegs war, > da z.B. in den lcd_routines.c oder .h oft das pinning des Displays am µC > versteckt ist. Das Pinning sollte niemals im Code versteckt sein, sondern an zentraler Stelle definiert werden, z.B. im "main.h" oder "hardware.h". http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296 In dem Beispiel sieht man auch sehr schön, wie man sich diese umständliche Schieberei-Schreibweise ersparen kann. Ein Pin wird dann einfach als Bitvariable angesehen. Peter
So hab ich's in Assembler gemacht
1 | ;create enable pulse 5 cycles auf 1 macht 0,75 us ändert kein Register |
2 | ;mit fallender Flanke werden Daten übernommen |
3 | lcd_enable: |
4 | sbi LCD_PORTB, PIN_E ;2; Enable high |
5 | nop |
6 | nop |
7 | nop |
8 | cbi LCD_PORTB, PIN_E ;2; Enable low |
9 | rcall delay50us ;ab H>L Enable braucht das Display 38 us |
10 | ret ;bis es wieder bereit ist |
in C sieht es so aus (nur abgeschrieben)
1 | // erzeugt den Enable-Puls
|
2 | void lcd_enable(void) |
3 | {
|
4 | LCD_PORT |= (1<<LCD_EN1); |
5 | _delay_us(10); // kurze Pause |
6 | // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
|
7 | // http://www.mikrocontroller.net/topic/80900
|
8 | LCD_PORT &= ~(1<<LCD_EN1); |
9 | }
|
Für mich, dachte ich, sollte das ident sein. cbi LCD_PORTB, PIN_E == LCD_PORT &= ~(1<<LCD_EN1) == LCD_PORT &= (0<<LCD_EN1) Mit cbi ändere ich ja nur den Status des Enable_pins und sonst kein anderes Bit des LCD_PORTs. Ich dachte dass &= ~(1<<LCD_EN1); auch nur dieses Bit ändert und nicht gleich alle Bits des Ports beeinflusst. Deshalb gefällt mir die Lösung von peda in avr.freaks, weil für mich nicht mißverständlich. O.k. die Sache ist geklärt. LG Rudi
Das hier ist noch einfacher zu verstehen, für mich fast wie Assembler, wieder am Beispiel des
1 | void lcd_enable(void) |
2 | {
|
3 | sbi (LCD_PORT, LCD_PIN_E); |
4 | cbi (LCD_PORT, LCD_PIN_E); //wenn die Pulsdauer stimmt |
5 | }
|
6 | |
7 | #define sbi(PORT, bit) (PORT|=(1<<bit)) // set bit in PORT
|
8 | #define cbi(PORT, bit) (PORT&=~(1<<bit))// clear bit in PORT
|
9 | #define LCD_PORT PORTD
|
10 | #define LCD_DDR DDRD
|
11 | #define LCD_PIN_RS 0
|
12 | #define LCD_PIN_E 3
|
auch abgeschrieben. Wie bekommt man die Ausführungszeiten in C heraus. Ist ja in Assembler höchst einfach. Da ist, wie von peda schon gesagt, die Bitschieberei nur 1x nötig zu definieren. Ich nähere mich halt langsam und verstehe, dass die Version auf AVR-freaks viel umfassender ist.
Rudi D. schrieb: > Wie bekommt man die Ausführungszeiten in C heraus. Ist ja in Assembler > höchst einfach. Erstmal rechnet ein Compiler alle Konstanten schon zur Compilezeit aus, d.h. das ~ und << erzeugt keinen Code. Und dann schlägt der Optimierer zu und erkennt, daß nur ein Bit gesetzt/gelöscht wird und die Adresse im Bereich der Bitbefehle liegt. Er mach also ein SBI/CBI daraus. Das geht aber nicht immer, die größeren AVRs haben auch Ports im Memory-Bereich. Dann muß er LDS+ANDI/ORI+STS nehmen. Muß man aber in Assembler auch. Peter P.S.: Ich hab mir die Schreibarbeit noch etwas vereinfacht und alle Ports in der sbit.h definiert: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=835728#835728
Rudi D. schrieb: > Wie bekommt man die Ausführungszeiten in C heraus. Am besten, indem du den vom Compiler genrierten Assembler-Code anschaust, denn ... > Ist ja in Assembler höchst einfach.
Peter Dannegger schrieb: > Ich hab mir die Schreibarbeit noch etwas vereinfacht und alle Ports in > der sbit.h definiert: > > http://www.avrfreaks.net/index.php?name=PNphpBB2&f... Habe 2 sbit.h gefunden 300 byte und 9,5kByte, die eine ein Teil der anderen. Da blicke ich noch nicht durch, zu neu für mich, to date. In C scheint's ja viele legale Möglichkeiten zu geben dasselbe Ziel zu erreichen. Weiss auch noch nicht was C allg. Statements sind und AVR extra ergänzt hat. Geschützte Bezeichnungen etc. Na ja, klein anfangen eben. Verschiedene Sachen von mir sind bei Burkhard K's Labor zu finden. Das war aus Not, dieses allererste Projekt, www.b-kainka.de/ELO/rc5trans.pdf LG Rudi
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.