51单片机两种PWM呼吸灯的实现方法(STC15FK60S2)

蓝桥杯板子.

这不是一个工程(毫无技术水平),时钟系统2.0还在赶,争取明天发.

可怜的孩子就写了一篇来完成新人任务.

还不懂硬件pwm,pwm还有别的很多作用,呼吸灯只是抛砖引玉.

延时版

#include <STC15F2K60S2.H>
#include <intrins.H>
unsigned char i,time;
void P2andP0(unsigned char p2,p0,p42)
{	
	P42=p42;
	P0=p0;
	P2=p2;
	P2=0;//防止被别的操作修改P0而影响了
}
void Delay1ms(unsigned char t)	//@12.000MHz
{
	while(t--); //一定要是空循环,不然用软件生成的一闪一闪很明显	
}

void main()
{
	P2andP1(0xA0,0,0);//初始化关闭嗡鸣器继电器
	while(1)
	{
		for(time=0;time<100;time++)//由暗到亮,以100为单位符合百分之多少多少的占空比
		{
			for(i=0;i<200;i++)//改变变化快慢,每个亮度持续时间
			{
				P2andP1(0x80,0,0);
				Delay1ms(time);
				P2andP1(0x80,0xFF,0);
				Delay1ms(100-time);//原理是改变亮暗的比例(占空比)
			}
		}
		for(time=100;time>0;time--)//由亮到按
		{
			for(i=0;i<200;i++)
			{
				P2andP1(0x80,0,0);
				Delay1ms(time);
				P2andP1(0x80,0xFF,0);
				Delay1ms(100-time);
			}
		}
	}
}

解释

`P2andP0()`函数用于同时设置单片机上的P2、P0和P42端口的值,并且特别将P2置零以防止对P0的操作影响到其他功能。

`Delay1ms(unsigned char t)`函数提供了一个基本延时,根据给定参数`t`循环一定次数以模拟大约1毫秒的延时,注释中提到工作频率为12.000MHz。

在`main()`函数中:

1. 首先调用`P2andP1(0xA0, 0, 0)`初始化关闭嗡鸣器继电器。
2. 进入一个无限循环,在循环内首先执行一个由暗到亮的过程:
   - `for(time=0;time<100;time++)`:改变亮度的占空比,从0%逐渐增加到100%。
     - 内嵌的循环`for(i=0;i<200;i++)`用于控制每个亮度级别下的持续时间。
       - 先设定P1端口输出低电平,然后延时指定时间。
       - 接着设定P1端口输出高电平,延时的时间与前面低电平阶段相反,从而调整占空比。
3. 然后执行一个由亮到暗的过程,与上述过程类似,只是时间变量`time`递减。

定时器版

这个led频率有点快,想慢点的弄个时间长点的定时器就可以了.

#include <STC15F2K60S2.H>
unsigned int compare=0;
unsigned char flag=0,flag1=0;
void P2andP1(unsigned char p2,p0,p42)
{
	P42=p42;
	P0=p0;
	P2=p2;
	P2=0;
}

void Timer0_Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x20;				//设置定时初始值
	TH0 = 0xD1;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA=1;
}

void main()
{		
	P2andP1(0xA0,0,0);//关闭蜂鸣器继电器
	Timer0_Init();//定时器初始化
	while(1)
	{ 
		if(flag==0)//由亮到暗
		{
			if(flag1==0)compare++;
			if(compare>99)flag1=1;
			if(flag1==1)compare--;
			if(compare<1)flag1=0;
		}		
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned int T=0;
	T++;
	T=T%100;
	if(T>=compare)//改变compare值以改变占空比
	{
		
		P2andP1(0x80,0,0);//开灯
	}
	else
	{
		P2andP1(0x80,0xFF,0);//关灯
	}	
}

解释

`P2andP1()`函数用于设置特定的端口输出值。

`Timer0_Init()`函数负责初始化定时器0:
- 设置定时器工作在1T模式。
- 设置定时器模式(这里没有明确指定具体模式,但基于上下文可能是模式0或者模式1,用于产生溢出中断)。
- 根据12MHz晶振频率计算并设置定时初值,使得定时器每1毫秒触发一次中断。
- 启动定时器0并使能定时器0中断,同时打开全局中断开关EA。

`main()`函数中:
- 首先关闭蜂鸣器继电器。
- 初始化定时器0。
- 进入一个无限循环,在循环内判断标志位`flag`以决定是否执行由亮到暗的过程。`flag1`和`compare`变量配合控制占空比的变化。

`Timer0_Isr()`函数是一个定时器中断服务程序,它会在定时器0每次溢出时被调用:
- 定义一个静态变量`T`记录中断次数,每过100次中断自增回零。
- 在中断服务程序中,根据`T`与`compare`的关系改变负载的状态:
  - 当`T`大于等于`compare`时,打开负载(例如LED)。
  - 否则,关闭负载。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值