Assembler Frequenz Teiler (Custom)

Die 2 Zeilen in der Kaskade sind Überbleibsel vom "runter ziehen", da standen die 2 jetzt eingebundenen Frequenzen noch mit davor, aber da jetzt eingebunden entfernt :)
Dass die da nicht eingebunden werden können ist klar. War nur um ständiges Scrollen zu verhindern welcher Pin jetzt was ist.

Bin jetzt nur grad am überlegen ob ich es direkt in der ISR einbinde (via RCALL), oder einfach ein Flag setze und in der Main behandle. Nicht dass die ISR nachher länger läuft als sie aufgerufen werden sollte.

Und whoops, hab mich verfused. Lustigerweise ging es trotzdem mit "Ext. Crystal Osc. 8MHz+" 0.o
Muss ich noch mal testen. "Crystal Oscillator" klang ja auf den ersten Blick ja auch richtig. Wobei... Für mögliche spätere Versionen könnte es sinnvoll sein zu versuchen den Pin frei zu lassen. Ein Quartz ist halt billiger als ein Oszi. Oder man könnte den Pin (oder einen Anderen) anderweitig nutzen. Wenn die Spannung unter Brown-Out fällt müsste doch eigentlich jeder Pin offen sein, man könnte also den Pin einfach per Software High setzen, Pull-Down dran, Mosfet dran und hätte somit für den Rest der Schaltung einen Schutz gegen Tiefentladung, oder?
 
Lustigerweise ging es trotzdem mit "Ext. Crystal Osc. 8MHz+" 0.o
Muss ich noch mal testen. "Crystal Oscillator" klang ja auf den ersten Blick ja auch richtig.
Das geht immer. XTAL2 ist der Ausgang des internen Oszillatorverstärkers, der bringt salopp gesagt den Quarz zum schwingen. XTAL1 ist der Eingang des Verstärkers, wo quasi der Takt eingeht. Wenn der Controller irgendeinen Takt an XTAL1 erwartet, solltest Du an XTAL1 immer mit einer externen Clock reinkommen... (hatte ALABEL als brutale Rettung bei Verfusungen erwähnt)
Mit Crystal-Oszillator ist der interne Oszillator gemeint, der mit einem externen Quarz/Resonator an den beiden XTALs arbeitet.
ich würds in der ISR lassen:


CodeBox Assembler
    // Generate 900Hz (toggle each period)
    SBI  PINB,   PB1  // Toggle pin
    //hier einbauen
    SUBI Count3, 1
BRNE to50Hz
    sbi pinregister,pin //60Hz
    ldi count3, cont3reload //=15
to50Hz:
    SUBI Count4, 1
BRNE to180Hz
    sbi pinregister, pin //50Hz
    ldi Count4, count4reload //=18
to180Hz:
//weiter wie gehabt
    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

Count3/Count4 wieder als reservierte Register, die reload-Werte als Compilerkonstante oder direkt...
(natürlich kannst Du an der Stelle auch'n Flag in einem GPIOR setzen, und die 18/15-Uhrwerke im Hauptprogramm an das Flag koppeln - bringt aber mMn keine wirklichen Vorteile.)
P.S.:
Dass die da nicht eingebunden werden können
Das meinte ich gar nicht so - hatte nur Bezug genommen, daß die noch fehlen... alles gut...:good3:
 
  • Like
Reaktionen: TommyB
@LotadaC: Du bist der Beste :good:

Jetzt läuft alles. Ok, 9MHz und 1,8MHz sind grad futsch, aber da hatte ich aber gestern schon Probleme mit. BreadBoard halt. Aber da es gestern funktionierte und der Rest der Frequenzen die davon abgeleitet sind ebenfalls gehen gehe ich mal davon aus dass alles ok ist.

Der freie Pin (XTAL2) dient jetzt als Power Good Signal, ist also immer High, außer der Brown-Out schlägt zu.
Hab die Konstanten auch mal nach oben gezogen.

Jetzt der aktuelle Code:


CodeBox Assembler
// *************** Bugfixing tn2313Adef.inc ****************
.INCLUDE <tn2313Adef.inc>  // Include chip defination
.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:       0xC0 0xDB 0xFF (Ext. Clock, Brown-Out 2.7V)
// ¯¯¯¯¯¯
// 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)
//        PA1 (Power Good) |< 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
//   PD3:   50Hz
//
//   Power Good signal is always high except if VCC is below 2.7V
//   so the rest of the circiut can be protected from low supply power.
//   Requires Pull-Down on this signal (something around 4k7, doesn't really matter).



// Program configuration
// - Temporary stuff
.DEF Temp1        = R16               // Generally used temporary register
// - Counter register
.DEF Count1       = R17               // Counter for 1.8kHz/900Hz
.DEF Count2       = R18             // Counter for 180Hz/90Hz
.DEF Count3       = R19               // Counter for 60Hz
.DEF Count4       = R20               // Counter for 50Hz
// - Cache (to speed up)
.DEF USIcntReload = R21               // USI reload value (fixed)
// - Hardware dividers
.EQU ReloadUSI    = (1<<USIOIF)|11  // f/2
.EQU ReloadOC0B   = 4               // f/10
.EQU ReloadOC0A   = 9               // f/20
.EQU ReloadOC1B   = 49              // f/100
.EQU ReloadOC1A   = 99              // f/200
// - Software dividers
.EQU ReloadCnt1   = 5                // /5 dividing, together with toggleing /10
.EQU ReloadCnt2   = ReloadCnt1      // same as above
.EQU ReloadCnt3   = 15                // f/300000
.EQU ReloadCnt4   = 18              // f/360000



// 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, ReloadCnt1 // 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

    // SUB part to generate 60Hz & 50Hz from 900Hz
    SUBI Count3, 1    // Decrement counter 3
  BRNE to50Hz         // If not 0 branch
    SBI  PIND,   PD4  // Toggle pin (60Hz)
    LDI Count3, ReloadCnt3 // Set reload value
  to50Hz:
    SUBI Count4, 1    // Decrement Counter 4
  BRNE ExitLF         // If not 0 branch
    SBI  PIND,   PD3  // Toggle pin (50Hz)
    LDI Count4, ReloadCnt4 // Set reload value
  ExitLF:
    // END SUB

    // Continue generate 900Hz (and following)
    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, ReloadCnt2 // 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 90Hz (toggle each period)
    SBI  PIND,   PD6  // Toggle pin
  //RJMP Done - no jump required, it's the exit

  Done:

RETI



// Program and chip initialization
Init:

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

    // Setup Outputs A (Power Good)
    LDI Temp1,   (1<<PA1)
    OUT DDRA,    Temp1

    // Set Power Good to high (will gets tri-state if broun-out catches us at 2.7V)
    //LDI Temp1,   (1<<PA1) - not required, it's loaded above.
    OUT PORTA,   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, ReloadUSI  // Preload, Overflow-Flag has to be cleared manually
    OUT USISR,   USIcntReload    // <- IRQ each 5 edges

    // Setup Timer0
    LDI Temp1,   ReloadOC0B      // OC0B generates f/10
    OUT OCR0B,   Temp1
    LDI Temp1,   ReloadOC0A      // 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(ReloadOC1B) // OC1B generates f/100
    OUT OCR1BH,  Temp1
    LDI Temp1,   LOW(ReloadOC1B)
    OUT OCR1BL,  Temp1
    LDI Temp1,   HIGH(ReloadOC1A) // OC1A generates f/200
    OUT OCR1AL,  Temp1
    LDI Temp1,   LOW(ReloadOC1A)
    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,  ReloadCnt1
    LDI Count2,  ReloadCnt2
    LDI Count3,  ReloadCnt3
    LDI Count4,  ReloadCnt4

    // 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


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

Assembly complete, 0 errors. 0 warnings
 
Jain, 9MHz werden direkt aus dem USART gewonnen (das beladen des UBRR mit 0 kannst Du eigentlich auch einsparen, hatte da vorher mit 1 (f/4) getestet.
Die 1,8MHz sind das PWM des Timers, der den anderen Pin mit 900kHz toggelt.
Breadboard klingt plausibel.

Das mit den 50/60Hz hat auf Anhieb gepaßt? Hatte das eigentlich nur unkontrolliert aus dem Handgelenk geschüttelt...

P.S.:
// By: LotadaC (makerconnect.de) - initial developer
// ¯¯¯ tightDev.Net - just a bit markup, added frequencies, project idea
:good2:
 
Da hast du aber richtig gut geschüttelt :)
Klappte auf Anhieb, musste nur die Register definieren, vorladen, und Pin Register und Nummer anpassen. Den selbsterklärenden Kleinkram halt.
Jetzt geht es nur noch darum das Board zu zeichnen und ggf. die Pins umzulegen dass sie etwas günstiger verlegbar sind. Feintuning.

Und Ehre wem Ehre gebührt ;)
So geschätzte 90% hast du ja gemacht. Ich hab's ja nur etwas anders geschrieben und n paar Kommentare dazu um zu verstehen was du warum wie gemacht hast. Und was soll ich sagen... Man lernt nie aus :)
Ja ok, die 2 Frequenzen hab ich eingefügt... War aber nur Copy'n'Paste von dir.
Anders als Andere schmücke ich mich nicht mit fremden Federn.

Der Dank geht aber natürlich auch an alle Anderen die hier mit geholfen hatten beim alternativen Lösungsvorschlag :wink:
 
:D
Schau mal in Init, speziell DDRD.

Das BreadBoard war also unschuldig :)
 
Auweia... böser Fehler...
Aber die beiden Blöcke (153,154 und 169, 170) hast Du sicher schon zusammengeführt
 
Jupp :)
Ich route denn mal die 2. Platine. Wird wieder lustig, mal was Anderes als ständig nur zu coden.
 

Ü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)