历史上的今天
返回首页

历史上的今天

今天是:2024年09月17日(星期二)

2021年09月17日 | STM8输出PWM变频时波形断开解决方法

2021-09-17 来源:eefocus

  在使用STM8单片机的PWM功能时,一直没出现过问题。但是在一个项目中需要在PWM波输出的过程中变频,这时候问题来了。在PWM输出过程中,输出的波形是不是的就会有一大段空白的地方,好像波形输出被关闭了一样。

输出波形如下图所示:

53c1609fefb95c85926520aa3ff4acc.jpg?imageView2/2/w/550

  放大后查看

50bc90ec5a41ea39ae96d5d0814b177.jpg?imageView2/2/w/550

  可以看到波形输出的过程中突然就消失了,而且还不是偶尔的出现一次。是频繁的出现。这就奇怪了?难道是单片机坏了?换了几个单片机测试都是这样的,那么肯定就是软件代码出问题了。那么到底是什么地方有问题了,于是开启找BUG模式,一行一行代码分析。


  代码分析了半天也没找不到哪行代码有问题,输出单一频率的PWM波一直很稳定,只是改变频率的时候就会出现波形断开情况,频率改变的越多,出现断开的这种情况就会越多,那么肯定就是在变频设置的这块有问题,网上找了半天也没找见有用的方法,看来还是得靠自己解决问题。


  于是开始看芯片手册,关于定时器相关的章节,一个字一个字往过分析。终于发现了一点端倪。

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

  在定时器时基单元介绍的时候提到了一个自动预装载的功能,并且还有一个影子寄存器。当我们设置寄存器的装载值时,其实不是直接设置的寄存器,而是值传递给通过ARR寄存器传递给影子寄存器,然后由影子寄存器去设置定时器的装载值。


  继续往下看,会讲到影子寄存器的作用。

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

  在向上计数模式中说到了使能和不使能ARPE的区别,从图上大概可以看出来,不使能预装载功能时,自动重装载寄存器和它的影子寄存器是同步的,相当于计数器溢出时,影子寄存器会被立即跟新。而使能了预装载功能后,计数器溢出时,影子寄存器不会立即更新,而是要等一段时间更新。


  这里说的是向上计数模式,而代码中使用的是PWM模式,下面继续看PWM模式介绍中有没有说这个预装载功能。

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

  在PWM模式中也提到了预装载寄存器,同时也说了要使能TIM1_CR1寄存器的ARPE位,那么是不是这个预装载寄存器没有开启导致的?


  于是在定时器初始化代码中开启预装载寄存器。

image.png?imageView2/2/w/550

image.png?imageView2/2/w/550

   开启TIM1_CR1寄存器中的APRE位,允许自动预装载寄存器。开启TIM1_CCMR1寄存器中OC1PE位,使能TIM1_CCR1寄存器的预装载功能。


   设置好之后继续测试测试

dee2ac2796e0f69bb500e81e7fcd28d.jpg?imageView2/2/w/550

   这时发现输出的波形竟然好了,中间没有断开的地方了。看来就是这个预装载寄存器导致的。


  现在仔细分析一下这个预装载功能,为什么在最开始没有开启这个功能呢?可能是被资料上的一句话误导了。

image.png?imageView2/2/w/550

  当禁止预装载功能时,写入的数据会立即起作用。想的是如果PWM要变频,肯定是数据要随时变化,需要改变频率后,立即输出就要发生改变。所以禁止了预装载功能。


  通过上面的资料分析和实验现象来看,对于这句话的理解可能出现了问题。立即生效也就是意味着发出PWM波的过程中,如果一个周期的波没有完全发出去,此时如果改变了频率,那么发送的上一个周期的波就会立即停止,重新开始发送新的周期波。这样的话,发出的波形就会出现不完整,如果代码中改变频率的速度非常快,那么有可能第一个周期的波还没有发出,频率改变了,又开始发第二个波,第二个波还没发出,频率又改变了。于是导致输出的波形有问题。


  而希望输出的波形是,每一个频率至少要输出一个完整的波形,然后在下一个周期再改变频率。所以这里必须要使能预装载寄存器,使能预装载寄存器后,设置的值不会立即生效,而是存入影子寄存器中,影子寄存器会在寄存器重新加载ARR值的时候,将改变后的值写入ARR寄存器,这样在波形输出的过程中,就不会发生一个周期的波形未输出完成时,ARR的值就被改变了。


  由此可见,这个预装载寄存器和影子寄存器主要是用来保证输出波形完整性的,它会自动的在一个波形输出完成后才设置下一次需要改变的值,而不会中断正在输出的波形。所以在使用PWM变频时,必须要开机预装载寄存器和自动重装载功能。


完整的PWM变频代码如下:


#include "pwm.h"


unsigned int tim1fre  = 290;            

unsigned int ch1_dc = 50;

unsigned int ch2_dc = 50;


void pwm_gpio_init( void )

{

    PC_DDR |= ( 1 << 6 );               //PC6 推挽输出

    PC_CR1 |= ( 1 << 6 );

 

    PC_DDR |= ( 1 << 7 );               //PC7 推挽输出

    PC_CR1 |= ( 1 << 7 );

    

    PC_ODR &= ~( 1 << 6 );

    PC_ODR |= ( 1 << 7 );

}

//定时器1初始化

void tim1_init( void )

{

    pwm_gpio_init();


    TIM1_CCMR1 = 0x60;                  //TIM1 CH1 输出模式 PWM1

    TIM1_CCMR1 |= ( 1 << 3 );           //开启预装载功能

    TIM1_CCER1 |= 0x01;                 //CC1为输出


    TIM1_CCMR2 = 0x60;                  //TIM1 CH2 输出模式 PWM1

    TIM1_CCER1 |= 0x10;                 //CC2为输出


    TIM1_PSCRH = 0x00;                  //预分频 0

    TIM1_PSCRL = 0x00;                  //16M


    TIM1_ARRH = tim1fre >> 8;               //设定自动重装载值高8位

    TIM1_ARRL = ( unsigned char )tim1fre;   //设置自动重装载值低8位


    TIM1_BKR |= ( 1 << 7 );                 //主输出使能  关闭刹车输

    TIM1_CR1 |= ( 1 << 7 );                 //使能预装载寄存器

    TIM1_CR1 |= ( 1 << 0 );                 //使能计数器

}

//TIM1 CH1  PC6

void tim1_ch1_dc( unsigned int ch1_dc )

{

    static unsigned int dc = 0;

    dc = tim1fre * ch1_dc / 100;

    TIM1_CCR1H = dc >> 8;               //捕获比较寄存器高8位

    TIM1_CCR1L = dc;                    //捕获比较寄存器低8位 占空比值

}

//TIM1 CH2  PC7

void tim1_ch2_dc( unsigned int ch2_dc )

{

    static unsigned int dc = 0;

    dc = tim1fre * ch2_dc / 100;

    TIM1_CCR2H = dc >> 8;

    TIM1_CCR2L = dc;

}


void tim1_fre( unsigned int freq )

{

    tim1fre = freq;

    TIM1_ARRH = freq >> 8;                     //设置频率

    TIM1_ARRL = freq;

}

推荐阅读

史海拾趣

AW Industries Inc公司的发展小趣事

除了追求经济效益外,AW Industries Inc还注重履行社会责任。公司积极参与环保事业,通过采用环保材料、减少废弃物排放等方式降低生产对环境的影响。同时,公司还关注员工福利和社会公益事业,通过捐款、资助等方式回馈社会。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。


请注意,这些故事是基于电子行业的一般情况虚构的,并不代表任何真实事件或公司。如果您需要关于特定公司的真实发展故事,建议您查阅相关资料或访问公司官网以获取更准确的信息。

ESTEK公司的发展小趣事

在电子行业竞争日益激烈的背景下,ESTEK公司也面临着诸多挑战和危机。然而,公司始终保持着清醒的头脑和坚定的信心。在面对市场波动、原材料价格上涨等挑战时,ESTEK公司迅速调整战略、优化生产流程、降低成本等措施,成功度过了危机。在危机中,ESTEK公司展现出了强大的韧性和生命力,为公司未来的发展奠定了坚实基础。

AMD(超微)公司的发展小趣事

在电子行业竞争日益激烈的背景下,ESTEK公司也面临着诸多挑战和危机。然而,公司始终保持着清醒的头脑和坚定的信心。在面对市场波动、原材料价格上涨等挑战时,ESTEK公司迅速调整战略、优化生产流程、降低成本等措施,成功度过了危机。在危机中,ESTEK公司展现出了强大的韧性和生命力,为公司未来的发展奠定了坚实基础。

Furukawa Electric Co Ltd公司的发展小趣事

ESTEK公司深知产品质量对于企业发展的重要性。因此,公司从源头上把控原材料的质量,并在生产过程中严格执行质量管理体系标准。通过一系列严格的质量管控措施,ESTEK公司的产品质量得到了有效保障。在市场上,ESTEK公司的产品以高质量、高可靠性著称,赢得了广大客户的信赖和好评。

CAMDENBOSS公司的发展小趣事

随着环保意识的日益增强,CAMDENBOSS公司积极响应全球绿色生产的号召。公司投入大量资源研发环保型电子连接器产品,采用环保材料和工艺,降低生产过程中的能耗和排放。同时,公司还加强了废弃物的回收和处理工作,实现了资源的循环利用和减少对环境的影响。

DAESAN公司的发展小趣事

在电子行业中,技术创新是企业发展的核心驱动力。DAESAN公司深知这一点,因此一直致力于技术研发和创新。他们投入大量资金和资源,引进先进的生产设备和技术人才,不断推出具有竞争力的新产品。其中,一款高性能的电子芯片引起了行业的广泛关注。这款芯片采用了最新的纳米技术和低功耗设计,不仅性能卓越,而且节能环保。DAESAN公司凭借这一技术创新,成功打开了高端电子市场的大门。

问答坊 | AI 解惑

各位大虾谁能给我个《plug and play system architecture》?非常感谢

各位大虾谁能给我个《plug and play system architecture》?非常感谢, 我的邮箱jerk66@163.com…

查看全部问答>

EVC连接SQLCE出问题:recordset 的open方法总是提示:first—chance exception in XX.exe:0X00000f0:s

EVC连接SQLCE出问题:recordset 的open方法总是提示:first—chance exception in XX.exe:0X00000f0:stack overflow。 程序如下          CVOConnection* m_Conn;          CVO ...…

查看全部问答>

问一下MSP430f42xx里的SAD( Sigma-Delta A/D)怎么用啊?

本帖最后由 paulhyde 于 2014-9-15 09:44 编辑 Sigma-Delta A/D 原理基本不懂····和逐次比较的有什么不同?还有怎样操作它?  …

查看全部问答>

如何关闭CPU

我的板子是用电池供电,现在需要个功能,在电压降低到1.8V时关闭CPU,通过上电复位。我用一块电压检测芯片来检测1.8V, 我不清楚,检测到1.8V,是进入低功耗4吗?还是怎么样? 进入低功耗4,但是电压重新达到3V时,我又实现不了复位。如何才能实 ...…

查看全部问答>

有源滤波

附件图是一个有源三阶切比雪夫滤波,输出端是PWM(0-5V)波,我不是很懂在里面的运算关系,比如传递函数的分析。但是我用电子电路仿真之后发现当PWM占空比一定时,在经过短暂时间,这个电路的输出电压会稳定在一个值,改变占空比,输出电压就会改变 ...…

查看全部问答>

基于ARM与SD卡的大容量数据存储技术的应用研究

0 引言   在现场测控系统中,RTU(远程测控终端)存储容量、存储数据的转移问题始终是RTU的重要环节。RTU的存储容量一般为几十K~几百K字节,数据转移通常采用不掉电静态RAM、EEPROM存储模块,或采用便携式计算机通过串行口读取RTU数据。 ...…

查看全部问答>

【悬赏求助】launchpad捕获按键按下的时间

最近在学习launchpad,中断方面困难重重。。。我想实现这样一个功能:P1.1设为输入,连接一个按键,然后利用中断判断按键按下的时间,要是短按的话就LED1翻转,长按的话LED2翻转。这样的话,我知道应该用捕获模式获取时间信息对吧,但是实现过程一 ...…

查看全部问答>

MSP430硬件I2C程序

MSP430硬件I2C程序,已测试通过,有兴趣的可探讨探讨…

查看全部问答>