精华内容
下载资源
问答
  • 当脉冲的上升沿来临时,将定时器打开;紧接着的下降沿来临时,读取定时器的值,假设定时时间为t1;下一个上升沿来临时关闭...t1/t2即为占空比,1/t2即为频率。一个比较好的思路,可以试一下~文档内附有部分代码和截图
  • 单片机测量PWM占空比的三种方法

    千次阅读 多人点赞 2019-10-26 14:21:15
    单片机测量PWM占空比的三种方法 PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,...

    单片机测量PWM占空比的三种方法

    PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,比如LED亮度调节、电机转速控制等。
    而在某些特殊应用中,我们也需要通过测量输入PWM的占空比,来实现不同的输出控制,这就需要使用到PWM占空比的测量方法。这里介绍三种不同的测量方法:阻塞方式、中断方式以及定时器捕获功能。

    1. 阻塞方式

    MCU阻塞方式测量PWM占空比的原理比较简单,也只需要使用到一个普通的IO端口(设置为输入模式,对于51而言那就是一个普通的双向口)。具体实现流程为:

    • 等待上升沿到来,然后开启定时器,开始计时;
    • 等待下降沿到来,记录下定时器的计数值,即得到PWM的高电平时间H
    • 同时,清零定时器,重新开始计数;
    • 等待上升沿到来,记录下定时器的计数值,即得到PWM的低电平时间L
    • 计算得出占空比:duty = H / (H + L);

    阻塞方式原理简单,而且只需要MCU有一个定时器的资源即可实现;但采集时阻塞CPU运行,阻塞的时间和输入PWM的周期相关,只适用于实时性较低的系统。

    另外,上述流程中存在着一个严重的BUG,即当输入的PWM占空比为0%或者100%时,程序会被一直阻塞,等待上升沿/下降沿的到来。所以解决方法是,在等待上升沿/下降沿的过程中,实时提取定时器的值,一旦定时时间超过1个周期的限定(一般可定义为2-3个周期时间),即退出等待,并根据端口电平判断此时占空比为0%(低电平)或100%(高电平)

    示例代码,仅供参考:

    //获取PWM输入脚的电平
    #define PWM_IN()   xxxxxx
    //定义超时时间(如2-3倍PWM周期)
    #define T1_TIMEOUT  xxxxxx
    
    uint8_t PWM_Analyse(void)
    {
        uint8_t duty = 0xFF;
        uint16_t pwm_H = 0;
        uint16_t pwm_L = 0;
    
        if (PWM_IN())   //初始为高电平,则开始等待低电平
        {
            TH1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
    
            TH1 = 0;
            TL1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
            pwm_L = (TH1 << 8) | TL1;
    
            TH1 = 0;
            TL1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
            pwm_H = (TH1 << 8) | TL1;
    
            duty = pwm_H * 100 / (pwm_H + pwm_L);
            return duty;
        }
        else    //当前为低电平,则开始等待高电平
        {
            TH1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
    
            TH1 = 0;
            TL1 = 0;
            while (PWM_IN()) //等待下降沿
            {
                if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
                {
                    duty = 100;
                    return duty;
                }
            }
            pwm_H = (TH1 << 8) | TL1;
    
            TH1 = 0;
            TL1 = 0;
            while (!PWM_IN()) //等待上升沿
            {
                if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
                {
                    duty = 0;
                    return duty;
                }
            }
            pwm_L = (TH1 << 8) | TL1;
    
            duty = pwm_H * 100 / (pwm_H + pwm_L);
            return duty;
        }
    
        return 0xFF;
    }
    

    2. 中断方式

    中断方式的PWM采集原理与阻塞方式相同,只是将判定移动至外部中断中。开启MCU端口的外部中断(上升沿和下降沿中断);如果MCU外部中断触发不支持上升和下降沿中断,则先开启上升沿中断,在中断处理中切换中断触发条件。

    处理方法:在中断处理函数中,根据当前电平状态,记录下定时器的值,并清零定时器的值,重新开始下一轮计时。

    0%和100%的处理:设定一个定时递增的变量,同时在外部中断中执行清零操作。若该变量超过一定值(说明外部中断有较长时间没有触发),则判定为0%或100%。

    uint16_t pwm_H = 0;
    uint16_t pwm_L = 0;
    uint16_t pwm_time_out = 0;
    void EXT1_ISR(void) interrupt EXTI1_VECTOR
    {
        if (PWM_IN())
        {
            pwm_L = (TH1 << 8) | TL1;    //记录低电平时间
            TH1 = 0;
            TL1 = 0;
        }
        else
        {
            pwm_H = (TH1 << 8) | TL1;    //记录高电平时间
            TH1 = 0;
            TL1 = 0;
        }
    
        //该变量定时递增(如1ms递增1),在外部中断中清零
        //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
        pwm_time_out = 0;
    
        return;
    }
    

    注:使用中断方式,则占空比计算不建议放在中断中处理;同时,为了保证占空比的准确性,可以连续2-3次计算结果一致时,再确定当前占空比的结果。

    3. MCU捕获方式

    采用捕获方式的前提是MCU支持捕获功能。当前部分厂家推出的51内核单片机,会包含一个定时器2,其拥有捕获功能;或者采用32位单片机,一般都带有捕获功能。捕获的原理很简单,当上升沿或下降沿来临时,MCU硬件将定时器/计数器的值保存在一个影子寄存器中,并产生捕获中断。
    通过固定每次上升/下降沿的计数器值,相减即可分别得出高电平值和低电平值,从而计算出占空比。
    pwm占空比捕获原理
    下面以某颗51内核的MCU为例,提供示例代码:

    unsigned int pwm_fall = 0, pwm_rise = 0;
    
    volatile unsigned int pwm_H;
    volatile unsigned int pwm_L;
    
    volatile unsigned char pwm_time_out;
    //------------------------------------------------------------
    void T2_interrupt(void) interrupt 5          //定时器2中断;
    {
    
        if (CCCON & 0x02) //CC1中断标志位
        {
            CCCON  &= 0xFD; //清除中断标志
    
            if (PWM_IN())   //上升沿触发
            {
                pwm_rise = CC1;     //获取捕获寄存器中的值
                pwm_L = pwm_rise - pwm_fall;
            }
            else
            {
                pwm_fall = CC1;     //获取捕获寄存器中的值
                pwm_H = pwm_fall - pwm_rise;
            }
    
            //该变量定时递增(如1ms递增1),在外部中断中清零
            //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
            pwm_time_out = 0;
        }
    }
    

    注: pwm_rise/pwm_fall/pwm_L/pwm_H都必须使用无符号数,否则相减时可能得到错误的值。

    总结

    方式一任何单片机都可以实现,但是阻塞方式会使系统的实时性变差;
    方式二在使用时,需要保证外部中断的最高优先级,不可以被其他中断打断,以保证其准确性;
    方式三的稳定性和准确性都较高,但是需要MCU硬件支持。

    展开全文
  • 用51单片机测量频率与占空比。利用数码管动态显示其结果,测量端口为P3.5(pulse)和GND。不同类型的单片机其数码管编码,位选段选可能不相同,需进行一定的修改。
  • 51单片机频率检测程序,频率显示在1602上
  • 利用51单片实现测量脉宽与占空比实验,附单片机程序
  • 本文涉及单片机的基础知识,希望对大家有所帮助。
  •  //声明单片机运行频率表12Mhz sbit KEY1=P1^0; //声明按键1占用脚 sbit KEY2=P1^1; //声明按键2占用脚 sbit KEY3=P1^2; //声明按键3占用脚 sbit KEY4=P1^3; //声明按键4占用脚 sbit OUTPUT=P2^0; //声明输出...

    本帖最后由 suqianfu 于 2020-4-11 22:29 编辑

    大佬,我添加了一点注释,不知道理解得对不对

    #include                                                 //调用头文件

    #define uchar unsigned char                                //

    #define uint unsigned int

    float fosc=12000000;                                        //声明单片机运行频率表12Mhz

    sbit KEY1=P1^0;                                                        //声明按键1占用脚

    sbit KEY2=P1^1;                                                        //声明按键2占用脚

    sbit KEY3=P1^2;                                                        //声明按键3占用脚

    sbit KEY4=P1^3;                                                        //声明按键4占用脚

    sbit OUTPUT=P2^0;                                                //声明输出占用脚

    uchar zkb;                                                                //声明占空比变量

    uint freq;                                                                //声明频率变量

    uchar TIMER0_L,TIMER0_H,TIMER1_L,TIMER1_H;//声明时间变量

    void delay(uchar n)                                                //延时函数

    {

    uchar i;                                                            //局部整型变量

    while(n--)                                                            //循环(执行次数)

    {for(i=255;i>0;i--)                                                //赋值I为255,I大于0,I--自减1.直至循环执行次数清零(无中生友系列)

    {}

    }}

    void chushihua(void)                //名为(初始化)之子函数

    {

    P1=0x0f;                                //赋值P1口数据

    freq=500;                                //赋值频率=500

    zkb=50;                                         //赋值占空比为50%

    TIMER0_L=0xe0;                         //定时变量,定时器0初始时间高8位赋值,具体定时时间自己查资料

    TIMER0_H=0xb1;                        //定时变量,定时器0初始时间低8位赋值,具体定时时间自己查资料

    TIMER1_L=0xf0;                        //定时变量,定时器1初始时间高8位赋值,具体定时时间自己查资料

    TIMER1_H=0xd8;                        //定时变量,定时器1初始时间低8位赋值,具体定时时间自己查资料

    TL0=0xe0;                                //定时器0初始时间高8位赋值,具体定时时间自己查资料

    TH0=0xb1;                                //定时器0初始时间低8位赋值,具体定时时间自己查资料

    TL1=0xf0;                                //定时器0初始时间高8位赋值,具体定时时间自己查资料

    TH1=0xd8;                                //定时器0初始时间高8位赋值,具体定时时间自己查资料

    TMOD=0x11;                                //设定定时器工作模式

    IT0=1;                                        //设定外部中断模式

    EX0=1;                                        //启动外部中断

    ET0=1;                                        //启动定时器0中断

    ET1=1;                                        //启动定时器1中断

    EA=1;                                        //启动全局中断使能

    TR0=1;                                    //启动定时器0

    TR1=1;                                    //启动定时器1

    }

    void main(void)                    //主程序

    {

    chushihua();                        //调用初始化子程序

    while(1)                                //循环

    { }

    }

    void Timer0_freq() interrupt 1        //中断子程序--频率

    {

    TR1=1;                                                    //启动定时器1

    TL0=TIMER0_L;                                        //定时器0高8位重新赋值定时函数,具体定时时间自己查资料

    TH0=TIMER0_H;                                        //定时器0低8位重新赋值定时函数,具体定时时间自己查资料

    OUTPUT=1;                                                //输出高电平

    }

    void Timer1_zkb() interrupt 3        //中断子程序--占空比

    {

    TR1=0;                                                    //关闭定时器1

    TL1=TIMER1_L;                                    //定时器1高8位重新赋值定时函数,具体定时时间自己查资料

    TH1=TIMER1_H;                                    //定时器1低8位重新赋值定时函数,具体定时时间自己查资料

    OUTPUT=0;                                                //输出低电平

    }

    void keyscan() interrupt 0 using 1        //中断子程序--按键检测

    {

    float TF0,TZ1;                                        //声明浮点变量....这句话不是看得太懂...理解错了勿怪

    EX0=0;                                                    //关闭外部中断

    delay(10);                                                //延时10

    if(P1!=0x0f)                                    //演示后如果检测到P1口不等于0X0F这个值,判断按键按下

    {

    if(KEY1==0) freq+=500;                    //如果是按键1按下,则频率变量增加500

    if(KEY2==0) freq+=50;                        //如果是按键2按下,则频率变量增加50

    if(freq>10000) freq=500;                //如果频率变量超过10000,则频率变量重新置为500

    if(KEY3==0) zkb+=10;                        //如果是按键3按下,则占空比变量增加10

    if(KEY4==0) zkb++;                                //如果是按键4按下,则占空比变量增加1

    if(zkb>100) zkb=1;                                //如果占空比超过100,则占空比变量重新置为1

    TF0=(65536-fosc/(12.0*freq));        //定时器溢出标记TF0赋值为65536减去时钟频率12分频        ??不是太理解

    TZ1=(65536-(fosc*zkb)/(12.0*100*freq));        //TZ1这个啥玩意?跟上一行大概意思吧

    TIMER0_H=(uint)TF0/256;

    TIMER0_L=(uint)TF0%256;

    TIMER1_H=(uint)TZ1/256;

    TIMER1_L=(uint)TZ1%256;

    }

    P1=0x0f;                                                //重新赋值P1口初始化

    EX0=1;                                                    //启动外部中断

    TR0=1;                                                        //重新启动定时器0TR0

    TR1=1;                                                    //重新启动定时器1TR1

    }

    展开全文
  • 单片机方波检测

    2018-11-27 17:49:42
    有仿真和代码可检验出方波的波形频率占空比,也可调整频率
  • 在此通过改变扰动法的占空比来解决传统扰动法带来的功率震荡和误判 问题,同时系统控制器采用高性能低功耗的ATmega32 单片机作为核心进行实验。测试结果表明,该方法能够保证 太阳能系统快速、稳定地跟踪最大...
  • 定时器和PWM作为单片机的基础,用来也是难点,通过PWM产生方波,并通过定时器配合外部中断来采集频率是非常好的练手实验

           已经有快半年没有整过32单片机,为了准备电赛最近又复习了一下单片机相关的知识。发现只是看教程、手册没有啥的也不知道自己有没有学会,于是决定做一个小小的测试。测试内容是通过PWM产生频率为20HZ的占空比为50%方波,并且通过单片机测量该方波的频率。啥话不说上图看成果:

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

    单片机产生频率为20HZ的占空比为50%方波

           通过单片机产生方波很容易,设置寄存器ARR的值就能确定周期。设置CCRx的值就能设置设置占空比。 当CNT寄存值小于CCRx的值时输出低电平,大于CCRx的值时输出高电平,到达ARR的值时溢出。知道基本的原理后通过寄存器初始化和使能相关的寄存器就可以了。

           这次实验采用TIM3 CH2不重映像,同时设置PWM模式为向上计数模式。配置步骤如下:
    在这里插入图片描述

    1. 开启TIM3时钟,并设置PA7为复用输出
    2. 初始化TIM3,设置TIM3的ARR和PSC值
    3. 设置TIM3_CH2的PWM模式,使能TIM3的CH2输出
    4. 使能TIM3
    5. 修改TIM3_CCR2来控制占空比
    //TIM3 PWM部分初始化 
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //①使能 GPIO 和 AFIO 复用功能时钟
    //	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PC7    
     
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
     
       //初始化TIM3
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    	
    	//初始化TIM3 Channel2 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
     
    	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
    	
    }
    

           以上代码就完成了PWM的初始化,如果要产生20HZ的波形,那么就相当于要没50ms要溢出一次,那么我们可以设置arr的值为499,psc的值为7199。Tout= ((arr+1)*(psc+1))/Tclk=(499+1)* ( 7199+1)/72=50ms 。说明计数到500次为50ms,那么设置CCR2的值为250就可以实现占空比为50%。

    单片机测量频率并显示

    测量频率的思路有很多种,网上有关于ADC测量电压,也有关于输入捕获的。但是上次电赛校赛,学长用的是外部中断结合定时器中断来实现的,思路也比较简单。就是下降沿触发外部中断,然后打开定时器计数。当再次进入外部中断时停止计数清楚相关的标志位。这样就得到了一个计数次数,通过计数次数就可以计算出电平经历变化用的时间,时间的倒数就是相关的频率。本次实验用的是外部中断三(EXTI3)对应PE3口。

    void EXTIX_Init(void)
    {
     
       	EXTI_InitTypeDef EXTI_InitStructure;
     	NVIC_InitTypeDef NVIC_InitStructure;
    
        KEY_Init();	 //	按键端口初始化
    
      	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟
      	
       //GPIOE.3	  中断线以及中断初始化配置 下降沿触发 //KEY1
      	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
      	EXTI_InitStructure.EXTI_Line=EXTI_Line3;
      	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
      	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
      	EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
    
      	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;			//使能按键KEY1所在的外部中断通道
      	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
      	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级1 
      	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
      	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
     
    }
    
    void EXTI3_IRQHandler(void)
    {
    	if(half_cricle == 0)
    	{
    		TIM2->CNT = 0;
    		TIM_Cmd(TIM2, ENABLE);  //使能TIMx	
    		half_cricle = 1;
    	}
    	else if(half_cricle == 1)
    	{
    		time_of_circle = TIM2->CNT;
    		TIM2->CNT = 0;
    		TIM_Cmd(TIM2, ENABLE);  //使能TIMx	
    	}
    	EXTI_ClearITPendingBit(EXTI_Line3);
    }
    

    定时器2初始化:

    void TIM2_Init(u16 arr,u16 psc)
    {
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    //	NVIC_InitTypeDef NVIC_InitStructure;
    
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
    
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
     
    //	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
    
    //	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    //	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
    //	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    //	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    //	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器							 
    }
    

    主函数:

    int main(void)
     {		
    	char str[10];
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
    	LED_Init();		  		//初始化与LED连接的硬件接口 
    	EXTIX_Init();         	//初始化外部中断输入
    	LCD_Init();
    	TIM3_PWM_Init(499,7199);
    	TIM2_Init(4999,7199);
    	LED0=0;					//先点亮红灯
    	TIM_SetCompare2(TIM3,250);//设置CCR2的寄存器值为250占空比为50%
    	LCD_ShowString(45,125,200,30,16,"-----freqency-----");
    	LCD_ShowString(130,165,32,30,16,"HZ");
    	while(1)
    	{	    
    		freq=10000.0 / (float)time_of_circle;
    		sprintf(str,"%.2f",freq);
    		LCD_ShowString(50,165,64,30,16,str);
    		LCD_ShowString(45,125,200,30,16,"-----freqency-----");
    		LCD_ShowString(130,165,32,30,16,"HZ");
    	}	 
    }
    

           以上就是几个主要的函数,用库函数配置比寄存器配置舒服多了,之前一直整寄存器版本的,现在接触库函数觉得实在是太方便啦!

           工程文件上传至资源中心了,有需要的伙伴可以下载!
           工程文件上传至资源中心了,有需要的伙伴可以下载!
           工程文件上传至资源中心了,有需要的伙伴可以下载!

           不积小流无以成江河,不积跬步无以至千里。而我想要成为万里羊,就必须坚持学习来获取更多知识,用知识来改变命运,用博客见证成长,用行动证明我在努力。
           如果我的博客对你有帮助、如果你喜欢我的博客内容,记得“点赞” “评论” “收藏”一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
    在这里插入图片描述

    展开全文
  • 基于51单片机的高级频率计(20M,低频可测占空比

    千次阅读 热门讨论 2014-07-31 23:32:39
    本系统是基于AT89S52的宽频率范围的频率计设计,主要实现的功能有:  (1)输入信号类型可是方波信号、正弦信号、... (4)对于低于200KHz的信号,信号的最低幅度可以是0.5V,基本系统可以实现微弱信号的检测  

    本系统是基于AT89S52(或STC89C52)的宽频率范围的频率计设计,生气

    主要实现的功能有:

    (1)输入信号类型可是方波信号、正弦信号、三角信号
    (2)系统测量频率的范围是1Hz-20MHz
    (3)系统测量频率过程中,量程是自动变换的,不需要用户手动操作,方便了用户的使用
    (4)对于低于200KHz的信号,信号的最低幅度可以是0.5V,基本系统可以实现微弱信号的检测

    (5)本系统对于低于10KHz的方波信号可以测量其占空比。

    本系统首先使用Protues仿真软件进行仿真,在仿真通过之后,在腐蚀板子,然后硬件实现。

    仿真图下:误差控制在千分之一内

                               

                               

    实物图:误差控制在千分字之一内。当然通过数据处理,可以做到更低


    采集低频信号,并显示占空比


    采集高频信号


    展开全文
  • 9、基于STM32单片机的颜色检测仪设计 文章目录9、基于STM32单片机的颜色检测仪设计引言1、系统概述1.1、设计任务1.2、设计要求2、方案设计与论证2.1、芯片选择方案2.2 、系统概述2.3、设计要求2.4、系统总体设计思路...
  • 光强检测仪 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我们...
  • 51单片机电机PWM调速控制系统霍尔测速仪温度检测4 本系统由STC89C52单片机、LCD1602液晶显示、L298N电机驱动模块 、按键、霍尔传感器、DS18B20温度传感器及电源组成。 1、通过按键可以控制电机的启动、停止、正转、...
  • 我们在学习51单片机用按键控制LED的时候,通常会遇到按键抖动的问题,这是因为按键里面内置弹簧片,不能够精确的控制,下面是其原理图(Powered by AxGlyph): 可以看到我们在按下按键的时候电平并没有立马变成低...
  • 基于STM32c8t6的5路pwm占空比测量,通过不断地轮流切换定时器通道去测量PWM占空比。在中断函数里,检测到上升沿之后TIM_SetCounter(TIMX,0);将计数器的值置零重新开始计数,同时将定时器中断触发方式切换为下降沿...
  • 2、通过温度传感器DS18B20检测温度。 3、通过液晶显示温度、PWM档位值、速度。 4、温度超过50度蜂鸣器报警。 STC89C52单片机最小系统说明: STC89C52单片机最小系统电路由复位电路、时钟电路和电源电路。拥有这三...
  • 设计一个电路,当检测到P1.0输入一个上升沿时,就从P0.0输出一个占空比为60%的周期性信号(周期大于1S);当检测到P0.1输入一个下降沿时,就从P1.1 输出一个占空比为50%的周期性信号(周期为600ms),信号输出外接扬声...
  • 可以实现直流电动机的正反转,以及对直流电动机设置转速,并且检测占空比
  • 图1所示为典型的BLDC电机框图,该电机包括一个梯形磁通的永磁同步电机、一个转子位置检测器(通常为三个霍尔传感器)和一个驱动电机的三相逆变器。另外,必须配置一个单片机(MCU),输出特定的脉冲宽度调制(PWM)模式来...
  • 51单片机学习

    千次阅读 多人点赞 2021-01-21 21:01:56
    单片机概述 1.什么是单片机 2.单片机的特点及应用领域 3.单片机的发展趋势 4.学习51单片机需要哪些基础知识 5.如何快速的掌握51单片机 微型计算机的应用形态 将cpu芯片、存储器芯片、I/O接口芯片和简单的I/O设备...
  • #include<reg52.h>#defineuintunsignedint #defineucharunsignedchar #defineZKB6//占空比初始值设定 #definemax_time100//设置超出时间 sbitgd1=P1^0;...
  • 【MSP430】捕获模式测量信号占空比

    千次阅读 2017-02-09 03:29:35
    代码来自2016北斗杯,用于测量空气pm2.5,该传感器通过测量信号的占空比估计颗粒浓度 (1)TimerB设置,工作在捕获模式: void TimerB_Init(){ TBCCTL0&=~(CCIS1+CCIS0); // 捕获源为P4.0,即CCI0A(也是CCI0B) ...
  • stm32测量信号频率及占空比

    千次阅读 多人点赞 2019-12-07 22:18:28
    基于stm32f103单片机对信号频率、占空比的测量。 最近开始仪器仪表方面的学习了,计划后期做一个示波器。所以这周就在stm32f103上面做了一个测量频率、占空比的小设计。总体上精度还是比较高的,测量频率量程在35Hz...
  • 即在不改变PWM方波周期的前提下,利用单片机控制PWM的占空比,从而来改变电压的大小实现灯光亮度的调节。 当人体在台灯的范围内且环境光线较弱时,自动感应开灯,且灯的亮度随着环境光线的改变而自动调节,一旦人...
  • 1、熟练使用各种电子元件及焊接工具,搭建起单片机硬件平台,包括:单片机最小系统,单片机电源监控系统,单片机程序仿真电路,单片机程序烧写电路,并上电进行各单元电路的功能测试;2、掌握LED电路的设计方法,...
  • 单片机双通道PWM信号的解析再生成 单片机双通道PWM信号的解析再生成 背景 设计方案 设计方案一(不可行) ...使用航模遥控器控制两个电机的转速,由于航模遥控器输出的PWM波占空比太低,并且可调范围很...
  • 等精度测量频率 常用的频率测量方法有直接测频法,测周期法和等精度测频法。 直接测频法是由时基信号产生闸门,对被测信号进行计数,此法只适合测高频信号。测周期法是由被测信号产生闸门,对时基脉冲进行计数,此法...
  • 3、PC6、PC7是PWM输出32khz的频率,根据检测到PD5/PD6的电压调节占空比,达到调光的效果 下面是我的功能代码,不知哪里有误,一直输不出pwm,麻烦各位大神帮忙看看。 void Init_ADC_GPIO(void) { GPIO_Init(GPIOD, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,620
精华内容 648
关键字:

单片机检测占空比