- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Atmega16 Rechtecksignal ausgabe!!!

  1. #1

    Atmega16 Rechtecksignal ausgabe!!!

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen!

    Ich muss ein Programmentwickeln, das auf dem Ausgabepin C0 ein Rechtecksignal ausgibt,
    dessen Periodendauer in Millisekunden über den am 8–Bit–Eingabekanal PortA anstehenden
    Wert festgelegt werden kann: Liegt dort z.B. der Wert 0000 0101 entsprechend
    dezimal 5 an, so soll die Periodendauer ca. 5 msec betragen. ¨Anderungen am Eingabekanal
    sollen sich ohne Neustart des Programms direkt auswirken.

    ach ja und dann noch ein Unterprogramm, das eine Zeitverzögerung von exakt 1msec erzeugt.
    Die Ausführungszeiten der benoetigten CALL und RETURN Befehle sollen dabei mit
    berücksichtigt werden.

    Kann mir hier vielleicht einer helfen, leider komm ich damit garnicht weiter...

    muss in assembler programmieren,und leider bin in noch ganz frisch in diesem thema

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Also ich würd das mit dem Rechtecksignal mit einem Comparematch Interrupt mit dem Timer1 machen.
    Wenn Du die Taktfrequenz geschickt auswählst Ich würd vermutlich 8 MHz nehmen kommst Du auf deine gewünschte Periodendauer.

    In das Comparematch Vergleichsregister trägst du je nach gewünschter Periodendauer den Vergleichswert ein (Tabelle oder den Controller rechnen lassen). Der Vergleichswert sollte der halben Periodendauer entsprechen, weoil Du ja eine positive und eine negative Halbwelle brauchst.

    Wenn dann der Timer diesen Wert erreicht hat löst er einen Comparematch Interrupt aus. Der interne Timer wird wieder auf 0 gesetzt, was man auch durch setzen eines Bits machen kann.
    In der gleichen Routine wird dann dein Port C0 von 0 nach eins bzw. von 1 nach 0 gesetzt.

    Die Abfrage von deinem Eingangsport PortA sowie die Neubeschreibung der Comparematchwerte würd ich auch in dieser Interrupt Routine machen um Überholeffekte zu vermeiden.

    Ob Du die Abfrage von PortA, sowie die Berechnung des Comparematchwertes in den Interrupt reinkriegst ist vor allem ein Timingproblem. Vor allem wenn eine Periodendauer von 1mS = 0,5mS für eine halbe Periode gefordert wird.

    Während des Schreibens der Comparematchwerte in ein Hilfsregister, das dann später in der Comparematch Routine abgefragt wird würd ich mit "CLI" eine Interruptausführung kurz unterbinden um zu Vermeiden, das zwischen dem Schreiben der beiden Bytes ein Interrupt auftreten kann.

    Wie genau diese Routine arbeitet ist hauptsächlich davon abhängig wieviele andere Interrupts auch noch aktiv sind, weil ein aktiver Interrupt die Ausführung eines weiteren verhindert.
    Ausserdem solltest Du die Abschaltung von Interrupts mit "CLI" im Hauptprogramm möglichst vermeiden und die Befehle bis zum "SEI" auf ein minimum beschränken, da es sonst zu einem kleinen Phasenjitter kommen kann.
    Ein weiterer Punkt ist im Tastverhältnis versteckt.
    Wenn ein Tastverhältnis von genau 50% gefordert ist musst Du dafür sorgen, das in diesem Comparmatchinterrupt genau gleich viele Taktzyklen fur das Ausschalten, sowie für das Einschalten des Ports C0 gebraucht werden.

    Eine möglichkeit wäre den PORTC0 in ein Register einzulesen, mit EOR 0b00000001 das letzte Bit umzukehren und den Registerwert wieder in den PORTC zurückzuschreiben.
    Da dabei immer die gleiche Befahlsanzahl durchlaufen wird, sollte auch das Tastverhältnis genau 50% betragen.

    Versuchs mal es ist eigentlich einfacher als man denkt.

    Die 1ms Zeitschleife würd ich einfach mal ins Blaue (so ungefähr)programmieren und mit dem Simulator (AVR STudio 4) die genauen Zeiten austesten.
    Normalerweise zählt man dazu einfach irgendwelche vorbelegten Registerwerte runter bis die 0 erreichen und springt dann aus der Routine wieder raus. Wenn während der Zählschleife natürlich Interrups auftreten braucht die Zeitroutine natürlich für die Abarbeitung mehr als 1ms.
    Wenn Du natürlich einen mathematischen Weg für sowas brauchst musst Du halt ein wenig rechnen.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.11.2006
    Ort
    Geislingen a. d. Steige
    Alter
    33
    Beiträge
    344
    Hi,
    kann der ausgang des rechtecksignals auch an PORTD 4 ausgegeben werden?
    Dann könntest du nämlich PWM verwenden und den wert von PORTA ins Output Compare Register schreiben.

    MfG Martin

  4. #4
    Hallo, danke für deine Hilfe wkrug...
    Aber leider komme ich immer noch nicht mit der Assembler programmierung klar, wie ich das alles zusammen schreibe!


    Und leider benötige ich das schon für morgen!
    Ich bin schon die ganze zeit am arbeiten,habs aber leider noch nicht hinbekommen...

    Mfg

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    17.04.2006
    Beiträge
    2.193
    Aber die Aufgabe hast Du sicher nicht erst seit gestern, oder?
    Wenn Du bis jetzt nicht die Befehle "zusammengeschrieben" bekommst, solltest Du lieber um Aufschub bitten anstatt zu hoffen, dass Du durch ein Wunder die Assemblerprogrammierung, die Funktionsregister und die Timer des AVR verstehst. Und wenn Du einen neuen Zeitrahmen hast, dann noch mal detailliert und von anfang an das Problem beschreiben und vor allem: wie weit Du eigentlich schon bist.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    na Du bist witzig, so mal über Nacht ....

    wichtige Infos fehlen:
    Welcher Controller in welcher Sprache zu programmieren?
    Sonstige Funktionen?

    in Bascom währen das so auf die Schnelle,
    wenn der Controller nix anderes machen soll
    irgendwas um die 6-7 Codezeilen, das währ in
    5 Minuten machbar
    (Mainloop mit Pinabfrage und waitms und toggle portd.4 oder wars portc.0?
    ist ja auch wurscht welcher)

    ... in ASM ists natürlich ne andere
    Geschichte, sprich n paar Zeilen mehr.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Muss der Ausgabepin unbedingt PortC,0 sein ?
    Wenn du den PortD,4 oder PortD,5 verwenden könntest würde deine Frequenzausgabe ohne weiteres zutun laufen. Stichwort OC1A OC1B pin.
    Du müsstest dann halt nur die Comparematch Register OCR1AH und OCR1AL mit den richtigen Daten füttern.

    Die nötigen Informationen über den Timer 1 findest Du im Datenblatt des ATMEGA 16 auf Seite 87...115.
    Die allgemeine Timer Beschreibung ist für den Prescaler (Vorteiler) wichtig.

    Mit ein bischen Assemblerkenntissen und ein wenig Mühe sollte sich sowas innerhalb von 5..6 Stunden proggen lassen (inkl. Datenblatt lesen).

    Übrigens solltest Du während einer Interruptroutine alle benutzten Register inklusive Statusregister auf dem Stack sichern un später auch wieder runterholen.

    bsp:

    tim1cmp_int:
    PUSH r16
    IN r16,SREG
    PUSH r16
    PUSH r17

    ; Dein Interrupthandlerprogramm welches r16 und r17 benutzen will.

    POP r17; Werte in umgekehrter Reihenfolge vom Stack holen
    POP r16
    OUT SREG,r16
    POP r16

    RETI ; Der Aussprung aus einer Interruptroutine ist immer RETI !

    Damit das auch so klappt musst Du am Anfang deines normalen Programmes den Stack initialisieren.

    LDI r16,low(RAMEND)
    LDI r17,high(RAMEND)
    OUT SPL,r16
    OUT SPH,r17

    Die Interruptvektortabelle muss natürlich auch stimmen, aber das ist im Datenblatt auf Seite 43 bestens beschrieben.
    Nicht benutzte Interrupts solltest du mit dem Befehl RETI belegen, damit dein Controller keinen Blödsinn macht.

    Beispiel:

    .CSEG
    .org 0
    jmp RESET ; Reset Handler
    RETI ; IRQ0 Handler
    RETI ; IRQ1 Handler
    RETI ; Timer2 Compare Handler
    RETI ; Timer2 Overflow Handler
    RETI ; Timer1 Capture Handler
    jmp TIM1_COMPA ; Timer1 CompareA Handler
    jmp TIM1_COMPB ; Timer1 CompareB Handler
    RETI ; Timer1 Overflow Handler
    jmp TIM0_OVF ; Timer0 Overflow Handler
    jmp SPI_STC ; SPI Transfer Complete Handler
    jmp USART_RXC ; USART RX Complete Handler
    jmp USART_UDRE ; UDR Empty Handler
    jmp USART_TXC ; USART TX Complete Handler
    jmp ADCC ; ADC Conversion Complete Handler
    jmp EE_RDY ; EEPROM Ready Handler
    jmp ANA_COMP ; Analog Comparator Handler
    jmp TWSI ; Two-wire Serial Interface Handler
    jmp EXT_INT2 ; IRQ2 Handler
    jmp TIM0_COMP ; Timer0 Compare Handler
    jmp SPM_RDY ; Store Program Memory Ready Handler

    Ich hoffe die Informationen haben Dir weitergeholfen.
    Schreiben solltest Du dein Prog schon selber.

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    26.05.2005
    Ort
    Kaiserslautern
    Beiträge
    794
    Hi Vitis:
    Controller: Atmega16 (Threadtitel)
    Sprache: Assembler ("muss in assembler programmieren")

    Sonstige Aufgaben wird er wohl nicht haben, sonst hätte er danach gefragt

    Gruß, CowZ

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    ok, ASM bin ich nicht bewandert, aber im Prinzip kannstes ja
    recht einfach realisieren, sprich Timer weglassen und ne
    Warteschleife.

    Wenn ich so auf die Schnelle was in ASM bräucht würd ich folgendes
    machen.
    Ich würds in Hochsprache Coden und mir die Kompilierte Geschichte
    dann straffen. Die Hex von Bascom oder GCC kannste im AVR-Studio
    ja decompilieren.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Ich würds in Hochsprache Coden und mir die Kompilierte Geschichte
    dann straffen
    So Einfach gehts dann doch nicht, weil eine Hochsprache erstmal eine ganze menge "Müll" definiert bevor der eigentliche Code losgeht.
    Mein Codevision löscht erstmal das ganze RAM und schreibt eine eigene Datei für die Interruptvektortabelle.
    Bascom sichert bei einem Interruptaufruf z.B. immer (kann man aber abschalten) den kompletten Registersatz.
    Da sieht man auf den ersten Blick, das das von nem Compiler produziert wurde.
    Ausserdem fehlen die ganzen Kommentare sowie teilweise die Variablenzuweisungen.

    Um vernünftig in ASM zu proggen braucht man ohne Vorkenntisse fast ein Jahr, mit Vorkenntnissen gehts auch in 1 bis 2 Monaten.

    Was nicht geht ist sowas über Nacht zu lernen (ohne wistudent entmutigen zu wollen).

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