基于STM32F4開發的智能臺燈
寫這篇博客的目的有2個,首先是記錄一下學習STM32大半年來的第一個自己動手開發的專案,整理一下開發程序和思路;其次也是希望可以和更多的同行交流開發經驗,有什么問題可以多多討論,集思廣益,共同進步~
設計目標以及功能說明
開發的智能臺燈功能有2個:
1.手動模式:可通過按鍵調節LED燈亮度,共10檔;
2.自動模式:當檢測到有人在的條件下,根據環境光照強度自動調節LED燈亮度;當檢測到無人在,將進入延時,延時時間結束將關閉LED燈,
原理圖

由于是在面包板上焊接的電路,原理圖畫的比較粗糙;
首先核心控制器件選用的是正點原子的STM32F407核心板,這款核心板功能非常齊全,應付一般的專案開發控制絕對是夠了,自己手頭上專案也是用這個做的,
手動模式下的LED控制:這個就比較簡單,直接核心板輸出一個定時器TIM13-PWM的脈寬調制信號到LED燈上,按鍵上下調節占空比即可調節亮度,相信了解PWM控制原理的小伙伴一看就知道是怎么回事~
自動模式下的LED控制:
1.紅外探測模塊可以去淘寶上搜索,有很多成熟的模塊選用,總的來說就是這種模塊可以在一定范圍內檢測到有人即可輸出高電平信號,沒有人就保持低電平;我選用的是HC-SR501,質量不是很好,本來有2種模式,不可重復觸發模式:即探測到人就輸出一定時間的高電平然后變為低電平;可重復觸發模式:探測到有人一直輸出高電平知道人離開延時結束,
2.將紅外探測模塊接到MCU的ADC1通道2,當adcx2得到的值大于1500,就說明有人,此時光敏電阻與電位器串聯的電路通過ADC1通道3檢測電壓信號即代表了環境亮度,然后經過簡單的數學公式建立通道3檢測的到的adcx3與PWM占空比的關系,就可以實作根據環境亮度實時調節LED亮度的功能,
3.當檢測到無人時,在程式里面設定了for回圈+delay,延時時間可以自己設定,延時一段時間后就跳出回圈,等待下一個紅外探測模塊的高電平進入回圈,
程式代碼
代碼是在keil5里面用C語言寫的,下面就把主程式的代碼放上來,里面注釋的很清楚,大家可以看一下
在這里插入代碼片int main (void)
{
volatile u8 t=0;
volatile u8 i=0;
volatile u8 key; //按鍵
volatile u16 led0pwmval = 499;//LED燈亮度值 0為最亮,499為最弱
volatile u8 SD_Mode = 0;//手動模式
volatile u16 adcx0;
volatile u16 adcx1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設定系統中斷優先級分組2
delay_init(168); //初始化延時函式
uart_init(115200); //初始化串口波特率為115200
LCD_Init(); //LCD初始化
LED_Init(); //初始化LED
KEY_Init(); //按鍵初始化
Adc_Init(); //adc初始化
TIM13_PWM_Init(500-1,84-1); //84M/84=1Mhz的計數頻率,重裝載值500,所以PWM頻率為 1M/500=2Khz.
TIM_SetCompare1(TIM13,led0pwmval); //修改比較值,修改占空比
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"CANOE @ Light");
delay_ms(5000);
while(1)
{
while (SD_Mode == 0)//自動模式
{
LCD_ShowString(30,70,200,16,16,"zidongmoshi");
LCD_ShowString(30,150,200,16,16,"LIGHT_VAL:");
key=KEY_Scan(0);
if(key==KEY0_PRES||key==WKUP_PRES) //在自動模式下,如果檢測到有按鍵按下,則退出自動模式進入手動模式
{
SD_Mode = 1;
}
TIM_SetCompare1(TIM13,499);
adcx0=Get_Adc_Average(ADC_Channel_2,10); //通過ADC1探測得到紅外探測模塊的輸出值,當有人活動時會監測得到高電平
if (adcx0 > 1500) //當探測得到高電平時,根據ADC通道3采集得到光敏電阻的值來調節亮度值
{
for(i=0;i<100;i++)
{
adcx1=Get_Adc_Average(ADC_Channel_3,10);//采集得到光敏電阻的值,環境亮度越暗得到的值越小,亮度越高得到的值越大
//adcx1的值處于1200~4000范圍內
led0pwmval = (adcx1 - 1200)/6;
TIM_SetCompare1(TIM13,led0pwmval); //修改比較值,修改占空比
POINT_COLOR=BLUE;//設定字體為藍色
LCD_ShowxNum(110,150,(500-led0pwmval),4,16,0); //顯示 亮度值
delay_ms(100);
key=KEY_Scan(0);
if(key==KEY0_PRES||key==WKUP_PRES) //在自動模式下,如果檢測到有按鍵按下,則退出自動模式進入手動模式
{
SD_Mode = 1;
i=100;
}
}
}
}
led0pwmval = 300;
while(SD_Mode == 1) //手動模式下 按鍵增減LED亮度
{
LCD_ShowString(30,70,200,16,16,"shoudongmoshi");
LCD_ShowString(30,90,200,16,16,"WK_UP:+ KEY0:-");
POINT_COLOR=BLUE;//設定字體為藍色
LCD_ShowString(30,150,200,16,16,"LIGHT_VAL:");
t++;
key=KEY_Scan(0);
if(key==WKUP_PRES)
{
if(led0pwmval<499)led0pwmval+=40;
TIM_SetCompare1(TIM13,led0pwmval); //修改比較值,修改占空比
}
else if(key==KEY0_PRES)
{
if(led0pwmval>45)led0pwmval-=40;
else led0pwmval=0;
TIM_SetCompare1(TIM13,led0pwmval); //修改比較值,修改占空比
}
if(t==10||key==KEY0_PRES||key==WKUP_PRES) //WKUP/KEY1按下了,或者定時時間到了
{
LCD_ShowxNum(110,150,(500-led0pwmval),4,16,0); //顯示 亮度值
LED0=!LED0;
t=0;
}
delay_ms(10);
}
}
}
實物圖

結束語
本人現在是科研狗一枚,這個小東西是在老師給的專案忙里偷閑花了3天時間做出來的,主要是為了熟悉STM32開發的一些東西,后面有時間還會陸續做一些其他有些意思的專案,大家如果有什么好玩的專案想法創意之類的可以私信我一起交流,有機會一起做些有意思的事~
有什么問題留言區或者私信我討論,郵件也可以(18642896070@163.com),歡迎交流~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/339263.html
標籤:其他
下一篇:Modbus RTU簡介(上)
