打印
[APM32F1]

apm32f103c8t6PWM输出3MHZ脉冲方波为什么不稳定?

[复制链接]
2831|61
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
叶萌|  楼主 | 2022-11-16 15:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
有没有大佬帮忙看看,为什么输出3mhz的脉冲方波,脉冲个数不稳定?代码如下,用的apm32f103c8t6,定时器1的通道1输出,帮忙看看,谢谢!
void  InitTime1Config(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波,可见脉冲个数不太稳定,有没有大佬指点一下,谢谢

3mhz2.jpg (404.83 KB )

3mhz2.jpg

3mhz.jpg (398.22 KB )

3mhz.jpg

使用特权

评论回复
沙发
叶萌|  楼主 | 2022-11-16 15:32 | 只看该作者

使用特权

评论回复
板凳
叶萌|  楼主 | 2022-11-17 09:06 | 只看该作者
17666100887 发表于 2022-11-17 08:58
我们是极海的代理,可以加我微信,17666100887

代理能懂这个嘛

使用特权

评论回复
地板
一叶倾城wwq| | 2022-11-17 11:03 | 只看该作者
什么驱动需要上兆的pwm?不稳定除了配置问题就是被其他中断打断了呗

使用特权

评论回复
评论
叶萌 2022-11-17 15:55 回复TA
不是驱动 就是和超声波发射之类的有关系 目前除了系统时钟的中断 没有任何其他中断 pwm输出会被中断打断吗 
5
叶萌|  楼主 | 2022-11-17 15:57 | 只看该作者
一叶倾城wwq 发表于 2022-11-17 11:03
什么驱动需要上兆的pwm?不稳定除了配置问题就是被其他中断打断了呗

我想问的就是会和芯片的精度有关系吗  比如这个mcu就是达不到3mhz的精度之类的

使用特权

评论回复
评论
叶萌 2022-11-22 16:59 回复TA
@一叶倾城wwq :用户手册只写了那些定时器能够pwm输出,没写最高能到多少兆,唉 
一叶倾城wwq 2022-11-19 18:29 回复TA
看看芯片PWM部分的规格书嘛,看上面标注的范围是多少,计算一下,一般估计做不到上兆的pwm,我还没用过上兆的pwm呢。 
6
一个人破| | 2022-11-24 15:33 | 只看该作者
外部晶振HSE的输入范围不是4~16MHz吗

111111.png (328.84 KB )

111111.png

使用特权

评论回复
7
一个人破| | 2022-11-24 15:36 | 只看该作者
觉得定时输出不准的话,不妨用MCO输出SYSCLK波形。看下定时器之前的时钟准不准

使用特权

评论回复
8
一个人破| | 2022-11-24 15:43 | 只看该作者
想知道你的时钟配置是怎样的:
时钟源是3MHz的晶振?
HSE是直接作为系统时钟吗,还是经过PLL倍频。

可以通过MCO先检查下时钟路径上的时钟是不是都是正常的,如果都是正常的,我们再排查代码问题

使用特权

评论回复
9
JunKook| | 2022-11-24 15:52 | 只看该作者
你好,请问你测出来的PWM脉冲个数不稳定是普遍现象吗?也就是说无论PWM的频率是多少,脉冲个数都不稳定是吗?

使用特权

评论回复
10
WuKaiLi| | 2022-11-24 16:40 | 只看该作者
本帖最后由 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)
    {
    }
}


示波器测试截图如下,不知道是否满足你的需求:

使用特权

评论回复
11
叶萌|  楼主 | 2022-11-25 16:34 | 只看该作者
一个人破 发表于 2022-11-24 15:33
外部晶振HSE的输入范围不是4~16MHz吗

我外部晶振是用的12m呀,我说的3mhz是接的外部触发脚想取代定时器触发3mhz

使用特权

评论回复
12
叶萌|  楼主 | 2022-11-25 16:35 | 只看该作者
一个人破 发表于 2022-11-24 15:43
想知道你的时钟配置是怎样的:
时钟源是3MHz的晶振?
HSE是直接作为系统时钟吗,还是经过PLL倍频。

MCO是什么,还没接触过

使用特权

评论回复
13
叶萌|  楼主 | 2022-11-25 16:37 | 只看该作者
JunKook 发表于 2022-11-24 15:52
你好,请问你测出来的PWM脉冲个数不稳定是普遍现象吗?也就是说无论PWM的频率是多少,脉冲个数都不稳定是吗 ...

不是噢 5k的频率就正常

使用特权

评论回复
14
叶萌|  楼主 | 2022-11-25 16:42 | 只看该作者
WuKaiLi 发表于 2022-11-24 16:40
由于MCU的定时器频率限制,建议你使用最大频率,并且不要进行分频。你的代码有一些问题:
1.计数值设置太小 ...

你好,看了一下你的代码,和我有区别的有两个,第一个我的系统频率是60mhz,第二个我是采取的中央对齐计数法,你可以看一下我的示波器图片,我感觉频率和占空比是合格的,但是脉冲数相对外部晶振来说不太稳定

使用特权

评论回复
15
叶萌|  楼主 | 2022-11-25 16:50 | 只看该作者
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以上,这样才能看出来脉冲个数的情况,非常谢谢

使用特权

评论回复
16
一个人破| | 2022-11-25 18:00 | 只看该作者
叶萌 发表于 2022-11-25 16:35
MCO是什么,还没接触过

Main Clock Output
通过配置可以输出时钟波形:SYSCLK、HSICLK、HSECLK、PLLCLK/2
平常对于时钟频率有怀疑的时候,用它可以很方便的排除是硬件问题还是程序问题。


22222.png (381.47 KB )

22222.png

33333333.png (267.82 KB )

33333333.png

使用特权

评论回复
17
一个人破| | 2022-11-25 18:05 | 只看该作者
叶萌 发表于 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引脚进行复用,然后选择自己想要测试的时钟就好了

使用特权

评论回复
18
一个人破| | 2022-11-25 18:09 | 只看该作者
叶萌 发表于 2022-11-25 16:35
MCO是什么,还没接触过

用示波器观察时钟波形稳不稳定的话,用触发模式比较方便。
选择波形的中间电平,看会不会有抖动的迹象

到时把波形也发出来看看吧

使用特权

评论回复
19
叶萌|  楼主 | 2022-11-26 09:19 | 只看该作者
一个人破 发表于 2022-11-25 18:09
用示波器观察时钟波形稳不稳定的话,用触发模式比较方便。
选择波形的中间电平,看会不会有抖动的迹象

好滴,谢谢,我试试!

使用特权

评论回复
20
叶萌|  楼主 | 2022-11-26 17:01 | 只看该作者
你好,我做了如下测试,发现这个12mhz直接MCO输出也是会有脉冲丢失的情况,代码和示波器图片如下,可以帮我看看吗
void  InitMCOConfig(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);
}


12mhz2.jpg (407.96 KB )

12mhz2.jpg

12mhz1.jpg (405.74 KB )

12mhz1.jpg

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

40

帖子

1

粉丝