Hallo, kann mir jemand sagen, ob ein Counter die 256 Schritte eines 8-Bit Timers zählen kann?
Timer und Counter sind EIN UND DIESELBE Sache! Ob Du ihn als Timer oder als Counter benutzt, hängt nur von der Taktquelle ab. Bei konstanter Frequenz arbeitet er als Timer (er zählt Zeitabschnitte mit konstanter Länge), und wenn Du ihn asynchron taktest, als Ereigniszähler...
Jo danke. Kannst du mir sagen, wie ich Bascom sage, das der Timer1 von 0 bis 128 =1 un dann bis 256 =0 sein soll?
Bascom? Nie gehört...;-) > ...das der Timer1 von 0 bis 128 =1 un dann bis > 256 =0 sein soll... Hä? Meinst Du vielleicht den Compare-Ausgang vom Timer? Dann musste ins Compare-Register 129 reinschreiben und den Pin entsprechend konfigurieren (löschen bei Compare Match und Setzen bei 0). Timer1 ist übrigens ein 16-Bit-Timer, der kann bis 65535 zählen...
Ja der Compare Ausgang. Da ich aber 3 Timer brauche die synchron laufen sollen, muss Timer1 ein 8-Bit Zähler sein. Hat keiner ne Idee wie ich die Timer unterschiedlich starten und stoppen kann?
@Johnny.m: Es geht um BASCOM! Erwartest du da nicht etwas viel Eigeninitiative? @Fabsi: CTC-Modus (ClearTimer on Compare) ist einer der Modi, in denen 16Bit-Timer betrieben werden können. Dabei wird der Timer beim Erreichen des TOP-Value, den man als Programmierer festlegen kann, auf 0 zurückgesetzt. Den Modus hatte ich in deinem anderen Thread schon angesprochen.
Das was Rahul schon ansatzweise in deinem ANDEREN THREAD vorgeschlagen hat!!! Ansonsten: Datenblatt bzw. Tutorial lesen und verstehen. Sonst hat das alles keinen Sinn.
@Rahul: Upps, Überschneidung! Hast natürlich recht (wie immer;-). Aber auch wenn man mit Basskomm oder so ähnlich programmiert sollte man das Datenblatt lesen.
Hallo Paul das ist keine schlechte Idee, aber irgendwie habe ich noch einen Fehler im Programm, vielleicht kannst du mir helfen. $Regfile = "m8def.dat" 'ATmega8-Deklarationen $Crystal = 3686400 Config Pinb.4 = Output On TIMER0 = OnTIMER0 OnTimer0: If tcnt0 <128 then PORTB.4 = 1 else PORTB.4 = 0 Return
Wie soll das auch gehen? >OnTimer0: > If tcnt0 <128 then PORTB.4 = 1 >else PORTB.4 = 0 >Return Der Timer ist "übergelaufen", also = 0. Da kann er nicht >=128 werden...
Du mußt den Timer natürlich auch als Counter einstellen. Weiter oben wolltest Du doch einen Couter haben.
....so habe ich das gemeint: Dim HORST as Byte :-)) Config Timer0 = Counter , Edge = Rising Tcnt0 = 0 Do Do Print Tcnt0 Horst = 0 Loop Until Tcnt0 = 128 Do Horst = 1 Print Tcnt0 Loop until Tcnt = 255 Loop End Paul
Und damit ist der AVR ausgelastet und kann nix anderes mehr machen, oder? ... (Man gut, dass es Assembler gibt...)
@Hannes Lux Ich verstehe Deine Frage nicht. :-) Um wie viel komplizierter ist es, sich die Assemblerbefehle für jeden Prozessor herauszusuchen, bzw. zu kennen. Wenn man weiß, das hinter Bascom keine große Firma sondern eigentlich nur ein einzelner Mann steht, kann man das Resultat nur bewundern. Ich habe mich vor Jahrzehnten mit Z80-Assembler geplagt und bin froh, daß ich jetzt mit einer Hochsprache ans Werk gehen kann. In der Not kann man auch Assembler im Bascom Quellcode verarbeiten. Aber jeder, wie es ihm gefällt. call Pizzadienst jmp hinterm Schreibtisch vor rol ror end :-)) Paul
@Fabian - Fabmann(at)web.de Vielleicht schaust Du dir das mal an. Ist für Bascomanfänger sehr verständlich. http://www.rowalt.de/mc/index.htm
> Ich verstehe Deine Frage nicht. :-) Hallo Paul... Die Frage (Bemerkung) war so gemeint: Mit dem vorgeschlagenen Programmcode läuft der Timer zwar im Hintergrund, die Reaktionen auf bestimmte Zählerstände des Timers übernehmen aber die ineinander verschachtelten Schleifen. Damit ist der AVR ziemlich ausgelastet und hat kaum noch Zeit für andere Aufgaben. Wenn ich das programmieren müsste, dann würde ich einen Interrupt nutzen, der vom Timer bei dem entsprechenden Zählerstand ausgelöst wird. In der jeweiligen Interrupt-Service-Routine wird dann der entsprechende Portpin verändert und der Timer für das nächste Interrupt-Ziel manipuliert. Dann kann sich das Hauptprogramm um andere Dinge kümmern, die Timer-relevanten Dinge werden im Interrupt erledigt. Einige AVRs bieten sogar über die OCxx-Ausgänge die Möglichkeit, total im Hintergrund (also ohne Interrupt mit zyklisch aufgerufenen Programmcode) PWM oder Rechtecksignale variabler Frequenz in verschiedenen Modi zu generieren. Mein "Man gut, dass es Assembler gibt" war etwas unglücklich gewählt, "Man gut, dass es Interrupts gibt" hätte es besser getroffen. Dass ich auf ASM stehe, hat damit zu tun, dass ich damit jede Information im Datenblatt des AVRs finde und mich nicht erst mit weiteren kryptischen BASIC-Befehlen (z.B. Config xyz) herumärgern muss. So hole ich mir die entsprechenden Infos (welche Bits ich in welchen I/O-Registern setzen/löschen muss, um ein bestimmtes Hardware-Feature zu nutzen bzw. zu konfigurieren) aus dem Datenblatt und greife mit IN/OUT darauf zu. Ähnlich ist es mit Zugriffen auf Flash (Tabellen), EEPROM und SRAM (über Pointer, also Arrays), es gilt nur das Datenblatt, und dessen Infos sind meines Erachtens besser verständlich als die Infos zu BASCOM-AVR (ja, auch ich habe bereits etwas in der BASCOM-Hilfe geschmökert). Dazu nutze ich eine Software (AVR-Studio), die völlig frei ist und keinerlei Beschränkungen (Demoversion) hat. Es ist nicht so, dass ich etwas gegen BASIC hätte, ich programmiere selbst in BASIC (C-Freaks mögen mir verzeihen, dass ich das "programmieren" nenne), allerdings dort, wo das Programm unter einem Betriebssystem läuft (PC) oder ein (im ROM) fest installierter BASIC-Interpreter die Funktionen eines Betriebssystems übernimmt (Commodore plus/4). Beim (kleinen) AVR bin ich aber so dicht an der Hardware, dass ich mit Assembler bedeutend mehr Übersicht über das, was ich tue, habe. Mit Z80-Assembler habe ich keine Erfahrung, aber den Plus/4 habe ich neben BASIC auch in Assembler programmiert, teils gemischt, also BASIC-Oberfläche mit eingebundenen ASM-Routinen. Beste Grüße, Bit- & Bytebruch... ...HanneS...
@Hannes Ja, das war jetzt nur mal so aus dem Kopf hingeschrieben. Ich ziehe eben immer noch Bascom der Assemblersache vor. Wenn es eine deutschsprachige Assemblerbefehlsliste gäbe, wär es einfacher. Wenn es manchmal nicht anders geht, (Zeitprobleme im Programm), flechte ich ein Stück Assembler in Bascom ein. Allerdings dauert mir die Sucherei nach den Befehlen, die das tun, was ich brauche zu lange. Da habe ich meist den Rest des Programms schneller fertig. apropos Bit- und Bytebruch. Mir ist eben ein Word in 2 Byte zerbrochen; wenn du mal 8 Bit brauchst, die liegen noch hier rum. :-)) Paul
@ Paul: Hallo habe dein Vorschlag ausprobiert, es funktioniert aber leider nicht, hast du vielleicht ne Idee wieso das so nicht funktioniert? $Regfile = "m8def.dat" 'ATmega8-Deklarationen $Crystal = 3686400 'Quarz:3,6864 MHz DDRB = &B00001111 'PB0 -PB3 Ausgang Config Timer0 = Counter , Edge = Rising Tcnt0 = 0 Do Do Print Tcnt0 PortB.1 = 0 Loop Until Tcnt0 = 128 Do Print Tcnt0 PortB.1 = 1 Loop until Tcnt0 = 255 Loop End
Gleich vorweg: Ich kenne BasCom nicht, kann also nicht sagen, ob du da einen gröberen Bock in der Config Section hast. Aber: Config Timer0 = Counter , Edge = Rising Der Timer zählt nur dann weiter, wenn er von extern einen Takt vorgegeben kriegt (das ist irgendein Input Pin). Du hast doch da ein Signal drauf liegen? Loop Until Tcnt0 = 128 Na, ja. Abhängig davon, wie schnell das externe Signal ist, ist es schon eher Zufall, ob du den Counter bei exakt 128 erwischt. Während der µC die Schleife Do Print Tcnt0 PortB.1 = 0 Loop Until Tcnt0 = 128 abarbeitet, vergeht ja auch Zeit. Ist das zu zählende Signal zu schnell, dann erhöht es sich um sagen wir mal 3 oder 4 in einem Schleifendurchlauf. War der bei einer Abfrage 127 dann wird der Counter das nächste mal abgefragt, wenn er den Wert 132 oder so erreicht hat. D.h. die 128 wirst du nie sehen. Wenn schon, dann machs so: Do Print Tcnt0 PortB.1 = 0 Loop Until Tcnt0 > 127 Aber wie gesagt: das hängt alles davon ab, welche Frequnz das Signal hat, daß du dem Counter zum zählen vorwirfst.
Ok danke ich sehe schon das ich es wohl nicht so machen kann, was ich will.Ich brauche nämlich 3 exakte Signale um 120° versetzt mit einem Pulspausenverhältnis von 1:1. Habe dabei schon die drei PWM-Ausgänge von meinem ATmega8 verwendet, aber so sind natürlich alle phasengleich: $Regfile = "m8def.dat" 'ATmega8-Deklarationen $Crystal = 3686400 'Quarz: 3,6864 MHz Config Pinb.1 = Output Config Pinb.2 = Output Config Pinb.3 = Output Config TIMER1 = PWM , PWM = 8 , Compare A PWM = Clear Up , Compare B PWM = Clear Up , Prescale = 1 Config TIMER2 = PWM , Compare PWM = Clear Down , Prescale = 1 DO PWM1a = 127 PWM1b = 127 Ocr2 = 127 Loop End Und ich denke, das ich in dieses Programm auch keine Phasenverschiebung bekomme. Deshalb war meine Idee einen Counter zählen zu lassen, der bei bestimmten Zählerständen mir Ausgänge setzt bzw zurücksetzt.
> Ich brauche nämlich 3 exakte Signale um 120° versetzt mit einem > Pulspausenverhältnis von 1:1. Das ist doch überhaupt kein Problem. Man richte sich einen Timer (als Timer, also am Prozessortakt) ein, der mit dem sechsfachen der benötigten Frequenz läuft. Dann lege man eine Tabelle im Flash (6 Einträge á 1 Byte) an, in der die Bitmuster der 6 Phasen einer Umdrehung eingetragen sind. Alle Ausgänge (Phasen) lege man sinnvollerweise auf einen Port. In der ISR dieses Timers zählt man ein Register (Phasenzähler) hoch und begrenzt den Zählumfang auf 0..5 (bei Erreichen von 6 wieder auf 0 setzen). Weiterhin setzt man den Z-Pointer auf den Anfang der Bitmustertabelle (*2) und addiert den Phasenzähler hinzu. Nun holt man mit LPM den Bitwert aus der Tabelle, liest den Port ein, maskiert die benötigten Bits aus und übernimmt die Bits aus der Tabelle und schreibt den Port zurück. Natürlich muss die ISR auch noch den Timer-Reload managen. Die gesamte Impulserzeugung erfolgt in der ISR und belastet (bei üblichen Frequenzen bzw. Drehzahlen) den Controller nur minimal. Das Hauptprogramm kann sich dann um die Bereitstellung des Timer-Reload-Wertes kümmern, mit dem Frequenz/Drehzahl exakt eingestellt werden kann. Ich denke mal, dass die ISR (in ASM) nicht mehr als 30..40 Takte brauchen wird, die maximale ISR-Frequenz wird bei 1MHz Controllertakt also bei 25..33kHz liegen, die max Drehfeldfrequenz dann bei 4..5,5kHz (50Hz sind 3000 Umdrehungen pro Minute!). ...
> apropos Bit- und Bytebruch. Mir ist eben ein Word in 2 Byte > zerbrochen; > wenn du mal 8 Bit brauchst, die liegen noch hier rum. @Paul: Kann ich schon brauchen, aber nur nibbleweise, da ich sie per DTMF versenden will. :-) ...
@Hannes: Genau das habe ich schon in seinem anderen Thread vorgeschlagen. Der erste "Bascom-Programmierer", der wirklich unbelehrbar ist... @Paul: Hast du kein Bit-Auffangregister?
> Genau das habe ich schon in seinem anderen Thread vorgeschlagen. Dann kann es ja nicht soooo falsch sein. > Der erste "Bascom-Programmierer", der wirklich unbelehrbar ist... Ich denke nichtmal, dass es an der Programmiersprache liegt. Denn vor dem Programmieren in einer definierten Programmiersprache hat man ja die Aufgabe zu analysieren und in kleinere Jobs zu zerlegen. Muss das dokumentiert werden (berufliches bzw. professionelles Arbeiten), so gibt es dafür Programmablaufpläne oder Struktogramme, beim "Bastler" genügt oftmals eine textliche Beschreibung oder eine Skizze mit ungenormten Symbolen (Kästchen mit Text). Ist diese Aufgabe erledigt, dann sollte es nicht schwer fallen, in der Programmiersprache, die man beherrscht und die für die Aufgabe geeignet ist, das Programm zu erstellen. Ich möchte aber fast meinen, dass schon das Problem besteht, die einzelnen Aufgaben des Programms zu formulieren. Müsste ich das "Drehfeld" am Druckerport eines (alten) PC erzeugen, dann würde ich das auch in BASIC machen (QBASIC oder QB). Nicht weil BASIC die dafür geeignetste Sprache wäre, sondern weil ich BASIC kann und der (wenn auch alte) PC genügend Ressourcen bereit stellt, die einen nicht zum effizienten Programmieren zwingen. Beim AVR würde ich das in Assembler lösen, aber nicht, weil etwa andere Sprachen nix taugen, sondern weil man in ASM recht dicht an der Hardware ist und der im Datenblatt des AVRs aufgelistete Befehlssatz verbindlich ist (ohne Rücksichtnahme auf Eigenheiten irgendwelcher Hochsprachen-Compiler). ASM also, weil das Problem überschaubar ist und ASM daher den schnellen Erfolg (auch bezüglich des effizienten Umgangs mit Rechenzeit) garantiert. Wie gesagt, es genügen Architekturbeschreibung und Befehlsliste aus dem Datenblatt des AVRs als Informationsquelle. Selbstverständlich kann man das auch in C machen. Dazu muss man aber C recht gut können und die Eigenheiten des Compilers kennen. Es schadet auch nix, den vom C-Compiler erzeugten ASM-Code zu verstehen. In BASCOM kann man das auch umsetzen. Doch habe ich mal gelesen, dass BASCOM beim Aufruf einer ISR sämtliche Register sichern und wiederherstellen soll. Wenn dem so ist, dann dauert der ISR-Aufruf - 10 Takte für Aufruf und Rücksprung - 4..8 Takte für SREG-Sicherung - 64 Takte für Sichern der Register - 64 Takte für Widerherstellen der Register - xx Takte für die eigentliche Arbeit, da ich nicht weiß, wie BASCOM das in Maschinencode umsetzen würde Die 128 Takte für Registersicherung würden das System dermaßen ausbremsen, dass ich gar nicht weiter darüber nachdenken möchte. In ASM (und vermutlich auch in C) brauche ich - 10 Takte für Aufruf und Rücksprung - 4 Takte für SREG-Sicherung - etwa 20..30 Takte für die eigentliche Arbeit, etwas mehr, wenn der Z-Pointer nicht exklusiv genutzt werden kann. ...
>Der erste "Bascom-Programmierer", der wirklich unbelehrbar ist... >Ich denke nichtmal, dass es an der Programmiersprache liegt. Ich auch nicht, aber "Bascom-Programmierer" scheinen irgendwie eine eigene Spezies zu sein. Manche von denen wollen einfach keinen Ratschlag/Verbesserungsvorschlag, sondern nur Zustimmung zu ihrer oder eine fertige Lösung haben. Das ist meine (völlig subjektive) Meinung zu diesem Thema. (Schlagt mich ruhig jetzt wieder!) @Hannes: Hast du die "ASM-Werbung" grundsätzlich in der Zwischenablage, oder tippst du die wirklich jedes Mal neu? ;)
Es gibt aber auch Leute, die können einfach nich programmieren bzw. werden es nie lernen. Die haben irre Schwierigkeiten in die Denkweise hineinzukommen. Versteht mich nicht falsch, ich mach das niemandem zum Vorworf. Soll einfach nur eine Tatsachenfeststellung sein. Schlimm wird es nur, wenn man solche Leute dann in (vermeintlich) leichte Aufgaben hineinjagt. Die kriegen das nie hin, egal wie viel und wie oft man Ihnen hilft. Auch hier wieder: Soll kein Vorwurf sein. Nur hab ich halt schon oft das Gefühl, dass denen gesagt wird: Mach das in Bascom, damit kann jeder programmieren. Und das stimmt einfach nicht.
@Rahul: Ich tippe das jedes mal neu, aber es wird immer seltener. Der Tag wird kommen, wo es mich nur noch "peripher tangiert" (am Arsch vorbei geht) und ich keinen Kommentar mehr dazu abgebe. Denn "Werbung" ist das nicht, ich verdiene nix daran. @Karl Heinz: Es ist wie mit dem Singen, Musikinstrument spielen (mit Dur und Moll, nicht mit Play und Stop), Malen, Dichten usw. Sowas kann man nur fördern (ausbilden) wenn das Talent dazu auch vorhanden ist. Ansonsten gibt es Frust ohne Ende. Die (vermeintlich) leichten Aufgaben sollte man dazu nutzen, um festzustellen, ob es sich lohnt, das Talent zu fördern. Programmieren kann ich zwar (nur) einigermaßen, aber es gibt viele Dinge, die ich gar nicht oder nur sehr schlecht kann. Aber man muss ja nicht alles können. Es ist schon was dran, dass manch Einer sich an BASCOM klammert, weil er denkt, dass man damit auch ohne Programmier-Denkweise programmieren kann. Aber man (ich) kann und will doch nicht immer darauf hinweisen, dass "Malen nach Zahlen" auch ein schönes Hobby sein kann... ...
>"Malen nach Zahlen" auch ein schönes Hobby sein kann...
Wenn man genug Wandfläche hat... ;)
Natürlich bin ich davon ausgegangen, daß "von draußen" ein Zähltakt anliegt. Ich habe auch nur ein Stück "Rohmaterial" gepostet, keine fertige Lösung. Da ich bis jetzt nicht wußte, was genau Du tun wolltest, sollte das nur als Beispiel dienen. MfG Paul
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.