用52单片机,过零检测,pwm,双向可控硅,控制220v灯泡,一个按键增加亮度,一个按键减少亮度写一个程序
时间: 2023-06-18 17:05:28 浏览: 108
52-1个独立按键控制LED状态转换(51单片机C语言实例Proteus仿真和代码)
5星 · 资源好评率100%
以下是基于52单片机的过零检测、PWM调光和双向可控硅控制220V灯泡的程序,其中一个按键用于增加亮度,另一个按键用于减少亮度。
```c
#include <reg52.h>
#include <intrins.h>
#define FOSC 11059200L
#define BAUD 9600
sbit ZP = P1^0; // 过零检测引脚
sbit PUL = P1^1; // PWM输出引脚
sbit UP = P1^2; // 增加亮度按键
sbit DOWN = P1^3; // 减少亮度按键
unsigned char code PWM_TABLE[101] = { // PWM占空比表
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
// 省略中间部分
91, 92, 93, 94, 95, 96, 97, 98, 99, 100
};
unsigned char pwm_duty = 50; // PWM占空比,初始值50%
unsigned char pwm_count = 0; // PWM计数器
void InitUART() { // 初始化串口
TMOD |= 0x20;
TH1 = TL1 = -(FOSC/12/32/BAUD);
TR1 = 1;
SM0 = 0;
SM1 = 1;
REN = 1;
EA = 1;
ES = 1;
}
void UART() interrupt 4 { // 串口中断处理函数
if (RI) {
RI = 0;
}
if (TI) {
TI = 0;
}
}
void delay_us(unsigned int us) { // 微秒级延时函数
while (us--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void delay_ms(unsigned int ms) { // 毫秒级延时函数
while (ms--) {
delay_us(1000);
}
}
void InitTimer0() { // 初始化计时器0
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = 0xFC;
TL0 = 0x18;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void Timer0() interrupt 1 { // 计时器0中断处理函数
static unsigned char pwm_index = 0; // PWM占空比索引
static bit pwm_flag = 0; // PWM标志位,0表示低电平,1表示高电平
static unsigned char dimming_count = 0; // 调光计数器
static unsigned char dimming_delay = 0; // 调光延时,防止频繁调光
TH0 = 0xFC;
TL0 = 0x18;
if (++pwm_count >= 100) { // PWM周期为100us,计数器到100时清零
pwm_count = 0;
}
if (pwm_count < PWM_TABLE[pwm_duty]) { // 根据PWM占空比计算输出电平
PUL = pwm_flag;
} else {
PUL = !pwm_flag;
}
if (dimming_count > 0) { // 调光计数器不为0时,延时
delay_us(10);
dimming_count--;
} else { // 调光计数器为0时,可以进行调光
if (!UP && pwm_duty < 100 && dimming_delay == 0) { // 增加亮度
pwm_duty++;
dimming_count = 10;
dimming_delay = 20;
} else if (!DOWN && pwm_duty > 0 && dimming_delay == 0) { // 减少亮度
pwm_duty--;
dimming_count = 10;
dimming_delay = 20;
}
if (dimming_delay > 0) { // 调光延时计数器
dimming_delay--;
}
}
if (ZP) { // 过零检测
pwm_index = 0;
pwm_flag = 0;
} else {
if (++pwm_index >= 100) { // PWM周期为100us,计数器到100时重新计数
pwm_index = 0;
pwm_flag = 1;
}
}
}
void main() {
InitUART(); // 初始化串口
InitTimer0(); // 初始化计时器0
while (1) {
RI = 0;
TI = 0;
}
}
```
需要注意的几点:
1. 程序中用到了串口,需要与电脑连接并通过串口调试工具进行调试;
2. 程序中用到了延时函数,需要根据实际硬件情况进行调整;
3. 程序中用到了调光功能,需要通过按键进行控制,同时为了防止频繁调光引起灯泡闪烁,加入了延时机制。
阅读全文