Hallo zusammen! Warum habe ich eine PWM-Frequenz von 63,5 kHz bei einem externen 16 MHz Quarz, wenn ich folgendes Register wie folgt beschreibe? CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0); ==> Prescaler = 128 Egal wie ich die Bits im Register verändere, ich erhalte immer ein 63,5 kHz PWM-Signal! ==> der Prescaler ist ständig auf Divisor 1 Warum? Ich müsste doch mit CLKPR-Register, die PWM-Frequenz ändern können!? Kann mir jemand helfen? Vielen DANK!
Hi >Warum? Ich müsste doch mit CLKPR-Register, die PWM-Frequenz ändern >können!? Kannst du auch. Aber zum Einstellen des Prescalers ist ein bestimmter Timing notwendig. Also noch mal Datenblatt lesen. MfG Spess
uCli schrieb: > Kann mir jemand helfen? Datenblattleser wissen mehr
1 | To avoid unintentional changes of clock frequency, a special write |
2 | procedure must be followed to change the CLKPS bits: |
3 | 1. Write the Clock Prescaler Change Enable (CLKPCE) bit to one and all |
4 | other bits in CLKPR to zero. |
5 | 2. Within four cycles, write the desired value to CLKPS while writing |
6 | a zero to CLKPCE. |
Hallo! Vielen Dank für euere Antworten. Leider funktioniert es noch nicht, kann mir jemand sagen, was ich in meinem Code falsch mache. Wo liegt der Fehler beim beschreiben des Prescaleregisters? #include <avr/io.h> #include <avr/interrupt.h> //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx // Ramp_Mode_Selection int ramp_mode = 0; // Mode: 4=Four_Ramp/2=Two_Ramp/1=One_Ramp/0=Center_Aligned // Define_Times float DUTY_CYCLE; double PSC_CYCLE; double DEAD_TIME_0; double DEAD_TIME_1; double ON_TIME_0; double ON_TIME_1; //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx void init_pwm_values(void) { }; // PWM_Overlapping_Selection void init_lapping(void) { int pwm_overlapping = 0; // Mode: 0=non_overlapping/1=overlapping if(pwm_overlapping == 1) { DEAD_TIME_0 = 50; ON_TIME_0 = 100; DEAD_TIME_1 = 75; ON_TIME_1 = 125; } else { DEAD_TIME_0 = 50; ON_TIME_0 = 75; DEAD_TIME_1 = 100; ON_TIME_1 = 125; } } // Power_Stage_Controll_2_Initalisation void init_psc2(void) { //PCNF2 = (0<<PCLKSEL2); // Slow_Clock_Input //CLK_I/O CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0); CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0); PSOC2 = (1<<POEN2A)|(1<<POEN2B); OCR2SA = DEAD_TIME_0; OCR2RA = ON_TIME_0; OCR2SB = DEAD_TIME_1; OCR2RB = ON_TIME_1; } // Ramp_Mode_Initialisation void init_ramp_mode(void) { switch (ramp_mode) { case 4: PCNF2 = (1<<PMODE21)|(1<<PCLKSEL2)|(1<<POP2); // Four_Ramp_Mode break; case 2: PCNF2 = (1<<PMODE20)|(1<<POP2); // Two_Ramp_Mode break; case 1: PCNF2 = (0<<PMODE21)|(0<<PMODE20)|(1<<POP2); // One_Ramp_Mode break; case 0: PCNF2 = (1<<PMODE21)|(1<<PMODE20)|(1<<POP2)|(0<<PCLKSEL2); // Center_Aligned_Mode // Slow_Clock_Input (PCLKSEL2 = 0) break; } } // Power_Stage_Controll_Input_Initialisation // page:167 void init_psc_input(void) { PFRC2A = 0; PFRC2B = 0; } // PWM_Output_Selection void init_pwm_out(void) { //PCTL2 = (0<<PPRE21)|(0<<PPRE20); // No_Divider_On_PSC_Input_Clock PCTL2 = (1<<PRUN2); // PWM_Output_enable } int main(void) { //init_pwm_values(); init_lapping(); // Exclude_from_build_for_defining_divergent_times init_psc2(); init_ramp_mode(); init_psc_input(); init_pwm_out(); while(1) { } } Wäre nett, wenn mir jemand weiterhelfen könnte! Danke! Gruß
1 | void init_psc2(void) |
2 | {
|
3 | //PCNF2 = (0<<PCLKSEL2); // Slow_Clock_Input //CLK_I/O
|
4 | |
5 | CLKPR = (1<<CLKPCE)|(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0); |
6 | |
7 | CLKPR = (0<<CLKPCE)|(0<<CLKPS3)|(1<<CLKPS2)|(1<<CLKPS1)|(1<<CLKPS0); |
sieh dir mal im Assemblerlisting an, was der Compiler da drauss macht. Da hier das Timing kritisch ist, ist es unabdingbar dass er hier eine kurze Sequenz daraus generiert, ohne viel Schnörkel.
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.