本帖最后由 闲来玩玩 于 2013-2-11 08:17 编辑
#define FCY 20000000 // 20 MIPS
#define FPWM 20000 // 20 kHz
#define DEADTIME (unsigned int)(0.000002 * FCY)
#define _DES_FREQ 60 // 需要产生60 Hz 正弦波
#define _DELTA_PHASE (unsigned int)(_DES_FREQ * 65536 / FPWM)
#define _0_DEGREES 0x0000
#define _120_DEGREES 0x5555
#define _240_DEGREES 0xAAAA
unsigned int Phase, Delta_Phase, Phase_Offset;
int Multiplier, Result;
sinetable[] =
{ 0,3212,6393,9512,12539,15446,18204,20787,23170,25329,
27245,28898,30273,31356,32137,32609,32767,32609,32137,31356,30273,28898,
27245,25329,23170,20787,18204,15446,12539,9512,6393,3212,0,-3212,-6393,
-9512,-12539,-15446,-18204,-20787,-23170,-25329,-27245,-28898,-30273,
-31356,-32137,-32609,-32767,-32609,-32137,-31356,-30273,-28898,-27245,
-25329,-23170,-20787,-18204,-15446,-12539,-9512,-6393,-3212 };
void InitMCPWM(void)
{
TRISE = 0x0100; // 将PWM 和FLTA 引脚分别配置为输出和输入
PTPER = (FCY/FPWM - 1) >> 1; // 计算期望频率所对应的周期
OVDCON = 0x0000; // 禁止所有PWM 输出。
DTCON1 = DEADTIME; // 死区时间为~2 us@ 20 MIPS 且预分频比为1:1
PWMCON1 = 0x0077; // 使能PWM 输出引脚并使能互补模式
PDC1 = PTPER; //相A 电压为0 伏。此值对应于50% 占空比
PDC2 = PTPER; // 相B 电压为0 伏。
PDC3 = PTPER; // 相C 电压为0 伏。
IFS2bits.PWMIF = 0; // 清零PWM 中断标志
IEC2bits.PWMIE = 1; // 允许PWM 中断
OVDCON = 0x3F00; // PWM 输出由PWM 模块进行控制
PTCONbits.PTMOD = 2; // 中心对齐PWM 工作
Phase = 0; // 复位Phase 变量
Delta_Phase = _DELTA_PHASE; // 将Phase 增量初始化为60Hz 正弦波模式
PTCONbits.PTEN = 1; // 启动PWM
return;
}
int main(void)
{
InitMCPWM();
while(1)
{ ;
}
}
void _ISR _PWMInterrupt(void)
{
//关PWM中断
//问题:每次进中断,变量Delta_Phase是不是要增一,增大到最大数又是多少?
Phase += Delta_Phase; // 将Delta_Phase 累加到Phase 变量中
Phase_Offset = _0_DEGREES; // 将正确的值加入相位偏移量中
Multiplier = sinetable[(Phase + Phase_Offset) >> 10]; // 获取正弦信息
asm("MOV _Multiplier, W4"); // 装载第一个乘数
asm("MOV _PTPER, W5"); // 装载第二个乘数
asm("MOV #_Result, W0"); // 将结果地址载入W0
asm("MPY W4*W5, A"); // 执行小数乘法
asm("SAC A, [W0]"); // 将乘法结果装入var 结果
PDC1 = Result + PTPER;
Phase=0;
//清中断标志,和开PWM中断。
}
|
|