Glück Auf! Ich habe hier eine Software PWM geschrieben, die auf einem ATmega8 mit 8Mhz internem Takt 16 Kanäle ansteuern kann. Die Ausgänge laufen auf 400Hz, was ausreichend ist für LED Ansteuerung u.ä. Der Code ist in Assembler geschrieben und schon etwas auf Geschwindigkeit (möglichst wenige CPU-Zyklen pro Durchlauf) optimiert. Die Größe des Codes spielt momentan keine Rolle, Assembliert ist das ganze grade mal 820 Byte groß... Momentan läuft nur ein kleines Demoprogramm (Wechselblinker) darauf, der TWI/I2C Teil ist noch in Arbeit. Als Ausgänge benutze ich die Ports B und D, was die Nutzung eines ext. Oszillators/Quarz sowie des UART ausschließt. Die Pins PortC0-3 sind unbelegt, diese können z.b. für die externe Adresszuweisung oder für die Erfassung von Analogwerten verwendet werden. Die TWI Schnittstelle werde ich als nächstes in Angriff nehmen. Für Konstruktive Kritik bin ich jederzeit offen! _.-=: MFG :=-._
hm, scheinbar hab ich noch einen schweren Bug drin, mit diesem Code passiert an den Ausgängen irgendwie gar nix. Mal schauen, morgen werde ich das ganze nochmal gründlich überarbeiten. _.-=: MFG :=-._
So, nach längerer Problemsuche habe ich meine Logikfehler rausbekommen. Im Anhang ist der neue, funktionierende Code. Schuld war ein Fehler bei der SRAM Adressierung sowie bei der Auswertung der Schwellwerte. _.-=: MFG :=-._
Hallo Marcus, hab gerade mal Deinen ASSEMBLER-CODE überflogen. Soll jetzt aber keine Nörgelei sein, clr XH ldi XL, low(0x0060) besser wäre: ldi XH, high(0x0060) ldi XL, low(0x0060) ------ ldi tmp1, 0b00000010 ; Timer 0 out TCCR0, tmp1 ; Prescaler 8 besser wäre: ldi tmp1, 1<<.... ; Timer 0 out TCCR0, tmp1 ; Prescaler 8 ------- Bei "Interruptroutinen" würde ich sicherheitshalber noch SREG sichern, denn man(n) weiß nich wan der Interrupt zuschlägt. Sollte es dann Probleme mit SREG geben, dann sucht man den Fehler stundenlang. Bernhard
Glück Auf! Hier mal ein Update des Codes. Mittlerweile habe ich das TWI Interface implementiert, es fehlt nur noch die Auswertung der übermittelten Kommandobytes. Ich habe die PWM Routine komplett umgebaut, es wird jetzt alles im Interrupt ausgeführt. Ausserdem habe ich das ganze nochmals gekürzt, assembliert ist das Programm nur 604 Byte groß. Eingestellt ist die PWM jetzt auf 100Hz, mit einer Auflösung von 100 Schritten, was ausreichend ist für die Ansteuerung von Leds o.ä. Sobald ich die Auswertung der Kommandos fertig habe und das ganze erfolgreich getestet ist, gibts auch noch einen Beispiel-Schaltplan + Platinenlayout. @Bernhard: Deine Tipps habe ich in der neuen Version berücksichtigt, danke! _.-=: MFG :=-._
Hallo Markus, Dein Pogramm-Code sieht doch ganz vernünftig aus, großes LOB an Dich. Bernhard
Glück Auf! nach einiger Zeit konnte ich mich mal wieder mit dem Programm beschäftigen. Im Anhang ist die aktuellste Version des Sourcecodes. Leider hatte ich bisher mangels pc <-> i2c Interface noch keine möglichkeit, das TWI Interface auf Funktionalität zu prüfen. Das Protokoll für die Steuerung ist ganz einfach aufgebaut: - Ansteuerung immer mit 2-Byte Befehlen - 1. Byte bestimmt die Funktion, - 2. Byte übergibt Parameter Befehle: 0x01 & 0x02 sind zzt nur testweise implementiert 0x08 - Setze alle Kanäle auf Wert aus 2tem Byte 0x09 - wie 0x08, nur faden statt setzen 0x10 - 0x1F -> Setze Kanal 1 - 15 auf Wert 0x20 - 0x2F -> Fade Kanal 1 - 15 auf Wert Beispiel: 0x08 0x00 - Setze alle Kanäle auf 0% 0x15 0x35 - Setze Kanal 6 auf 53% 0x2C 0x0A - Fade Kanal 13 auf 10% 0x09 0x32 - Fade alle Kanäle auf 50% Ich hoffe es funktioniert auf Anhieb, wenn Fehler auftreten immer her damit! _.-=: MFG :=-._
Hallo. Genau sowas suche ich. Allerdings mit einer auflösung von 8 Bit. (256 schritte) Wäre auch nicht weiter wild, wenn ich mit 16 MHz als MCU Frequenz arbeiten müsste. Könntest du mir den Code dementsprechend umbauen? Leider habe ich von Assembler gar keine ahnung. Ich prügel mich gerade mit C rum, und das reicht mir schon. Gruß
>Ich prügel mich gerade mit C rum, und das reicht mir schon.
Dann lern´ doch ASM, ist eigentlich einfacher und absolut logisch, man
muß sich halt um alles selber kümmern, aber dafür weiß man meist auch
genau, was der Controller treibt (oder soll).
Glück Auf! ganz einfach: du setzt die Konstante "PWM_MAX" auf 255 (d.h. 256 Schritte auflösung) und die Konstante "TIM0_ST" auf 216 (dass ist der teiler um dann wieder auf die Frequenz von 100Hz zu kommen) Die Werte ermitteln sich so: CPUCLK = prescaler * (255 - TIM0_ST) * (PWM_MAX + 1) * 100Hz also hier: 8.000.000Hz = 8 * (255 - 216) * (255 + 1) * 100Hz die 216 in TIM0_ST ist etwas aufgerundet, mit TIM0_ST = 215 gehts auch net ganz auf... _.-=: MFG :=-._ PS: 16MHz geht nicht, da die XTAL Anschlüsse durch die PWM belegt sind... PPS: Das I2C Interface ist immer noch Beta und (leider noch) undokumentiert, d.h. es kann funktionieren, muss aber nicht...
Hallo Markus ! Gibt es eine Möglichkeit, diesen Assemblercode in ein C-Programm einzubinden, und so einen Ablauf ohne Steuerung von außen zu erreichen ? Ich möchte ungern einen zweiten Controller dafür "opfern" - wobei ich denke, dass es bestimmt auch beides in einem Controller geht - ich weiß eben nur nicht, wie ! Gruß, Andreas
Glück Auf! Hm, also mit dem einbetten in C-code bin ich leider nicht so bewandert. Aber irgendwo in den tiefen der Codesammlung versteckt findet sich afaik auch ein PWM-Code in C, könnte der dir weiterhelfen? _.-=: MFG :=-._
Hallo Markus ! Wenn der Code das kann, was Dein Code kann, dann ist die Antwort auf Deine Frage "Ja". Ich stelle mir das mit dem Einbinden so vor, dass der Assemblerteil quasi eigenständig läuft, und ich mit dem C-Teil die Register manipuliere, um die gewünschte Art der Darstellung zu erreichen. Dafür könnte aus Deinem Code die komplette I2C-Routine gelöscht werden. Vielleicht liest ja jemand mit, der mir erklären kann, wie man diese Einbettung von Assembler in C vornimmt, und was man da beachten muss ? Gruß, Andreas
Hallo, ich habe mir deinen Code geladen und bin gerade beim ausprobieren - auch was die kommunikation via twi bzw. i2c angeht. Doch leider muß ich feststellen, dass die i2c kommunikation nicht funktioniert - liegt es an mir, oder ist dort u.U. noch ein Fehler drin??? MfG
Hallo! Leider ist es möglich, dass es an dem Code liegt - seit meinem letzten Post habe ich nicht weiter daran gearbeitet, mangels Zeit und Bedarf daran. Ich befürchte, dass der I2C Part noch einiges an Überarbeitung und Optimierung braucht. Der Code, so wie er jetzt ist, ist in großen Teilen nach den Zustandsbeschreibungen im ATmega8 Datenblatt sowie der Atmel Application Note für TWI entstanden. Sorry dass ich dir nicht weiter helfen kann dabei :-( _.-=: MFG :=-._
Hallo Markus, ich habe folgende Zeile korrigiert - damit läuft es dann auch ALT:
1 | TWICLR: ; TWINT loeschen, wieder empfangsbereit gehen |
2 | ;ldi tmp1, (1<<TWINT)|(1<<TWEA) |
3 | ;out TWCR, tmp1 |
NEU:
1 | ldi temp, 1<<TWINT|1<<TWEA|1<<TWEN|1<<TWIE |
Gruß Jonas
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.