51单片机,外部中断检测过零检测,双向可控硅,控制220v灯泡亮度,超声波测距离,写个程序
时间: 2023-11-23 10:07:42 浏览: 115
以下是一个基于51单片机的程序,其中实现了外部中断检测过零检测和双向可控硅来控制220V灯泡的亮度,同时还使用超声波传感器来测量距离:
```c
#include <reg51.h>
sbit Trig = P1^0; // 超声波发射引脚
sbit Echo = P1^1; // 超声波接收引脚
sbit ZCD = P3^2; // 过零检测引脚
sbit SCR = P3^3; // 可控硅控制引脚
unsigned int distance = 0; // 超声波测量得到的距离
unsigned char brightness = 0; // 灯泡亮度
void delay(unsigned int count) // 延时函数
{
unsigned int i, j;
for(i = 0; i < count; i++)
for(j = 0; j < 120; j++);
}
void init_interrupt() // 初始化外部中断
{
ZCD = 1; // 过零检测引脚初始电平为高
IT0 = 1; // 外部中断0触发方式为下降沿
EX0 = 1; // 开启外部中断0
EA = 1; // 开启总中断
}
void init_timer() // 初始化定时器
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xFC; // 定时器0初值
TL0 = 0x18; // 定时器0初值
ET0 = 1; // 开启定时器0中断
EA = 1; // 开启总中断
TR0 = 1; // 启动定时器0
}
void main()
{
init_interrupt();
init_timer();
while(1)
{
Trig = 1; // 发射超声波脉冲
delay(10); // 延时10us
Trig = 0;
while(!Echo); // 等待超声波接收
TH0 = 0; // 定时器清零
TL0 = 0;
while(Echo); // 等待超声波停止接收
distance = (TH0 << 8) + TL0; // 计算距离
distance = distance / 58; // 转换为厘米
if(distance < 20) // 如果距离小于20cm
brightness = 255; // 灯泡全亮
else if(distance > 100) // 如果距离大于100cm
brightness = 0; // 灯泡全灭
else
brightness = (100 - distance) * 2; // 计算亮度
}
}
void interrupt0() interrupt 0 // 外部中断0服务函数
{
SCR = 0; // 可控硅关断
delay(1); // 延时1ms
SCR = 1; // 可控硅开通
}
void interrupt_timer0() interrupt 1 // 定时器0中断服务函数
{
static unsigned char count = 0;
TH0 = 0xFC; // 定时器0初值
TL0 = 0x18;
count++;
if(count >= 255 - brightness) // 控制灯泡亮度
{
SCR = 0;
count = 0;
}
else
SCR = 1;
}
```
上述程序通过定时器来控制灯泡的亮度,超声波传感器测量距离来调节亮度,外部中断检测过零点来控制可控硅的导通。需要注意的是,这个程序是一种基础实现方式,可能还需要根据实际情况进行优化。