在一些应用领域需要严格控制PWM输出次数,由于APM8S007stimer的单次模式是输出完一次PWM后,就会关掉stimer,再去使能之前会有一个短暂的低电平,没办法避免;
建议使用连续模式,数周期的模式去控制发送的PWM次数,以下为STIMER配置例程:
u8 pwm_output_cnt = 0;
// 用于测试
P2_MD0 &= ~GPIO_P23_MODE_SEL(0x03);
P2_MD0 |= GPIO_P23_MODE_SEL(0x01);
FOUT_S23 = GPIO_FOUT_AF_FUNC;
// 配置STIMER0的PWM端口:P21--STMR0_PWM
P2_MD0 &= ~GPIO_P21_MODE_SEL(0x03);
P2_MD0 |= GPIO_P21_MODE_SEL(0x01);
FOUT_S21 = GPIO_FOUT_STMR0_PWMOUT; // 选择stmr0_pwmout
// 配置STIMER1的PWM端口:P22--STMR1_PWM
P2_MD0 &= ~GPIO_P22_MODE_SEL(0x03);
P2_MD0 |= GPIO_P22_MODE_SEL(0x01);
FOUT_S22 = GPIO_FOUT_STMR1_PWMOUT; // 选择stmr1_pwmout
// STMR0和STMR1互补配置:STMR0和STMR1为互补模式: STMR1的周期和占空比由STMR0控制,其他行为STMR1自行控制
STMR_CON0 &= ~STMR_01_SYSNCMP_SEL(0x3);
STMR_CON0 |= STMR_01_SYSNCMP_SEL(0x2); // STMR0和STMR1为互补模式
STMR_DTEN |= STMR_01_DUTY_EN(0x1); // STMR0/STMR1死区使能
STMR_EDGESEL &=~(STMR_0_EDGE_SEL(0x1) | // STMR0 PWM下降沿触发STMR1死区事件
STMR_1_EDGE_SEL(0x1)); // STMR1 PWM下降沿触发STMR0死区事件
STMR_DTDAT &=~(STMR_0_DUTY_DAT(0x1) | // STMR0 PWM死区时间内输出0
STMR_1_DUTY_DAT(0x1)); // STMR1 PWM死区时间内输出0
STMR_DTCON |= STMR_01_DUTY_TYPE(0x6); // STMR0无死区,STMR1向下或向上计数时比较点-死区时间
STMR01_DT = STMR_01_DUTY_VAL(250); // 死区时间
#define STMR01_PEROID_VAL (SYSCLK/1/2000 - 1) // 周期值=系统时钟/分频/频率*2(计数类型选择中心对齐所以需要乘2) - 1
// STIMER0/1配置1kHz PWM
STMR0_PSC = STMR_PRESCALE_VAL(0x0); // 不分频
STMR0_PRH = STMR_PRD_VAL_H((STMR01_PEROID_VAL >> 8) & 0xFF); // 周期高八位寄存器
STMR0_PRL = STMR_PRD_VAL_L((STMR01_PEROID_VAL >> 0) & 0xFF); // 周期低八位寄存器
STMR0_CMPAH = STMR_CMPA_VAL_H(((STMR01_PEROID_VAL/2) >> 8) & 0xFF); // 比较值A点高八位寄存器
STMR0_CMPAL = STMR_CMPA_VAL_L(((STMR01_PEROID_VAL/2) >> 0) & 0xFF); // 比较值A点低八位寄存器
STMR_PWMVALA |= STMR_0_PWMVALA(0x1); // 计数CNT大于等于比较值A,PWM输出1,小于输出0
STMR_PWMEN |= STMR_0_PWM_EN(0x1); // PWM输出使能
STMR_CNTMD |= STMR_0_CNT_MODE(0x1); // 选择连续计数模式
STMR_LOADEN |= STMR_0_LOAD_EN(0x1); // 自动装载使能
STMR_CNTCLR |= STMR_0_CNT_CLR(0x1); // 计数清零
STMR_CNTTYPE |= STMR_0_CNT_TYPE(0x1); // 计数类型选择中心对齐
// STIMER1配置
STMR1_PSC = STMR_PRESCALE_VAL(0x0); // 不分频
STMR_PWMVALA &= ~STMR_1_PWMVALA(0x1); // 计数CNT小于比较值A,PWM输出1,大于等于输出0
STMR_PWMEN |= STMR_1_PWM_EN(0x1); // PWM输出使能
STMR_CNTMD |= STMR_1_CNT_MODE(0x1); // 选择连续计数模式
STMR_LOADEN |= STMR_1_LOAD_EN(0x1); // 自动装载使能
STMR_CNTCLR |= STMR_1_CNT_CLR(0x1); // 计数清零
STMR_CNTTYPE |= STMR_1_CNT_TYPE(0x1); // 计数类型选择中心对齐(向上计数再向下计数)
// 计数使能
STMR_CNTEN |= STMR_0_CNT_EN(0x1) | STMR_1_CNT_EN(0x1); // 计数使能
pwm_output_cnt = 1;//想要控制的次数
P23 = 0;
do{
while(!(STMR0_IF & STMR_PRD_FLAG(0x1) && STMR1_IF & STMR_PRD_FLAG(0x1)));
STMR0_IF |= STMR_PRD_FLAG(0x1);
STMR1_IF |= STMR_PRD_FLAG(0x1);
P23 = 0;
P23 = 1;
P23 = 0;
pwm_output_cnt--;
} while(pwm_output_cnt > 0);
P23 = 0;
// 计数不使能
STMR_CNTEN &= ~(STMR_0_CNT_EN(0x1) | STMR_1_CNT_EN(0x1));
|