找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1707|回復: 0
打印 上一主題 下一主題
收起左側

基于stm32的溫度傳感警示器

[復制鏈接]
跳轉到指定樓層
樓主
ID:729302 發(fā)表于 2020-4-14 21:33 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一、硬件管理
1、STM32開發(fā)板簡介··························· 3
2、DS1820數(shù)字溫度計···························3
3、3.5寸液晶LCD顯示屏·························4
4、硬件整體實物圖···························5
二、軟件方案
1、設計思路····································5
2、軟件流程圖··································5
  3、軟件代碼實現(xiàn)·································6
       (1)主程序實現(xiàn)····························6
       (2)溫度傳感器子程序·························9
三、工程訓練小結·································12
一、硬件管理
1、STM32開發(fā)板簡介
STM32系列單片機是意法半導體集團生產(chǎn)的一種基于專為要求高性能、低成本、低功耗的嵌入式應用專門設計的ARM Cortex-M3內核。體現(xiàn)了現(xiàn)代單片機為控制器發(fā)展的新趨勢,目前深受用戶歡迎,正在逐漸成為單片機世界的新潮流。從STM32系列單片機的問世到快速普及,
并為業(yè)界廣為采用,最主要的原因是它具有完整的單片機系列芯片,可以讓使用者根據(jù)不同的需求,選擇最合適的單片機芯片。
STM32,有非常豐富的外設與內設資源,一般單片機內存相對比較小,沒辦法移入大量程序,而STM32集成了32512KB的內存和,6~64KB的靜態(tài)存儲器,可以放足夠大的代碼,不用擔心內存溢出。并且內部集成了2個12位的us級的A/D轉換器和12位D/A轉換器,開發(fā)者并不需要外接模數(shù)或數(shù)模轉換芯片來額外增加成本。STM32系列有上百個I/O口和多個外部中斷向量,通過配置寄存器,可以將端口映射到這些向量上。另外,STM32有豐富的通信接口:IIC、USART、SPI、IIS、CAN、USB2.0和SDIO。這些資源是32位單片機所不具有的,足夠的資源使得它的開發(fā)空間也更加強大。
本項目涉及范圍廣,功能相對比較多,所以主控芯片必須得具有足夠的外設接口,高速的處理速度和較高的性價比。單片機由于自身條件的限制,無法滿足此項目的要求。因此,本項目選用的是性能優(yōu)異,廉價,功耗低,并屬于STM32系列的STM32F103VCT6芯片。STM32具有32位單片機所有的優(yōu)點,并且,價格上也比較低,所以比較適合應用于智能產(chǎn)品。STM32F103微控制器作為智能化環(huán)境檢測調節(jié)裝置的核心,核心算法以及所有的控制算法和控制命令,都由STM32F103單片機完成。STM32F103最小系統(tǒng)包括晶振電路、復位電路、電源電路。
2、DSl820 數(shù)字溫度計
DSl820數(shù)字溫度計提供 9 位溫度讀數(shù),指示器件的溫度。信息經(jīng)過單線接口送入 DSl820 或從 DSl820 送出,因此從中央處理器到 DSl820 僅需連接一條線(和地)。
讀、寫和完成溫度變換所需的電源可以由數(shù)據(jù)線本身提供,而不需要外部電源。因為每一個 DSl820 有唯一的系列號(silicon serial number),因此多個 DSl820 可以存在于同一條單線總線上。這允許在許多不同的地方放置溫度靈敏器件。此特性的應用范圍包括 HVAC 環(huán)境控制,建筑物、設備或機械內的溫度檢測,以及過程監(jiān)視和控制中的溫度檢測。
   
具體連線:PG11(STM32)~DQ(DS1820)
3、3、3.5寸液晶LCD顯示屏

連接方案:排線插針對準開發(fā)板相應LCD排針插口即可
4、硬件整體實物圖
二、軟件方案
1、設計思路
  本工程設計采用keil5軟件進行軟件的編寫和編譯,通過JLINK燒錄入STM32開發(fā)板,上電后進行具體的溫度檢測報警功能實現(xiàn)。
2、軟件流程圖
3、軟件代碼實現(xiàn)
(一)主程序如下:
#include "sys.h"
#include "delay.h"
#include "lcd.h"
#include "touch.h"         
#include "usmart.h"  
#include "sdio_sdcard.h"   
#include "w25qxx.h"   
#include "ff.h"  
#include "exfuns.h"   
#include "fontupd.h"
#include "text.h"      
#include "led.h"
#include "bjdj.h"
#include "timer.h"
#include "usart.h"
#include "gizwits_product.h"
#include "string.h"               
#include "tpad.h"
#include "exti.h"
#include "ds18b20.h"
#include”BEEP”
dataPoint_t currentDataPoint;
u8 wifi_sta=0;
int main(void)
{         
        u8 t=0;                           
        short temperature;              
        delay_init();                     //延時函數(shù)初始化         
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷優(yōu)先級分組為組2:2位搶占優(yōu)先級,2位響應優(yōu)先級
        uart_init(115200);                 //串口初始化為 115200
        LED_Init();                                  //初始化與LED連接的硬件接口
        LCD_Init();                                   //初始化LCD  
        while(font_init())                        
        {            
                LCD_ShowString(60,50,240,16,16,"Font Error!");
                delay_ms(200);                                 
                LCD_Fill(60,50,320,66,WHITE);//清除顯示
                delay_ms(200);      
        }
        Show_Str_Mid(40,30,"丁夢周 P21614086",16,240);
        Show_Str_Mid(40,60,"姚學峰 P21614021",16,240);
        Show_Str_Mid(40,90," 洪犇  P21614090",16,240);
        Show_Str_Mid(40,120,"李發(fā)宇 P21614082",16,240);
        while(DS18B20_Init())        //DS18B20初始化      
        {
                LCD_ShowString(120,130,200,16,16,"DS18B20 Error");
                delay_ms(200);
                LCD_Fill(30,130,239,130+16,WHITE);
                delay_ms(200);
        }                                                                  
        POINT_COLOR=BLUE;//設置字體為藍色
        LCD_ShowString(120,150,200,16,16,"Temp:   . C");         
        while(1)
        {                        
                if(t%10==0)                        //每100ms讀取一次
                {                                                                          
                        temperature=DS18B20_Get_Temp();      
                        if(temperature<0)
                        {
                                LCD_ShowChar(120+40,150,'-',16,0);                        //顯示負號
                                temperature=-temperature;                                        //轉為正數(shù)
                        }else LCD_ShowChar(120+40,150,' ',16,0);                        //去掉負號
                        LCD_ShowNum(120+40+8,150,temperature/10,2,16);        //顯示正數(shù)部分            
                           LCD_ShowNum(120+40+32,150,temperature%10,1,16);        //顯示小數(shù)部分
                        if(temperature>300)
                        {
                                LED0=0;
                        }
                        else
                        {
                                LED0=1;
                        }
                }                                 
                 delay_ms(10);
                t++;
        }
}
主程序說明:
在開發(fā)板上電后進行所有模塊及內存進行初始化,初始化后開始進行DSI820溫度傳感器的檢測,采用0.1秒的檢測時間間隔,每次采集的數(shù)據(jù)輸入到內存ROM中作進一步調整,并與固定的值相比較,將比較結果產(chǎn)生的電平通過數(shù)據(jù)總線輸出到相應的串口控制蜂鳴器和LED指示燈的工作狀態(tài),同時調整結束后得到一個十位和個位的非整數(shù)集合,顯示在LCD屏幕之上,數(shù)值根據(jù)周圍溫度變化動態(tài)而變化。
溫度傳感器子程序:
void DS18B20_Rst(void)         
{                 
        DS18B20_IO_OUT();         //SET PG11 OUTPUT
    DS18B20_DQ_OUT=0;         //拉低DQ
    delay_us(750);            //拉低750us
    DS18B20_DQ_OUT=1;         //DQ=1
        delay_us(15);             //15US
}
//等待DS18B20的回應
//返回1:未檢測到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void)           
{   
        u8 retry=0;
        DS18B20_IO_IN();        //SET PG11 INPUT         
    while (DS18B20_DQ_IN&&retry<200)
        {
                retry++;
                delay_us(1);
        };         
        if(retry>=200)return 1;
        else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
        {
                retry++;
                delay_us(1);
        };
        if(retry>=240)return 1;            
        return 0;
}
//從DS18B20讀取一個位
//返回值:1/0
u8 DS18B20_Read_Bit(void)         
{
    u8 data;
        DS18B20_IO_OUT();        //SET PG11 OUTPUT
    DS18B20_DQ_OUT=0;
        delay_us(2);
    DS18B20_DQ_OUT=1;
        DS18B20_IO_IN();        //SET PG11 INPUT
        delay_us(12);
        if(DS18B20_DQ_IN)data=1;
    else data=0;         
    delay_us(50);           
    return data;
}
//從DS18B20讀取一個字節(jié)
//返回值:讀到的數(shù)據(jù)
u8 DS18B20_Read_Byte(void)     
{        
    u8 i,j,dat;
    dat=0;
        for (i=1;i<=8;i++)
        {
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }                                                   
    return dat;
}
//寫一個字節(jié)到DS18B20
//dat:要寫入的字節(jié)
void DS18B20_Write_Byte(u8 dat)     
{            
    u8 j;
    u8 testb;
        DS18B20_IO_OUT();        //SET PG11 OUTPUT;
    for (j=1;j<=8;j++)
        {
        testb=dat&0x01;
        dat=dat>>1;
        if (testb)
        {
            DS18B20_DQ_OUT=0;        // Write 1
            delay_us(2);                           
            DS18B20_DQ_OUT=1;
            delay_us(60);            
        }
        else
        {
            DS18B20_DQ_OUT=0;        // Write 0
            delay_us(60);            
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}
//開始溫度轉換
void DS18B20_Start(void)
{                                                                 
    DS18B20_Rst();         
        DS18B20_Check();         
    DS18B20_Write_Byte(0xcc);        // skip rom
    DS18B20_Write_Byte(0x44);        // convert
}
//初始化DS18B20的IO口 DQ 同時檢測DS的存在
//返回1:不存在
//返回0:存在            
u8 DS18B20_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
      
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);         //使能PORTG口時鐘
      
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;                                //PORTG.11 推挽輸出
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOG, &GPIO_InitStructure);
        GPIO_SetBits(GPIOG,GPIO_Pin_11);    //輸出1
        DS18B20_Rst();
        return DS18B20_Check();
}  
//從ds18b20得到溫度值
//精度:0.1C
//返回值:溫度值 (-550~1250)
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
        short tem;
    DS18B20_Start ();                          // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();         
    DS18B20_Write_Byte(0xcc);        // skip rom
    DS18B20_Write_Byte(0xbe);        // convert            
    TL=DS18B20_Read_Byte();         // LSB   
    TH=DS18B20_Read_Byte();         // MSB  
                     
if(TH>7)                    
    {   TH=~TH;
        TL=~TL;
        temp=0;                                        //溫度為負  
    }else temp=1;                                //溫度為正                    
    tem=TH;                                         //獲得高八位
    tem<<=8;   
    tem+=TL;                                        //獲得底八位
    tem=(float)tem*0.625;                //轉換     
        if(temp)return tem;                 //返回溫度值
        else return -tem;   
}
子程序簡要說明:
由于傳輸線只有一根,即(DQ),系統(tǒng)經(jīng)歷了一段至少420us的低電平(ds1820溫度傳稿器端輸出信息至MCU),釋放總線并初始化,MCU形成了一個最少為15us-60us的上升沿脈沖輸出至傳感器,此時DS1820溫度傳感器處于相應MCU輸出信號的狀態(tài),若DS1820工作模式正常,便會產(chǎn)生一個60~240us級的低電平信號,并發(fā)送至MCU,此過程便是兩端通信的建立過程。
當接收建立后,由溫度傳感器進行間隔0.1秒的動態(tài)讀取數(shù)據(jù),并串行輸入至MCU的內存中,經(jīng)過按位取或的移位操作,將串行數(shù)據(jù)變?yōu)?6位二進制數(shù)儲存在TH,TL寄存器中,當TH高5位出現(xiàn)1時,判定為負數(shù),取反,未出現(xiàn)1,判定為正數(shù)并將TH及高八位賦給tem。將得到的tem值進行擴展,移位展寬成16位的二進制數(shù)后,通過乘與0.625完成16進制到10進制的轉換。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表