用52单片机,过零检测电路,用三象限双向可控硅电源隔离和光耦隔离电路,控制220v50hz电灯泡,实现8种亮度,一个按键控制增加亮度,一个按键控制减小亮度的程序
时间: 2024-05-10 19:17:14 浏览: 81
以下是用52单片机实现过零检测电路,用三象限双向可控硅电源隔离和光耦隔离电路,控制220v50hz电灯泡,实现8种亮度的程序:
```c
#include <reg52.h>
// 定义控制灯泡亮度的变量
unsigned char brightness = 0; // 初始亮度为0
unsigned char key_count = 0; // 按键计数器
// 定义过零检测标志位
bit zero_crossing_flag = 0;
// 定义过零检测计数器
unsigned int zero_crossing_count = 0;
// 定义增加亮度按键和减小亮度按键的引脚
sbit key_increase = P3^0;
sbit key_decrease = P3^1;
// 定义三象限双向可控硅的控制引脚
sbit thyristor1 = P2^0; // 正半周控制
sbit thyristor2 = P2^1; // 负半周控制
// 定义过零检测引脚
sbit zero_crossing = P2^2;
// 定义光耦的控制引脚
sbit optocoupler = P1^0;
// 定义延时函数
void delay(unsigned int i)
{
while(i--);
}
// 过零检测中断服务函数
void zero_crossing_interrupt() interrupt 0
{
zero_crossing_flag = 1; // 标志位设为1
zero_crossing_count = 0; // 计数器清零
}
// 主函数
void main()
{
// 定时器0初始化
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0x3C; // 定时器初值为0x3C
TL0 = 0xB0; // 定时器初值为0xB0
ET0 = 1; // 允许定时器0中断
TR0 = 1; // 启动定时器0
// 外部中断0初始化
EX0 = 1; // 允许外部中断0
EA = 1; // 允许中断总开关
// 主循环
while(1)
{
if(zero_crossing_flag) // 过零检测标志位为1,说明当前为过零点
{
zero_crossing_flag = 0; // 标志位设为0
if(brightness == 0) // 如果当前亮度为0,关闭灯泡
{
thyristor1 = 0;
thyristor2 = 0;
}
else if(brightness == 8) // 如果当前亮度为8,灯泡全亮
{
thyristor1 = 1;
thyristor2 = 1;
}
else // 否则,根据亮度控制双向可控硅
{
if(zero_crossing_count >= brightness)
thyristor1 = 0;
else
thyristor1 = 1;
if(zero_crossing_count >= (8 - brightness))
thyristor2 = 0;
else
thyristor2 = 1;
}
// 增加亮度按键检测
if(key_increase == 0) // 按键按下
{
delay(1000); // 延时去抖动
if(key_increase == 0) // 再次检测按键是否按下
{
key_count++; // 计数器加1
if(key_count >= 5) // 计数器达到阈值
{
key_count = 0; // 计数器清零
if(brightness < 8) // 亮度加1
brightness++;
}
}
}
else // 按键未按下,计数器清零
{
key_count = 0;
}
// 减小亮度按键检测
if(key_decrease == 0) // 按键按下
{
delay(1000); // 延时去抖动
if(key_decrease == 0) // 再次检测按键是否按下
{
key_count++; // 计数器加1
if(key_count >= 5) // 计数器达到阈值
{
key_count = 0; // 计数器清零
if(brightness > 0) // 亮度减1
brightness--;
}
}
}
else // 按键未按下,计数器清零
{
key_count = 0;
}
}
}
}
// 定时器0中断服务函数
void timer0_interrupt() interrupt 1
{
TH0 = 0x3C; // 定时器初值为0x3C
TL0 = 0xB0; // 定时器初值为0xB0
zero_crossing_count++; // 过零检测计数器加1
if(zero_crossing_count >= 100) // 过零周期为20ms,计数器达到2000时为一周期
{
zero_crossing_count = 0; // 计数器清零
optocoupler = 1; // 光耦导通,保证控制信号完整
}
if(zero_crossing_count == 2) // 过零点前2ms,光耦截止,双向可控硅关闭
{
optocoupler = 0;
thyristor1 = 0;
thyristor2 = 0;
}
}
```
以上程序中,我们使用了定时器0来实现过零点的检测,每20ms发生一次中断,通过计数器来判断当前是否为过零点。同时,我们使用外部中断0来检测按键的按下情况,通过计数器来判断是否达到阈值,从而控制灯泡的亮度。
在控制灯泡的亮度时,我们使用了三象限双向可控硅,根据亮度控制正半周和负半周的触发时刻。同时,为了保证控制信号完整,我们使用了光耦隔离电路,将控制信号隔离开来,避免电路中的干扰。
需要注意的是,以上程序中使用的是直接控制220V电源的方式,需要特别注意安全问题。在实际应用中,应该使用专门的交流电源模块来提供稳定的电源,并采用更加安全可靠的电路来控制灯泡的亮度。
阅读全文