历史上的今天
返回首页

历史上的今天

今天是:2025年05月27日(星期二)

正在发生

2019年05月27日 | STM32用一个定时器输出多路不同频率及占空比的PWM(输出比较

2019-05-27 来源:eefocus

我们使用STM32输出PWM时会使用定时器的PWM输出模式来进行生成,但是这样子生成PWM是有局限的,它只能生成四路频率相同的PWM,当你设定了TIMx_PSC(预分频寄存器)和TIMx_ARR(自动重装载寄存器),这时PWM的频率就被定下来了,为系统的时钟/TIMx_PSC+1/TIMx_ARR+1,你可以通过改变各个通道的CCR寄存器来改变占空比。但是如果我们想生成多路不同频率的PWM的话,使用这个方法只能使用多个定时器了,这样对于定时器资源较少的板子无疑是不可取的,在前几周准备蓝桥杯比赛的时候我发现了32定时器有一个输出比较的模式,可以生成多路不同频率及占空比的PWM。


    配置代码如下:


__IO u16 CCR1_Val=40;//72000000/36/40=50KHZ

__IO u16 CCR2_Val=20000;//72000000/36/20000=100HZ

float zhankong1=0.5;

float zhankong2=0.5;

u16 capture=0;

u8 pa6_state=0,pa7_state;

 

//比较输出PWM配置

void TIM3_PWM_Init2(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);//IO口配置

 

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);//TIM3中断配置

TIM_TimeBaseStructure.TIM_Period = 39999;

TIM_TimeBaseStructure.TIM_Prescaler = 35;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//定时器基本配置

/* Output Compare Toggle Mode configuration: Channel1 */

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = CCR1_Val;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

TIM_OC1Init(TIM3, &TIM_OCInitStructure);//通道1设置为输出比较模式

 

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

 

/* Output Compare Toggle Mode configuration: Channel2 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

 

TIM_OC2Init(TIM3, &TIM_OCInitStructure);//通道2也设置为输出比较模式

 

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);//使能预装载

/* TIM enable counter */

TIM_Cmd(TIM3, ENABLE);//定时器3使能

/* TIM IT enable */

TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);//通道1、通道2中断使能

}

    定时器的中断服务函数:


void TIM3_IRQHandler(void)

{

  /* TIM3_CH1 toggling with frequency = 50KHz */

  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)

  {

    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );

    capture = TIM_GetCapture1(TIM3);

  if(pa6_state==0)

  {

  TIM_SetCompare1(TIM3, capture + (u16)CCR1_Val *zhankong1 );

  pa6_state=1;

  }

  else

  {

  TIM_SetCompare1(TIM3, capture + (u16)CCR1_Val *(1-zhankong1) );

  pa6_state=0;

  }

  }

 

  /* TIM3_CH2 toggling with frequency = 100 Hz */

  if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)

  {

    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

    capture = TIM_GetCapture2(TIM3);

   if(pa7_state==0)

  {

  TIM_SetCompare2(TIM3, capture + (u16)CCR2_Val *zhankong2 );

  pa7_state=1;

  }

  else

  {

  TIM_SetCompare2(TIM3, capture + (u16)CCR2_Val *(1-zhankong2) );

  pa7_state=0;

  }

  }

}

    原理讲解:

        输出比较个人感觉原理还是有那么一点复杂的,可能我会讲的不太清楚,如果你看完以后有一点迷糊或者没有看懂,还是希望你可以仔细的阅读官方手册与代码,然后如果有问题或者有不同的看法欢迎留言


        首先关于我们配置了IO口,这个就是TIM3的通道1、通道2对应的IO口,分别是PA6和PA7


        接下来我们设置了定时器3的中断以及定时器的一些基本配置,比如预分频值、重加载值等,我们这里设置预分频值为35(实际会+1为36),重装载值为39999(实际会+1为40000)


        然后我们来配置通道1和通道2,配置为输出比较模式,使能输出,设置比较值为CCR1_Val,设置有效电平为低电平,同样通道2也是如此的配置


        最后我们使能预装载,使能定时器,使能中断


        接下来就到了输出比较模式的核心----中断服务函数了,中断服务函数中的处理是十分关键的,当有中断触发(CNT寄存器的值累加到了某个通道的比较值时),就会触发中断,根据中断的标志来判断是哪个通道触发了中断,紧接着它会查看当前CNT寄存器的值(使用TIM_GetCapturex函数),然后它判断现在是高电平还是低电平(这个是由有效电平控制,并有state标志位来判断),由此来设置新的比较值(使用TIM_SetComparex函数),这样就可以连续的生成固定频率固定占空比的PWM。


        有几个需要注意的点:因为CNT的值是从0计数到ARR寄存器值的,而我们每次会设置CCRx_Val这个值,所以说ARR寄存器的值最好是你每个通道CCRx_Val的公倍数,否则在每次重加载的时候波形会发生混乱。我们可以通过改变CCRx_Val来改变PWM的频率,通过改变zhankongx来改变PWM的占空比,这两个值是随时都可以修改的。


    总结:

       使用输出比较的方法可以在使用1个定时器的情况下有效的生成两路不同频率及占空比的PWM,它对比PWM输出模式的缺点肯定就是它会有中断的处理,如果生成的PWM频率较高时它会频繁的进入比较中断,这可能会给单片机带来较大的负担,但是在输出较低频率的PWM时,这种方法还是很好用的。



推荐阅读

史海拾趣

BB公司的发展小趣事

如今,BB公司已经走过了数十年的发展历程,成为电子行业中一颗璀璨的明星。然而,公司并没有因此停下脚步。相反,BB公司始终保持着强烈的创新意识和进取精神,不断寻求新的发展机遇和挑战。未来,BB公司将继续致力于技术创新和市场拓展,为电子行业的繁荣发展贡献更多力量。

以上是关于BB公司发展起来的五个相关故事。这些故事不仅展现了BB公司的成长历程和发展成就,也凸显了其在电子行业中的重要地位和影响。相信在未来的日子里,BB公司将继续书写更加辉煌的篇章。

Goldentech Discrete Semiconductor Inc公司的发展小趣事

在20世纪90年代末,Goldentech Discrete Semiconductor Inc.(以下简称“Goldentech”)由一群来自顶尖学术机构的半导体专家创立。公司从成立之初就专注于研发高性能的离散半导体器件,特别是针对当时迅速发展的移动通信市场。Goldentech的创新团队成功开发出了一种新型的低功耗、高频率的晶体管,这一技术突破迅速吸引了多家手机制造商的注意。凭借这一技术优势,Goldentech在短时间内成为移动通信领域离散半导体器件的主要供应商之一,推动了公司业务的快速增长。

Comair Rotron公司的发展小趣事

随着电子行业的竞争加剧,Comair Rotron意识到单打独斗已难以满足市场需求。因此,公司开始积极寻求与行业内其他企业的合作机会。通过与多家知名电子企业建立战略合作关系,Comair Rotron不仅获得了更多的业务机会,还通过与合作伙伴的技术交流和资源共享,不断提升自身的技术水平和产品质量。

BOOKLY公司的发展小趣事

在电子行业的激烈竞争中,BOOKLY公司以其卓越的技术创新能力脱颖而出。公司初创时,仅是一个由几位电子工程师组成的小团队,专注于研发高效能、低功耗的芯片技术。经过数年的艰苦努力,BOOKLY成功推出了一款颠覆性的芯片产品,被广泛应用于智能手机和电脑领域,迅速赢得了市场份额。此后,公司不断投入研发,拓展产品线,逐渐在电子行业建立了自己的品牌地位。

Bud Industries公司的发展小趣事

在电子行业的激烈竞争中,BOOKLY公司以其卓越的技术创新能力脱颖而出。公司初创时,仅是一个由几位电子工程师组成的小团队,专注于研发高效能、低功耗的芯片技术。经过数年的艰苦努力,BOOKLY成功推出了一款颠覆性的芯片产品,被广泛应用于智能手机和电脑领域,迅速赢得了市场份额。此后,公司不断投入研发,拓展产品线,逐渐在电子行业建立了自己的品牌地位。

Alpha Wire公司的发展小趣事

BOOKLY公司深知品质是赢得市场的关键。因此,公司从创立之初就建立了严格的质量管理体系,确保每一款产品的品质和性能都达到最高标准。同时,BOOKLY还注重品牌塑造,通过精心的品牌设计和营销活动,提升了品牌知名度和美誉度。这些努力使得BOOKLY的产品在市场上获得了良好的口碑和广泛的认可。

问答坊 | AI 解惑

【电子书】万用表测试电工电子元器件300例【PDG格式】

【电子书】万用表测试电工电子元器件300例【PDG格式】 【电子书】万用表测试电工电子元器件300例【PDG格式】_ 【电子书】万用表测试电工电子元器件300例【PDG格式】_ 【电子书】万用表测试电工电子元器件300例【PDG格式】_ [ 本帖最后由 emily ...…

查看全部问答>

CCD摄像机质量对网络摄像机的影响

  1. 问题的提出         网络摄象机技术的发展,特别是宽带网络的普及,使得基于网络的网络监控应用正在普及。灵活的监视和控制配置、与信息网络紧密融合、长距离远程监控等优势都是传统监控所不可比拟的。如何 ...…

查看全部问答>

新手来问问题,请老鸟们指导

我手头有一块2410的板子,可是和电脑不能连接。能不能帮我分析分析 系统里除了驱动只装了360安全卫士,其他软件安装顺序是:1、CE5.0 2、EVC 3、USB驱动(用USB线连接) 4、activesync 连接之后打开板子的电源,托盘里activesync的小标一直没有反 ...…

查看全部问答>

那位兄弟有三星的NAND FLASH的驱动,我不要通用的啊,现代的我有,就是要改成三星的,

那位兄弟有三星的NAND FLASH的驱动,我不要通用的啊,现代的我有,就是要改成三星的, 有就发到我邮箱里啊?ricky5200@163.com 谢谢啊,…

查看全部问答>

申请 eZ430-RF2500 板子(Air mouse)

一个主要用于HTPC操作用的空中无线鼠标,让HTPC操作变得简单、快捷、随意 [ 本帖最后由 ygtqkuang 于 2011-1-17 19:26 编辑 ]…

查看全部问答>

STM32Primer2隆重登场

看来像手机... 在香港的Farnell网站可以下订单. 价钱港币718.9, 免运费. 比Primer1, 改良了不少. STM32F103E (512 Kbytes Flash) Li-Ion battery with smart loading& ...…

查看全部问答>

STM8S产品,在工厂怎样烧录?

各位好,       我们公司目前正在 基于 STM8S103 设计产品.       我知道,在研发阶段,可以使用 ST-LINK3 的 SWIM 口烧录STM8S103.       但是,在工厂,客户那边,怎样烧写 ...…

查看全部问答>

如何使用指针读取寄存器的值?

TMS320LF2407A。 ADC采样结果寄存器RESULT0的地址是0x7408。 unsigned int *p = (unsigned int*)0x7408; x = *p; y = *(p + 1); 能否这样访问RESULT0和RESULT1。…

查看全部问答>

恭贺新春!

祝各位龙年大吉!龙腾虎跃!龙马精神!阖家幸福!财源广进! …

查看全部问答>

设计反激电源式电源步骤

在初次设计电源之前,应确保电源所采用的印刷电路板符合Power Integrations器件数据手册中指定的布局指南。如果在实验用面包板或原始样板上搭建设计的电路,会引入很多寄生元件,这样会影响电源的正常工作。而且,许多实验用面包板都无法承载开关电 ...…

查看全部问答>