- // 头文件
- #include "STC8H.H" // 引入STC8系列单片机的头文件
- #include "intrins.h" // 引入Keil的内部函数头文件
-
-
- // 数据存储
- #define HIGH_THRESHOLD 3000 // 亮度变暗的上阈值
- #define LOW_THRESHOLD 2900 // 亮度变亮的下阈值
- #define HIGH_Voltage 819 // 1V
- #define LOW_Voltage 573 // 0.7V
- #define STABLE_COUNT 20 // 设定连续检测 20 次才切换状态
-
-
- // 端口定义
- sbit LED = P5^4; // LED
- sbit DELAY = P3^5; // 继电器
- sbit GM = P3^3; // 定义AD光敏输入端口
- sbit HP = P1^3; // 电网电压
- sbit PH0 = P1^0; // 主
- sbit PH1 = P1^1; // 从
-
-
- /*-------------------------------------------光敏探头ADC检测-----------------------------------------------------*/
- // 1ms延时函数
- void delay_ms(uint16 x)
- {
- uint16 j, i;
- for(j = 0; j < x; j++)
- {
- for(i = 0; i < 1580; i++); // 延时代码
- }
- }
-
- // ADC初始化
- void ADC_INIT()
- {
- ADCCFG &= ~0x0f; // 50KSPS
- ADCCFG |= 0x02; // SPEED(2)
- ADCTIM = 0x35; // CSSETUP(0), CSHOLD(1), SMPDUTY(21)
- ADC_CONTR&=0xDF; // 清AD转换完成标志
-
- EADC = 0; // 禁止ADC中断
- ADCCFG|=0x20; // ADC转换结果12位数
- ADC_CONTR|=0x40; //启动AD转换,ADC_START=1
- }
-
- // ADC口检测AD转换值函数
- uint16 GET_ADC_DATA(void)
- {
- uint16 AD_DATA = 0; // ADC数据存储位
- ADC_CONTR&=0xDF; // 清AD转换完成标志
- ADC_CONTR&=0xBF; // 关闭AD转换,ADC_START=0
- // 数据高八位存RES 低2位存RESL
- AD_DATA = ADC_RES; // 首先读取高八位的数值
- AD_DATA <<= 8;
- AD_DATA|= ADC_RESL; // 读取低4位
- ADC_CONTR|=0x40; //启动AD转换,ADC_START=1
- return AD_DATA;
- }
-
- // 转换ADC电压值
- void datapros()
- {
- static uint16 stable_counter = 0; // 计数器
- static bit light_on = 0; // 当前灯的状态
-
- uint16 temp = GET_ADC_DATA();
- uint16 voltage = (((float)temp / 4095) * 4095);
-
- // 记录状态是否需要改变
- bit new_state = light_on;
-
- if (!light_on && voltage > HIGH_THRESHOLD) // 低亮度,尝试开灯
- {
- new_state = 1;
- }
- else if (light_on && voltage < LOW_THRESHOLD) // 高亮度,尝试关灯
- {
- new_state = 0;
- }
-
- // 仅在状态需要改变时,进行稳定性检查
- if (new_state != light_on)
- {
- stable_counter++; // 状态变化时,增加稳定计数
- if (stable_counter >= STABLE_COUNT) // 只有状态连续 N 次不变,才真正执行
- {
- light_on = new_state;
-
- if(light_on == 0) // 检测需要关闭灯
- {
- PH0 = 0; // 主
- PH1 = 0; // 从
-
- LED = 0;
- DELAY = 0;
- }
- else if(light_on == 1)
- {
- LED = 1;
- DELAY = 1;
- }
-
- stable_counter = 0; // 计数器归零
- }
- }
- else
- {
- stable_counter = 0; // 状态没有变化,重置计数
- }
- }
-
- // HP转换ADC电压值----电网电压检测
- void HPdatapros()
- {
- static uint16 stable_counter = 0; // 计数器
- static bit light_on = 0; // 当前灯的状态
- bit new_state = light_on; // 记录状态是否需要改变
-
- uint16 temp = GET_ADC_DATA();
- uint16 voltage = (((float)temp / 4095) * 4095);
-
- if(voltage > HIGH_Voltage) // 电网电压超过1V
- {
- PH0 = 0; // 主
- PH1 = 0; // 从
- }
-
- if (light_on && voltage > LOW_Voltage) // 电网电压超过0.7V
- {
- new_state = 0;
- }
-
- // 仅在状态需要改变时,进行稳定性检查
- if (new_state != light_on)
- {
- stable_counter++; // 状态变化时,增加稳定计数
- if (stable_counter >= STABLE_COUNT) // 只有状态连续 N 次不变,才真正执行
- {
- light_on = new_state;
-
- if(light_on == 0) // 检测需要关闭高压
- {
- PH0 = 0; // 主
- PH1 = 0; // 从
-
- delay_ms(5000); // 5s
-
- PH0 = 1; // 主
- PH1 = 1; // 从
- }
- stable_counter = 0; // 计数器归零
- }
- }
- else
- {
- stable_counter = 0; // 状态没有变化,重置计数
- }
- }
- /*-------------------------------------------光敏探头 电网电压ADC检测------------------------------------------------*/
-
- // 系统初始化
- void system_init()
- {
- delay_ms(1000); // 延时1s 待市电稳定
-
- // 引脚定义
- P3M0 |= 0x20; P3M1 &= ~0x20; // P35 强推挽
- P5M0 |= 0x10; P5M1 &= ~0x10; // P54 强推挽
- P1M0 |= 0x03; P1M1 &= ~0x03; // P10 11 强推挽
-
- LED = 0; // 关灯
- DELAY = 0; // 继电器打开
- PH0 = 0; // 主
- PH1 = 0; // 从
-
- ADC_INIT(); // ADC初始化
- }
- void main()
- {
- system_init();
-
- while(1)
- {
- ADC_CONTR = 0x8B;
- datapros();
-
- ADC_CONTR = 0x83; // ADC3
- //HPdatapros(); // 电网电压实时检测
- }
- }
复制代码
现在的问题是,当我没有调用电网电压检测的两行代码时 光敏检测是正常的
但是一旦调用会导致LED delay 包括PH0 1四个全部都变成低电平
原来的光敏也不起作用,这个时候电网电压检测引脚是接地的 也就是0V
正常不应该会影响到
代码写的不好,大佬高抬贵手给看看如何能保证这两个检测互不干扰
|