可以帮我解释一下这一段代码的意思吗
第15到24行,中断内部为什么是这样写的
程序目的是led呼吸灯
#include <reg52.h>
sbit key_s2 = P3^0;
sbit key_s3 = P3^1;
unsigned char pwm_led_val = 0;//LED占空比值 0-20 0最亮
unsigned char pwm_t;//周期
void delay(unsigned int z)//毫秒级延时
{
unsigned int x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
//定时器0中断
void timer0() interrupt 1
{
pwm_t++;
if(pwm_t == 20)
{
pwm_t = 0; P1 = 0xff;
}
if(pwm_led_val == pwm_t)
P1 = 0;
}
void main()
{
TMOD |= 0x02;//定时器0模式2
TL0 = 240;//低八位寄存器赋初值
TH0 = 240;//高八位寄存器赋初值,自动重置初值使用
TR0 = 1;//启动定时器0
ET0 = 1;//允许定时器0中断
EA = 1;//总中断开关允许
while(1)
{
if(key_s2 == 0) //S2按下LED变暗
{
delay(5);
if(key_s2 == 0)
{
if(pwm_led_val < 20)
{
pwm_led_val++;
}
while(!key_s2);
}
}
if(key_s3 == 0) //S3按键LED变亮
{
delay(5);
if(key_s3 == 0)
{
if(pwm_led_val > 0)
{
pwm_led_val--;
}
while(!key_s3);
}
}
}
}
中断服务函数里只能做简短的计算和判断,不然会影响系统性能的!
pwm_t;//周期;pwm_led_val = 0;//LED占空比值 0-20 0最亮
通过pwm_t和pwm_led_val 控制LED灯亮灭时间。pwm_t从0-20的时间即20次进入中断的时间是周期,主函数中按键s2和s3调节pwm_led_val 从0-20,即调节LED亮灭时间。初始pwm_led_val 为0时,pwm_t从0加到20以后led灯一直亮,通过s2按键将pwm_led_val加到5,pwm_t从0加到5时led是亮的,从5加到20时led是灭的。
这段C语言代码的功能是实现LED的呼吸灯。具体实现方式是利用定时器0,控制不同时间段LED灯的亮灭顺序,从而实现呼吸灯的效果。其中涉及到定时器的初始化以及中断处理,下面对15至24行进行详细解释:
void timer0() interrupt 1 {
//...
}
void InitTimer0(){
TMOD |= 0x01; //设置为Timer0工作模式
TH0 = 0xfc; //给定时器初值,定时1ms
TL0 = 0x67;
ET0 = 1; //打开TIM0中断
EA = 1; //打开总中断
TR0 = 1; //启动定时器0
}
void main(void){
//...
InitTimer0();
//...
}
其中timer0()是定时器0的中断处理函数,定时器0初始化采用模式1形式,工作方式是16位自动重载,需要清把TH和TL清零。其中TH用高8位表示计时器计数值的高8位,TL用低8位表示计时器计数值的低8位。TH和TL在每次定时器归零的时候都会自动重装载初始值,定时时间就是初始值的时间长度。
对于具体的LED控制,在timer0()函数中根据定时器计数值的状态来控制LED的亮灭顺序。
void timer0() interrupt 1 {
if(cnt < bright || (cnt-bright) > darken){ // bright < cnt < (bright + darken)
LED = 1;
}else{
LED = 0;
}
cnt++;
if(cnt >= (bright + darken)){
cnt = 0;
}
}
其中cnt计数器记录定时器溢出的次数,bright和darken记录的是定时时间的百分比,用来控制LED灯的亮度。在计数值处于[bright, bright+darken]之间时,LED灯始终保持亮的状态;反之在其他状态时LED灯会灭掉。