apm32f103c8t6PWM输出3MHZ脉冲方波为什么不稳定?
有没有大佬帮忙看看,为什么输出3mhz的脉冲方波,脉冲个数不稳定?代码如下,用的apm32f103c8t6,定时器1的通道1输出,帮忙看看,谢谢!voidInitTime1Config(void){
GPIO_Config_T GPIO_ConfigStruct;
TMR_BaseConfig_T TMR_TimeBaseStruct;
TMR_OCConfig_T OCcongigStruct;
RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_TMR1 ));
GPIO_ConfigStruct.pin = GPIO_PIN_8;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_CENTERALIGNED2;
TMR_TimeBaseStruct.division = 4;
TMR_TimeBaseStruct.period = 2;
TMR_ConfigTimeBase(TMR1, &TMR_TimeBaseStruct);
OCcongigStruct.idleState = TMR_OC_IDLE_STATE_RESET;
OCcongigStruct.mode = TMR_OC_MODE_PWM1;
OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;
OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH;
OCcongigStruct.outputNState = TMR_OC_NSTATE_ENABLE;
OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;
OCcongigStruct.polarity = TMR_OC_POLARITY_HIGH;//Êä³ö¼«ÐÔΪHIGH
OCcongigStruct.pulse = 1;
TMR_ConfigOC1(TMR1, &OCcongigStruct);
TMR_ConfigOC1Preload(TMR1, TMR_OC_PRELOAD_ENABLE);
TMR_EnablePWMOutputs(TMR1);
TMR_EnableAUTOReload(TMR1);
TMR_Enable(TMR1);
} 下面还有示波器的图片,黄色为3mhz晶振的效果,可见脉冲个数稳定在15k,蓝色是我的代码输出的wm波,可见脉冲个数不太稳定,有没有大佬指点一下,谢谢
17666100887 发表于 2022-11-17 08:58
我们是极海的代理,可以加我微信,17666100887
代理能懂这个嘛 什么驱动需要上兆的pwm?不稳定除了配置问题就是被其他中断打断了呗 一叶倾城wwq 发表于 2022-11-17 11:03
什么驱动需要上兆的pwm?不稳定除了配置问题就是被其他中断打断了呗
我想问的就是会和芯片的精度有关系吗比如这个mcu就是达不到3mhz的精度之类的 外部晶振HSE的输入范围不是4~16MHz吗 觉得定时输出不准的话,不妨用MCO输出SYSCLK波形。看下定时器之前的时钟准不准 想知道你的时钟配置是怎样的:
时钟源是3MHz的晶振?
HSE是直接作为系统时钟吗,还是经过PLL倍频。
可以通过MCO先检查下时钟路径上的时钟是不是都是正常的,如果都是正常的,我们再排查代码问题 你好,请问你测出来的PWM脉冲个数不稳定是普遍现象吗?也就是说无论PWM的频率是多少,脉冲个数都不稳定是吗? 本帖最后由 WuKaiLi 于 2022-11-24 16:49 编辑
由于MCU的定时器频率限制,建议你使用最大频率,并且不要进行分频。你的代码有一些问题:
1.计数值设置太小,为2,不利于精度;
2.翻转电平错误,计数值你设置的2,理论计数为0,1,2;你设置的翻转值为1,则电平持续时间的计数值为0,翻转电平时间持续的的计数值为1,2;所以你占空比不对;
我写了一个demo,供你参考,注意:系统频率为72M;
int main(void)
{
GPIO_Config_T GPIO_ConfigStruct;
TMR_BaseConfig_T TMR_TimeBaseStruct;
TMR_OCConfig_T OCcongigStruct;
RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_TMR1 | RCM_APB2_PERIPH_GPIOB));
GPIO_ConfigStruct.pin = GPIO_PIN_13;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOB, &GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_8;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
TMR_TimeBaseStruct.division = 0;
TMR_TimeBaseStruct.period = 23;
TMR_ConfigTimeBase(TMR1, &TMR_TimeBaseStruct);
OCcongigStruct.idleState = TMR_OC_IDLE_STATE_RESET;
OCcongigStruct.mode = TMR_OC_MODE_PWM1;
OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;
OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH;
OCcongigStruct.outputNState = TMR_OC_NSTATE_ENABLE;
OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;
OCcongigStruct.polarity = TMR_OC_POLARITY_HIGH;
OCcongigStruct.pulse = 12;
TMR_ConfigOC1(TMR1, &OCcongigStruct);
TMR_ConfigOC1Preload(TMR1, TMR_OC_PRELOAD_ENABLE);
TMR_EnableAutoReload(TMR1);
TMR_Enable(TMR1);
TMR_EnablePWMOutputs(TMR1);
while(1)
{
}
}
示波器测试截图如下,不知道是否满足你的需求:
一个人破 发表于 2022-11-24 15:33
外部晶振HSE的输入范围不是4~16MHz吗
我外部晶振是用的12m呀,我说的3mhz是接的外部触发脚想取代定时器触发3mhz 一个人破 发表于 2022-11-24 15:43
想知道你的时钟配置是怎样的:
时钟源是3MHz的晶振?
HSE是直接作为系统时钟吗,还是经过PLL倍频。
MCO是什么,还没接触过{:cry:} JunKook 发表于 2022-11-24 15:52
你好,请问你测出来的PWM脉冲个数不稳定是普遍现象吗?也就是说无论PWM的频率是多少,脉冲个数都不稳定是吗 ...
不是噢 5k的频率就正常 WuKaiLi 发表于 2022-11-24 16:40
由于MCU的定时器频率限制,建议你使用最大频率,并且不要进行分频。你的代码有一些问题:
1.计数值设置太小 ...
你好,看了一下你的代码,和我有区别的有两个,第一个我的系统频率是60mhz,第二个我是采取的中央对齐计数法,你可以看一下我的示波器图片,我感觉频率和占空比是合格的,但是脉冲数相对外部晶振来说不太稳定 WuKaiLi 发表于 2022-11-24 16:40
由于MCU的定时器频率限制,建议你使用最大频率,并且不要进行分频。你的代码有一些问题:
1.计数值设置太小 ...
你好,我根据你的代码改了以下代码,
TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
TMR_TimeBaseStruct.division = 0;
TMR_TimeBaseStruct.period = 19;
OCcongigStruct.pulse = 10;
目前接收到的频率和占空比是和我之前的一样,然后呢脉冲个数还是有缺失的情况,可以辛苦你用你的代码再实验一次吗,把示波器调到us级别,脉冲个数1k以上,这样才能看出来脉冲个数的情况,非常谢谢 叶萌 发表于 2022-11-25 16:35
MCO是什么,还没接触过
Main Clock Output
通过配置可以输出时钟波形:SYSCLK、HSICLK、HSECLK、PLLCLK/2
平常对于时钟频率有怀疑的时候,用它可以很方便的排除是硬件问题还是程序问题。
叶萌 发表于 2022-11-25 16:35
MCO是什么,还没接触过
void MCO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO通道时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_MCOConfig(RCC_MCO_SYSCLK);//这里可以选择你想测试的时钟
}将PA8引脚进行复用,然后选择自己想要测试的时钟就好了
叶萌 发表于 2022-11-25 16:35
MCO是什么,还没接触过
用示波器观察时钟波形稳不稳定的话,用触发模式比较方便。
选择波形的中间电平,看会不会有抖动的迹象
到时把波形也发出来看看吧 一个人破 发表于 2022-11-25 18:09
用示波器观察时钟波形稳不稳定的话,用触发模式比较方便。
选择波形的中间电平,看会不会有抖动的迹象
好滴,谢谢,我试试! 你好,我做了如下测试,发现这个12mhz直接MCO输出也是会有脉冲丢失的情况,代码和示波器图片如下,可以帮我看看吗
voidInitMCOConfig(void)
{
GPIO_Config_T GPIO_ConfigStruct;
RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA));
GPIO_ConfigStruct.pin = GPIO_PIN_8;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
RCM_ConfigMCO(RCM_MCOCLK_SYSCLK);
}