- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Atmega 8 verzögerungsschleifen?

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240

    Atmega 8 verzögerungsschleifen?

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo wie ihr seht bin ich neu hier, will zuerst kurz was über mich sagen. ich habe eine Ausbildung zum Elektromechaniker gemacht und hab als Servicetechniker gearbeitet. Nun habe ich gerade angefangen in Konstanz Wirtschaftsingenieurwesen Elektrotechnik zu studieren.

    So nun zu meiner eigentlichen Frage:

    Ich beschäftige mich schon einige Zeit mit dem Atmega8 und bin über das LED lauflicht Stadium hinaus... Jetzt will ich ein LCD Display ansteuern. Ich habe mir dazu die LCD Routines von www.mikrocontroller.net besorgt. Dort sind die Schleifen für die Verzögerung aber auf ein 4 MHz Takt ausgelegt. Ich habe auf meinem Board aber ein 12 MHZ Quarz. wie kann ich die Werte die in das Register geladen werden nun umrechen? Ich häng die Schleifen einfach mal an damit ihr das seht. Außerdem würde ich gerne wissen was das "$" Zeichen bedeutet. Ich hab bis jetzt nämlich einfach immer Binäre Werte oder eben Dezimale Werte in die Register geladen.

    Vielen Dank schonmal im Voraus!!!

    MFG

    Mr Bean

    delay50us: ;50us Pause

    ldi temp1, $42
    delay50us_: dec temp1
    brne delay50us_
    ret ;wieder zurück

    delay 5ms: ;5ms Pause

    ldi temp1, $21
    WGLOOP0: ldi temp2, $C9
    WGLOOP1: dec temp2
    brne WGLOOP1
    dec temp1
    brne WGLOOP0
    ret ;wieder zurück

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    "$" das ist hexadezimal. $42 ==> 4*16^^1 + 2*16^^0 ==> dez. 66

    Bei solchen Schleifen werden Maschinenzyklen verbraten.
    Bei 4 MHZ sollten es für 50 µS also 50*4 --> 200 Zyklen sein.
    Und dazu mußt du du Zyklen jedes Befehls in der schleife zusammenrechnen

    LDI temp1, $42 ---> 1 Zyk.
    delay50uS:
    DEC temp1 ---> 1 Zyk.
    BRNE delay50uS springen 2 Zyk, nicht springen 1 Zyk
    d.h. 1 * 2 + (temp1-1) * 3

    insgesamt also
    1 + 2 + 65 * 3 --> 197 Zyklen

    FÜr 12 MHZ brauchst du offenbar 3-mal soviele Zyklen. Also, Bleistift raus und rechnen
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Gast
    Vielen Dank erstnal für die Antwort! Hab meine Schleifen jetzt um gemodelt. Das sollte nun eigentlich ncihtmehr das Problem sein. Trotzdem bin ich so langsam am verzweifeln. Versuche den ganzen Tag schon dieses Display zum laufen zu bekommen. Aber es will nicht wie ich will. Ich hab jetzt mal meinen Code angehängt. Wie das Display an den Controller angeschlossen ist steht auch da drin. Vielleicht kann mir ja jemand weiterhelfen. Würde mich sehr freuen.

    MFG

    Mr Bean

    Code:
    .include "m8def.inc"
    
    .def temp1 = r16
    .def temp2 = r17
    .def temp3 = r18
    
    			ldi temp1, LOW(RAMEND)		;LOW-Byte der obersten RAM-Adresse
    			out SPL, temp1
    			ldi temp1, HIGH(RAMEND)		;High-Byte der obersten Ram-Adresse
    			out SPH, temp1
    
    			ldi temp1, 0xFF				;PortB=Ausgang
    			out DDRB, temp1
    
    			rcall lcd_init				;Display initialisieren
    			rcall lcd_clear				;Display löschen
    
    			ldi temp1, 'T'				;Zeichen anzeigen
    			rcall lcd_data
    
    			ldi temp1, 'e'
    			rcall lcd_data
    
    			ldi temp1, 's'
    			rcall lcd_data
    
    			ldi temp1, 't'
    			rcall lcd_data
    
    loop:
    			rjmp loop
    
    
    
    ; LCD Routinen
    
    ;4-Bit Interface
    ;BDB4-BDB7: PB0 - Pb3
    ;RS: PB4
    ;E: PB7
    
    ;sendet ein DAtenbyte an das LCD
    
    lcd_data:
    			mov temp2, temp1			;"Sicherungskopie" für die Übertragung des zweiten Nibbles
    			swap temp1					;vertauschen
    			andi temp1, 0b00001111		;oberes Nibble auf 0 setzen
    			sbr temp1, 1<<4				;entspricht 0b00010000
    			out PORTB, temp1			;ausgeben
    			rcall lcd_enable			;Enable-Routine aufrufen
    
    
    			andi temp1, 0b00001111		;obere Hälfte auf null setzen
    			sbr temp2, 1<<4				;entspricht 0b00010000
    			out PORTB, temp2			;ausgeben
    			rcall lcd_enable			;enable routine aufrufen
    			rcall delay50us			;Delay routine aufrufen
    			ret							;zurück zum Hauptprogramm
    			
    ;sendet einen Befehl an das LCD
    
    lcd_command:							;wie lcd_data, nur ohne RS zu setzen
    
    			mov temp2, temp1				
    			swap temp1	
    			andi temp1, 0b00001111
    			out PORTB, temp1
    			rcall lcd_enable
    			andi temp2, 0b0001111
    			out PORTB, temp2
    			rcall lcd_enable
    			rcall delay50us
    			ret
    
    ;erzeugt den Enable-Puls
    
    lcd_enable:
    
    			sbi PORTB, 7				;Enable high
    			nop							;6 Taktzyklen warten
    			nop
    			nop
    			nop
    			nop
    			nop
    			nop
    			nop
    			nop
    			cbi PORTB, 7				;Enable wieder low
    			ret							;wieder zurück
    
    ;Pause nach jeder Übertragung
    
    delay50us:								;50us Pause
    
    			ldi  temp1, $E9
    WGLOOP0:  	dec  temp1
              	brne WGLOOP0
    			ret							;wieder zurück
    
    ;Längere Pause für manche Befehle
    
    delay5ms:								;5ms Pause
    
    			ldi temp1, $8F
    WGLOOP2:	ldi temp2, $E7
    WGLOOP3:	dec temp2
    			brne WGLOOP3
    			dec temp1
    			brne WGLOOP2
    
    			ldi  temp1, $01
    WGLOOP4:  	dec  temp1
              	brne WGLOOP4
    
    			ret							;wieder zurück
    			
    ;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
    
    lcd_init:
    			ldi temp3,50
    powerupwait:
    			rcall delay5ms
    			dec temp3
    			brne powerupwait
    			ldi temp1, 0b00000011		;muss 3 mal hintereinander gesendet werden zur Initialisierung 
    			out PORTB, temp1			;1
    			rcall lcd_enable
    			rcall delay5ms
    			rcall lcd_enable			;2
    			rcall delay5ms
    			rcall lcd_enable			;3
    			rcall delay5ms
    			ldi temp1, 0b00000010		;4Bit Modus einstellen
    			out PORTB, temp1
    			rcall lcd_enable
    			rcall delay5ms
    			ldi temp1, 0b00101000
    			rcall lcd_command
    			ldi temp1, 0b00001100
    			rcall lcd_command
    			ldi temp1, 0b00000100
    			rcall lcd_command
    			ret
    
    ;sendet einen Befehl zur Löschung des Displays
    
    lcd_clear:
    
    			ldi temp1, 0b00000001		;Display Löschen
    			rcall lcd_command
    			rcall delay5ms
    			ret

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    Also LCD's bringen mich eigentlich auch immer zum verzweifeln. Habe es zwar über die parallele Schnittstelle und einen PC-Programm geschafft Schrift auszugeben, aber mit dem µC noch nicht.

    Schreib mal bitte welches LC-Display du hast, weil manche mit der Routine von Mikrocontroller.net nicht funktionieren. Das Problem hatte ich nämlich auch und habe mich sehr lange daran versucht.

    Aber dieses Problem, welches hier angesprochen wurde, muß doch irgendwie zu beheben sein. Meistens hat man ja nicht ausreichend Timerinterrupts und Schleifen sind auch eher unschön. Gibt es keine bessere Möglichkeit?

    Wäre es möglich mit einem Programm die Timerzeiten immer neu zu berechnen und den Timer neu einzustellen.
    Beispiel:
    Aufgabe 1: Interrupt soll nach zwei Minuten auslösen
    neue Aufgabe 2 kommt nach einer Minute hinzu und soll nach 30sek den Interrupt auslösen.

    Dadurch muß der Timerwert nach einer Minute von einer Minute Restzeit auf 30sek gestellt werden und nach Ablauf von Aufgabe 2 die letzten 30sek wieder in den Timerwert geschrieben werden, damit die Zeit für Aufgabe 1 weiterläuft.
    Vielleicht geht es eleganter, indem man einen externen Takt zählt, der halt nicht 12MHz beträgt.

    Dieses Schleifenproblem wird mit steigender Frequenz immer größer und deswegen sollte man hierfür vielleicht eine Lösung finden.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    38
    Beiträge
    4.255
    Ein kleines Programm, um die Verzögerungsschleifen zu berechnen:
    http://www.elektronik-projekt.de/inc...&contentid=183

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Der sauberste Weg Leerlaufzeiten zu überbrücken ist übrigens über einen Timer .....

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    das denke ich auch, aber davon hat man leider nicht unbegrenzt viele und wenn man den Takt nicht in Form von ca. 1KHz extern bereitstellt, dann wird man leider auch bei Zeiten von einigen Sekunden auf Registerinkrementieren zurückgreifen müssen, wodurch der Timerinterrupt mehrmals auslöst. Das ist auch nicht gerade optimal. Vielleicht gibt es ja Timer-IC's die 30 Timer beinhalten und die man über I2C beschreiben kann, damit der µC seine Rechenkapazität an Schleifen verschwenden muß.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Hallo

    Vielen Dank nochmal für die Antworten. Zuersteinmal es ist ein 2 Zeilen Display mit 16 Zeichen. Ich hab es bei Reichelt gekauft und es scheint von Displaytech zu sein. Als IC ist ein KS0070B.PCC drauf. Denke aber eher nicht daß das Problem beim Display liegt. Wohl eher an der Software... Naja Die Diskusion um die Schleifen ist ja nicht schlecht. Ich weiß auch, daß das nicht gerade die sauberste Art ist zu programmieren. aber im Moment will ich eigentlich nur mal soweit kommen daß ich ein paar Zeichen auf dem Display erscheinen lassen kann. Und das sollt sich doch eigentlich so machen lassen. Ich weiß so langsam aber echt nichtmehr wo der Fehler noch liegen könnte... Gibt es eine Möglichkeit zu Testen Ob die Hardware (Display) defekt ist? Wenn ich das Display an µC anschließe, dann erscheint ein schwarzer Balken in der ersten Zeile. Ich hoffe da immernoch etwas auf euch...

    MFG

    Bean

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    Also ich habe ein LCD von Electronic Assembly. EA DIP204-4NLED (Reichelt: LCD 204 DIP) mit einem KS0073 Kontroller drauf und bei dem funktioniert die Mikrocontroller.net-Ansteuerung NICHT. Bei dem muß ich andere Timings verwenden oder andere Befehle benutzen.
    Habe mir dann von Pollin noch ein anderes günstiges Display geholt; WDC2704M und bei dem soll angeblich die Ansteuerung funktionieren.
    Das dein Display schwarze Zeilen anzeigt ist ein gutes Zeichen, denn das tut er, wenn er nicht richtig initialisiert wurde.
    Also am besten mal deinen Code mit dem Datenblatt des Displays vergleichen und schauen, ob die Warteschleifen richtig sind und die Befehle auch richtig sind.

    Durchmessen kann man eher schlecht. Könntes den Stromverbrauch messen. Wenn der zu hoch ist, dann ist das Display wohl defekt (Größenordnung 1A wurde mir von EA gesagt). Aber das schliesse ich eher aus.
    Was ich nicht ganz verstehe ist, warum ich wenn ich nur Spannung und Kontrastspannung anlege, auf unterschiedlichen Leitungen etwas messe. Die Leitungen muß ich ja mit dem µC ansteuern und wie soll das gehen, wenn auf einigen Leitungen schon Spannung vorhanden ist. Das verwundert mich bei beiden Displays.
    Habe die Displays erstmal in die Kiste geworfen weil ich mir nicht länger die Zähne daran ausbeissen möchte. Wenn du eine funktionierende Routine hast, dann poste mal bitte den Code. Vielleicht läuft er ja auch auf meinen LCDs
    Man weiss ja dummerweise auch nie, an welcher Stelle der Fehler ist.

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    40
    Beiträge
    240
    Hallo

    Ich glaube mir ist gerade etwas eingafallen wo der Fehler liegen könnte. Und zwar betreibe ich das LCD ja im 4-Bit Modus. dann muss ich doch bei der Initialisierungs routine die nibbles (4Bit) der Datenwörter auch erst vertauschen? (siehe oben in meinem Code) Hab jetzt grad leider keine Zeit zum das zu probieren, werd am Wochenende hoffentlich dazu kommen. Wenn mir jemand diesen Fehler bestätigen könnte wäre das natürlich auch klasse...

    MFG

    Bean

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests