精华内容
下载资源
问答
  • 本例程由c语言编写,使用stc89c52rc单片机定时器实现,6ms周期pwm输出,实现led31级亮度调节。
  • 本程序是用51单片机通过PWM(脉冲宽度调制)方式控制LED,达到呼吸灯的效果。
  • 51单片机PWM的控制(呼吸灯

    万次阅读 多人点赞 2017-05-31 15:27:16
    PWM 51单片机 呼吸灯

    一、PWM

    Pulse Width Modulation脉冲宽度调制,简称PWM。

    PWM(脉冲宽度调制)对模拟信号电平进行数字编码的方法,计算机只能输出0或5V的数字电压值而不能输出模拟电压,而我们如果想获得一个模拟电压值,则需通过使用高分辨率计数器,改变方波的占空比来对一个模拟信号的电平进行编码。

    仍输出数字信号,因为满幅值的直流供电只有5V(1)和0V(0)两种。电压是以一种连接(1)或断开(0)的重复脉冲序列被夹到模拟负载上去的,连接即是直流供电输出,断开即是直流供电断开。通过对连接和断开时间的控制,只要带宽足够,可以输出任意不大于最大电压值的模拟电压。

         输出电压=(接通时间/脉冲时间)*最大电压值
    

    这里写图片描述

    二、51单片机的Timer

    作者用的单片机是STC89C52,其内部有3个16位Timer,分别为T/C0,T/C1,T/C2,通过配置相关寄存器即可实现Timer的功能控制。

    控制PWM需要用到定时器来生成不同占空比的波形,采用定时器中断的方式。

    相关寄存器:

    1.IE寄存器

    名称 功能
    0 EX0 外部中断0的中断允许位
    1 ET0 Timer0的溢出中断允许位
    2 EX1 外部中断1的中断允许位
    3 ET1 Timer1的溢出中断允许位
    4 ES 串行口中断允许位
    5 ET2 Timer
    6 - -
    7 EA 中断允许总控制位

    2. TCON寄存器

    名称 功能
    0 IT0 外部中断0的触发方式选择位。功能和IE1类似
    1 IE0 外部中断0的中断请求标志位。功能和IE1类似
    2 IT1 外部中断1的触发方式选择位。当IT1=1时,为下降沿触发方式,也就是从高到低的跳变会触发外部中断1。当IT1=0时,为低电平触发,也就是单片机检测到该引脚电平为低时,会触发外部中断1
    3 IE1 外部中断1的中断请求标志位。当IE1=1的时候,表示外部中断1被触发,正在请求单片机处理中断事件。当单片机相应中断,处理中断事件时,该位由单片机自动清零
    4 TR0 启动定时器/计数器0启动位,功能和TR1类似
    5 TF0 定时器/计数器T0溢出中断请求标志位。功能和TF1类似.
    6 TR1 启动定时器/计数器1启动位,TR=1启动计时,TR=0停止计时
    7 TF1 定时器/计数器T1溢出中断请求标志位。当T1溢出时,该位自动置1。单片机响应相应中断时,系统自动清零TF1,也可以程序清零

    3. TMOD寄存器

    控制Timer0/1的工作方式

    名称 功能
    0 M0 工作方式选择位
    1 M1 工作方式选择位
    2 C/T 计数器模式和定时器模式选择位,C/T=1时,为计数器模式,C/T=0时,为定时器模式。C为counter的缩写,T为timer的缩写,这样方便理解
    3 GATE T1(0)的启动源选择位,GATE=1时,用外部中断引脚INT1(INT0)上的高电平来启动T1(T0);GATE=0时,用TCON里的TR1(TR0)来启动T1(T0)。
    4 M0 相似于0位
    5 M1 相似于1位
    6 C/T 相似于2位
    7 GATE 相似于3位
    M1 M0 工作方式
    0 0 方式0,由TH1(TH0)的8位和TL1(TL0)的低5位组成一个13位定时器。
    0 1 方式1,由TH1(TH0)的8位和TL1(TL0)的8位组成一个16位定时器。
    1 0 方式2,TL1(TL0)溢出后,TH1(TH0)的数值自动填充到TL1(TL0)。
    1 1 方式3,仅适用于T0,T0分成两个8位计数器,T1停止计数。

    4. Timer0/1计数寄存器

    TL0
    TL1
    TH0
    TH1

    当定时开启后,TL0(TL1)自动跟随机器周期加一。当TL0(TL1)满了后,自动清零同时向TH0(TH1)进一位,不需要手动操作.

    而当TL0(TL1)和TH0(TH1)都满了以后,此时如果定时中断和总中断都已经打开,那么就会发生溢出中断,同时这两个寄存器清零

    三、运用PWM完成呼吸灯

    1. 硬件电路

    这里写图片描述

    2. 软件驱动

    unsigned char PWM_COUNT; //计数
    unsigned int HUXI_COUNT;    //占空比更新时间
    unsigned char PWM_VLAUE;    //占空比比对值
    bit direc_flag;             //占空比更新方向
    
    void timer0_init()
    {
        TMOD=0x02;          //模式设置,00010000,定时器0,工作于模式2(M1=1,M0=0)
        TH0=0x47;               //定时器溢出值设置,每隔200us发起一次中断。
        TL0=0X47;
        TR0=1;                  //定时器0开始计时
        ET0=1;                  //开定时器0中断
        EA=1;                       //开总中断
        PWM_COUNT =0;
    }
    void time0() interrupt 1
    {   
        PWM_COUNT++;
        HUXI_COUNT++;
        if(PWM_COUNT == PWM_VLAUE)      //判断是否到了点亮LED的时候
            LED = 1;                    //点亮LED
        if(PWM_COUNT == 10)             //当前周期结束
        {
            LED = 0;                    //熄灭LED
            PWM_COUNT = 0;              //重新计时
        }
        if((HUXI_COUNT == 600) && (direc_flag == 0))
        {                               //占空比增加10%
            HUXI_COUNT = 0;
            PWM_VLAUE++;
            if(PWM_VLAUE == 9)          //占空比更改方向
                direc_flag = 1; 
        }
        if((HUXI_COUNT == 600) && (direc_flag == 1))
        {                               //占空比减少10%
            HUXI_COUNT = 0;
            PWM_VLAUE--;
            if(PWM_VLAUE == 1)          //占空比更改方向
                direc_flag = 0; 
        }   
    }
    void main()
    {
        HUXI_COUNT = 0;
        PWM_COUNT = 0;
        PWM_VLAUE = 5;
        direc_flag = 0;
        LED = 1;            //默认LED熄灭   
        timer0_init();      //定时器0初始化
        while(1);
    }
    展开全文
  • 51单片机呼吸灯PWM波) 编写语言:C 运行情况:完美运行
  • 利用pwm实现51单片机呼吸灯功能,使用的是汇编语言。
  • 通过STC89C51单片机,通过定时器实现PWM呼吸灯。通过STC89C51单片机,通过定时器实现PWM呼吸灯。通过STC89C51单片机,通过定时器实现PWM呼吸灯
  • 干货,干货,代码可用,51单片机按键控制PWM呼吸灯,#include #define uchar unsigned char #define uint unsigned int sbit s1=P3^0; sbit s2=P3^4; sbit s3=P3^5; sbit beep=P2^3; uint pwm; uint num; //延时 ...
  • 基于51单片机pwm控制的呼吸灯程序

    热门讨论 2011-11-04 21:39:24
    基于51单片机,通过定时器输出pwm波,全局变量控制占空比,达到led呼吸灯的目的。欢迎下载。
  • 今天回答了一个关于用汇编语言控制51单片机产生PWM波实现呼吸灯效果的问题。结果好久不写程序,一时手生,出了不少错误,索性记录一下,也为自己的知乎账号增加的内容。要实现呼吸灯效果本质上是产生占空比可变的PWM...

    今天回答了一个关于用汇编语言控制51单片机产生PWM波实现呼吸灯效果的问题。结果好久不写程序,一时手生,出了不少错误,索性记录一下,也为自己的知乎账号增加的内容。

    要实现呼吸灯效果本质上是产生占空比可变的PWM波,大体思路如下:

    1. 用定时器1控制PWM的频率,我用的开发板板载晶振11.059MHz,近似为12MHz(因为51的定时频率是晶振的1/12,以12MHz计算比较容易),一个定时周期近似为1us,定时器初值设置为64536(16位模式,最大计数值65536),定时1000次,一个周期约为1ms,可生成1kHz频率的PWM。
    2. 用定时器0控制占空比,占空比从0到1再到0,周而复始。假设LED阳极通过限流电阻接VCC,阴极接单片机P2.7引脚,实现过程大致为:定时器1中断程序将P2.7置1,并启动定时器0,定时器0中断程序中将P2.7复位,并停止定时器0。
    3. 通过一个二进制位(20H.0)控制占空比变化方向,0减小,1增大,每次进入定时器0中断,首先判断20H.0,若为0,将定时器0的计数初值加1,若为1,将定时器0计数初值减1。加减操作后判断是否加到最大值(65535)或减到最小值(64536),若到达最大或最小值,20H.0取反。

    (也可以只用一个定时器产生1ms的时间基准,然后设一个变量进行计数,通过软硬结合的定时方法产生PWM)

    以下为用两个定时器纯硬件定时实现程序截图(不支持汇编语言,截图看起来比较好看)

    结尾处有源程序链接,提取码:6msi

    829cc446103dea0f47d09cd8cef6effb.png

    f7a3e8502c22ed4e8c2b2e49a7f1f260.png
    知乎视频www.zhihu.com
    51单片机汇编程序实现PWM呼吸灯pan.baidu.com
    展开全文
  • //一个PWM周期内的:周期计数,占空比,方向 sbit LED = P2^2; //位定义,led引脚 sbit LED2 = P2^3; void InterruptInit(); //中断初始化配置的函数声明 void Time0(); //定时器0中断的函数声明 void ...

    51单片机通过定时器0产生 20ms/50HZ 的可调节 PWM

     小灯的有效显示应该是50hz,所以周期是20ms

    频率过小显示比较暗,频率过大不好调节

    定时器0,16位自动重装载值,定时长度200us,重装载值100,周期总计20ms

    小灯P22/P23口,

    #include <STC15.H>					//52头文件 
    
    
    u8 Tcount, dutyfactor, direct;		//一个PWM周期内的:周期计数,占空比,方向
    
    sbit LED = P2^2;					//位定义,led灯引脚
    sbit LED2 = P2^3;
    
    void InterruptInit();	//中断初始化配置的函数声明
    void Time0(); 			//定时器0中断的函数声明
    void breatheLED();		//呼吸灯主程序的函数声明
    
    //主函数
    void main() {
        P2M1 &= 0<<2; //p22 //设置小灯IO口为推挽
        P2M1 &= 0<<3; //p23 //设置小灯IO口为推挽
        P2M0 |= 1<<2;
        P2M0 |= 1<<3;
        InterruptInit();				//初始化中断配置
    
        while(1) {
            breatheLED();
        }
    }
    
    //中断初始化配置
    void InterruptInit() {
    	AUXR |= 0x80;		//定时器时钟1T模式
    	TMOD &= 0xF0;		//设置定时器模式
    	TL0 = 0xA0;		//设置定时初值
    	TH0 = 0xF6;		//设置定时初值
    	TF0 = 0;		//清除TF0标志
        ET0 = 1;		//打开定时器0中断允许
        EA  = 1;		//打开总中断
    	TR0 = 1;		//定时器0开始计时
    
    }
    
    
    void Time0() interrupt 1  //定时器0中断
    {
        //200us初值重装
        TL0 = 0xA0;		//设置定时初值
    	TH0 = 0xF6;		//设置定时初值
        Tcount++;//一个PWM周期内,计数
    }
    
    /*  占空比调节示意 
    0  dutyfactor 小于这个数为低电平占比时间
    0 1 2 3 4 5 6 7 8 9 10 Tcount  1个周期20ms
    1
    0 1 2 3 4 5 6 7 8 9 10
    2
    0 1 2 3 4 5 6 7 8 9 10
    */
    
    void breatheLED() //呼吸灯
    {
        if(Tcount >= 100)
        {   
            Tcount = 0;	
    		dutyfactor++;   
        }
        if(Tcount <= dutyfactor)
        {   
            LED = 0;				
    		LED2 = 0;
        }
        else
        {
            LED = 1;		
    		LED2 = 1;
        }
    }

     以下注释去掉可以得到呼吸灯效果

    #include <STC15.H>					//52头文件 
    
    
    u8 Tcount, dutyfactor, direct;		//一个PWM周期内的:周期计数,占空比,方向
    
    sbit LED = P2^2;					//位定义,led灯引脚
    sbit LED2 = P2^3;
    
    void InterruptInit();				//中断初始化配置的函数声明
    void Time0(); 						//定时器0中断的函数声明
    void breatheLED();					//呼吸灯主程序的函数声明
    
    //主函数
    void main() {
        P2M1 &= 0<<2; //p22
        P2M1 &= 0<<3; //p23
        P2M0 |= 1<<2;
        P2M0 |= 1<<3;
        InterruptInit();				//初始化中断配置
    
        //循环实现呼吸灯功能
        //PWM周期:20ms;占空比:0~100;占空比每一份:200us;一次呼吸灯效果(暗->亮->暗):4s
        while(1) {
            breatheLED();				//呼吸灯效果实现
        }
    }
    
    //中断初始化配置
    void InterruptInit() {
    	AUXR |= 0x80;		//定时器时钟1T模式
    	TMOD &= 0xF0;		//设置定时器模式
    	TL0 = 0xA0;		//设置定时初值
    	TH0 = 0xF6;		//设置定时初值
    	TF0 = 0;		//清除TF0标志
        ET0 = 1;		//打开定时器0中断允许
        EA  = 1;		//打开总中断
    	TR0 = 1;		//定时器0开始计时
    
    }
    
    
    void Time0() interrupt 1  //定时器0中断
    {
        //200us初值重装
        TL0 = 0xA0;		//设置定时初值
    	TH0 = 0xF6;		//设置定时初值
        Tcount++;//一个PWM周期内,计数
    }
    
    
    
    void breatheLED() //呼吸灯主程序
    	
    {
        if(Tcount >= 100)
        {   //一个PWM周期(100次*200us)
            Tcount = 0;	//下一个PWM周期内,重新计数
    		dutyfactor++;
    //        if(direct == 0)
    //        {
    //            dutyfactor++;
    //        }
    //        else
    //        {
    //            dutyfactor--;
    //        }
        }
    
        //根据占空比值判断方向是否需要改变
    //    if(dutyfactor <= 0)//正方向,占空比开始增加
    //    {  
    //        direct = 0;					
    //    }
    //    else if(dutyfactor >= 100)//负方向,占空比开始减少
    //    {   
    //        direct = 1;					
    //    }
    	if(dutyfactor >= 100)//负方向,占空比开始减少
        {   
            direct = 0;					
        }
    
        if(Tcount <= dutyfactor)
        {   //周期计数值<占空比
            LED = 0;					//当前PWM周期的当前计数周期内灯亮
    		LED2 = 0;
        }
        else
        {
            LED = 1;					//当前PWM周期的当前计数周期内灯灭
    		LED2 = 1;
        }
    }

    参考:https://blog.csdn.net/a992970569/article/details/108619899

    展开全文
  • 51单片机控制PWM的脉宽,实现手机呼吸灯效果,51单片机爱好者可以下载使用
  • PWM的程序讲解: 通过控制正电平的脉冲所占的时间比来控制小灯的亮暗程度或者电机转速的快慢 等等很多需要调速的地方都可以使用PWM 以小灯为例占空比越大(即高电平所占的时间更长)就越亮 源码: #include<reg...

    PWM的程序讲解:
    通过控制正电平的脉冲所占的时间比来控制小灯的亮暗程度或者电机转速的快慢 等等很多需要调速的地方都可以使用PWM
    以小灯为例占空比越大(即高电平所占的时间更长)就越亮
    源码:

    
    
    #include<reg52.h>
     /* 
     产生周期为1ms(1kHZ)的PWM,设置中断的时间基准为0.01ms
     然后中断100次即为1ms。
      1、当time>=100时,time清零(此语句保证频率为1kHZ);
    
       2、当time>n时(n应该在0-100之间变化开),让单片相应的I/O口输出低电平;
    
       3、当time<=n时,让单片相应的I/O口输出高电平,此时占空比就为%
    
     下面程序产生50%占空比的pwm:
     */
    #define u16 unsigned int
     
    #define u8 unsigned char
    
    sbit PWM=P2^0;// P2.0输出pwm
    u8 time; // 定义占空比的变量
    
    void Init()
    {
    	TMOD|=0x01;//定时器0工作方式1	 
    	TH0=0xff;//(65536-10)/256;//赋初值定时	 
    	TL0=0xf7;//(65536-10)%256;//0.01ms 
    	EA=1;//开总中断 
    	ET0=1;//开定时器0中断	 
    	TR0=1;//启动定时器0
    }
    void main()
    {
    	Init();
    	while(1);
    
    }
    void Tim0() interrupt 1
    {
     
    	TR0=0;//赋初值时,关闭定时器	 
    	TH0=0xff;//(65536-10)/256;//赋初值定时 
    	TL0=0xf7;//(65536-10)%256;//0.01ms 
    	TR0=1;//打开定时器 
    	time++; 
    	if(time>=100) //1khz 
    	time=0; 
    	if(time<=30) / /占空比%50,可改 
    	PWM=1;	 
    	else PWM=0;
    }
    
    
    
    展开全文
  • } 4、呼吸灯逻辑分析,在总频率不变的情况下 ,改变高电平的占比,让高电平的占比逐渐增加,低电平的占比就会减少,这个时候我们就能看到这个灯逐渐变亮。 结合以下代码: /***********呼吸灯代码***********/ void...
  • 51单片机呼吸灯

    2020-03-21 10:33:15
    呼吸灯 代码 #include"reg52.h" typedef unsigned int u16; typedef unsigned char u8; sbit pwm=P2^1; bit dir; u16 count,timer,value; //全局变量 void tim0_init() //定时器初始化函数 ...
  • 课程设计题十八:七彩呼吸灯 要求: (1) 起始状态时,七个灯处于同频率“呼吸”状态。...51单片机只能依靠定时器完成PWM。并且基于PWM原理下,proteus无法仿真出小灯的亮暗,只能看实物。 #include "reg51.h" #inc
  • 51单片机利用PWM、定时器实现呼吸灯

    千次阅读 多人点赞 2020-09-16 13:06:24
    一次呼吸灯效果(暗->亮->暗):4s #include <reg52.h> //52头文件 typedef unsigned char u8; //别名 u8 Tcount, dutyfactor, direct; //一个PWM周期内的:周期计数,占空比,方向 sbit ...
  • 3pwm呼吸灯.zip

    2019-11-20 20:01:58
    STC89C52_51单片机_例程3_PWM_呼吸灯_
  • PWM呼吸灯

    2019-10-05 14:17:14
    PWM呼吸灯,从51单片机开始玩的东西,在FPGA上再实现一次,见代码: 一、设计文件 1 //====================================================================== 2 // --- 名称 : breathing_led 3 // --- ...
  • STC89C52_51单片机_例程3_PWM_呼吸灯

    千次阅读 2019-11-20 20:06:08
    STC89C52_51单片机_例程3_PWM_呼吸灯_ 代码链接 0000000000000000000000 呼吸灯 #include<reg52.h> sbit pwmout = P1^0; unsigned long periodcnt = 0; unsigned char highrh = 0; unsigned ...
  • [DIY多模式]51单片机心形流水灯+呼吸灯+蜂鸣器音乐总体设计1.基础硬件DIY设计1).整体原理图2).PCB电路3).3D_PCB2.单片机程序设计1)呼吸灯[简易模拟PWM]2)蜂鸣器音乐3)几种简易流水灯方式3.效果展示1).实物...
  • 今天,小小学渣又来复习51的定时器啦! 实例一:方波发生器 源码如下: main.c #include <reg52.h> sbit Square=P1^5; //设置方波输出引脚P1^5 void main(void){ TMOD=0x02; //配置TMOD:定时器,工作方式2...

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

51单片机pwm呼吸灯