組み込みの(ハードウェア)高速 PWMを使用して、80Mhz (F_osc) のクロックで 10% デューティ サイクルの 1kHz PWM を生成しようとしています。
ドキュメントによると、ベース期間 (PTPER の数値) は次のように計算されます。
PTPER = F_osc / [(F_pwm) x (PWM_Clk_Prescale)]
F_osc = 80Mhz、F_pwm = 1khz、Prescale = 8 を代入すると、PTPER=10,000 のカウントが得られます。
ただし、オシロスコープの出力から、PWM 周波数が ~2khz であることがわかります。.
私は何か間違ったことをしていますか?以下は私のコードです -
#include<p33EP512MU810.h>
#include<p33Exxxx.h>
//---------------- compiler directives------------------
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // Clock Switching Enabled and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystal
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software
//------------------------------------------------------
//function to initialise oscillator and set up clock
void Init_Oscillator(void)
{
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 12M*40/(3*2)=80Mhz for 12M input clock
// 0.5M < Fin/N1 < 8MHz
// 100M < Fin*M/N2 < 200M
// Fcy = Fosc / 2 = 40 MIPS
PLLFBD = 38; // M=80
CLKDIVbits.PLLPOST = 0; // N2=2
CLKDIVbits.PLLPRE = 1; // N1=3
OSCTUN = 0; // Tune FRC oscillator, if FRC is used
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
// Clock switch to incorporate PLL
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to
// Primary Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01); // Start clock switching
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch (to XT w/ PLL) to occur
while(OSCCONbits.LOCK!=1) {}; // Wait for PLL to lock
}
void Init_PWM(void)
{
/**** PTCON: PWM Time Base Control Register ****/
PTCONbits.PTEN = 0; // Timer Enable bit: DISABLE MCPWM
//---------------------------------------------------------------
//Prescaler 1:8
PTCON2bits.PCLKDIV = 0b011; // PCLKSEL: 1,2,4,8,16,32,64
//mode selection
PWMCON1 = 0x0000; //PTPER holds period count of PWM
//Independent mode enable
IOCON1 = 0xCC00; //fig 14-35 of PWM manual
// 0xCC00 => PENH high, PENL high, PMOD: 11- True Independent PWM o/p
//---------------------------------------------------------------
/**** PTPER: PWM Time Base Period Register ****/
PTPER = 10000; // Period Value bits
//Enable PWM timer
PTCONbits.PTEN = 1; // Timer Enable bit: ENABLE MCPWM
}
//--- extra settings:
// 1) Stop in IDLE MODE :: PTCONbits.PTSIDL = 1 (yes)
// 2) Setting a particular pin as output ==> IOCONxbits.PENH(/L) = 1(enabled)
// 3) MDC,PDC,SDC et al depend on the PWM MODE.
// Resp, selection of PTPER,PHASE,SPHASE.
//---
int main(void)
{
Init_Oscillator();
Init_PWM();// Initialize PWM module
PDC1 = 1000; // This sets the duty cycle.
while(1); //loop forever //while
return 0;
}