Assembler Frequenz Teiler (Custom)

ok, das wär blöd, weil es zu unterschiedlichen Ergebnissen führen könnte.
 
Naja, Du hast ja auch Deine Spezialgebiete...

Zum Thema:
frequenzies2.png
Bisher nur Hardware:
Da ich keinen Oszillator hierhabe, und der Sockel auf meinem STK500 mit meinen Quarzen nicht ordentlich anschwingen will, nur mit dem internen 8MHz-Oszillator:
  • schwarz (grau) ist der interne Takt über CKOUT gefused: f/1
  • braun ist "Trick 17" - SCK des asynchronen USART mit UBRR=0. Das an Tx ausgegebene Byte scheint dabei irgendwie geschrottet zu werden (Bild aus #38), aber die SCK paßt. Über TxD hätte man sonst f/4 bekommen können, da der Transmitter eh an sein muß. (laut Datenblatt soll die UASRT-CLK <= f(MCU/4) sein). braun ist f/2
  • rot ist CompareB von Timer0 mit 50% -> f/10
  • orange ist CompareA = Überlauf von Timer0. wird getoggelt. -> f/20
  • gelb dito CompareB von Timer2 -> f/100
  • grün dito CompareA von Timer2 -> f/200
  • blau dito CompareB Timer1 -> f/1000
  • lila dito CompareA T1 -> f/2000
Im UDRE-IRQ wird ein beliebiges Byte (Register) ins Datenregister gestopft, sodaß die USCK dauerfeuert. Muß im Durchschnitt alle 16 Takte geschehen, da das Tx-UDR gepuffert ist sind Aussetzer bis zum doppelten erlaubt. Man könnte auch von acht auf neun Datenbits erhöhen (glaub ich). Die UDRE-IRQ spart den Sprung aus der IVT ein, ich komme auf 10 Takte (4 IRQ-Einsprung (=Rücksprungadresse pushen), 2 UDR beladen, 4 Reti).
Weitere Stufen müßte man an den T1-CompareA koppeln. Von den 2000 Takten Zeitfenster blieben ca 666 verfügbar, da der Controller dauernd in die USART-IRQ hopst. sollte trotzdem reichen.
Compareflag pollen, Überläufe zählen, ggf zähler zurücksetzen, Bein toggeln, nächste Stufe...
Oder man pollt auch die USART (das hopsen dauert ja länger als pollen und UDR beschreiben) regelmäßig - dann sollten sich auch in den Software-Stufen keine Unregelmäßigkeiten ergeben (der IRQ könnte ja 10 Takte verzögern).

Hmm... Trick 18?...
Bei 'ner USI hat man Zugriff auf den 4bit-Zähler, wenn ich mich recht erinner. Man könnte also vielleicht aus den f/2000 die nächste Stufe ableiten. Ich vermute, daß das leider mit'ner richtigen SPI nicht geht...
 
Bei 'ner USI hat man Zugriff auf den 4bit-Zähler, wenn ich mich recht erinner.
korrekt, allerdings würde der so bei jeder Flanke inkrementieren. Wären also acht Perioden. Da man den Counter auch beschreiben kann, könnte man alle fünf Perioden auf das Flag reagieren/'n IRQ Triggern lassen, das wären dann die geforderten f/10000. f/20000 wären dann in reiner SW mitzuerledigen.
leider mit'ner richtigen SPI nicht geht
leider auch korrekt, wenn Du keinen AVR mit USART, drei Timern mit je zwei nutzbaren PWM und USI findest (und nebenbei die genannten Funktionen nicht um die Beine konkurrieren), wäre der Rest in Software anzugehen.

Oder man pollt auch die USART (das hopsen dauert ja länger als pollen und UDR beschreiben) regelmäßig
Quark... man schreibt einfach regelmäßig was in's UDR - war das UDR vorher leer, steht jetzt was drin; wenn nicht, wird das schreiben ignoriert. Wenn man das alle sieben Takte oder so macht steht immer was im UDR.
Dann könnte man sogar die HW-Stufen im TimerCompareIRQ abarbeiten lassen (um konstante Reaktionszeiten zu haben). Im IRQ dann zusätzlich alle sieben Takte was ins UDR prügeln, außerhalb der ISR (also in der Main-Loop) ununterbrochen das UDR füttern...

@TommyB : wie siehts nun aus? (meine Neugier bezüglich USCK als Takthalbierer ist befriedigt, der Rest sollte trivial sein...)
IC-Grab mit Zähler/FlipFlops?
AVR?
Muß ich den Code zum LA-Log da oben noch hochladen, und Du machst selbst weiter?
Oder soll ich mich nochmal ransetzen, und den Rest dazutippen (und das dann hochladen)?

P.S.: wie man sieht, reicht mein Logic8 nicht für alle Frequenzen - vielleicht bekommst Du @dino03 überredet, daß dann mal zu testen. Der hat (auch) 'n Logic16, und vielleicht auch'n 18MHz-Oszillator...

P.P.S.: ATmega88
 
Ich tendiere grade eher zu der AVR Lösung, habe da aber noch nichts gezeichnet.
Von mir aus auch gerne eine Mixtur aus Beiden, halt was am Platzsparenden ist.

Gestern und Heute volles Programm. Screencasts aufzeichnen, teilweise auch noch in Englisch... Daher hatte ich mich auch noch nicht gemeldet.

Die Idee das Diskret aufzubauen war genial und ich habe wieder eine Menge dazu gelernt. Ich wusste z.B. gar nicht dass es Dezimalzähler gibt 0.o
Die Chips sind trotzdem geordert, nur um mal damit rum zu spielen ;)
 
Wenn vier 390er in SMD und Quarzoszillator zu viel Platz brauchen, kannst Du auch einen 74LVC1G74 an den Oszillator hängen, dann hast Du 18 MHz und 9 MHz.
Mit den 9 MHz einen kleinen AVR betreiben, der die restlichen Frequenzen dann locker erzeugen kann.
 
Nunja, ich denke daß Oszillator+AVR+CounterIC(s) im allgemeinen größer ausfallen wird als Oszillator+Mega48/88.
Allerdings hättest Du den Mega entweder als DIP zu verbauen oder als TQFP. Also wäre der Alabel'sche Leiterplattentrick mit den SOICs nicht anwendbar.
Prinzipiell wäre meine Programmidee auch mit'nem Tiny441 oder so anwendbar, aber der ist nur mit 16MHz angegeben. Wahrscheinlich würde er auch mit 18MHz laufen. Wäre ein SOIC14.
Interessanterweise hätte der drei Timer und zwei UARTs - die beiden Transmitter und die sechs PWMs wären verlockend, bis auf UDRs pumpen alles in Hardware. Bräuchte alle Pins, aber leider liegen alle USART-Pins auch auf den acht PWM-Pins. Läßt sich also trotz remapping bei den PWMs und USART0 so nicht machen.
Ein USART und sechs PWM geht (wie beim Mega88), die letzten beiden Frequenzen dann in Software.
Soll ich das mit dem Mega88 fertigstellen?
Oder soll ich das auf einen Tn441/841 anpassen?

Nachtrag: Der Tiny2313/4313 hätte einen USART und zwei Timer mit je zwei PWM. Also f/2 mittels USART und f/10, f/20, f/100, f/200 in Hardware. Für f/1000 wäre "Trick18" anwendbar in der ISR könnte man dann die restlichen vier Frequenzen erledigen.
An Tn2313/4313 anpassen?

Oder soll ich nur den bisherigen Code hochladen?

Oder willst Du das ganz allein umsetzen?
 
Zuletzt bearbeitet:
Mit TQFP-32 hab ich kein Problem das händisch zu verlöten. Kommt zwar auf Lochraster etwas blöd (jeden 3. Pin hochbiegen und Kupferlackdraht), aber die Platinen werden bestimmt eh gefertigt, von daher ist das egal.

Wenn der 441 eigentlich nur mit 16MHz läuft... Vielleicht würde der das packen, ist mir aber zu unsicher, grade wenn es in "Produktion" geht (immerhin sagenhafte 10stk ^^).

Der Tiny2313 wäre natürlich auch etwas preiswerter, daher attraktiver. Aber an den 40ct Unterschied soll es nicht scheitern. Nimm den den du am sinnvollsten erachtest :)

Alleine umsetzen... Auf deine Ideen wie du es jetzt schon erfolgreich umgesetzt hast wäre ich wohl nie gekommen, daher eher nicht ;)
 
Bevor ich jetzt den Mega aus'm STK popel, mach ich das mal fertig.
Die beiden Tinies hätte ich als SOIC hier, auch passende Nullkraftsockel - müßte ich aber mit Jagwires ans STK hängen.
Also würde ich das danach auf den Tn2313 abändern (um Trick18 zu testen).

Auf deine Ideen wie du es jetzt schon erfolgreich umgesetzt hast wäre ich wohl nie gekommen
Nana...
Pro Timer zwei unterschiedliche PWM in reiner HW generieren zu lassen ist ja kein Ding - dann muß man nur noch 'nen Controller mit möglichst vielen solchen Timern, möglichst ohne Pinkollisionen finden.
Trick18 wird bei jedem Controllerdatenblatt mit USI angedeutet - Alternative Nutzung des 4bit-Flankenzählers bei Nichtverwendung des USI. Knackpunkt an der Sache ist, daß man den Counter beim USI beschreiben kann, und somit ähnlich wie bei einem Timer mit manuellem Timer-Reload den IRQ auch alle zehn Flanken Triggern lassen kann.
Trick17 ist schon... ähm... unkonventioneller... , und ich war mir nicht sicher, ob sich erstens der halbe Systemtakt erreichen läßt, und lückenlose Transfers anstoßen lassen
 


CodeBox Assembler
//ATmega88
.def count=r17
rjmp init
.org OC1Aaddr
 subi count, 1
 brne done
 ldi count, 5
 sbi PINB, PB4
 sbic PINB, PB4
 sbi PINB, PB5
done:
 reti
init:
//Outputs
 //   XCK  TXD   OC0A   OC0B    OC2B
 ldi r16, (1<<PD4)|(1<<PD1)|(1<<PD6)|(1<<PD5)|(1<<PD3)
 out DDRD, r16
 //     OC2A     OC1A     OC1B
 ldi r16, (1<<PB3)|(1<<PB1)|(1<<PB2)|(1<<PB4)|(1<<PB5)
 out DDRb, r16
 //Timer syncronisation
 ldi r16, (1<<TSM)|(1<<PSRASY)|(1<<PSRSYNC)
 out GTCCR, r16
//Timer0
 //OC0B generates F/10
 ldi r16, 4
 out OCR0B, r16
 //OC0A generates f/20
 ldi r16, 9
 out OCR0A, r16
 // fast PWM - OC0A toggle, OC0B PWM
 ldi r16, (1<<COM0A0)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00)
 out TCCR0A, r16
 // fastPWM, prescaler=1 start
 ldi r16, (1<<WGM02)|(1<<CS00)
 out TCCR0B, r16
//Timer2
 //OC2B generates F/100
 ldi r16, 49
 sts OCR2B, r16
 //OC2A generates f/200
 ldi r16, 99
 sts OCR2A, r16
 // fast PWM - OC2A toggle, OC2B PWM
 ldi r16, (1<<COM2A0)|(1<<COM2B1)|(1<<WGM21)|(1<<WGM20)
 sts TCCR2A, r16
 // fastPWM, prescaler=1 start
 ldi r16, (1<<WGM22)|(1<<CS20)
 sts TCCR2B, r16
//Timer1
 //OC1B generates F/1000
 ldi r16, high(499)
 sts OCR1BH, r16
 ldi r16, low(499)
 sts OCR1BL, r16
 //OC1A generates f/2000
 ldi r16, high(999)
 sts OCR1AH, r16
 ldi r16, low(999)
 sts OCR1AL, r16
 // fast PWM - OC1A toggle, OC1B PWM
 ldi r16, (1<<COM1A0)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10)
 sts TCCR1A, r16
 ldi r16, (1<<OCIE1A)
 sts TIMSK1, r16 //<--IRQ
 // fastPWM, prescaler=1 start
 ldi r16, (1<<WGM13)|(1<<WGM12)|(1<<CS10)
 sts TCCR1B, r16
//USART  XCK0 generates f/2
 ldi r16, (1<<TXEN0)
 sts UCSR0B, r16
 ldi r16, (1<<UMSEL00)|(1<<UCSZ01)|(1<<UCSZ00)
 sts UCSR0C, r16
 ldi r16, 0
 sts UBRR0L, r16
 out GTCCR, r16  //Timer syncronisation
 ldi count, 5 //<-- SW-Counter preload
//ready
 sei
loop:
 sts UDR0, r16
 rjmp loop

f/1 kann mit CKOUT-Fuse an B0 ausgegeben werden
f/2 -> D4 (XCK)
f/10 -> D5 (OC0B)
f/20 -> D6 (OC0A)
f/100 -> D3 (OC2B)
f/200 -> B3 (OC2A)
f/1000 -> B2 (OC1B)
f/2000 -> B1 (OC1A)
f/10000 -> B4 (frei gewählt)
f/20000 -> B5 (dito)

habe in der Timer-ISR UDR nicht nachgeladen. Wenn da noch mehr drangekoppelt werden sollten (sind ja noch Beine frei), müßte dies gemacht werden...
Mit dem internen Oszi erhalte ich so die 8MHz..400Hz - mit 'nem externen Takt mußt Du selbst testen...

P.S.: 140Bytes
P.P.S.: die Timersynchronisation hab ich nur drinn, damit beim LA die Flanken "schön" untereinanderstehen. Ansonsten könne die Zeilen 22, 23 (Prescaler clear&block) und 76 (prescaler freigeben) raus
 


CodeBox Assembler
// *************** Bugfixing tn2313Adef.inc ****************
.equ UMSEL0 = 6 ; USART Mode Select Bit 0
.equ UMSEL1 = 7 ; USART Mode Select Bit 1
// *********************************************************

//ATtiny2313A

.def count=r17
.def USIcntReload=r18
rjmp init
.org USI_OVFaddr
 out USISR, USIcntReload//<- IRQ each 5. edge, Flag clear
 sbi PINB, PB5  //toggle each edge
 sbic PINB, PB5
 rjmp done   //toggle each period
 sbi PINB, PB6
 subi count, 1  //each fifth
 brne done
 ldi count, 5
 sbi PINB, PB0  //toggle
 sbic PINB, PB0
 sbi PINB, PB1  //...period
done:
 reti
init:
//Outputs
 //     OC0B  XCK
 ldi r16, (1<<PD5)|(1<<PD2)
 out DDRD, r16
 //    f/2000   f/1000    OC1B  OC1A    OC0A   f/20000  f/10000
 ldi r16, (1<<PB6)|(1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
 out DDRb, r16
//USI
 ldi r16, (1<<USIOIE)|(1<<USICS1)
 out USICR, r16 //each edge increments USI-conter, IRQ enabled
 ldi USIcntReload, (1<<USIOIF)|11 //Preload, Overflow-Flag has to be cleared manually
 out USISR, USIcntReload  //<- IRQ each 5 edges
//Timer0
 //OC0B generates F/10
 ldi r16, 4
 out OCR0B, r16
 //OC0A generates f/20
 ldi r16, 9
 out OCR0A, r16
 // fast PWM - OC0A toggle, OC0B PWM
 ldi r16, (1<<COM0A0)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00)
 out TCCR0A, r16
 // fastPWM, prescaler=1 start
 ldi r16, (1<<WGM02)|(1<<CS00)
 out TCCR0B, r16
//Timer1
 //OC1B generates F/100
 ldi r16, high(49)
 out OCR1BH, r16
 ldi r16, low(49)
 out OCR1BL, r16
 //OC1A generates f/200
 ldi r16, low(99)
 out OCR1AL, r16
 // fast PWM - OC1A toggle, OC1B PWM
 ldi r16, (1<<COM1A0)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10)
 out TCCR1A, r16
 // fastPWM, prescaler=1 start
 ldi r16, (1<<WGM13)|(1<<WGM12)|(1<<CS10)
 out TCCR1B, r16
//USART  XCK0 generates f/2
 ldi r16, (1<<TXEN)|(1<<UCSZ2)
 out UCSRB, r16
 ldi r16, (1<<UMSEL0)|(1<<UCSZ1)|(1<<UCSZ0)
 out UCSRC, r16
 ldi r16, 0
 out UBRRL, r16
 ldi count, 5 //<-- SW-Counter preload
//ready
 sei
loop:
 rjmp loop

freqs3.png
f/1könnte zwar auch via Fuse ausgegeben werden, allerdings entspricht der Pin dem XCK -> also direkt vom Oszillator abgreifen
f/2 -> D2 (XCK)
f/10 -> D5 (OC0B)
f/20 -> B2 (OC0A)
f/100 -> B4 (OC1B)
f/200 -> B3 (OC1A) --> außerdem auf B7= USCK verbunden
f/1000 -> B5 (frei gewählt)
f/2000 -> B6 (dito)
f/10000 -> B0 (dito)
f/20000 -> B1 (dito)

  • Für den letzten hat mein LA nicht genug Kanäle, ich hab's natürlich trotzdem getestet.
  • beim Tn2313(A) gabs ja diverse Fehler in DB und Definitionsdatei - Beim Studio 6.1 fehlt zB. UMSEL1:0.
  • das USI-Counter-Overflow-Flag muß manuell zurückgesetzt werden (wird wegen ClockHold usw (TWI) nicht automatisch durch den IRQ erledigt)
  • Timersynchronisation geht hier so nicht, da keine Blockade wie beim M88 erfolgt sondern nur ein Reset, welcher bei Prescaler=1 quasi keinen Effekt hat.
  • mein Tn2313A scheint mit 9,6MHz internem R-C-Oszi recht flott zu sein...
  • TxD (D1) wird vom Transmitter belegt (auch wenn man nix transmittiert. Der muß halt an sein. Gilt auch oben beim M88)
Achso, wegen:
"Trick 17" - SCK des asynchronen USART mit UBRR=0. Das an Tx ausgegebene Byte scheint dabei irgendwie geschrottet zu werden
Das Tx-Signal paßt schon irgendwie - das ist nur kein "normaler" UART-Output - sieht irgendwie ... ähm ... "Flankenverschränkt" ... aus. @dino03 ?? In den Datenblättern wird der USART nur sehr stiefmütterlich behandelt. Hab jetzt weder nach AppNotes gesucht, noch meinen Output näher analysiert. Würde Thomas hier eh nicht weiterhelfen.

Insbesondere läuft die XCK immer (wenn der Transmitter aktiviert ist) im Dauerfeuer, UDR muß nie beladen werden. Kann dann also auch aus der Loop beim Mega88 raus.

@TommyB : Bitte testen

P.S.: Die USI-Clk kann man wohl auch an den T0-Compare hängen, aber ob SCK dann trotzdem zappelt, weiß ich nicht. Ebenso geht aus Table16-2 nicht ganz hervor, welcher der beiden Compares da gemeint ist. Hab also 'ne externe Leitung genommen...
 
Zuletzt bearbeitet:
  • Like
Reaktionen: TommyB
Sehr geehrter Herr BAUMANN,
Vielen Dank für Ihre Bestellung. Wir werden diese schnellstmöglich prüfen und bearbeiten.
Ich fahr denn mal los, am WE wird rum probiert :)
 
Ich habe selber noch etwas Hand angelegt (nicht am Source selbst, nur an der Optik. Kommentare, Großschreibung, sowas).



CodeBox Assembler
// *************** Bugfixing tn2313Adef.inc ****************
.INCLUDE <tn2313Adef.inc>
.EQU UMSEL0 = 6 ; USART Mode Select Bit 0
.EQU UMSEL1 = 7 ; USART Mode Select Bit 1
// *********************************************************



// Project: ClockDividor
// ¯¯¯¯¯¯¯¯
// Description: The system clock gets devided into several frequencies.
// ¯¯¯¯¯¯¯¯¯¯¯¯ See wireing for details.
//              A crystal oszillator (18MHz) is required on pin 5.
//
// Device: ATtiny2313A
// ¯¯¯¯¯¯¯
// Fuses: 0x## 0x## 0x## 0x##
// ¯¯¯¯¯¯
// By: LotadaC (makerconnect.de)
// ¯¯¯ tightDev.Net (just a bit markup)
//
// Wireing:
// ¯¯¯¯¯¯¯¯         _____ _____
//                 |     V     |
//  (ISP Reset/dW) |  1     20 | VCC (5V)
//              nc |  2     19 | (ISP SCK)
//              nc |  3     18 | PB6 (=f/2000), (ISP MISO)
//              nc |  4     17 | PB5 (=f/1000), (ISP MOSI)
//   XTAL1 (18MHz) |  5     16 | OC1B (=f/100)
//   XCK0?? (=f/2) |  6     15 | OC1A (=f/200)
//              nc |  7     14 | OC0A (=f/20)
//              nc |  8     13 | PB1 (=f/20000)
//    OC0B (=f/10) |  9     12 | PB0 (=f/10000)
//             GND | 10     11 | nc
//                 |___________|
//
// Resulting frequencies:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//   XTAL1: 18MHz (from oszillator)
//   XCK0:  9MHz
//   OC0B:  1.8MHz
//   OC0A:  0.9MHz
//   OC1B:  180kHz
//   OC1A:  90kHz
//   PB5:   18kHz
//   PB6:   9kHz
//   PB0:   1.8kHz
//   PB1:   0.9kHz
// 180Hz?
// 90Hz?
// 50Hz möglich? f/360000 (weil Netzfrequenz)
// 60Hz möglich? f/300000 (weil Netzfrequenz)
// Pins wären ja noch frei.


// Program configuration
.DEF Count = R17
.DEF USIcntReload = R18



// Start of application
.ORG 0x0000    RJMP Init



// USI Overflow ISR
// NOTICE: This ISR is written inside the IVT and may need to be changed if other
//         interrupts are used in future.
.ORG USI_OVFaddr

    OUT  USISR, USIcntReload    // <- IRQ each 5. edge, Flag clear
    SBI  PINB,  PB5                // toggle each edge
    SBIC PINB,  PB5
  RJMP Done                        // toggle each period
    SBI  PINB,  PB6
    SUBI Count, 1                // each fifth
  BRNE Done
    LDI  Count, 5
    SBI  PINB,  PB0                // toggle
    SBIC PINB,  PB0
    SBI  PINB,  PB1                // ...period
  Done:

RETI



Init:

    // Setup Outputs (OC0B  XCK)
    LDI R16,    (1<<PD5)|(1<<PD2)
    OUT DDRD,   R16

    // Setup Outputs (f/2000, f/1000, OC1B, OC1A, OC0A, f/20000, f/10000)
    LDI R16,    (1<<PB6)|(1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
    OUT DDRB,   R16

    // Setup USI
    LDI R16,    (1<<USIOIE)|(1<<USICS1)
    OUT USICR,  R16 // each edge increments USI-conter, IRQ enabled
    LDI USIcntReload, (1<<USIOIF)|11 // Preload, Overflow-Flag has to be cleared manually
    OUT USISR,  USIcntReload // <- IRQ each 5 edges

    // Setup Timer0
    LDI R16,    4        // OC0B generates f/10
    OUT OCR0B,  R16
    LDI R16,    9        // OC0A generates f/20
    OUT OCR0A,  R16
    LDI R16,    (1<<COM0A0)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00) // fast PWM - OC0A toggle, OC0B PWM
    OUT TCCR0A, R16
    LDI R16,    (1<<WGM02)|(1<<CS00) // fastPWM, prescaler=1 start
    OUT TCCR0B, R16

    // Setup Timer1
    LDI R16,    HIGH(49) // OC1B generates f/100
    OUT OCR1BH, R16
    LDI R16,    LOW(49)
    OUT OCR1BL, R16
    LDI R16,    LOW(99)  // OC1A generates f/200
    OUT OCR1AL, R16
    LDI R16,    (1<<COM1A0)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10) // fast PWM - OC1A toggle, OC1B PWM
    OUT TCCR1A, R16
    LDI R16,    (1<<WGM13)|(1<<WGM12)|(1<<CS10) // fastPWM, prescaler=1 start
    OUT TCCR1B, R16

    // Setup USART (XCK0 generates f/2)
    LDI R16,    (1<<TXEN)|(1<<UCSZ2)
    OUT UCSRB,  R16
    LDI R16, (1<<UMSEL0)|(1<<UCSZ1)|(1<<UCSZ0)
    OUT UCSRC,  R16
    LDI R16,    0
    OUT UBRRL,  R16

    // Set software counter preload
    LDI Count,  5

    // Enable interrupts
    SEI

// RJMP Loop - Not required, it's the next sub.



// Main application loop. May add WDR and SLEEP to it?
Loop:

    RJMP Loop

//End of file


Finally, ich habs kompiliert bekommen. Herrjeh, ich bin schon zu lange raus ^^'
Der tiny wird ziemlich beleidigt sein :D

Code:
AVRASM: AVR macro assembler 2.1.42 (build 1796 Sep 15 2009 10:48:36)
Copyright (C) 1995-2009 ATMEL Corporation

C:\Programmierung\ClockDividor\ClockDividor.asm(2): Including file 'C:\Program Files (x86)\Atmel\AVR Tools\AvrAssembler2\Appnotes\tn2313Adef.inc'
C:\Programmierung\ClockDividor\ClockDividor.asm(149): No EEPROM data, deleting C:\Programmierung\ClockDividor\ClockDividor.eep

ATtiny2313A memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x000000 0x00007e     96      0     96    2048   4.7%
[.dseg] 0x000060 0x000060      0      0      0     128   0.0%
[.eseg] 0x000000 0x000000      0      0      0     128   0.0%

Assembly complete, 0 errors. 0 warnings

Gesteckt ists auch schon, jetzt muss ich nur noch meinen Drachen lauffähig machen. Dauert noch n bissl, das USB Kabel wird grad andersweitig genutzt (Drucker).

Was sagst du zu den anderen Frequenzen? Sollte doch auch per Software gehen, oder nicht?
XCK0 Pin ist richtig? Der heißt bei dem Chip wohl anders (oder ich bin blind)...
 
heißt bei dem Chip wohl anders
Ja, XCK ohne die Null. Generell ist beim USART des Tn2313 da keine null (beim m88 hingegen schon, obwohl das da auch der einzige ist). Ich hab das als C&P-Fehler natürlich extra miteingebaut - ist ja schließlich ein Tiny2313A :vroam:

Wegen der restlichen Frequenzen: klar kannst Du aus den vorhandenen Frequenzen (die Timer-Events können ja nebenbei auch IRQs triggern) weitere Software-Frequenzen generieren. Die sind ja schon hecht "tief". Du mußt nur sehen, inwiefern Du die wirklich (hinreichend genau) treffen kannst.
Ich schau da selbst später nochmal drüber...

Beim USI-TOV-IRQ kannst Du natürlich auch aus der IVT raushopsen (lassen) - nach dem USI kommen noch EEPROM, Watchdog und die beiden PCINTs. Der entsprechende Hinweis im Code ist natürlich gut - ich habs ja nur als "proof of concept" implementiert.

P.S.: ich hatte mir zwei Register reserviert, mußt Du ggf später beachten. Hatte keine Lust, den Controller ständig vom Schreibtisch (=Rechenregister) aufstehen zu lassen, um die Ordner (=Datenbytes) zum Aktenschrank (=SRAM) zu schleppen/von da zu holen. Ist zwar nicht so weit wie das Archiv im Keller (=Eeprom), aber...

Der tiny wird ziemlich beleidigt sein
Das hast Du schon gesehen?
 
Jo die Register hab ich wohl gesehen :)

Also, die Resultate (Gemessen mit PeakTech 2025 und untere Frequenzen zusätzlich mit Billig-Oszi):
XTAL1: 17,99MHz - OK (Soll: 18,00MHz)
XCK: 8,998MHz - OK (Soll: 9,000MHz)
OC0B: 1,799 MHz - OK (Soll: 1,800MHz)
OC0A: 899,8kHz - OK (Soll: 900,0kHz)
OC1B: 179,9kHz - OK (Soll: 180,0kHz)
OC1A: 89,98kHz - OK (Soll: 90,00kHz)
PB5: Kein Ausgang - Nicht OK (Soll: 18,00kHz)
PB6: Kein Ausgang - Nicht OK (Soll: 9,000kHz)
PB0: Kein Ausgang - Nicht OK (Soll: 1,800kHz)
PB1: Kein Ausgang - Nicht OK (Soll: 900,0Hz)

Mal schaun was da schief läuft.

p.s.: Nettes p.s. :D
 
Ooops, sorry, das hab ich dezent überlesen.

XTAL1: 17,99MHz - OK (Soll: 18,00MHz)
XCK: 8,998MHz - OK (Soll: 9,000MHz)
OC0B: 1,799 MHz - OK (Soll: 1,800MHz)
OC0A: 899,8kHz - OK (Soll: 900,0kHz)
OC1B: 179,9kHz - OK (Soll: 180,0kHz)
OC1A: 89,98kHz - OK (Soll: 90,00kHz)
PB5: 17,99kHz - OK (Soll: 18,00kHz)
PB6: 8,998kHz - OK (Soll: 9,000kHz)
PB0: 1,799kHz - OK (Soll: 1,800kHz)
PB1: 899,8Hz - OK (Soll: 900,0Hz)

Also alle Werte locker innerhalb der Toleranz.
Und nein, so schlimm ist's nicht, hab noch Stocherdrähte hier :)
Außerdem hätt ich wohl Lötzinn genommen. Büroklammern hab ich nicht hier, bin ja nicht MacGuyver :D
 
180 und 90Hz kannst Du genauso an 900Hz koppeln, wie 1800 und 900Hz an 9kHz. An 900Hz (genau genommen das toggeln bei 1800Hz) kannst Du außerdem mit zwei seperaten Zählern die beiden Netzfrequenzen koppeln.
900Hz/15=60Hz
900Hz/18=50Hz

Du könntest im Code noch kommentieren, daß der TxD-Pin durch den USART verwendet wird (für Dich also nicht mehr frei ist).
 
Hab ich sogar schon kommentiert :)
PinA1 (XTAL2) scheint ebenfalls nicht nutzbar zu sein, zumindest bekomm ich da nur ein Low Level 0.o
Umgelegt auf PortD gehts.

180Hz und 90Hz funktionieren jetzt auch.
PD0: 179.9Hz - OK (Soll: 180Hz)
PD6: 89,98Hz - OK (Soll: 90Hz)

Fehlen nur noch 50 und 60Hz.
Aktueller Stand:


CodeBox Assembler
// *************** Bugfixing tn2313Adef.inc ****************
.INCLUDE <tn2313Adef.inc>
.EQU UMSEL0 = 6 ; USART Mode Select Bit 0
.EQU UMSEL1 = 7 ; USART Mode Select Bit 1
// *********************************************************



// Project:     ClockDividor 1.1
// ¯¯¯¯¯¯¯¯
// Description: The system clock gets devided into several frequencies.
// ¯¯¯¯¯¯¯¯¯¯¯¯ See wireing for details.
//              A crystal oszillator (18MHz) is required on pin 5.
//
// Device:      ATtiny2313A
// ¯¯¯¯¯¯¯
// Fuses:       0xDF 0xDB 0xFF
// ¯¯¯¯¯¯
// By:          LotadaC (makerconnect.de) - initial developer
// ¯¯¯          tightDev.Net - just a bit markup, added frequencies, project idea
//
// Wireing:
// ¯¯¯¯¯¯¯¯                _____ _____
//                        |o    U     |
//         (ISP Reset/dW) |> 1     20 | VCC (5V)
//        PD0 (=f/100000) |< 2     19<| USCK - Conected to OC1A (ISP SCK)
//  nc (TxD, used by USI) |- 3     18>| PB6 (=f/2000), (ISP MISO)
//        nc (not usable) |- 4     17>| PB5 (=f/1000), (ISP MOSI)
//          XTAL1 (18MHz) |> 5     16>| OC1B (=f/100)
//             XCK (=f/2) |< 6     15>| OC1A (=f/200)
//        PD3 (=f/300000) |< 7     14>| OC0A (=f/20)
//        PD4 (=f/360000) |< 8     13>| PB1 (=f/20000)
//           OC0B (=f/10) |< 9     12>| PB0 (=f/10000)
//                    GND | 10     11>| PD6 (=f/200000)
//                        |___________|
//
// Resulting frequencies:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//   XTAL1: 18MHz (INPUT from oszillator)
//   XCK:   9MHz
//   OC0B:  1.8MHz
//   OC0A:  0.9MHz
//   OC1B:  180kHz
//   OC1A:  90kHz
//   PB5:   18kHz
//   PB6:   9kHz
//   PB0:   1.8kHz
//   PB1:   0.9kHz
//   PD0:   180Hz
//   PD6:   90Hz
//   PD4:   60Hz TODO
//   PD3:   50Hz TODO
//
// Power consumption:
// ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//   Controller: 8.600 mA (without load)
//   Oscillator: 0.507 mA
//   Total:      9.107 mA



// Program configuration
.DEF Temp1        = R16
.DEF Count1       = R17
.DEF Count2       = R18
.DEF USIcntReload = R19



// Start of application
.ORG 0x0000    RJMP Init



// USI Overflow ISR
// NOTICE: This ISR is written inside the IVT and may need to be changed if other
//         interrupts are used in future.
.ORG USI_OVFaddr

    // IRQ each 5th edge, Clear flag
    OUT  USISR,  USIcntReload

    // Generate 18kHz (toggle each edge)
    SBI  PINB,   PB5  // Toggle pin
    SBIC PINB,   PB5  // If low skip next command
  RJMP Done           // Only each 2nd period, so below is f/2

    // Generate 9kHz (toggle each 2nd period)
    SBI  PINB,   PB6  // Toggle pin
    SUBI Count1, 1    // Decrement Count1. If 0 Z flag is set
  BRNE Done           // Only each 5th period, so below is f/5

    // Generate 1.8kHz (each fifth from above, toggle)
    LDI  Count1, 5    // Reload Count1 initial value for 18k/9k
    SBI  PINB,   PB0  // Toggle pin
    SBIC PINB,   PB0  // If low skip next command
  RJMP Done           // Only each 2nd period, so below is f/2

    // Generate 900Hz (toggle each period)
    SBI  PINB,   PB1  // Toggle pin
    SUBI Count2, 1    // Decrement Count2. If 0 Z flag is set
  BRNE Done           // Only each 5th period, so below is f/5

    // Generate 180Hz (each fifth from above, toggle)
    LDI  Count2, 5    // Reload Count2 initial value for 180/90
    SBI  PIND,   PD0  // Toggle pin
    SBIC PIND,   PD0  // If low skip next command
  RJMP Done           // Only each 2nd period, so below is f/2

    // Generate 900Hz (toggle each period)
    SBI  PIND,   PD6  // Toggle pin
  // no jump required, it's the exit


// PD4 = 60hz
// PD3 = 50hz

  Done:

RETI



// Program and chip initialization
Init:

    // Setup Outputs (OC0B, XCK)
    LDI Temp1,   (1<<PD5)|(1<<PD2)
    OUT DDRD,    Temp1

    // Setup Outputs A (f/20000)
    LDI Temp1,   (1<<PA1)
    OUT DDRA,    Temp1

    // Setup Outputs B (f/2000, f/1000, OC1B, OC1A, OC0A, f/20000, f/10000)
    LDI Temp1,   (1<<PB6)|(1<<PB5)|(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0)
    OUT DDRB,    Temp1

    // Setup Outputs D (f/200000, f/360000, f/300000, f/100000)
    LDI Temp1,   (1<<PD6)|(1<<PD4)|(1<<PD3)|(1<<PD0)
    OUT DDRD,    Temp1

    // Setup USI
    LDI Temp1,   (1<<USIOIE)|(1<<USICS1)
    OUT USICR,   Temp1      // each edge increments USI-conter, IRQ enabled
    LDI USIcntReload, (1<<USIOIF)|11 // Preload, Overflow-Flag has to be cleared manually
    OUT USISR,   USIcntReload // <- IRQ each 5 edges

    // Setup Timer0
    LDI Temp1,   4        // OC0B generates f/10
    OUT OCR0B,   Temp1
    LDI Temp1,   9        // OC0A generates f/20
    OUT OCR0A,   Temp1
    LDI Temp1,   (1<<COM0A0)|(1<<COM0B1)|(1<<WGM01)|(1<<WGM00) // fast PWM - OC0A toggle, OC0B PWM
    OUT TCCR0A,  Temp1
    LDI Temp1,   (1<<WGM02)|(1<<CS00) // fastPWM, prescaler=1 start
    OUT TCCR0B,  Temp1

    // Setup Timer1
    LDI Temp1,   HIGH(49) // OC1B generates f/100
    OUT OCR1BH,  Temp1
    LDI Temp1,   LOW(49)
    OUT OCR1BL,  Temp1
    LDI Temp1,   LOW(99)  // OC1A generates f/200
    OUT OCR1AL,  Temp1
    LDI Temp1,   (1<<COM1A0)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10) // fast PWM - OC1A toggle, OC1B PWM
    OUT TCCR1A,  Temp1
    LDI Temp1,   (1<<WGM13)|(1<<WGM12)|(1<<CS10) // fastPWM, prescaler=1 start
    OUT TCCR1B,  Temp1

    // Setup USART (XCK0 generates f/2)
    LDI Temp1,   (1<<TXEN)|(1<<UCSZ2)
    OUT UCSRB,   Temp1
    LDI Temp1,   (1<<UMSEL0)|(1<<UCSZ1)|(1<<UCSZ0)
    OUT UCSRC,   Temp1
    LDI Temp1,   0
    OUT UBRRL,   Temp1

    // Nothing to do in PRR, we use any component in there

    // Disable analog comperator (unused)
    LDI Temp1,   (1<<ACD)|(1<<ACI)
    OUT ACSR,    Temp1 // apply and wait 2 cycles
    NOP
    NOP
    OUT ACSR,    Temp1 // twice to ensure no interrupt has fired

    // Setup sleep mode (idle)
    LDI Temp1,   (1<<SE)
    OUT MCUCR,   Temp1

    // Setup the dog (0.25s)
    LDI Temp1,   (1<<WDE)|(1<<WDP2)
    OUT WDTCSR,  Temp1

    // Set software counter preload
    LDI Count1,  5
    LDI Count2,  5

    // Enable interrupts
    SEI

// RJMP Loop - Not required, it's the next sub.



// Main application loop
Loop:

    // Kick the dog
    WDR

    // Fall asleep (to save power)
    SLEEP

    // Restart application loop
    RJMP Loop

//End of file
 
:stupid:
Fehlen nur noch 50 und 60Hz.
Ja, die stehen ja außerhalb der Kaskade, die mußt Du zwischen 100 und 101 einbauen. Der Teil wird mit 1800Hz ausgeführt. Du zählst zwei weitere Counter runter, und toggelst bei 18 (toggelt mit 100Hz =50Hz Frequenz) bzw 15 (toggelt mit 120Hz -> 60Hz)... subi Counter, brne nächster test, sbi Bein, reload Counter - zweimal das ganze
Bei den 900Hz (1800Hz) sind halt drei Frequenzen angekoppelt...
PinA1 (XTAL2) scheint ebenfalls nicht nutzbar zu sein
Fuses: 0xDF 0xDB 0xFF
Du hast Doch einen externen Quarzoszillator an XTAL1, hast Du auch als externe Clock gefused, oder als externer Crystal?
Laut Table10-4 (alternate functions Port A - overrides) sollte der Pin bei externer Clock frei sein.
Laut Figure6-2 (Clock System - external clock pin drive) hingegen ist XTAL2 n.c.
:stupid:
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)