过零检测:
检测的是什么:交流电的电压
零:电压变成零
为什么需要这个检测:因为在交流电下,零点时继电器闭合产生的电火花最小,可以延长继电器的使用寿命。所以我们检测零点,通过延时,让继电器在下一个零点闭合。保护继电器。
1:逻辑:按键按下后使能过零中断,过零中断中,动作继电器。注意:如果没有过零信号。也要在延迟40ms后闭合继电器。避免过零检测电路坏了影响产品使用。
void GPIO_IRQHandler(void)
{
if(rex_InterruptStatus(ZERO))//判断是否是过零检测中断
{
GPIO_ClearAllInterrupt();//清除中断标志位
zero_interrupe_disable();//失能过零中断
zero_delay_relay();//延迟5ms后动作继电器
return;
}
zero_detect_timer_start(void);//按键中断进--使能过零中断以及开定时timer
}
/*
zero_delay_relay()
{
delay(5);
zero_detect_timer_callback();//动作继电器函数
}
*/
2:注意:按键中断和过零中断进入的是一个中断
a:有过零信号的情况下:按键中断:,使能过零引脚中断,判断中断引脚是否是为过零脚,如果是,延迟5ms,继电器拉高电平-即闭合继电器。
b:没有过零信号的情况下:按键中断里,设置一个过零定时器timer,40ms后,动作继电器。
void zero_detect_timer_start(void)
{
zero_interrupe_enable();
SYS_SetTimer(&zero_timer, 40, TIMER_SINGLE, zero_detect_timer_callback);
}
其中需要注意的点是,有过零信号的情况下,会在中断里动作继电器。同时,过零定时器timer也会开始定时,也会动作继电器。这样导致动作了两次继电器。因此我们需要在有过零信号的情况下,动作继电器时,把timer给释放掉,这样就不会动作两次继电器啦。
void zero_detect_timer_callback(void)
{
rex_gpio_set(gpio_relay_map[i], g_elem_state[i].state.relay_coil);
SYS_ReleaseTimer(&zero_timer);//释放timer
}
3:已知:交流电波形周期10ms,继电器吸合需要的时间为4-5ms。检测到零点以后,延迟5ms再进行继电器的闭合,延迟的时间加上继电器闭合使用的时间,实际继电器闭合正好来到检测到的下一个零点:实现了让继电器在零点闭合的功能。