单片机中的pwn - CSDN
  • pwn波形和占空比

    千次阅读 2016-09-20 20:16:01
    今天做小车学到的两个知识点,感觉蛮重要的,整理一下。 PWM就是脉冲宽度调制,也就是占空比可变的脉冲波形. 脉冲宽度调制是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被...

      今天做小车学到的两个知识点,感觉蛮重要的,整理一下。


    PWM就是脉冲宽度调制,也就是占空比可变的脉冲波形.
    脉冲宽度调制是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。


    电流跟踪型PWM变流电路就是对变流电路采用电流跟踪控制。也就是,不用信号波对载波进行调制,而是把希望输出的电流作为指令信号,把实际电流作为反馈信号,通过二者的瞬时值比较来决定逆变电路各功率器件的通断,使实际的输出跟踪电流的变化。采用滞环比较方式的电流跟踪型变流器的特点:
    ①硬件电路简单;
    ②属于实时控制方式,电流响应快;
    ③不用载波,输出电压波形中不含特定频率的谐波分量;
    ④与计算法和调制法相比,相同开关频率时输出电流中高次谐波含量较多;
    ⑤采用闭环控制.

    占空比(Duty Ratio)在电信领域中有如下含义:
    例如:脉冲宽度1μs,信号周期4μs的脉冲序列占空比为0.25。
    在一段连续工作时间内脉冲占用的时间与总时间的比值。
    在CVSD调制(continuously variable slope delta modulation)中,比特“1”的平均比例(未完成)。
    引申义:
    在周期型的现象中,某种现象发生后持续的时间与总时间的比。
    例如,在成语中有句话:「三天打渔,两天晒网」,如果以三天为一个周期,“打渔”的占空比则为三分之一。


    频率不控制什么,但是频率的高低会产生其他一些副作用。比如在电机控制中,频率太低会导致运动不稳定,如果频率刚好在人耳听觉范围,有时还会听到呼啸声。对于需要进行直流滤波的场合,频率越高,滤波的效果就越好。但是也不是说频率高一定好,太高的频率电机可能反应不过来。而且,如果PWM是由单片机产生的,那么他的频率和位数是成反比的(一些低端的单片机频率基本是确定的,位数也是确定的,不存在这个问题),比如说,单片机频率10M,如果PWM频率是5M,那么一个PWM周期内就只有两个机器周期,那么占空比的值就只有 0、50%、100%这三种。如果PWM频率是5k,那么一个PWM周期有2000个机器周期,占空比最小就可以去到1 / 2000 = 0.05%。所以实际运用中,要根据硬件因素设定频率,一旦设定了,也就不需要更改了,因为硬件是不会改变的。
    占空比才是真正PWM应用的,其实就是开关的打开和关断的时间比值,这个比值在宏观上可以欺骗人眼,于是形成和电位器一样的作用。比如对一个电灯来说,你在1秒内,打开开关0.5秒,再关闭0.5秒,如此反复,那么电灯就会闪烁,但是如果是1毫秒内,0.5毫秒打开,0.5毫秒关闭,由于视觉暂留作用,也可能由于灯光的亮灭速度赶不上开关速度(还没全亮就又没电了),于是人眼不感觉电灯在闪烁,而是感觉灯的亮度少了一半。同理,如果是0.1毫秒开,0.9毫秒灭,感觉灯的亮度就只有1/10了。对于电机的原理也差不多,开关开时电机加速,关闭时电机减速,根据是加速时间多还是减速时间多,我们感觉总体的转速就是快了或慢了。当然,具体分析时还需考虑电机的电感作用,电感有滤波效果,但是用这个方式去理解也是成立的。
    回到前面的频率问题,就如刚才说的,1秒内,0.5秒开,0.5秒灭,占空比是50%对吧?那么,1毫秒内,0.5毫秒开,0.5毫秒灭,占空比也是50%,对吧?如果是1秒呢,频率就是1HZ,如果是1毫秒,频率就是1KHZ,显然,同样是50%占空比,如果频率是1HZ,那电机肯定是跳着走的,灯光肯定闪得可以跳舞,不具有调速和调光的意义。

    
    

    展开全文
  • 蓝桥杯——PWM

    2020-03-21 22:45:00
    PWM全称为脉冲宽度调制,在实际生活很多地方都会见到这个技术的影子,例如灯的明暗调控,电机的转动速度还有幅度等等。在这些应用我们需要使用不同的电压来达到目的,输出不同电压的方式有两种,一种是直接输出...

    一、原理部分

    PWM全称为脉冲宽度调制,在实际生活中很多地方都会见到这个技术的影子,例如灯的明暗调控,电机的转动速度还有幅度等等。在这些应用中我们需要使用不同的电压来达到目的,输出不同电压的方式有两种,一种是直接输出指定的电压值,还有一种就是PWM。
    在这里插入图片描述
    Ton为高电平持续时间
    Toff为低电平持续时间
    Ts一个周期时间
    占空比=高电平持续时间/周期
    简单来说一个io口只能输出固定的电压值如5V或者0V,我们要获取其他的电压值就可以通过占空比来控制io口的电压输出。假如现在需要一个3V的电压值,那么占空比就是60%,高电平持续时间占周期的60%,低电平占周期的40%。假设周期为10ms,那么就要让此io口输出高电平6ms的时间然后输出低电平4ms的时间,这样我们就输出了一个3V的电压。

    在单片机中我们可以通过定时器来实现PWM的输出

    具体步骤

    一、开一个定时器

    根据题目要求,假如题目要1khz的信号也就是周期为1ms,涉及到的占空比为10的整数倍时,就可以开100us的定时器,如果设计到的占空比不是10的整数倍时那么定时器就要开10us的。其他的以此类推。

    二、定义一个变量用来当做周期使用

    定义变量pwm_cycle变量,每次执行中断服务函数时这个变量自加,达到了题目要求的时间便清零。

    三、定义一个控制pwm占空比的变量

    定义变量pwm,pwm和占空比有关系,然后让pwm和pwm_cycle进行比较,pwm大的时候执行高电平,pwm小的时候执行低电平。这样就完成了一个可以自己控制占空比的信号输出。

    二、代码部分

    实验平台:CT107D
    实验芯片:stc15f2k60s2
    实验现象:呼吸灯
    代码如下

    #include<stc15f2k60s2.h>
    bit flag_pwn;
    unsigned char led_dat;
    void Timer0Init()		//10us@12.000MHz
    {
    		AUXR |= 0x80;		
    		TMOD &= 0xF0;	
    		TL0 = 0x88;		
    		TH0 = 0xFF;		
    		TF0 = 0;		
    		TR0 = 1;		
    		ET0 = 1;
    		EA = 1;
    }	
    void ShowLed(unsigned char led_dat)
    {
    		P2 = P2&0x1f|0x80;
    		P0 = led_dat;
    		P2 = P2&0x1f;
    }
    
    void T0_time() interrupt 1
    {
    		static unsigned int count = 0,n = 0,pwn = 0;
    		TL0 = 0x88;		
    		TH0 = 0xFF;	
    		if(++count >= 1000)  //周期10ms
    		{
    				count = 0;
    		}
    		if(++n >= 100)     //每隔1ms变化一次pwn
    		{
    				n = 0;
    				if(flag_pwn == 0)   
    				{
    						pwn++;                 //PWN增加,灯泡由亮到暗
    						if(pwn == 1000)
    						{
    								flag_pwn = 1;
    						}					
    				}
    				else if(flag_pwn == 1)
    				{
    						pwn--;                //PWN减少,灯泡由暗到亮
    						if(pwn == 0)
    						{
    								flag_pwn = 0;
    						}
    				}
    		}
    		
    		if(count > pwn)        //亮
    		{
    				ShowLed(0x00);
    		}
    		else                   //暗
    		{
    				ShowLed(0xff);
    		}		
    }
    
    void CloseFucker()
    {
    		P2 = P2&0x1f|0xa0;
    		P0 = 0xaf;
    		P2 = P2&0x1f;
    }
    
    void main()
    {
    		CloseFucker();
    		Timer0Init();
    		while(1)
    		{
    			;
    		}
    }
    
    展开全文
  • 在中断软件模拟PWN

    千次阅读 2016-08-13 13:02:11
    软件模拟pwn

    在做一个项目,因为脑残没有把RGB接到硬件定时器引脚上,所以,只能软件模拟咯。

    首先中断配置什么的就不详细说了

        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        /* 设置TIM2CLK 为 72MHZ */
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5 , ENABLE);
        /* 自动重装载寄存器周期的值(计数值) */
        TIM_TimeBaseStructure.TIM_Period=200;
        /* 累计 TIM_Period个频率后产生一个更新或者中断 */
        /* 时钟预分频数为72 */
        TIM_TimeBaseStructure.TIM_Prescaler= 71;
        /* 对外部时钟进行采样的时钟分频,这里没有用到 */
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
        TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
        TIM_ClearFlag(TIM5, TIM_FLAG_Update);
        TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
        TIM_Cmd(TIM5, ENABLE);                                                                      
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5 , DISABLE);      /*先关闭等待使用*/    
        //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5 , ENABLE);  //开启使用
    
        NVIC_InitTypeDef NVIC_InitStructure; 
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                                     
        NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;   
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

    上中断代码

    
      void TIM5_IRQHandler(void)
     {
    
        if ( TIM_GetITStatus(TIM5 , TIM_IT_Update) != RESET ) 
        {   
            TIM_ClearITPendingBit(TIM5 , TIM_FLAG_Update);           
        }   
    static u16 pwm_tmpR = 0,pwm_tmpG=0,pwm_tmpB=0;
    static u32 pwn_counterR=0,pwn_counterG=0,pwn_counterB=0;
    static char RGBmode = 0;
    
        switch(RGBmode)  //切换模式
        {
            case 0:  //红灯亮 绿灯逐渐亮
                pwn_counterR=0x2fff;
                pwn_counterG++;
                if(pwn_counterG>0x2fff)
                {
                    RGBmode++;
                }
                break;
            case 1://绿灯亮 红灯逐渐灭
                pwn_counterG=0x2fff;
                pwn_counterR--;
                if(pwn_counterR==0)
                {
                    RGBmode++;
                }
                break;
            case 2://绿灯亮 蓝灯逐渐亮
                pwn_counterG=0x2fff;
                pwn_counterB++;
                if(pwn_counterB>0x2fff)
                {
                    RGBmode++;
                }
                break;
            case 3://蓝灯亮  绿灯逐渐灭
                pwn_counterB=0x2fff;
                pwn_counterG--;
                if(pwn_counterG==0)
                {
                    RGBmode++;
                }
                break;
            case 4:
                pwn_counterB=0x2fff;
                pwn_counterR++;
                if(pwn_counterR>0x2fff)
                {
                    RGBmode++;
                }
                break;
            case 5:
                pwn_counterR=0x2fff;
                pwn_counterB--;
                if(pwn_counterB==0)
                {
                //  RGBmode++;
                    RGBmode=0;
                }
                break;
            default :
                pwn_counterG=0;
                pwn_counterR=0;
                pwn_counterB=0;
                RGBmode=0;
                break;
    
        }
    
        pwm_tmpR+=10;
        pwm_tmpG+=10;
        pwm_tmpB+=10;
        pwm_tmpR&=0xff;
        pwm_tmpG&=0xff;
        pwm_tmpB&=0xff;
    
        if(pwm_tmpR < pwn_counterR>>5)  //红灯占空比pwn_counterR
        {
            change_LED_value(LED_R,1);
        }
        else
        {
            change_LED_value(LED_R,0);
        }
        if(pwm_tmpG < pwn_counterG>>5)
        {
            change_LED_value(LED_G,1);
        }
        else
        {
            change_LED_value(LED_G,0);
        }
        if(pwm_tmpB < pwn_counterB>>5)
        {
            change_LED_value(LED_B,1);
        }
        else
        {
            change_LED_value(LED_B,0);
        }
     }
    

    说明

    change_LED_value(LED_B,0); //蓝灯灭
    change_LED_value(LED_B,1); //蓝灯亮

    展开全文
  • 再次感谢ReCclay大佬文章的启迪: 《觉得自己再有必要开一篇PWM的文章了》 作者:ReCclay ... 实验原理: 通过上图就可以 看出,占空比越高,高电平越久,小灯泡就越暗 ...(这里高电平小灯泡灭,低电平小灯泡亮) ...

    再次感谢ReCclay大佬文章的启迪:

    《觉得自己再有必要开一篇PWM的文章了》 作者:ReCclay
    [如果想要更深入详细了解PWN,请务必点击这篇文章↑↑↑↑]

    实验原理:

    在这里插入图片描述在这里插入图片描述在这里插入图片描述

    通过上图就可以 看出,占空比越高,高电平越久,小灯泡就越暗
    (这里高电平小灯泡灭,低电平小灯泡亮)

    所以只要控制占空比,就可以控制小灯泡的亮暗

    代码:

    先设置一个10us的定时器

    void Timer0Init()		//10us@12.000MHz
    {
    		AUXR |= 0x80;		
    		TMOD &= 0xF0;	
    		TL0 = 0x88;		
    		TH0 = 0xFF;		
    		TF0 = 0;		
    		TR0 = 1;		
    		ET0 = 1;
    		EA = 1;
    }
    

    中断里控制PWN

    void T0_time() interrupt 1
    {
    		static uint count = 0,n = 0;
    		TL0 = 0x88;		
    		TH0 = 0xFF;	
    		if(++count >= 1000)   //周期10ms
    		{
    				count = 0;
    		}
    		if(count<PWN)         //亮 ,PWN越高,小灯泡越亮
    		{
    				ShowLed(0x00);
    		}
    		else 					   //灭
    		{
    				ShowLed(0xff);
    		}		
    }
    

    应用:

    呼吸灯:
    main.c

    ******************************************************************************
    * 文件名:呼吸灯
    * 描  述:
    * 作  者:思索与猫
    * 日  期:  19/3/17 
    * 备  注: 
    *         
    ******************************************************************************
    #include<stc15f2k60s2.h>
    #include<sys.h>
    void main()
    {
    		CloseFucker();
    		Timer0Init();
    		while(1)
    		{
    				;
    		}
    }
    

    sys.h

    #ifndef __SYS_H_
    #define __SYS_H_
    
    #include<stc15f2k60s2.h>
    typedef unsigned char uchar;
    typedef unsigned int uint;
    
    void Timer0Init();
    void CloseFucker();
    
    void ShowLed(uchar led_dat);
    
    #endif
    

    sys.c

    #include<sys.h>
    bit flag_pwn;
    void Timer0Init()		//10us@12.000MHz
    {
    		AUXR |= 0x80;		
    		TMOD &= 0xF0;	
    		TL0 = 0x88;		
    		TH0 = 0xFF;		
    		TF0 = 0;		
    		TR0 = 1;		
    		ET0 = 1;
    		EA = 1;
    }
    
    void T0_time() interrupt 1
    {
    		static uint count = 0,n = 0,pwn = 0;
    		TL0 = 0x88;		
    		TH0 = 0xFF;	
    		if(++count >= 1000)  //周期10ms
    		{
    				count = 0;
    		}
    		if(++n >= 100)     //每隔1ms变化一次pwn
    		{
    				n = 0;
    				if(flag_pwn == 0)   
    				{
    						pwn++;                 //PWN增加,灯泡由亮到暗
    						if(pwn == 1000)
    						{
    								flag_pwn = 1;
    						}					
    				}
    				else if(flag_pwn == 1)
    				{
    						pwn--;                //PWN减少,灯泡由暗到亮
    						if(pwn == 0)
    						{
    								flag_pwn = 0;
    						}
    				}
    		}
    		
    		if(count > pwn)        //亮
    		{
    				ShowLed(0x00);
    		}
    		else                   //暗
    		{
    				ShowLed(0xff);
    		}		
    }
    
    void CloseFucker()
    {
    		P2 = P2&0x1f|0xa0;
    		P0 = 0xaf;
    		P2 = P2&0x1f;
    }
    

    display.c

    #include<sys.h>
    void ShowLed(uchar led_dat)
    {
    		P2 = P2&0x1f|0x80;
    		P0 = led_dat;
    		P2 = P2&0x1f;
    }
    
    
    展开全文
  • 本例程由c语言编写,使用stc89c52rc单片机定时器实现,6ms周期pwm输出,实现led灯31级亮度调节。
  • 51单片机PWM控制电机

    千次阅读 多人点赞 2015-01-04 13:29:13
    小时候玩的四驱车,给直流马达接通电源就嗤嗤的跑出去了。电机种类众多,就属控制直流电机最简单,只要对调正负极就能改变电机的转向。另外,直流电机负载能力强,适合做越野车的驱动电机。为了做可调速的越野车,就...
  • 51单片机PWM输出

    千次阅读 2019-01-06 13:42:55
    学期快结束了,51单片机的学习也差不多告一段落,也快要转入新的学习阶段,寒假找个时间看看32,小白哈哈哈,下面是我学习51定时器弄出来的小东西,一个PWM的输出。还请大神指点。 刚开始觉得PWM输出应该不难,很...
  • 利用51单片机输出pwm

    万次阅读 多人点赞 2017-06-07 09:57:52
    51单片机是可以输出PWM的,比较的麻烦。此时需要用到内部定时器来实现,可用两个定时器实现,也可以用一个定时器实现。  用两个定时器的方法是用定时器T0来控制频率,定时器T1来控制占空比。大致的的编程思路是这样...
  • 51单片机PWM的控制(呼吸灯)

    万次阅读 多人点赞 2017-05-31 15:27:16
    PWM 51单片机 呼吸灯
  • 参考:51单片机按键控制输出pwm的占空比 原理图: 程序: #include<reg51.h> #define uint unsigned int #define uchar unsigned char sbit PWM=P1^0;// P1.0输出pwm sbit K1=P1^4;//占空比加5 sbit K2=P1^...
  • 51单片机入门教程(5)——定时器中断

    千次阅读 多人点赞 2020-05-06 08:27:11
    51单片机入门教程(5)——定时器中断一、中断的概念二、定时器中断2.1 软件延时的不足2.2 中断寄存器2.2.1 中断允许控制寄存器 IE2.2.2 定时器工作方式寄存器 TMOD2.2.3 定时器控制寄存器 TCON2.2.4 定时器初值...
  • 利用单片机定时器产生的占空比可调的PWM程序,采用C51编写的。
  • 基于51单片机模拟PWM

    2020-07-28 23:32:30
    脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域。本程序基于51单片机所涉及的模拟PWM的脉宽输出。
  • pwn呼吸灯

    2019-08-20 15:58:39
    这是百度百科的原理介绍 这是某大神的回答 既然原理懂了 我看下代码 void Timer1Init() { TMOD|=0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。 TH1 = 0xFF; TL1 = 0xff; //1us ...voi...
  • 4种单片机驱动继电器方案

    千次阅读 2019-07-01 14:05:54
    在网上论坛看到一个贴子收集的,供大家参考 方案一:三极管驱动 方案二:ULN2003驱动 方案三:光耦+三极管驱动 方案四:光耦+ULN2003驱动 ...光耦内阻比较大,不能直接驱动负载,后面要加一级驱动管 ...
  • 阮工的单片机编程经验集V2.0:如何做稳定单片机程序 ,阮丁远于20191208 : ================================================================================================ 20191207 : 5V等电源输入时...
  • 1、首先连接好电路图 我连接的P1^0 2、初始化LED sbit LED1 = P1^0; //初始化LED 3、初始化T0 /***********T0初始化***********/ void time_Init() { TMOD = 0x01; TH0 = 0x00; TL0 = 0x0f;...void tim...
  • 这个是MSP430F149单片机的PWM输出,通过按键控制占空比的增减
  • 单片机编程百问百解:(个人工作遇到的问题点进行罗列) 1.当一个单片机IO引脚有模拟 输入捕获 外部中断 等几个功能同时被设定的情况下 MCU是怎么工作的?  在PIC单片机中首先第一关就是模拟与数字 其次才是输入...
  • 有关STC15X问题

    2019-12-27 15:37:33
    单片机中EEPROM和FLASH,一般单片机的FLASH为程序存储器,用来存放单片机程序的,就是由单片机编程人员编制的单片机程序通过烧写器(有称编程器)下载到单片机的FLASH。 EEPROM为一种数据存储器,断电后数据不会...
1 2 3 4 5 6
收藏数 120
精华内容 48
热门标签
关键字:

单片机中的pwn