蓝桥杯板子.
这不是一个工程(毫无技术水平),时钟系统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)。
- 否则,关闭负载。