大家好,我是雜燴君。本次分享一個很久之前做的一個小模塊。
功能用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);
}
}
驗證:
如果文章對你有幫助,麻煩幫忙點贊、收藏、轉發,謝謝!
猜你喜歡:分享一份不錯的嵌入式資料彙總貼
私信回複【嵌入式書籍】,可獲取博主精心整理的嵌入式電子書一份
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!