【PWM问题】STC8H8K64U是否可以实现2路PWM输出和6路检测
现在基于开天斧三.2开发板,通过使用高级PWM内部模块CC1,CC2,CC3,CC4,CC7,CC8进行捕获模块,进行外部PWM信号进行检测周期检测。通过PWM5,PWM6输出两路PWM信号。现象是CC1,CCC2,CC3,CC4能够正常检测到周期信号,PWM5,PWM6也能够正常输出占空比不同的PWM信号。PWM7,PWM8完全没有反应,希望各位前辈和大拿给指点一二,不胜感激。配置代码如下:所有IO都配置成了准双向口了。
void pwm_init()
{
PWMA_CCER1 = 0x00;
PWMA_CCMR1 = 0x01;// CC1为输入模式,切映射到TI1FP1
PWMA_CCMR2 = 0x01;// CC2为输入模式,切映射到TI2FP2
PWMA_CCER1 = 0x11;// 使能 CC1 上的捕获功能,使能CC2上的捕获功能
PWMA_CCER1 |= 0x02; //设置捕获极性为CC1 的下降沿
PWMA_CCER1 |= 0x20; //设置捕获极性为CC2的下升沿
PWMA_CCER2 = 0x00;
PWMA_CCMR3 = 0x01; //ICC3 为输入模式且映射到TI3FP3 上
PWMA_CCMR4 = 0x01;//CC4 为输入模式且映射到TI4FP4上
PWMA_CCER2 =0x11;//使能 CC3 上的捕获功能,使能CC4 上的捕获功能
PWMA_CCER2 |= 0x02; //设置捕获极性为CC3 的下升沿
PWMA_CCER2 |= 0x20; //设置捕获极性为CC4 的下降沿
PWMA_CR1 = 0x01;
PWMA_IER = 0x1E; //使能CCI/CC2/CC3/CC4 捕获中断
PWMA_PS =0x00;
PWMA_PS |= PWM1_2;//C0 -P2.0
PWMA_PS |= PWM2_2;//C1 -P2.2
PWMA_PS |= PWM3_2;//C2 -P2.4
PWMA_PS |= PWM4_2;//C3 -P2.6
PWMB_CCER1 = 0x00; // 写 CCMRx 前必须先清零 CCxE 关闭通道
PWMB_CCMR1 = 0x68; //通道模式配置 PWM5
PWMB_CCMR2 = 0x68; // 通道模式配置 PWM6
PWMB_CCER1 = 0x33; // 配置通道输出使能和极性 PWM5 PWM6
PWMB_ARRH = (u8)(PWM_PERIOD >> 8); // 设置周期时间
PWMB_ARRL = (u8)PWM_PERIOD;
PWMB_ENO = 0x00;
PWMB_ENO |= ENO6P; // 使能输出
PWMB_ENO |= ENO5P; // 使能输出
PWMB_PS = 0x00; // 高级 PWM 通道输出脚选择位
PWMB_PS |= PWM5_4; //7.4
PWMB_PS |= PWM6_4; // 选择 PWM6_4 通道 P7.5
PWMB_PS |= PWM7_4; //7.6
PWMB_PS |= PWM8_4; //7.7
PWMB_BKR = 0x80;// 使能主输出
PWMB_CR1 |= 0x81; // ARR预装载,开始计时
PWM6_Duty = PWM_PERIOD / 100 * 30;
PWMB_CCR6H = (u8)(PWM6_Duty >> 8); // 设置占空比时间
PWMB_CCR6L = (u8)(PWM6_Duty);
PWMB_CCR5H = (u8)(PWM6_Duty >> 8); // 设置占空比时间
PWMB_CCR5L = (u8)(PWM6_Duty);
PWMB_CCER2 = 0x00;
PWMB_CCMR3 = 0x01; //CC7 为输入模式且映射到TITFP8上
PWMB_CCMR4 = 0x01; //CC8 为输入模式且映射到TITFP8 上
PWMB_CCER2 = 0x11; //使能 CC7上的捕获功能,使能CC8 上的捕获功能
PWMB_CCER2 |= 0x02;//设置捕获极性为CC7的下升沿
PWMB_CCER2 |= 0x20;//设置捕获极性为CC8 的下降沿
PWMB_CR1 = 0x01; //使能计数器B
PWMB_IER = 0x18; //使能CC7/CC8 捕获中断 18
}
中断程序:
void PWMA_ISR() interrupt PWMA_VECTOR
{
u16 ccr;
if(PWMA_SR1 &0x02)
{
PWMA_SR1 &=~0x02;
ccr = (PWMA_CCR1H<<8)+PWMA_CCR1L;
Cycles = ccr - ccr1;
ccr1 = ccr;
}
if(PWMA_SR1 &0x04)
{
PWMA_SR1 &=~0x04;
ccr = (PWMA_CCR2H<<8)+PWMA_CCR2L;
Cycles = ccr - ccr2;
ccr2 = ccr;
}
if(PWMA_SR1 &0x08)
{
PWMA_SR1 &=~0x08;
ccr = (PWMA_CCR3H<<8)+PWMA_CCR3L;
Cycles = ccr - ccr3;
ccr3 = ccr;
}
if(PWMA_SR1 &0x10)
{
PWMA_SR1 &=~0x10;
ccr = (PWMA_CCR4H<<8)+PWMA_CCR4L;
Cycles = ccr - ccr4;
ccr4 = ccr;
}
}
void PWMB_ISR() interrupt PWMB_VECTOR
{
u16 ccr;
if(PWMB_SR1 &0x02)
{
PWMB_SR1 &=~0x02;
ccr = (PWMB_CCR5H<<8)+PWMB_CCR5L;
Cycles = ccr - ccr5;
ccr5 = ccr;
}
if(PWMB_SR1 &0x10)
{
PWMB_SR1 &=~0x10;
ccr = (PWMB_CCR8H<<8)+PWMB_CCR8L;
Cycles = ccr - ccr6;
ccr6 = ccr;
}
}
主程序:
void SystemInit()
{
GPIO_config();
UART_config();
//Timer0初始化
TMOD &= 0xf0; // 16 bits timer auto-reload
AUXR |= 0x80; // Timer0 set as 1T
TH0 = (u8)(Timer0_Reload / 256);
TL0 = (u8)(Timer0_Reload % 256);
ET0 = 1; // Timer0 interrupt enable
TR0 = 1; // Tiner0 run
pwm_init();
EA = 1;
}
/**********************************************/
void main(void)
{
u8 i;
EAXSFR(); /* 扩展寄存器访问使能 */
SystemInit();
while (1)
{
if(SystemTick%2000 == 0)
{
for(i=0;i<6;i++)
{
printf("CH%d: %d ",(int)i,Cycles);
Cycles = 0;
}
}
}
}
由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每次捕获都刚好PWM溢出,计算出的周期值始终是0.
在发生捕获动作时将当前的计数值保存到PWMx_CCRn里面,如果同时使能了PWM输出,计数值记到PWMx_ARR后就立即归零了.
(正常的计算方法是按照记到FFFF再归零,开启输出后计数值是记到ARR值就立即归零,所以PWMx_ARR最好设置FFFF)
附件是PWMA通道既有捕获输入,又有PWM输出的实现例子,供参考。 乘风飞扬 发表于 2024-8-1 14:53
由于同一组的PWM输出和捕获同步,测量的周期值与输出的周期相同,都是ARRH,ARRL,如果直接反馈接入,则每 ...
感谢感谢,我学习一下。
页:
[1]