📄 pwm.c
字号:
/****************************************************************
*
* Microchip 16-bit Embedded Control Design Contest
*
* Entry # MT2268
*
* Spa Pump Controller
*
*****************************************************************
*
* PWM output control routines
*
*****************************************************************/
#include "PumpCtl.h"
#include "PWM.h"
/*
Initialize the PWM module
*/
void PWM_init (void)
{
PTCON = 0x1; // Disable PWM module
PTPER = _PWM_PERIOD - 1; // Set timebase period
MDC = _PWM_PERIOD / 2; // Make sure all duty cycle values are valid
PWM_REG (PDC, PWM_CH_run) = _PWM_MIN_DUTY_INV;
PWM_REG (PDC, PWM_CH_com) = _PWM_MIN_DUTY_INV;
PWM_REG (PDC, PWM_CH_aux) = _PWM_MIN_DUTY_INV;
PWM_REG (PDC, PWM_CH_pfc) = _PWM_MIN_DUTY_PFC;
PWM_REG (DTR, PWM_CH_run) = _PWM_DEADTIME - 1; // Set deadtime for all channels
PWM_REG (DTR, PWM_CH_com) = _PWM_DEADTIME - 1;
PWM_REG (DTR, PWM_CH_aux) = _PWM_DEADTIME - 1;
PWM_REG (DTR, PWM_CH_pfc) = _PWM_DEADTIME - 1;
PWM_REG (ALTDTR, PWM_CH_run) = _PWM_DEADTIME - 1;
PWM_REG (ALTDTR, PWM_CH_com) = _PWM_DEADTIME - 1;
PWM_REG (ALTDTR, PWM_CH_aux) = _PWM_DEADTIME - 1;
PWM_REG (ALTDTR, PWM_CH_pfc) = _PWM_DEADTIME - 1;
PWM_REG (IOCON, PWM_CH_run) = 0xC301; // Set complementary mode with override
PWM_REG (IOCON, PWM_CH_com) = 0xC301; // for INV channels
PWM_REG (IOCON, PWM_CH_aux) = 0xC301;
PWM_REG (IOCON, PWM_CH_pfc) = 0x5701; // Set independent active-low for PFC channel
PWM_REG (FCLCON, PWM_CH_run) = 0x0044; // Set SFLT1 to active-low
PWM_REG (FCLCON, PWM_CH_com) = 0x0044; // latched fault input for INV
PWM_REG (FCLCON, PWM_CH_aux) = 0x0044;
PWM_REG (FCLCON, PWM_CH_pfc) = 0x004D; // and SFLT2 non-latched for PFC
PWM_REG (PWMCON, PWM_CH_run) = 0; // Clear all fault status latches
PWM_REG (PWMCON, PWM_CH_com) = 0;
PWM_REG (PWMCON, PWM_CH_aux) = 0;
PWM_REG (PWMCON, PWM_CH_pfc) = 0;
PWM_REG (PWMCON, PWM_CH_run) = 0x1000; // Enable fault interrupt for all channels
PWM_REG (PWMCON, PWM_CH_com) = 0x1000;
PWM_REG (PWMCON, PWM_CH_aux) = 0x1000;
PWM_REG (PWMCON, PWM_CH_pfc) = 0x1080; // and disable deadtime for PFC channel
PWM_REG (LEBCON, PWM_CH_pfc) = 0x3800 | (_PWM_BLANKING - 1);
// Set fault blanking for both PFC edges
SEVTCMP = 0x0010; // Set special event compare time just after start of cycle
PTCON = 0x8800; // Enable PWM module and special event interrupt
}
/*
Set PWM output override mode
*/
void PWM_mode (BYTE channel, BYTE mode)
{
BYTE ovr_dat, ovr_en;
switch (mode) {
case PWM_MODE_off:
ovr_dat = 0; // Set PWMxH low, PWMxL low
ovr_en = 1;
break;
case PWM_MODE_low:
ovr_dat = 1; // Set PWMxH low, PWMxL high
ovr_en = 1;
break;
case PWM_MODE_high:
ovr_dat = 2; // Set PWMxH high, PWMxL low
ovr_en = 1;
break;
case PWM_MODE_run:
ovr_dat = 0;
ovr_en = 0; // Disable override
break;
default:
return;
}
if (channel == PWM_CH_pfc) {
DISABLE_INTS;
// Override always sets PFC PWM pin inactive
PWM_REG_BITS (IOCON, bits.OVRDAT, PWM_CH_pfc) = 0;
if (ovr_en) // Set both enable bits (per Rev A1 Errata #11)
PWM_REG (IOCON, PWM_CH_pfc) |= 0x0300;
else
PWM_REG (IOCON, PWM_CH_pfc) &= ~0x0300;
ENABLE_INTS;
}
else {
DISABLE_INTS; // Set inverter override pin values
PWM_REG_BITS (IOCON, bits.OVRDAT, PWM_CH_run) = ovr_dat;
PWM_REG_BITS (IOCON, bits.OVRDAT, PWM_CH_com) = ovr_dat;
PWM_REG_BITS (IOCON, bits.OVRDAT, PWM_CH_aux) = ovr_dat;
if (ovr_en) {
PWM_REG (IOCON, PWM_CH_run) |= 0x0300;
PWM_REG (IOCON, PWM_CH_com) |= 0x0300;
PWM_REG (IOCON, PWM_CH_aux) |= 0x0300;
}
else {
PWM_REG (IOCON, PWM_CH_run) &= ~0x0300;
PWM_REG (IOCON, PWM_CH_com) &= ~0x0300;
PWM_REG (IOCON, PWM_CH_aux) &= ~0x0300;
}
ENABLE_INTS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -