STC89C52定时器实现呼吸灯

STC89C52定时器实现呼吸灯

基本思路

💡 小灯的亮度不能直接控制,但是在足够小的单位时间内,控制小灯的亮灭时间比例,就可以在人的视觉上呈现出不同的亮度。可以使用定时器实现PWM波形。

  • 闪烁周期

    共2s,前1s内由灭到亮,后1s由亮到暗。

  • PWN周期

    1s之内100个PWM周期,每个周期10ms。

  • 占空比highValPro变化

    使用定时器1中断,每10ms,即一个PWM周期变化一次,前1s逐渐增大到1,后1s逐渐减小到0。

    void highValProChange() interrupt 3       // 1ms          *10
    {
    	TL1 = 0x66;		
    	TH1 = 0xFC;		
    	T1OverflowTimes++;
    	if(T1OverflowTimes>=10){
    		if(flag==0)
    			highValPro++;
    		else highValPro--;
    		T1OverflowTimes = 0;
    		if( highValPro==100||highValPro==0) flag=!flag;
    	}	
    	
    }
    
  • PWN内高低电平转换

    使用定时器0中断,通过全局变量time在一个PWN周期内计时(计数),当time<highValPro时,输出高电平小灯亮,否则输出低电平,小灯灭。time每一百分之一个PWN周期即100us自增一次。

    void timeChange() interrupt 1         //100us * 100
    {
    	TL0 = 0xA4;
    	TH0 = 0xFF;
    	if(time<100)
    		time++;
    	else time = 0;
    }
    

整体代码

#include<reg52.h>
#include<intrins.h>
typedef unsigned int u16;
typedef unsigned char u8;
void Timer0Init(void);
void Timer1Init(void);
u8 highValPro =1;          //Proportion of hignval
u8 time = 0;								//every 100us ++
u8 T1OverflowTimes = 0;
u8 flag=0;
void main()
{
	EA =1;                      //打开中断总使能
	Timer0Init();               //定时器0初始化
	Timer1Init();               //定时器1初始化
	TMOD = 0x11;
	while(1){

		if(time<highValPro)       //占空比内区域
			P2 = 0xEF;
		else P2 = 0xFF;           //超出占空比部分
		
	}
}
void Timer0Init(void)		   //100us
{
	//AUXR &= 0x7F;		
	//TMOD &= 0xF0;
	TMOD |= 0x01;		         //设置工作方式为16位
	TL0 = 0xA4;
	TH0 = 0xFF;
	TF0 = 0;                 
	TR0 = 1;                 //开始计时
	ET0 = 1;                 //允许中断
}
void Timer1Init(void)		//1ms@11.0592MHz
{
	//AUXR &= 0xBF;		
	//TMOD &= 0x0F;	
	TMOD |= 0x10;		          //设置工作方式为16位
	TL1 = 0x66;		
	TH1 = 0xFC;		
	TF1 = 0;		
	TR1 = 1;		             //开始计时
	ET1 = 1;                 //允许中断
}

void timeChange() interrupt 1         //100us * 100;控制PWN周期内分时time计数
{
	TL0 = 0xA4;
	TH0 = 0xFF;
	if(time<100)
		time++;
	else time = 0;                      //每满100开始新周期计数
}

void highValProChange() interrupt 3       // 1ms *10;改变一次
{
	TL1 = 0x66;		
	TH1 = 0xFC;		
	T1OverflowTimes++;
	if(T1OverflowTimes>=10){
		if(flag==0)
			highValPro++;
		else highValPro--;
		T1OverflowTimes = 0;
		if( highValPro==100||highValPro==0) flag=!flag;   //每一秒,flag变化,控制占空比变化方向
	}	
}
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用51单片机实现定时器1控制LED亮2秒灭2秒循环闪烁,可以按照以下步骤进行编程: 1. 首先,需要引入8051的头文件,例如 `reg51.h`。 2. 定义LED所连接的IO口,例如 `sbit LED = P1^0;`,这里假设LED连接在P1口的第0位。 3. 初始化定时器1,并设置为工作模式1(16位自动重装载),并设置定时器的初值。 4. 编写定时器1中断服务子程序(ISR),在该子程序中切换LED的状态。 5. 在主函数中,开启定时器1中断,并启动定时器1。 下面是一份示例代码: ```c #include <reg51.h> sbit LED = P1^0; // LED连接在P1口的第0位 void Timer1_ISR() interrupt 3 // 定时器1中断服务子程序 { static unsigned int count = 0; // 计数器 TH1 = 0xFC; // 设置定时器初值,用于实现2秒的定时 TL1 = 0x66; count++; // 计数器加1 if(count == 1000) // 当计数器达到1000时,表示2秒时间已过 { count = 0; // 重置计数器 LED = ~LED; // 切换LED状态 } } void main() { TMOD = 0x10; // 设置定时器1为工作模式1(16位自动重装载) TH1 = 0xFC; // 设置定时器初值,用于实现2秒的定时 TL1 = 0x66; ET1 = 1; // 开启定时器1中断 EA = 1; // 全局中断使能 TR1 = 1; // 启动定时器1 while(1); } ``` 这段代码会使LED每2秒闪烁一次。你可以根据需要修改LED连接的IO口和定时器初值来实现不同的闪烁频率。编译并下载该代码到51单片机,即可看到LED按照指定的闪烁频率工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值