历史上的今天
返回首页

历史上的今天

今天是:2025年07月13日(星期日)

正在发生

2020年07月13日 | 51单片机入门经验分享9-定时器模拟实现PWM呼吸灯效果

2020-07-13 来源:51hei

众所周知,PWM的应用是及其广泛的,现在很多高速的单片机内部都集成了硬件PWM,使用起来也很简单,配置好频率和装入计数值就可以工作了,但是在一些低成本的场合,我们选择的单片机没有硬件PWM功能模块,但是我们还存在这个需求怎么办呢?这个时候,我们需要用PWM来模拟实现他,但实现PWM必须要了解PWM的原理,这里我们先了解下。


PWM全称是脉冲宽度调制解调,比如1个小灯,按照500MS亮一次,500MS灭一次,周期是1S,频率是1HZ,在这里,1个周期说明白了就是2个方波,有高电平和低电平组成,在周期固定的情况下,我们通过不断的调整高电平所占的整个周期比例,即所谓的占空比,就可以实现小灯”不是那么亮“的效果,如果连续起来,就可以实现呼吸灯的效果了,先来用定时器0实现小灯500MS闪烁的效果,通过DEBUG来看下波形。我们把下面的代码拷贝进去,看下现象


单片机源码:

/********************************************************

*描述:工程模板,点亮led        500MS闪烁 12MHZ

********************************************************/

#include "stc15w.h"



/*******************************************************************************

* 文件名:位定义

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

bit flag500ms = 0;//500ms标志位

sbit LED0 = P1^0;//

sbit DATA0 = P2^0;//


/*******************************************************************************

* 文件名:数据类型定义

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

typedef unsigned char uint8;

typedef unsigned int  uint16;

typedef unsigned long uint32;


/*******************************************************************************

* 文件名:函数前置声明

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/


void Bsp_Power_Init(void);

void Timer0Init(void);


/*******************************************************************************

* 文件名:主循环入口

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void main(void)

{

        Bsp_Power_Init();//LED端口初始化

        Timer0Init();

        LED0 = 1;


        while(1)

        {


                if(flag500ms)

                {

                        flag500ms = 0;


                        DATA0 = ~DATA0;//

                }

                        

        }

}


/*******************************************************************************

* 文件名:void Bsp_Power_Init()

* 描  述: 数码管上电显示

* 功  能:编程模块化

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void Bsp_Power_Init(void)

{

        P0M1 = 0xFC;

        P0M0 = 0X03;

        P0 = 0X00;


        P1M1 = 0xE0;

        P1M0 = 0X1F;

        P1 = 0X00;



        //P2口开漏输出

        P2M1 = 0XFF;

        P2M0 = 0XFF;

        P2 = 0Xff;

//        //P54,P55口为推挽输出

        P5M1 = 0X00;

        P5M0 = 0X00;

        P5 = 0xFF;


        //P37,P36,3.2,P3.3 P3.4口为推挽输出

        P3M1 = 0X00;

        P3M0 = 0XFC;

        P3 = 0X23;


}


/*******************************************************************************

* 文件名:void Bsp_Power_Init()

* 描  述: 数码管上电显示

* 功  能:编程模块化

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void Timer0Init(void)                //1毫秒@12MHZ

{

        AUXR &= 0x7f;                    //定时器时钟12T模式

        TMOD &= 0xF0;                    //设置定时器模式

        TMOD |= 0x01;                    //设置定时器模式

        TL0 = (65535 - 1000) % 256;                //设置定时初值

        TH0 = (65535 - 1000) / 256;                //设置定时初值

        ET0 = 1;

        TR0 = 1;                //定时器0开始计时

        EA = 1;

}


/*******************************************************************************

* 文件名:void TIME0_INTER(void) interrupt 1

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void TIME0_INTER(void) interrupt 1

{

        static uint16 tmr500ms = 0;


        TL0 = (65535 - 1000) % 256;                //设置定时初值1ms

    TH0 = (65535 - 1000) / 256;                //设置定时初值


        tmr500ms++;


        if(tmr500ms >= 500)

        {

                tmr500ms = 0;


                flag500ms  = 1;

        }

                                       

}


从DEBUG可以看到,是500MS变化一次,说明我们的设置是对的,但是在这里还是说明一点,我们用的而是STC15W系列的芯片,但是定时器我配置成了12T模式,和STC89C52是一样使用的。既然我们实现了这个500MS高电平,500MS低电平的效果,我们再来实现下200MS亮,800MS灭的效果吧,程序代码如下:


/********************************************************

*描述:工程模板,点亮led        500MS闪烁 12MHZ

********************************************************/

#include "stc15w.h"



/*******************************************************************************

* 文件名:位定义

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

sbit LED0 = P1^0;//

sbit DATA0 = P2^0;//


/*******************************************************************************

* 文件名:数据类型定义

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

typedef unsigned char uint8;

typedef unsigned int  uint16;

typedef unsigned long uint32;


/*******************************************************************************

* 文件名:函数前置声明

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/


void Bsp_Power_Init(void);

void Timer0Init(void);


/*******************************************************************************

* 文件名:主循环入口

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void main(void)

{

        Bsp_Power_Init();//LED端口初始化

        Timer0Init();

        LED0 = 1;


        while(1);


}


/*******************************************************************************

* 文件名:void Bsp_Power_Init()

* 描  述: 数码管上电显示

* 功  能:编程模块化

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void Bsp_Power_Init(void)

{

        P0M1 = 0xFC;

        P0M0 = 0X03;

        P0 = 0X00;


        P1M1 = 0xE0;

        P1M0 = 0X1F;

        P1 = 0X00;



        //P2口开漏输出

        P2M1 = 0XFF;

        P2M0 = 0XFF;

        P2 = 0Xff;

//        //P54,P55口为推挽输出

        P5M1 = 0X00;

        P5M0 = 0X00;

        P5 = 0xFF;


        //P37,P36,3.2,P3.3 P3.4口为推挽输出

        P3M1 = 0X00;

        P3M0 = 0XFC;

        P3 = 0X23;


}


/*******************************************************************************

* 文件名:void Bsp_Power_Init()

* 描  述: 数码管上电显示

* 功  能:编程模块化

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void Timer0Init(void)                //1毫秒@12MHZ

{

        AUXR &= 0x7f;                    //定时器时钟12T模式

        TMOD &= 0xF0;                    //设置定时器模式

        TMOD |= 0x01;                    //设置定时器模式

        TL0 = (65535 - 1000) % 256;                //设置定时初值

        TH0 = (65535 - 1000) / 256;                //设置定时初值

        ET0 = 1;

        TR0 = 1;                //定时器0开始计时

        EA = 1;

}


/*******************************************************************************

* 文件名:void TIME0_INTER(void) interrupt 1

* 描  述:

* 功  能:

* 作  者:大核桃

* 版本号:1.0.1(2017.05.23)

*******************************************************************************/

void TIME0_INTER(void) interrupt 1

{

        static uint16 tmr200ms = 0;

        static bit a = 0;//翻转状态变量



        if(a)

        {

                TL0 = (65535 - 1000) % 256;                //设置定时初值1ms

推荐阅读

史海拾趣

AnDAPT__Inc.公司的发展小趣事

AnDAPT Inc.是一家专注于可编程电源管理解决方案的创新型公司。以下是关于该公司发展的相关故事:

  1. 公司成立与初期阶段:AnDAPT Inc.成立于2014年,总部位于美国加利福尼亚州圣何塞。公司的创始人之一是Raghunandan "Raghu" Anandan,他在可编程电源管理领域拥有丰富的经验和专业知识。公司成立之初,致力于开发一种新型的可编程电源管理解决方案,以满足日益复杂和多样化的电子设备对电源管理的需求。

  2. 技术创新与产品开发:AnDAPT Inc.在其成立初期即开始着手开发基于可编程电源管理技术的解决方案。公司团队结合了数字信号处理(DSP)和模拟电路设计等领域的专业知识,不断推动技术创新和产品开发。他们的主要产品是基于可编程电源管理器件的芯片,能够根据应用需求动态调整电源管理参数,提供高效、灵活和智能的电源解决方案。

  3. 市场拓展与合作伙伴关系:随着公司技术的不断成熟和产品的不断推出,AnDAPT Inc.开始加大对市场的拓展力度。公司与电子设备制造商、系统集成商以及电源管理解决方案提供商建立了紧密的合作关系,共同推动可编程电源管理技术的应用和推广。通过与行业领先的合作伙伴进行合作,AnDAPT Inc.不断拓展产品的应用领域和市场份额。

  4. 技术认证与市场认可:AnDAPT Inc.的产品经过严格的技术认证和市场测试,在业界获得了良好的口碑和市场认可。公司的可编程电源管理解决方案被广泛应用于各种电子设备,包括消费类电子产品、工业自动化设备、汽车电子系统等。其技术创新和产品性能得到了行业专家和客户的一致好评。

  5. 持续发展与未来展望:作为一家专注于可编程电源管理技术的创新型公司,AnDAPT Inc.将继续致力于技术创新和产品开发。公司将不断推出新的产品和解决方案,满足客户不断变化的需求,并积极参与行业标准的制定和技术进步的推动。在未来,AnDAPT Inc.将继续保持敏锐的市场洞察力和技术领先地位,助力客户实现产品创新和市场竞争优势。

Aleph America Corporation公司的发展小趣事

Aleph America Corporation 是一家专注于光电传感器和光电开关解决方案的公司。以下是关于该公司发展的5个相关故事:

  1. 公司成立及发展: Aleph America Corporation 成立于1986年,总部位于美国新泽西州。公司专注于光电传感器技术的研发和生产,并提供广泛的光电开关产品线,包括光电接近传感器、光电开关、光电耦合器等。随着市场对自动化和安全系统需求的增长,Aleph 在行业内逐渐建立了良好的声誉。

  2. 技术创新与产品质量: Aleph America Corporation 致力于技术创新和产品质量的提升。公司拥有一支专业的研发团队,不断引入先进的光电传感技术,并且注重产品的生产工艺和质量控制,确保产品具有稳定的性能和可靠的品质。

  3. 应用领域广泛: Aleph 的产品广泛应用于各种工业和商业应用领域。光电传感器和光电开关被广泛应用于自动门、电梯、安防系统、自动化生产线等领域,为客户提供了安全可靠的解决方案。

  4. 全球市场拓展: 随着全球市场的不断扩大,Aleph 在海外市场的拓展也逐渐加强。除了在美国设立总部和生产基地外,公司还在欧洲、亚洲等地设立了销售办事处和代理商网络,以便更好地满足全球客户的需求。

  5. 参与行业标准和认证: Aleph America Corporation 积极参与行业标准的制定和产品认证工作。公司的产品符合国际标准和认证要求,如CE认证、UL认证等,确保产品在全球范围内的市场准入和使用安全。

以上故事展示了 Aleph America Corporation 在光电传感器和光电开关领域的发展历程和成就,突出了其在技术创新、产品质量、市场拓展和行业认证方面的重要贡献。

Holmes Co Inc公司的发展小趣事

面对日益增长的全球市场需求,Holmes Electronics决定实施全球化战略。他们首先在亚洲建立了生产基地,利用当地的成本优势和供应链资源,大幅提高生产效率并降低成本。随后,公司又在欧洲和美国设立了研发中心和销售网络,以更好地服务当地客户并捕捉市场机会。这一全球化战略不仅使Holmes Electronics的产品遍布全球,还增强了公司的市场响应能力和品牌影响力。

Chemi-Con公司的发展小趣事

随着电子行业的快速发展,Chemi-Con公司不断加大对研发的投入,致力于技术创新和产品升级。公司研发团队在铝电解电容器的基础上,不断推出性能更优、体积更小、寿命更长的产品,满足了市场对于高效、可靠电容器的迫切需求。此外,Chemi-Con还积极拓展产品线,涉足了多层陶瓷电容器、薄膜电容器等多个领域,为客户提供更加丰富的选择。

ERNI Electronics公司的发展小趣事

ERNI Electronics一直致力于技术创新和产品升级。继成功开发出世界上第一个DIN连接器后,公司又发展了多种电路板连接器和输入/输出连接器。这些连接器具有不同的针脚大小和间距,满足了各种应用场景的需求。此外,ERNI还推出了高速数据传输连接器、坚固耐用的M8/M12连接器以及最新的MiniBridge单排电缆连接器系统等创新产品,不断推动电子行业的发展。

Ho Chien Electronics Group Inc公司的发展小趣事

随着公司规模的扩大和产品线的丰富,ERNI Electronics开始积极拓展全球市场。1980年,公司在美国建立了分公司,为后续成为全球供应商打下了坚实的基础。此后,ERNI在新加坡建立了亚洲区总部,并在中国、台湾、韩国、泰国、马来西亚和印度等地设立了销售办事处。这一系列举措使得ERNI的产品能够覆盖更广泛的市场,满足了全球客户的需求。

问答坊 | AI 解惑

电路在线测试仪系列简介

:ICT4040XP电路板故障检测仪 电路板故障检测仪◆先进的测试技术,强大的驱动能力,任何故障原因的电路板皆可修好◆友好简单的中文操作界面,不经专业训练,任何人均可成为维修专家◆无需电路原理图,不必知道器件型号,对任何电路板皆可快 ...…

查看全部问答>

微型红外追踪及无线遥控车设计!

微型红外追踪及无线遥控车设计!…

查看全部问答>

IDS语音器件分段地址的获取

本帖最后由 paulhyde 于 2014-9-15 03:55 编辑 各位大虾:你们好!   再下最近在做一个基于单片机的语音播报时钟,但是在语音器件分段地址的获取遇到了问题!主要功能是通过按键播报当前系统时间,我选用的语音芯片是ISD2560,用的AT89S5 ...…

查看全部问答>

设备上WINCE 环境下怎样实现URL 连接服务器

在虚拟机上 能够正常实现连接服务器 取得文件;现在,在设备上,则提示“无法连接服务器”; 代码: CInternetSession IS; CFile * pFile; CString sURL; sURL = (char *)strDataURL; sURL.MakeUpper();   pFile=IS.OpenURL(sURL, ...…

查看全部问答>

急!求通过GSM模块,发送中文短信源码

那位大哥,有在win ce 环境下,通过GSM模块发送中文短信源码?如分不够可以再加,,…

查看全部问答>

TEXT()编译出错

在EVC中写一应用程序. 书写如下: printf(TEXT(\"创建表失败,错误码:%d,错误原因:%s\\n\"), result, zErrMsg ); 在VC中这样编译OK. 但EVC编译出错. 请问怎么才能保证输出不是乱码的书写语法? …

查看全部问答>

求助:IAR能看程序运行的时间吗?

                                 最近用IAR4.2调试STM32程序,不知道能不能用IAR来查看程序运行的时间,比如说从一个循环开始到这个循环结束总共用 ...…

查看全部问答>

关于STM32F101R8T6的串口下载电路

请问大侠们,STM32F101R8T6是否有使用串口来下载程序的电路,而不是使用JTAG来下载!…

查看全部问答>

Good to Great !概伦电子2012招聘职位!

概伦电子2012招聘职位 公司简介      概伦电子科技有限公司(ProPlus Electronics Co., Ltd.)致力于提升先进半导体工艺下集成电路设计的竞争力,提供创新的电子设计自动化(EDA)解决方案,其产品发展方向包括针对于十 ...…

查看全部问答>

接收中断标志

stm32f10x_it.c uint16_t  xx; void USART1_IRQHandler(void) {                  USART_ClearITPendingBit(USART1,USART_IT_RXNE);   &n ...…

查看全部问答>