文章目錄
- 1 簡介
- 2 緒論
- 2.1 課題背景
- 3 系統設計
- 3.1 系統架構
- 3.2 硬體部分
- 3.2.1 DS18B20 簡介
- 3.2.2 LCD1602 液晶屏簡介
- 3.3 軟體部分
- 3.3.1 整體軟體流程
- 3.3.2 初始化
- 3.3.3 溫度采集與顯示
- 3.4 實作效果
- 3.5 部分相關代碼
- 4 最后
1 簡介
Hi,大家好,這里是丹成學長,今天向大家介紹一個 單片機專案
基于stm32的智能溫控風扇設計與實作
大家可用于 課程設計 或 畢業設計
技術解答、畢設幫助、開題指導
print("Q 746876041")
2 緒論
2.1 課題背景
隨著科技的日新月異,智能家居逐漸走入普通家庭,風扇作為基本的家用電器也將成為智能家居的一部分,這里介紹的是以STM32單片機為控制單元并結合嵌入式技術設計的一款具有溫控調速、液晶顯示溫度等資訊的智能電風扇,經過前期設計、制作和最終的測驗得出,該風扇電源穩定性好,操作方便,運行可靠,功能強大,價格低廉,節約能耗,能夠滿足用戶多元化的需求,該風扇具有的人性化設計和低廉的價格很適合普通用戶家庭使用,
3 系統設計
3.1 系統架構
設計采用STM32單片機做主控芯片,通過DS18B20采集溫度,將溫度顯示在LCD1602上,根據溫度的不同,利用STM32對風扇進行調速,總體硬體設計如下圖所示

3.2 硬體部分
3.2.1 DS18B20 簡介
DS18B20 是美國 DALLAS 半導體公司繼 DS1820 之后最新推出的一種改進型智能溫度傳感器, 與傳統的熱敏電阻相比, 它能夠直接讀出被測溫度并且可根據實際要求通過簡單的編程實作 9~12 位的數字值讀數方式,

3.2.2 LCD1602 液晶屏簡介
1602 液晶也叫 1602 字符型液晶, 它是一種專門用來顯示字母、 數字、 符號等的點陣型液晶模塊, 它由若干個 5X7 或者 5X11 等點陣字符位組成, 每個點陣字符位都可以顯示一個字符, 每位之間有一個點距的間隔, 每行之間也有間隔, 起到了字符間距和行間距的作用, 正因為如此所以它不能很好地顯示圖形

3.3 軟體部分
3.3.1 整體軟體流程
控制系統軟體使用 C 語言編程,
使用模塊化設計, 除主程式外, 還有各功能子程式, 分別執行直流電機驅動調速及溫度采集、 顯示等功能, 編輯環境采用集成開發環環境 Keil,
程式總體運行流程圖如下:

3.3.2 初始化
系統初始化包括 STM32 系統定時器初始化, GPIO 口初始化以及 LCD1602 初始化等,

3.3.3 溫度采集與顯示
DS18B20 溫度傳感器進行溫度采集時, 要依次進行初始化, ROM 操作指令, 存盤器操作指令, 資料傳輸等操作

3.4 實作效果


3.5 部分相關代碼
/************************************************
作者:丹成學長,Q746876041
************************************************/
1.主函式
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include <LCD1602.h>
#include "bsp_ds18b20.h"
int main()
{ int PWM,low,zhouqi;
float wendu;
int wendu1;
zhouqi=500;
low=zhouqi-PWM;
SysTick_Init();
init1602();
lcdpos(1,0);
writestring("TEM: 00.0");
GPIO_SetBits(GPIOB,GPIO_Pin_0);
while( DS18B20_Init())
{
lcdpos(0,0);
writestring(" no ds18b20 exit");
}
lcdpos(0,0);
writestring("ds18b20 exit");
for(;;)
{
DS18B20_Get_Temp(wendu);
if (wendu<0)
{ lcdpos(1,4);
writestring("-");
}
wendu1=wendu*100;
lcdpos(1,5);
write_dat(wendu1/10000+0x30);
lcdpos(1,6);
write_dat(wendu1%10000/1000+0x30);
lcdpos(1,7);
write_dat(wendu1%1000/100+0x30);
lcdpos(1,9);
write_dat(wendu1%100/10+0x30);
lcdpos(1,10);
write_dat(wendu1%10+0x30);
Delay_ms(2000);
if(wendu1>30)
{ low=500;
GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
}
if(wendu1<15)
{ low=0;
GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
}
if(wendu1>=15&wendu1<20)
{ low=100;
GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
Delay_ms(low);
}
if(wendu1>=20&wendu1<25)
{
low=200;
GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
Delay_ms(low);
}
if(wendu1>=25&wendu1<30)
{ low=300;
GPIO_SetBits(GPIOB,GPIO_Pin_0);
Delay_ms(PWM);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
Delay_ms(low);
}
}
}
2.DS18B20 子程式
#include "bsp_ds18b20.h"
/*
* 函式名: DS18B20_GPIO_Config
* 描述 : 配置 DS18B20 用到的 I/O 口
* 輸入 : 無
* 輸出 : 無
*/
static void DS18B20_GPIO_Config(void)
{
/*定義一個 GPIO_InitTypeDef型別的結構體*/
GPIO_InitTypeDef GPIO_InitStructure;
/*開啟 DS18B20_PORT 的外設時鐘*/
RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
/*選擇要控制的 DS18B20_PORT 引腳*/
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
/*設定引腳模式為通用推挽輸出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*設定引腳速率為 50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*呼叫庫函式, 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);
}
/*
* 函式名: DS18B20_Mode_IPU
* 描述 : 使 DS18B20-DATA 引腳變為輸入模式
* 輸入 : 無
* 輸出 : 無
*/
static void DS18B20_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*選擇要控制的 DS18B20_PORT 引腳*/
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
/*設定引腳模式為浮空輸入模式*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
/*呼叫庫函式, 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}
/*
* 函式名: DS18B20_Mode_Out_PP
* 描述 : 使 DS18B20-DATA 引腳變為輸出模式
* 輸入 : 無
* 輸出 : 無
*/
static void DS18B20_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*選擇要控制的 DS18B20_PORT 引腳*/
GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
/*設定引腳模式為通用推挽輸出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*設定引腳速率為 50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*呼叫庫函式, 初始化 DS18B20_PORT*/
GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}
/*
*主機給從機發送復位脈沖
*/
static void DS18B20_Rst(void)
{
/* 主機設定為推挽輸出 */
DS18B20_Mode_Out_PP();
DS18B20_DATA_OUT(LOW);
/* 主機至少產生 480us 的低電平復位信號 */
Delay_us(750);
/* 主機在產生復位信號后, 需將總線拉高 */
DS18B20_DATA_OUT(HIGH);
Delay_us(15);
}
/*
* 檢測從機給主機回傳的存在脈沖
* 0: 成功
* 1: 失敗
*/
static uint8_t DS18B20_Presence(void)
{
uint8_t pulse_time = 0;
/* 主機設定為上拉輸入 */
DS18B20_Mode_IPU();
while( DS18B20_DATA_IN() && pulse_time<100 )
{
pulse_time++;
Delay_us(1);
}
/ * 經過 100us 后, 存在脈沖都還沒有到來*/
if( pulse_time >=100 )
return 1;
else
pulse_time = 0;
/* 存在脈沖到來, 且存在的時間不能超過 240us */
while( !DS18B20_DATA_IN() && pulse_time<240 )
{
pulse_time++;
Delay_us(1);
}
if( pulse_time >=240 )
return 1;
else
return 0;
}
/*
* 從 DS18B20 讀取一個 bit
*/
static uint8_t DS18B20_Read_Bit(void)
{
uint8_t dat; /* 讀 0 和讀 1 的時間至少要大于 60us */
DS18B20_Mode_Out_PP();
/* 讀時間的起始: 必須由主機產生 >1us <15us 的低電平信號 */
DS18B20_DATA_OUT(LOW);
Delay_us(10);
/ * 設定成輸入, 釋放總線, 由外部上拉電阻將總線拉高 */
DS18B20_Mode_IPU();
//Delay_us(2);
if( DS18B20_DATA_IN() == SET )
dat = 1;
else
dat = 0;
/* 這個延時引數請參考時序圖 */
Delay_us(45);
return dat;
}
/*
* 從 DS18B20 讀一個位元組, 低位先行
*/
uint8_t DS18B20_Read_Byte(void)
{
uint8_t i, j, dat = 0;
for(i=0; i<8; i++)
{
j = DS18B20_Read_Bit();
dat = (dat) | (j<<i);
}
return dat;
}
/*
* 寫一個位元組到 DS18B20, 低位先行
*/
void DS18B20_Write_Byte(uint8_t dat)
{
uint8_t i, testb;
DS18B20_Mode_Out_PP();
for( i=0; i<8; i++ )
{
testb = dat&0x01;
dat = dat>>1;
/* 寫 0 和寫 1 的時間至少要大于 60us */
if (testb)
{
DS18B20_DATA_OUT(LOW);
/* 1us < 這個延時 < 15us */
Delay_us(8);
DS18B20_DATA_OUT(HIGH);
Delay_us(58);
}
else
{
DS18B20_DATA_OUT(LOW);
/* 60us < Tx 0 < 120us */
Delay_us(70);
DS18B20_DATA_OUT(HIGH);
/* 1us < Trec(恢復時間) < 無窮大*/
Delay_us(2);
}
}
}
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳過 ROM */
DS18B20_Write_Byte(0X44); /* 開始轉換 */
}
uint8_t DS18B20_Init(void)
{
DS18B20_GPIO_Config();
DS18B20_Rst();
return DS18B20_Presence();
}
float DS18B20_Get_Temp(float f_tem)
{
uint8_t tpmsb, tplsb;
short s_tem;
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳過 ROM */
DS18B20_Write_Byte(0X44); /* 開始轉換 */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_Write_Byte(0XCC); /* 跳過 ROM */
DS18B20_Write_Byte(0XBE); /* 讀溫度值 */
tplsb = DS18B20_Read_Byte();
tpmsb = DS18B20_Read_Byte();
s_tem = tpmsb<<8;
s_tem = s_tem | tplsb;
I f( s_tem < 0 ) /* 負溫度 */
f_tem = (~s_tem+1) * 0.0625;
else
f_tem = s_tem * 0.0625;
return f_tem;
}
/*******************************************************************
篇幅有限,只展示部分代碼
作者:丹成學長,Q746876041
********************************************************************/
4 最后
技術解答、畢設幫助、開題指導
print("Q 746876041")

單片機畢設專案大全:
https://blog.csdn.net/huawei123444/article/details/119822845
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/325542.html
標籤:其他
