0 前言
?? 這兩年開始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長(zhǎng)自己做的項(xiàng)目系統(tǒng)達(dá)不到老師的要求。
為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長(zhǎng)分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天要分享的是
?? 基于單片機(jī)的家用燃?xì)獾目梢暬瘜?shí)時(shí)監(jiān)控報(bào)警儀
??學(xué)長(zhǎng)這里給一個(gè)題目綜合評(píng)分(每項(xiàng)滿分5分)
- 難度系數(shù):4分
- 工作量:4分
- 創(chuàng)新點(diǎn):3分
1 簡(jiǎn)介
本項(xiàng)目設(shè)計(jì)主要功能是可以用于家用燃?xì)獾目梢暬瘜?shí)時(shí)監(jiān)控的迷你報(bào)警器,傳感器部分和米家等絕大多數(shù)網(wǎng)絡(luò)上的家用燃?xì)鈭?bào)警使用的一致,還支持便捷更換傳感器。具備WIFI模塊,支持AT命令的設(shè)置。
2 主要器件
- HK32F031K6U6主控芯片
- SP485E芯片
- ch340e芯片
- MIC5219-3.3穩(wěn)壓芯片
- WiFi模塊
3 實(shí)現(xiàn)效果
4 設(shè)計(jì)原理
4.1 硬件部分
本項(xiàng)目涉及到的功能模塊有:
- USB轉(zhuǎn)TTL通信
- USB與單片機(jī)通信
- USB與WIFI模塊通信
- 單片機(jī)驅(qū)動(dòng)OLED液晶屏
- 單片機(jī)驅(qū)動(dòng)AHT20/21溫濕度芯片
- 單片機(jī)PWM驅(qū)動(dòng)蜂鳴器
- 單片機(jī)AD采集可燃傳感器的電壓值等功能。
前面和USB相關(guān)的測(cè)試方法就是插電腦和正常使用的485轉(zhuǎn)接線進(jìn)行連線傳輸,嘗試不同的波特率和傳輸速率進(jìn)行收發(fā)通信,不丟包,穩(wěn)定傳輸就是通過測(cè)試,否則要檢查硬件電路上的問題,是否有虛焊和器件上的損壞。
OLED和溫濕度芯片采用IIC相關(guān)的驅(qū)動(dòng),單輸出IIC可以不加上拉電阻能實(shí)現(xiàn)功能,但是交互式的,要獲取數(shù)據(jù)的就必須加上上拉電阻才能收數(shù)正常。而且燃?xì)鈧鞲衅魇谴呋紵绞降?,本身?huì)發(fā)熱,且發(fā)熱量還不小,故應(yīng)該盡可能的把溫濕度芯片和可燃傳感器分的遠(yuǎn)點(diǎn),不然溫度和濕度測(cè)試的都不準(zhǔn)確。每個(gè)功能模塊通過軟件編程實(shí)現(xiàn)功能后都要進(jìn)行對(duì)比。屏幕驅(qū)動(dòng)比較直觀,看到什么就是什么了,溫濕度需要進(jìn)行一定的補(bǔ)償。
最后蜂鳴器和按鍵功能的增加,蜂鳴器是5020的封裝,想要實(shí)現(xiàn)比較亮的聲音就要分析和測(cè)試,不斷調(diào)教,找到比較響亮的蜂鳴聲。按鍵功能可以做很多的聯(lián)動(dòng),這里把它做成了控制屏幕顯示反轉(zhuǎn)的功能。
主要原理圖文章來源:http://www.zghlxwxcb.cn/news/detail-835887.html
4.2 軟件部分
整體邏輯流程如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-835887.html
5 部分核心代碼
void HAL_Delay_us_init(uint8_t SYSCLK)
{
fac_us=SYSCLK;
}
void HAL_Delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told,tnow,tcnt=0;
uint32_t reload=SysTick->LOAD;
ticks=nus*fac_us;
told=SysTick->VAL;
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow;
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break;
}
};
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*
****************************************************************************************************
** 函數(shù)名稱: Get_analog_voltage(u8 ch)
** 完成時(shí)間: 2017.5.24
** 編 寫 人: DIX
** 入口參數(shù): u8 ch
** 返 回 值: 電壓值
** 功能說明: ADC信號(hào)轉(zhuǎn)換為電壓值mV
** 備注說明: 獲得ADC模擬出的電壓 12位精度 (0~3.3V之間的mV值)
****************************************************************************************************
*/
uint16_t Get_analog_voltage(uint8_t AD)
{
uint32_t sum=0; //采樣20次的累計(jì)和
uint8_t count;
uint16_t A_AD_Value; //單通道AD的變量值
ADC_ChannelConfTypeDef sConfig;
hadc.Instance->CHSELR = 0;
if(AD==8)
{
sConfig.Channel = ADC_CHANNEL_8;
}
else
{
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
}
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
A_AD_Value=0; //AD值清0
for(count=0;count<50;count++) //重復(fù)采樣50次
{
HAL_ADCEx_Calibration_Start(&hadc); //校準(zhǔn)ADC
HAL_ADC_Start(&hadc); //開啟ADC
HAL_ADC_PollForConversion(&hadc, 10); //等待轉(zhuǎn)換過程
sum += HAL_ADC_GetValue(&hadc); //獲得50采樣的累計(jì)和
}
A_AD_Value=sum/50; //AD采樣50次后取平均值
A_AD_Value=(uint16_t)(A_AD_Value*3300/4096); //擴(kuò)大了1000倍整數(shù)為1mV值
sum=0; //清0總值
return A_AD_Value; //返回值
}
int8_t Temper_Judgment(void)
{
int8_t temper;
uint16_t adc_value=0;
adc_value = Get_analog_voltage(0);
temper = (int8_t)((adc_value-449)/1.61);
return temper; //返回值
}
//u16進(jìn)制轉(zhuǎn)換為字符串
void u16tostr(u16 dat)
{
u8 temp[4];
u8 i=0,j=0,k=0;
while(dat)
{
temp[i]=(dat%10+0x30);
i++;
dat/=10;
}
j=i;
k=j;
// for(i=0;i<j;i++)
// {
// str1[i] = temp[j-i-1];
// }
for(i=0;i<4;i++)
{
if(4-k>i)
str1[i] =' ';
else
{
//j=j-1;
str1[i] = temp[--j];
}
}
if(!i)
{str1[i++]='0';}
//return str1;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
u8 x=1;
// u32 CT_data[2]={0};
// volatile float hum=0,tem=0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_Delay_us_init(24); //系統(tǒng)24MHz時(shí)鐘
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC_Init();
MX_USART2_UART_Init();
MX_TIM3_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM6_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2); //開啟定時(shí)器2
HAL_TIM_Base_Start_IT(&htim3); //開啟定時(shí)器3
HAL_TIM_Base_Start_IT(&htim1); //開啟定時(shí)器6
OLED_Init();
OLED_Clear();
OLED_DisplayTurn(1);
//AHT20.alive=!AHT20_Init(); //AHT20溫濕度傳感器初始化
temphum_init(); //ATH20初始化
/*打開串口1空閑中斷*/
//__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); //使能串口2中斷
/*打開串口1接收DMA中斷*/
//HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE); //串口接收DMA通道
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(btimer) //1s中斷
{
btimer = 0;bcont++;
// Now_U = Get_analog_voltage(8); //采用內(nèi)部ADC采樣
if(bcont==1)
{
OLED_Clear(); //清屏
//HAL_Delay(1000); //延時(shí)1秒
OLED_DrawBMP(0,0,64,6,BMP5); //圖片顯示LOGO
}
if(bcont==5)
{
OLED_Clear(); //清屏
OLED_ShowCHinese(4,0,11); //第
OLED_ShowCHinese(24,0,12); //六
OLED_ShowCHinese(44,0,13); //屆
OLED_ShowCHinese(4,2,14); //立
OLED_ShowCHinese(24,2,15); //創(chuàng)
OLED_ShowCHinese(44,2,16); //杯
OLED_ShowCHinese(0,4,3); //燃
OLED_ShowCHinese(16,4,17); //氣
OLED_ShowCHinese(32,4,19); //監(jiān)
OLED_ShowCHinese(48,4,20); //測(cè)
//OLED_ShowString(8,4,"Ex",16);
//OLED_ShowString(0,4," O L E D",16);
//OLED_ShowString(0,4," 29.1",16); //數(shù)據(jù)
//OLED_ShowCHinese(44,4,21); //℃
}
if(bcont==9)
{
OLED_Clear(); //清屏
//OLED_ShowString(0,0,"12.6",16); //數(shù)據(jù)
//OLED_ShowString(32,0,"%LEL",16); //可燃單位
OLED_ShowCHinese(0,0,22); //溫
OLED_ShowCHinese(16,0,23); //濕
OLED_ShowCHinese(32,0,24); //度
OLED_ShowString(0,2," 26.2",16); //數(shù)據(jù)
OLED_ShowCHinese(44,2,21); //℃
OLED_ShowString(0,4,"50.7",16); //數(shù)據(jù)
OLED_ShowString(40,4,"%RH",16); //濕度單位
}
if(bcont>=19)
{
Now_U = Get_analog_voltage(8); //采用內(nèi)部ADC采樣
Temper=Temper_Judgment(); //溫度換算函數(shù)
// /*--------AHT20讀取數(shù)據(jù)---------*/
// if(AHT20.alive)// 如果AHT20傳感器存在,則讀取溫濕度數(shù)據(jù)
// {
// //讀取AHT20的 20Bit原始數(shù)據(jù)
// AHT20.flag = AHT20_ReadHT(AHT20.HT);
// //實(shí)際標(biāo)準(zhǔn)單位轉(zhuǎn)換
// StandardUnitCon(&AHT20);
// }
if(bcont==19)
{
OLED_Clear(); //清屏
}
if(Now_U>=900 && Now_U<2000)
{
OLED_ShowCHinese(32,4,7); //警
OLED_ShowCHinese(48,4,8); //戒
}
else if(Now_U>=2000)
{
OLED_ShowCHinese(32,4,9); //危
OLED_ShowCHinese(48,4,10); //險(xiǎn)
}
else
{
OLED_ShowCHinese(32,4,5); //安
OLED_ShowCHinese(48,4,6); //全
}
u16tostr(Now_U);
OLED_ShowString(0,0,"U:",16); //電壓
OLED_ShowString(16,0,str1,16); //數(shù)據(jù)
OLED_ShowString(48,0,"mV",16); //電壓?jiǎn)挝?/span>
memset(str1,0,4);
OLED_ShowNum(4,2,Calculate_Concentration(Now_U),3,16); //顯示濃度
if(Calculate_Concentration(Now_U)>=10)
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
else
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
memset(str1,0,4);
OLED_ShowString(32,2,"%LEL",16); //可燃單位
OLED_ShowString(0,4,"Ex",16); //可燃標(biāo)致
}
if(bcont>=50)
{
// AHT20_Read_CTdata(CT_data); //不經(jīng)過CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù)
// hum = CT_data[0]*100*10/1024/1024; //計(jì)算得到濕度值(放大了10倍)
// tem = CT_data[1]*200*10/1024/1024-500; //計(jì)算得到溫度值(放大了10倍)
// HAL_Delay(2000); //延時(shí)1秒
bcont=0;
}
}
if(!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin))
{ //讀取KEY按鍵引腳,低電平表示按下
//HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); //LED引腳電平取反
HAL_Delay(10); //延時(shí)
OLED_Clear();
x=!x; //變量取反
OLED_DisplayTurn(x);
while(!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin))//等待松手,防松手抖動(dòng)
HAL_Delay(10); //延時(shí)
}
}
/* USER CODE END 3 */
}
6 最后
到了這里,關(guān)于單片機(jī)項(xiàng)目分享 單片機(jī)家用燃?xì)獾目梢暬瘜?shí)時(shí)監(jiān)控報(bào)警儀 - 物聯(lián)網(wǎng) 嵌入式 stm32的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!