stm32智能灯控(基于STM32实现的普通灯泡调光模块)
大家好,我是杂烩君。本次分享一个很久之前做的一个小模块。
功能用STM32控制一个普通灯泡的亮度,一路开关控制普通灯泡电源的通断,另外两路开关分别控制普通灯泡亮度的增加和减小。
调光控制器的原理通过STM32控制双向可控硅的导通来实现白炽灯(纯阻负载)亮度的调整。双向可控硅的特点是导通后即使触发信号去掉,它仍将保持导通;当负载电流为零(交流电压过零点)时,它会自动关断。所以需要在交流电的个半波期间都要送出触发信号,触发信号的送出时间就决定了灯泡的亮度。
调光的实现方式就是在过零点后一段时间才触发双向可控硅开关导通,这段时间越长,可控硅导通的时间越短,灯的亮度就越低;反之,灯就越亮。这就需要提取出交流电压的过零点,并以此为基础,确定触发信号的送出时间,达到调光的目的。
硬件
控制部分:主控单元以 STM32F103RBT6 单片机为核心,交流电压过零点信号提 取电路中产生的同步信号 TB 接到STM32F103RBT6 的 EXTI_Line0,此信号的下降沿将使 STM32F103RBT6 产生中断,以此为延时时间的起点。控制部分使用的是现有的最小系统板。
驱动部分:驱动部分主要由可控硅组成。可控硅在电路中能够实现交流电的无触点控制,以小电流控制大电流。动作快、寿命长、可靠性高。所以这里选用的是可控硅。 驱动部分使用的是自己绘制的电路板,电路原理图:
负载部分:本电路智能控制纯阻负载白炽灯。
软件要控制的对象是 50Hz 的正弦交流电,通过光耦取出其过零点的信号(同步信号),将这个信号送至单片机的外部中断,单片机接收到这个同步信号后启动一个延时程序,延时的具体时间由按键来改变。
当延时结束时,单片机产生触发信号,通过它让可控硅导通,电流过可控硅流过白炽灯,使灯发光。延时越长,亮的时间就越短,灯的亮度越暗(并不会有闪烁的感觉,因为重复的频率为 100Hz,且人的视觉有暂留效应)。由于延时的长短是由按键决定的,所以实际上就是按键控制了光的强弱。
经过实际调试得出,延时时间为0~7ms内的值。在程序中,我把7ms分割为14等份(实际上,分割的分数越大,调节的精度会更高,但是,为了有明显的现象,取14)。对于按键的处理,采用查询法,并且采用按下一次就响应一次的方法,即长按不能连续调整。
主程序:
int main(void)
{
GPIO_Configuration();
USART_Configuration();
EXTI_Configuration();
printfLogo();
Bright=14-z; //亮度缺省值为7(通过调Z间接得到Bright)
printf("当前亮度 = % d \r\n", Bright);
while(1)
{
//S1(PC6) 调高灯的亮度
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6) == Bit_RESET)
{
delay_ms(5); //消除抖动
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6) == Bit_RESET)
{
z--;
//等待按键释放
while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6) == Bit_RESET);
if(z==1)
{
z=14;
}
Bright=14-z;
printf("当前亮度 = % d \r\n", Bright);
}
}
//S2(PC7) 调低灯的亮度
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7) == Bit_RESET)
{
delay_ms(5); //消除抖动
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7) == Bit_RESET)
{
z ;
//等待按键释放
while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_7) == Bit_RESET);
if (z==14)
{
z=1;
}
Bright=14-z;
printf("当前亮度 = % d \r\n", Bright);
}
}
//S3(PC8) 调节灯的亮灭
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8) == Bit_RESET)
{
delay_ms(5); //消除抖动
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8) == Bit_RESET)
{
/*S3_Num为S3按下的次数,当按下的次数为奇数时灯灭
当按下的次数为偶数时,灯亮,并且亮度值为默认值7*/
S3_Num=S3_Num 1;
//等待按键释放
while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_8) == Bit_RESET);
if(S3_Num%2==1)
{
__set_PRIMASK(1); //关闭总中断,灯灭
printf("灯灭\r\n");
}
else
{
__set_PRIMASK(0); //打开总中断,灯亮
printf("灯亮,且亮度值为默认值% d \r\n", Bright);
}
}
}
}
}
外部中断函数:
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{
delay_us(500*z); //调节z的值来调节灯的亮度
GPIO_ResetBits(GPIOC,GPIO_Pin_11);
delay_us(100);
GPIO_SetBits(GPIOC,GPIO_Pin_11);
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
验证:
如果文章对你有帮助,麻烦帮忙点赞、收藏、转发,谢谢!
猜你喜欢:分享一份不错的嵌入式资料汇总贴
私信回复【嵌入式书籍】,可获取博主精心整理的嵌入式电子书一份
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com