50% PWM für H-Brücke mit Attiny1614

Gast #6765690
Lesenswert?

Hallo,

ich würde gerne ein 50% Duty Cycle erzeugen für zwei mosfet gates mit 
einer Totzeit um einen KS zu verhindern. Taktrate 20, 50, 70 und 100 
kHz.

Der TCD0 Timer des  Attiny1614 sollte diese Funktion bieten, falls ich 
das Datenblatt nicht falsch verstehe. Datenblatt im Anhang. Pin PA4 und 
PA5 wären die Ausgänge. Leider bekomme ich es nicht hin...

Mein Versuch:
1
int main(void) {
2
    PORTA.DIRSET |= 0b00110000;
3
    
4
    TCD0.CTRLA = 0b00001010; // 20 MHz; CNTPRES = 0x1; SYNCPRES = 0x1;
5
    TCD0.CTRLB = 0x01; // TWO RAMP 0x1
6
    TCD0.CTRLC = 0x00; // TCD_FIFTY_bm;
7
    
8
    TCD0.CMPASETL = 0b00000000;
9
    TCD0.CMPASETH = 0b00000000;
10
    
11
    TCD0.CMPBSETL = 0b00111111;
12
    TCD0.CMPBSETH = 0b00000000;
13
    
14
    TCD0.CMPACLRL = 0b00111110;
15
    TCD0.CMPACLRH = 0b00000000;
16
            
17
    TCD0.CMPBCLRL = 0b11111110;
18
    TCD0.CMPBCLRH = 0b11111111;
19
    
20
    TCD0.STATUS = TCD_ENRDY_bm;
21
    TCD0.CTRLA = TCD_ENABLE_bm;
22
    sei();
23
    
24
    while (1) {
25

26
    }
27
}

Würde mich über Hinweise freuen.
Angehängte Dateien:
Gast #6765712
Lesenswert?

void tcd_capt_start(void){
    // Event setup(trigger = PA1)
    EVSYS.ASYNCCH0 = EVSYS_ASYNCCH0_PORTA_PIN1_gc;
    EVSYS.ASYNCUSER6 = EVSYS_ASYNCUSER6_ASYNCCH0_gc;

    // TCD setup(capture mode)
    TCD0.CTRLA = 0;
    TCD0.CMPBCLR = 0xFFF;
    TCD0.INTFLAGS = TCD_TRIGA_bm;
    TCD0.INTCTRL = TCD_TRIGA_bm;
    TCD0.EVCTRLA = TCD_CFG_ASYNC_gc | TCD_ACTION_CAPTURE_gc | 
TCD_TRIGEI_bm;
    TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
    while (!(TCD0.STATUS & TCD_ENRDY_bm));
    TCD0.CTRLA = TCD_CLKSEL_EXTCLK_gc | TCD_ENABLE_bm;
}
Gast #6765857
Lesenswert?

> Klappt leider nicht.

Und wenn die Zeile von kurzwelle eingebaut wird?
> while (!(TCD0.STATUS & TCD_ENRDY_bm));

Denn ENRDY ist readonly, folglich
> TCD0.STATUS = TCD_ENRDY_bm;
Unsinn; und "Ensure" heißt nicht "Enable".
Gast #6765893
Lesenswert?

Auf die Schnelle, ist zwar Assembler und für einen AVR128DB28, hilft 
aber vielleicht trotzdem weiter - dies erzeugt an PA4 ein Rechtecksignal 
mit Tastgrad 0.5:
1
    sbi     VPORTA_DIR,4                                ; TCD.WOA
2
    putiw   TCD0_CMPBCLR,4095
3
    putiw   TCD0_CMPASET,2047
4
    puti    CPU_CCP,CPU_CCP_IOREG_gc
5
    puti    TCD0_FAULTCTRL,0b00010000                   ; COMPAEN
6
     lds    tmp0,TCD0_STATUS
7
     sbrs   tmp0,0                                      ; ENRDY
8
    rjmp    pc-3
9
    puti    TCD0_CTRLA,0b0_00_00_00_1                   ; enable
#6766136
Lesenswert?

Hallo,

µC: AVR128DB48
Taktquelle: interne 16MHz

Im Eingangscode gibts mehrere Dinge. Den CPU Registern fehlt die 
Schreibberechtigung und das Eventsystem wird nicht benötigt. Die Compare 
Register muss man nicht unterteilen. Die Frequenzen kannste sicherlich 
selbst anpassen. Formeln stehen im Manual.
1
void initTCD0 (void) // 12 Bit Timer -->> max 4096
2
{   
3
    // Duty Cycle 50%
4
    const uint16_t lowTime  {500};
5
    const uint16_t highTime {500};
6
     
7
    TCD0.CTRLA = TCD_CLKSEL_OSCHF_gc;
8
        
9
    TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
10
    
11
    TCD0.CMPASET = lowTime;                 // WOA     
12
    TCD0.CMPACLR = lowTime + highTime;      // WOA
13
    TCD0.CMPBSET = lowTime;                 // WOB                    
14
    TCD0.CMPBCLR = lowTime + highTime;      // WOB
15
        
16
    /* Enable the PWM channels */
17
    CPU_CCP = CCP_IOREG_gc;
18
    TCD0.FAULTCTRL = (TCD_CMPAEN_bm | TCD_CMPA_bm | TCD_CMPBEN_bm | TCD_CMPB_bm);
19
    
20
    /* Wait for TCD to be ready for enabling */
21
    while (!(TCD0.STATUS & TCD_ENRDY_bm)) { ; }
22
        
23
    TCD0.CTRLA |= TCD_ENABLE_bm;    // Enable TCD0
24
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren