历史上的今天
返回首页

历史上的今天

今天是:2024年08月31日(星期六)

2018年08月31日 | stm32之定时器运用———呼吸灯

2018-08-31 来源:eefocus

呼吸灯原理

1.在模拟电路中,呼吸灯的实现可以通过一个呈现正弦的电压控制,这个电压是连续变化的,所以肉眼看上去就是逐渐变暗,逐渐变亮。

2.而在数字电路中如何实现这种效果呢?就需要通过pwm,也就是脉冲宽度调制,将模拟量转换为数字量。只要能够用连续电压控制的东西都是可以通过pwm方式来驱动,效果是一样的。

3.

这里写图片描述

上面一块区域的面积等于对应下来的矩形的面积,当然,取得块的间隔越小(即pwm的周期越小),效果越好。这时,如果周期定了,就可以通过改变占空比来实现面积的改变,从而模拟出上面那张图的电压的连续变化。

注意:pwm波的高度是一定的,所以只能通过改变宽度(占空比)来实现面积的改变

4.说明:观察这张图,会发现下面的pwm波是中心与上面的对齐(即pwm中心为高电平),然后左右扩展,每个波的周期还是一样。当然这时可以的。但更多的是运用左对齐(起始为高电平),然后向右扩展直到面积到达要求。

5.stm32实现pwm输出的原理:设点一个值为a,然后在设置一个重装值b,b>a.开始计数,当计数值小于a时,输出高电平,当计数值大于a时,输出低电平,直到计数到b,到b后又重复来一遍。所以改变这个a就可以改变占空比、

6.PWM 的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号,信号频率是由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。其示意图如图 19.1.2 所示:

这里写图片描述

从图 19.1.2 中可以看到,PWM 输出频率是不变的,改变的是 CCR 寄存器内的值,此值的改变将导致 PWM 输出信号占空比的改变。占空比其实就是一个周期内高电平时间与周期的比值。PWM 输出比较模式总共有 8 种,具体由寄存器 CCMRx 的位 OCxM[2:0]配置。我们这里只讲解最常用的两种 PWM 输出模式:PWM1 和 PWM2,PWM1 和 PWM2 这两种模式用法差不多,区别之处就是输出电平的极性不同。如图 19.1.3 所示:

这里写图片描述

pwm输出配置步骤


其实 PWM 输出和上一章一样也是通用定时器的一个功能,因此还是要用到定时器的相关配置函数


1.因为pwm是由定时器输出的,既然用到定时器,就先要使能定时器的时钟:


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//我们用的为tim14定时器

1

2.因为用到io作为输出,所以要打开io口的时钟:


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//注意:io口的外设均是挂在AHB1总线上的

1

3.通过看手册,TIM14 的 CH1 通道对应的管脚是 PF9,而pf9有很多复用功能,所以要选择pf9的输出模式:通过函数:


void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource,

uint8_t GPIO_AF);//前两个参数不说了。第三个参数为复用为哪种功能,这里我们使用的是 TIM14 功能,所以参数为 GPIO_AF_TIM14

1

2

所以函数为:GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);//AF就是复用的意思


4.配置io口,同之前led时一样,只不过参数有些变化:


      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//PF9 管脚模式配置为复用输出

      GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//速度不变

      GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推完输出不变

      GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上啦输出不变

      GPIO_Init(GPIOF,&GPIO_InitStructure);

1

2

3

4

5

6

5.初始化定时器参数,包含自动重装值,分频系数,计数方式等.同前面使用定时器中断


      TIM_TimeBaseInitStructure.TIM_Period = pre;//预装值,这里依然通过参数传递进来

      TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//预分频系数

      TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//固定不变

      TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数

      TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);

1

2

3

4

5

6.定时器基本的参数配置完了,但是还没设置它为pwm输出模式: 

用到的函数为:


void TIM_OCxInit(TIM_TypeDef* TIMx,TIM_OCInitTypeDef* TIM_OCInitStruct);//

1

注意:我们知道每个通用定时器有多达 4 路 PWM 输出通道(对于 TIM9-TIM14 最多有 2 路),所以TIM_OCxInit 函数名中的 x 值可以为 1/2/3/4。函数的第一个参数相信大家一看就清楚,是用来选择定时器的。第二个参数是一个结构体指针变量:


typedef struct

{

uint16_t TIM_OCMode; //比较输出模式

uint16_t TIM_OutputState; //比较输出使能

uint16_t TIM_OutputNState; //比较互补输出使能

uint32_t TIM_Pulse; //脉冲宽度

uint16_t TIM_OCPolarity; //输出极性

uint16_t TIM_OCNPolarity; //互补比较输出极性

uint16_t TIM_OCIdleState; //空闲状态下比较输出状态

uint16_t TIM_OCNIdleState; //空闲状态下比较输出状态

}

1

2

3

4

5

6

7

8

9

10

11

这里我们比较常用的 PWM 模式所需的成员变量: 

TIM_OCMode:比较输出模式选择,总共有 8 种,最常用的是 PWM1 和 PWM2。 

TIM_OutputState:比较输出使能,用来使能 PWM 输出到 IO 口。 

TIM_OCPolarity:输出极性,用来设定输出通道电平的极性,是高电平还是低电平。 

结 构 体 内 其 他 的 成 员 变 量 TIM_OutputNState , TIM_OCNPolarity , 

TIM_OCIdleState 和 TIM_OCNIdleState 是高级定时器才用到的。


所以配置完为:


TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;     

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OC1Init(TIM14,&TIM_OCInitStructure);

1

2

3

4

5

7.开启定时器


TIM_Cmd(TIM14,ENABLE);

1

8.修改 TIMx_CCRx 的值控制占空比(这一步写在主函数中,因为要实时去改变占空比).


其实经过前面几个步骤的配置,PWM 已经开始输出了,只是占空比和频率是固定的,例如本章要实现呼吸灯效果,那么就需要调节 TIM14 通道 1 的占空比,通过修改 TIM14_CCR1 值控制。调节占空比函数是:


void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);//对 于 其 他 通 道 , 分 别 有 对 应 的 函 数 名 , 函 数 格 式 是 TIM_SetComparex(x=1/2/3/4)。

1

分析:第一个参数不说了,第二个参数是计数值。。注意:这个计数值一定要小于前面设定定时器时总的预装载值(TIM_TimeBaseInitStructure.TIM_Period = pre);


代码:


pwm.c


#include "pwm.h"


void TIM14_PWM_Init(u16 pre,u16 psc)

{

      GPIO_InitTypeDef GPIO_InitStructure;

      TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

      TIM_OCInitTypeDef TIM_OCInitStructure;



      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//´ٍ؟ھ¶¨ت±ئ÷µؤت±ضس

          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//زٍخھسأµ½¶ث؟ع£¬ثùزشزھت¹ؤـ¶ث؟عت¼ت±ضس£¬ءيحâioµؤحâةè¶¼تا¹ز½سشعAHB1×ـدكةدµؤ


          GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);


      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;

          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//ثظ¶ب

      GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//حئحئحىتن³ِ

      GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//ةدہ­

      GPIO_Init(GPIOF,&GPIO_InitStructure);//شع³ُت¼»¯ز»دآ


          TIM_TimeBaseInitStructure.TIM_Period = pre;//ةèضأ¶¨ت±ئ÷µؤضـئع£¬ز²¾حت£×¢زâ£؛صâہïخھ´«µؤ²خت‎

      TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//¶¨ت±ئ÷ش¤·ضئµدµت‎

          TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//ح¨³£²»ذق¸ؤثû£¬¹ج¶¨µؤ£¬ز»°مآج²¨µؤت±؛ٍسأ

      TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//دٍةد¼ئت‎£¬´سءم؟ھت¼¼ئت‎£¬¼ئت‎µ½ضط×°ضµ

      TIM_TimeBaseInit(TIM14,&TIM_TimeBaseInitStructure);//³ُت¼»¯ز»دآ


          TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

        TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

          TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

        TIM_OC1Init(TIM14,&TIM_OCInitStructure);


        TIM_Cmd(TIM14,ENABLE);


}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

mian.c


int main()

{

    u8 fx = 0;

    u32 i = 0;//ำรภดภผำ

    RCC_HSE_Config(8,336,2,7);

    Beep_Init();

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    SysTick_Init(168);

    key_init();

    LED_Init();

    TIM14_PWM_Init(500-1,84-1);//2000hz,ึฦฺถจมห,0.5MS


    //while(1)

    //{

        //  if(fx==0)

            //{

                //  i++;

                //  if(i==300)

                //  {

                    //      fx=1;

                //  }

            //}


            //else

            //{

            //      i--;

                //if(i==0)

            //  {

                //      fx=0;

                //}

            //}

         // TIM_SetCompare1(TIM14,i);

            //delay_ms(10);

    //}



    /********the second code*****/

        while(1)

        {

           while(i<=300)

           {

              TIM_SetCompare1(TIM14,i);

              delay_ms(10);

              i++;

           }


           while(i!=0)

           {

              TIM_SetCompare1(TIM14,i);

              delay_ms(10);

              i--;

           }

      }

}


补充: 

1.主函数中注释代码是官方的代码,下面是我自己原创的代码。官方代码是引用了一个变量来判断方向。


2.观察主函数的代码,我们设定的定时器为0.5ms,意思就是pwm波的周期为0.5ms,而每次执行完TIM_SetCompare1(TIM14,i);波形(占空比)就会改变,而后面写的delay_ms(10);是为了维持这一个波形一段时间,反映在模拟信号上就是电压变化的很平缓,很慢,自然亮度的变化也就很缓慢自然。自然,这个延迟时间知道要大于你定时时间好几倍吧-.-


扩展


试试用pwm输出来控制板子上的蜂鸣器来实现控制他的声音大小


提示:看电路图发现beep连在pf9上,而pf9本来就是tim13的复用口。所以只需在这个代码基础上修改定时器的标号为tim13即可


推荐阅读

史海拾趣

EMC Component Group公司的发展小趣事

由于篇幅限制,我无法完整提供五个长达500字以上的关于EMC Component Group公司(通常简称为EMC)的发展故事。然而,我可以概述五个与公司发展历程相关的重要事件或阶段,每个事件以精简的方式描述。

  1. 成立与初期发展

1979年,Richard Egan和Roger Marino两位创始人决定不再为别人打工,共同创立了EMC公司。最初,公司的业务并不专注于存储,而是销售办公家具。随着对市场的深入了解,他们发现了内存市场的商机,开始成为英特尔的渠道代理,为小型机提供内存。这一转变为EMC积累了第一桶金,也为公司未来的发展奠定了重要基础。

  1. 业务转型与内存业务的发展

在一位客服的建议下,EMC开始研发并销售Prime Computer的兼容内存。这些产品以同类产品一半的价格提供更高的性能,迅速在市场上获得认可。随着内存业务的不断发展,EMC逐渐成为了该领域的领导者。

  1. 存储解决方案的推出

进入21世纪,EMC开始将业务重心转向存储解决方案。2002年,公司推出了Centera,这是世界上第一个内容寻址存储(CAS)解决方案。此后,EMC不断推出创新的存储产品和技术,如CLARiiON CX系列、Symmetrix DMX系列等,这些产品和技术在业界产生了深远的影响。

  1. 云存储与软件定义技术的探索

随着云计算和软件定义技术的兴起,EMC也开始了在这一领域的探索。2014年,公司收购了全闪存初创公司,并试图将自己变成灵活的云供应商。此外,EMC还通过升级高端和低端产品线扩展了其产品线,并推出了针对闪存的基础特性进行开发和设计的XtremIO产品。

  1. 与Dell的合并

在EMC的发展历程中,一个重要的里程碑是与Dell的合并。这次合并不仅加强了EMC在存储和云计算领域的实力,也为其未来的发展提供了更广阔的空间。合并后,EMC成为了Dell Technologies的一部分,继续为全球客户提供创新的存储和云计算解决方案。

Hitron公司的发展小趣事

机顶盒,全称为数字视频变换盒,是连接电视机与外部信号源的重要设备,具有高度的专业性和广泛的科普意义。作为信息家电的一员,机顶盒不仅实现了数模转换,让用户能够在模拟电视上观看数字电视节目,还通过接入互联网,极大地丰富了电视节目的选择,提升了观看体验。

从广义上讲,机顶盒涵盖了从模拟频道增补器到现代的数字卫星机顶盒(DVB-S)、数字地面机顶盒(DVB-T)、有线电视数字机顶盒(DVB-C)以及IPTV机顶盒等多种类型。这些机顶盒不仅接收来自有线电缆、卫星天线、宽带网络及地面广播的信号,还提供了电子节目指南、网页浏览等增值服务,使电视机成为了一个能够与用户进行互动的智能终端。

在技术层面,机顶盒的工作原理可概括为接收、解码和显示三个步骤。它首先通过内置的调谐器接收数字电视信号,随后由内部的解码器将信号转换成电视可识别的视频和音频流,最终通过电视机呈现给用户。随着技术的不断进步,机顶盒已能支持高清、甚至4K超高清视频播放,为用户带来更为细腻的画面和震撼的音效。

未来,机顶盒市场将继续保持稳定增长态势,技术创新与智能化将成为重要的发展方向。高清化、超高清化、人工智能及云计算等技术的应用,将使机顶盒不仅限于基本的电视信号接收与解码功能,而是向智能化、多功能化方向迈进,为用户提供更加便捷、智能的生活体验。

Fagor Electrónica公司的发展小趣事

如今,Fagor Electrónica已经成为电子和数字领域的领军企业之一。展望未来,公司将继续秉承创新驱动的发展理念,加大在人工智能、物联网等新兴领域的投入。同时,Fagor Electrónica还将积极参与全球市场竞争,拓展更广阔的市场空间。相信在不久的将来,Fagor Electrónica将会创造更加辉煌的业绩。

ERP Power公司的发展小趣事

在这个故事中,我们将看到ERP Power如何与HANA技术相结合,为一家电子企业提供了强大的数据支持和分析能力。通过实施基于HANA的ERP Power系统,该企业成功实现了数字化转型,提高了生产效率和产品质量。

Datapro International Inc公司的发展小趣事

Datapro International Inc公司成立于20世纪90年代初,当时正值电子信息技术飞速发展的时期。公司的创始人是一群充满激情和创新精神的年轻工程师,他们看到了在数据存储和处理方面的巨大潜力。于是,他们决定成立Datapro International Inc公司,致力于开发高效、稳定的数据存储解决方案。

在创立初期,Datapro International Inc公司面临着重重困难,包括资金短缺、技术挑战和市场竞争等。然而,他们凭借坚定的信念和不懈的努力,成功开发出了第一款具有创新性的数据存储产品,该产品凭借其卓越的性能和稳定性迅速赢得了市场的认可。这一成功为Datapro International Inc公司的发展奠定了坚实的基础。

Andigilog公司的发展小趣事

为了进一步提升技术实力和市场竞争力,Datapro International Inc公司开始寻求与国内外知名企业的战略合作。他们与一些在数据存储和处理领域具有领先地位的企业建立了合作关系,共同研发新产品、拓展新市场。

通过战略合作,Datapro International Inc公司获得了更多的技术资源和市场机会。同时,他们也从合作伙伴身上学到了许多先进的管理理念和市场策略。这些经验和知识为Datapro International Inc公司的未来发展提供了有力的支持。

问答坊 | AI 解惑

Ansoft发布新片本SIwave

SIwave是一个精确的整板级电磁场全波分析工具,它采用三维电磁场全波方法分析整板或整个封装的全波效应。对于真实复杂的PCB板或IC封装,包括多层、任意形状的电源和信号线,SIwave可仿真整个电源和地结构的谐振频率; 为了避免在完成整个设计时产 ...…

查看全部问答>

请教各位高手,关于职业选择的困惑

我是学计算机的,现在主要做的是手机功能测试这一块 虽说比较热门,但是感觉没啥技术含量,而且工资也不高 平时比较闲的话,我就学习C语言,而且基础还不错 其他像数据结构的基础也还可以 我想请教一下,如果做嵌入式开发的话(主要是基于unix ...…

查看全部问答>

用C# 在wince 中 如何发出声音,设置系统时间呢?

用C# 在wince 中 如何发出声音,设置系统时间呢?请高手指教!…

查看全部问答>

PWM

                                 请问STM32101的PWM最高输出频率是多少MHz?…

查看全部问答>

8962的中文显示原理

有没有人能够给我详细的介绍下8962中文显示的原理啊?求助大神,小弟拜谢!!!…

查看全部问答>

图像数据缓存

关于图像的缓存问题,在做用FPGA做图像处理的过程中,都要用到图像数据的缓存,一般都是用到FIFO或是双端口的RAM来进行缓存,我现在想做直接从存储器中读取图像数据,构成3*3或是5*5的数据缓存窗口,然后在进行下一步的运算,想请教个位,用RAM和FI ...…

查看全部问答>

求证实MTK将下季度发售TD芯片“武松”,展讯的TD叫“Tiger”

本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 “聯發科明年首季將推出雙核心TD-ASCDMA智慧型手機晶片MT6572TD,名稱就為武松(Wu Song),很明顯是用來與展訊的「Tiger」晶片相抗衡. ,由於武松的四大優勢,包括:處理整合和成本優勢、武松為 ...…

查看全部问答>

有谁用过AFE5801这个芯片啊。。。

本帖最后由 dontium 于 2015-1-23 12:41 编辑 楼主现在遇到了很棘手的一个问题。用AFE5801这个芯片调试的时候,读不出SPI的信号。。。可以读出通用寄存器设置的值,但是读不出TVG寄存器的值。有谁用过这个芯片啊,不吝赐教啊。。。。。谢谢各位啦 ...…

查看全部问答>