51单片机之LED呼吸灯&直流电机调速

关键词:跟B站江科大自化协老师学;LED呼吸灯;直流电机调速;PWM

 LED呼吸灯:

实验愿景:希望LED灯像呼吸一样由亮变暗,再由暗变亮,依次循环往复

尝试1:让LED灯亮

void main()
{
    LED=0;
    while(1)
    {
    }
}
实验现象:LED发出较亮的光

 尝试2:让LED灯亮、暗,放到while(1)循环中不断执行

void main()
{
    while(1)
    {
        LED=0;
        LED=1;
    }
}
 实验现象:LED仍一直发出亮光

解释:LED亮灭速度很快,且在不断循环,肉眼看不出区别

改进目的:让人眼能分辨出LED的亮、灭

改进1:联想PWM占空比,可以通过让LED=0;和LED=1;的比例不同,实现亮、暗分明

 代码如下:

#include <REGX52.H>

sbit LED=P2^0;
void main()
{			
	while(1)
	{
		LED=0;
		LED=1;
		LED=1;
		LED=1;
		LED=1;
		LED=1;
		LED=1;
		LED=1;
	}
}
 实验现象:LED发出稳定亮光
反思:很多的LED=1;相当于让LED较长时间停留在灭的状态,相当于Delay,可能是Delay的次数不够,所以仍看不出明显变化,但重复复制粘贴LED=1;操作多且没有可重复操作性,所以前面可以加上自定义的Delay模块(不必精准的时间延时,只需一定次数的Delay),再在main中2个LED操作后分别加上Delay

改进2:

void Delay(unsigned int t)
{
	while(t--);	
}
void main()
{			
	while(1)
	{
		LED=0;
		Delay(20);
		LED=1;
		Delay(100);
	}
}
 实验现象:通过调节2个Delay(分别简写D1、D2)中的值,发现LED亮的程度有变化,但肉眼看仍是稳定发光

D1(20);D2(100)  低高 ——>LED较暗

D1(100);D2(20)  高低 ——>LED较亮

D1(100);D2(100)  同 ——>LED较亮

D1(1000);D2(1000)  同——>LED较亮

猜想:如果想实现呼吸灯亮->暗->亮->...的现象,就需要Delay中的值有落差及变化,再结合PWM中占空比基本保持不变,就可以让2个Delay中的和等于1个常数,内部进行变化,但每次循环的总体是不变的(这里我有点解释不清,有懂的网友可以批评指正,谢谢!)

改进3:

void main()
{			
	unsigned char Time;
	while(1)
	{
		for(Time=0;Time<100;Time++)
		{
			LED=0;
			Delay(Time);
			LED=1;
			Delay(100-Time);
		}
		
	}
}
 实现现象:LED仍稳定发光,肉眼看不出明显变化

猜想:每一个Time=i 相当于脉冲的一个周期,但这个周期只有1次,不能稳定存在一小段时间,而整个for循环又很快,所以视觉上1个Time的变化不明显,即亮暗比不明显,所以可以在for的内部,再添一个循环,循环变量为i

改进4:

void main()
{			
	unsigned char Time,i;
	while(1)
	{
		for(Time=0;Time<100;Time++)
		{
			for(i=0;i<20;i++)
			{			
				LED=0;
				Delay(Time);
				LED=1;
				Delay(100-Time);
			}
		}
    }
}
实现现象:实现了LED呼吸灯从暗到亮的可见过程,但下一个循环就是直接再从暗到亮,视觉上存在突变, 所以再来1个for循环,实现呼吸效果

 最终版本:

void main()
{			
	unsigned char Time,i;
	while(1)
	{
		for(Time=0;Time<100;Time++)
		{
			for(i=0;i<20;i++)
			{			
				LED=0;
				Delay(Time);
				LED=1;
				Delay(100-Time);
			}
		}
		for(Time=100;Time>0;Time--)
		{
			for(i=0;i<20;i++)
			{			
				LED=0;
				Delay(Time);
				LED=1;
				Delay(100-Time);
			}
		}
	}
}
实现现象:实现LED呼吸灯效果

收获提升:

1.学会LED不同明暗程度的调节(亮灭比不同,通过Delay中的数值进行调节)

2.学会让一个脉冲在一小段时间保持稳定存在,即再在内部添一个for循环,实现亮->灭的可见过程

3.运用联想PWM的相关知识

直流电机调速

实验愿景:希望依次按下按键,数码管上显示不同的档位0-3,LED灯随档位不同亮度发生变化。将LED灯换成Motor,使电机可按不同档位的速度运转

实验所需模块:定时器、数码管显示、按键控制

理论依据:

 实验过程:

S1:定时器初始化以及定时器中断设置

其中,定时器的时间进行修改,原本是1ms,但太慢了调至100us,因为对于PWM驱动电机来说,在一定范围,频率越高越好,越快越稳定,但过快也没必要,一来是对资源比较占用,二来是可能会增加开关损耗,硬件电路允许,一般调至10k-20k(频率过低会出现抖动,1k左右可能会有蜂鸣器的叫声,不会有太大影响,但人耳能听见,可以再调高至人耳听不见的范围)——>main中每隔100us就进入中断函数一次

S2:根据PWM产生方法,设置计数器Counter和比较值Compare,让Counter在定时器中断中每次加1,直至100又清零重来,同时在中断中将Counter和Compare进行比较,从而分支LED输出时高电平还是低电平。

#include "Timer0.h"
#include "Key.h"
#include "Nixie.h"

sbit LED=P2^0;
unsigned char Counter,Compare;
unsigned char KeyNum,Speed=0;
void Timer0_Routine() interrupt 1
{
	
	TL0 = 0x9C;				
	TH0 = 0xFF;	
	Counter++;
	Counter%=100;//if(Counter>=100) Counter=0;同样的功能
	if(Counter<Compare) LED=0;
	else LED=1;
}

S3:while循环中实现按键控制、数码管显示

每按下按键1,档位Speed加1,0-3循环,并将Speed和Compare进行一一匹配,最后数码管静态显示档位

void main()
{
	Timer0_Init();
	//Compare=5;
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)
		{	
			Speed++;
			Speed%=4;
			if(Speed==0) Compare=0;
			if(Speed==1) Compare=5;//低电平占5%,亮的占5%
			if(Speed==2) Compare=50;
			if(Speed==3) Compare=100;//将Speed和Compare一一对应
		}
		Nixie(1,Speed);
	}
}

 S4:在引脚定义和中断函数中,将LED换成Motor,并将其极性反转

最终代码:

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
#include "Key.h"
#include "Nixie.h"

sbit Motor=P1^0;

unsigned char Counter,Compare;
unsigned char KeyNum,Speed=0;
void main()
{
	
	Timer0_Init();
	//Compare=5;
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)
		{	
			Speed++;
			Speed%=4;
			if(Speed==0) Compare=0;
			if(Speed==1) Compare=5;//低电平占5%,亮的占5%
			if(Speed==2) Compare=50;
			if(Speed==3) Compare=100;//将Speed和Compare一一对应
		}
		Nixie(1,Speed);
	}
}

void Timer0_Routine() interrupt 1
{
	
	TL0 = 0x9C;				
	TH0 = 0xFF;	
	Counter++;
	Counter%=100;//if(Counter>=100) Counter=0;同样的功能
	if(Counter<Compare) Motor=1;
	else Motor=0;
	//Motor和LED的极性是反的,LED低电平亮,Motor高电平运转,所以只需调节1和0,即可改变极性
}

收获提升:

1.实现按下按键,数码管上显示不同的档位0-3,LED灯随档位不同亮度发生变化。

2.Counter%=100;//if(Counter>=100) Counter=0;同样的功能

3.定时器中断中放入计数和判断功能,不占用main中内存,实现多个任务进行

 特别感谢B站江科大自化协老师的教程,本文描述、整理如有错误,欢迎批评指正!

  • 15
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值