大家好,我是杂烩君。本次分享一个很久之前做的一个小模块。
功能
用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 rn", 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 rn", 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 rn", 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("灯灭rn"); } else { __set_PRIMASK(0); //打开总中断,灯亮 printf("灯亮,且亮度值为默认值% d rn", 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); }}
验证:
如果文章对你有帮助,麻烦帮忙点赞、收藏、转发,谢谢!
猜你喜欢:
分享一份不错的嵌入式资料汇总贴
私信回复【嵌入式书籍】,可获取博主精心整理的嵌入式电子书一份
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!