我的嵌入式學習作品,算是學習STM32后的總結,如有可改進的地方,歡迎討論。
1. 功能描述
開機默認溫度設定值為25°C,設定濕度設定值為35%,LCD界面顯示測得溫濕度如下。當溫濕度傳感器讀到溫度或濕度有一個值大于設定值時,則風機打開,在溫度大于36度或濕度大于80%時,則風機100%全開,當溫度和濕度都小于設定值時,則風機關閉,當溫度在溫度設定值到36°之間,濕度在濕度設定值到80%之間,則風機按線性比例以1%~99%占空比輸出。另外,根據光照強度,當光敏傳感器值小于0.7 v則打開繼電器,反之則關閉繼電器。
11.png (1018 Bytes, 下載次數: 63)
下載附件
2020-6-18 23:47 上傳
各按鍵功能如下:
· mode按鍵:模式設定,按一下進入設定模式,再按一下進入正常運行模式,設定模式下LCD顯示如下圖:
22.png (1022 Bytes, 下載次數: 74)
下載附件
2020-6-18 23:47 上傳
· select按鍵:選擇鍵,在設定模式按一下select按鍵,選中設置濕度(H),再按一下選中設置溫度(T),若選中H,則H閃爍,若選擇T,則T閃爍。在正常工作模式下,此按鍵沒作用。
· +按鍵:在設置模式下,如果選中H狀態下,則每按下+按鍵,濕度設置值+1,同樣,選中T狀態,則溫度設定值+1。在正常工作模式下,此按鍵沒作用。
· -按鍵:作用和按鍵3類似,選中H狀態下,則每按下-鍵,濕度是定值-1,選中T狀態下,則每按下-鍵,溫度設定值-1。在正常工作模式下,此按鍵沒作用。
· enter鍵:為確定鍵,在設定模式下,按下enter鍵,則退出設定模式,進入正常工作模式,按照新的設定值進行工作。在正常工作模式下,此按鍵沒作用。
2.Proteus仿真原理圖如下:
33.png (93.2 KB, 下載次數: 74)
下載附件
2020-6-18 23:47 上傳
3.部分源碼如下:(代碼比較簡單,所以注釋比較少)光照AD采集
voidget_ADValue(void)
{
HAL_ADC_Start(&hadc1);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_Delay(100);
if(HAL_ADC_PollForConversion(&hadc1,50)== HAL_OK)
{
adc_value =HAL_ADC_GetValue(&hadc1);
voltage =adc_value*330/4096;
// printf("光敏AD值 :%d\n\r",adc_value);
// printf("光敏電壓 :%d.%d%dV\n\r",voltage/100,voltage/10,voltage%10);
}
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);
HAL_ADC_Stop(&hadc1);
if(voltage<70)//控制繼電器開關
{
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LED4_GPIO_Port,LED4_Pin,GPIO_PIN_SET);
}
HAL_Delay(500);
}
按鍵掃描系統
uint8_tkeyscan(uint8_t kk)
{
static uint8_t keyflag = 1;
if(kk) keyflag = 1;
if(keyflag &&(KEY0==0||KEY1==0||KEY2==0||KEY3==0||KEY4==0))
{
HAL_Delay(5);
keyflag = 0;
if(KEY0==0) return 1;
else if(KEY1==0) return 2;
else if(KEY2==0) return 3;
else if(KEY3==0) return 4;
else if(KEY4==0) return 5;
}
elseif(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)keyflag = 1;
return 0;
}
voidkey_system(void)
{
key_num=keyscan(0);
switch(key_num)
{
case 1:
mode1++;//模式標志位
flag=1;//設定模式下更新屏幕顯示的標志位 可減少閃屏
LCD1602_WriteCmd(0x01);//清屏
if(mode1>1)
{
mode1 = 0;
menu = 0;
LCD1602_WriteCmd(0x0c);//關光標關閃爍
}
break;
case 2:
if(mode1==0) break;
else
{
flag=1;
menu++;//設置對象選擇標志位
if(menu>1) menu =0;
}
break;
case 3:
if(mode1==0) break;
flag=1;
if(menu==0) humi++;
else temp++;
break;
case 4:
if(mode1==0) break;
flag=1;
if(menu==0) humi--;
else temp--;
break;
case 5:
if(mode1==0) break;
else
{
mode1 = 0;
menu = 0;
LCD1602_WriteCmd(0x01);
LCD1602_WriteCmd(0x0c);
}
break;
default: break;
}
}
風機PWM調速控制
uint8_tMAX(uint8_t x,uint8_t y)//較大值判斷
{
uint8_t max;
if(x>y) max=x;
else max=y;
return max;
}
uint16_tFAN_control(void)
{
uint16_t pwm;
if(temperature<temp &&humidity<humi) pwm=0;
if(temperature>36 &&temperature>temp) pwm=100;
if(humidity>80 &&humidity>humi) pwm=100;
if(temperature>=temp ||humidity>=humi)
{
if(humidity<=80 &&humidity>=humi)
{
num1=(uint8_t)humidity-humi;
num2=80-humi;
pwmh=num1*100/num2;
}
if(temperature<=36 &&temperature>=temp)
{
num1=(uint8_t)temperature-temp;
num2=36-temp;
pwmh=num1*100/num2;
}
pwm=MAX(pwmh,pwmt);
}
if(temperature>36 &&temperature>temp) pwm=100;
if(humidity>80 &&humidity>humi) pwm=100;
return pwm;
}
主程序
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
LCD1602_Init();
LCD1602_ShowStr(0,0,"INT...",6);
MX_TIM4_Init();
MX_ADC1_Init();
MX_USART1_UART_Init();
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
HAL_Delay(100); while (1)
{
DHT11_Show_Data();//調用溫濕度檢測子程序
get_ADValue();//調用光強AD值子程序
do//這里用do循環先執行,再判斷模式標志位值,為1時只執行循環體內程序,可減少軟件仿真時卡頓,未測試單片機運行
{
key_system();
if(mode1==0)
{
LCD1602_ShowStr(0,0,"H T FAN ",15);
LCD1602_ShowChar(0,1,(uint8_t)humidity/10+0x30);
LCD1602_ShowChar(1,1,(uint8_t)humidity%10+0x30);
LCD1602_ShowChar(4,1,(uint8_t)temperature/10+0x30);
LCD1602_ShowChar(5,1,(uint8_t)temperature%10+0x30);
if(pwm_value==0) LCD1602_ShowStr(8,1,"OFF",3);
else LCD1602_ShowStr(8,1,"ON",3);
}
else
{
if(menu==0&&flag==1)//標志位為1時更新顯示
{
LCD1602_ShowStr(0,0,"SET H T",11);
LCD1602_ShowChar(6,1,humi/10+0x30);
LCD1602_ShowChar(7,1,humi%10+0x30);
LCD1602_ShowChar(10,1,temp/10+0x30);
LCD1602_ShowChar(11,1,temp%10+0x30);
write_guanbiao(6,0,1);
flag=0;//標志位置0
HAL_Delay(200);
}
else if(flag==1)
{
LCD1602_ShowStr(0,0,"SET H T",11);
LCD1602_ShowChar(6,1,humi/10+0x30);
LCD1602_ShowChar(7,1,humi%10+0x30);
LCD1602_ShowChar(10,1,temp/10+0x30);
LCD1602_ShowChar(11,1,temp%10+0x30);
write_guanbiao(10,0,1);
flag=0;
HAL_Delay(200);
}
}
}while(mode1==1);
pwm_value=FAN_control();
__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,pwm_value);
HAL_Delay(10);
}
}