|
一、硬件管理
1、STM32開發(fā)板簡介··························· 3
2、DS1820數(shù)字溫度計···························3
3、3.5寸液晶LCD顯示屏·························4
4、硬件整體實物圖···························5
二、軟件方案
1、設(shè)計思路····································5
2、軟件流程圖··································5
3、軟件代碼實現(xiàn)·································6
(1)主程序?qū)崿F(xiàn)····························6
(2)溫度傳感器子程序·························9
三、工程訓(xùn)練小結(jié)·································12
一、硬件管理
1、STM32開發(fā)板簡介
STM32系列單片機是意法半導(dǎo)體集團生產(chǎn)的一種基于專為要求高性能、低成本、低功耗的嵌入式應(yīng)用專門設(shè)計的ARM Cortex-M3內(nèi)核。體現(xiàn)了現(xiàn)代單片機為控制器發(fā)展的新趨勢,目前深受用戶歡迎,正在逐漸成為單片機世界的新潮流。從STM32系列單片機的問世到快速普及,
并為業(yè)界廣為采用,最主要的原因是它具有完整的單片機系列芯片,可以讓使用者根據(jù)不同的需求,選擇最合適的單片機芯片。
STM32,有非常豐富的外設(shè)與內(nèi)設(shè)資源,一般單片機內(nèi)存相對比較小,沒辦法移入大量程序,而STM32集成了32512KB的內(nèi)存和,6~64KB的靜態(tài)存儲器,可以放足夠大的代碼,不用擔(dān)心內(nèi)存溢出。并且內(nèi)部集成了2個12位的us級的A/D轉(zhuǎn)換器和12位D/A轉(zhuǎn)換器,開發(fā)者并不需要外接模數(shù)或數(shù)模轉(zhuǎn)換芯片來額外增加成本。STM32系列有上百個I/O口和多個外部中斷向量,通過配置寄存器,可以將端口映射到這些向量上。另外,STM32有豐富的通信接口:IIC、USART、SPI、IIS、CAN、USB2.0和SDIO。這些資源是32位單片機所不具有的,足夠的資源使得它的開發(fā)空間也更加強大。
本項目涉及范圍廣,功能相對比較多,所以主控芯片必須得具有足夠的外設(shè)接口,高速的處理速度和較高的性價比。單片機由于自身條件的限制,無法滿足此項目的要求。因此,本項目選用的是性能優(yōu)異,廉價,功耗低,并屬于STM32系列的STM32F103VCT6芯片。STM32具有32位單片機所有的優(yōu)點,并且,價格上也比較低,所以比較適合應(yīng)用于智能產(chǎn)品。STM32F103微控制器作為智能化環(huán)境檢測調(diào)節(jié)裝置的核心,核心算法以及所有的控制算法和控制命令,都由STM32F103單片機完成。STM32F103最小系統(tǒng)包括晶振電路、復(fù)位電路、電源電路。
2、DSl820 數(shù)字溫度計
DSl820數(shù)字溫度計提供 9 位溫度讀數(shù),指示器件的溫度。信息經(jīng)過單線接口送入 DSl820 或從 DSl820 送出,因此從中央處理器到 DSl820 僅需連接一條線(和地)。
讀、寫和完成溫度變換所需的電源可以由數(shù)據(jù)線本身提供,而不需要外部電源。因為每一個 DSl820 有唯一的系列號(silicon serial number),因此多個 DSl820 可以存在于同一條單線總線上。這允許在許多不同的地方放置溫度靈敏器件。此特性的應(yīng)用范圍包括 HVAC 環(huán)境控制,建筑物、設(shè)備或機械內(nèi)的溫度檢測,以及過程監(jiān)視和控制中的溫度檢測。
具體連線:PG11(STM32)~DQ(DS1820)
3、3、3.5寸液晶LCD顯示屏
連接方案:排線插針對準(zhǔn)開發(fā)板相應(yīng)LCD排針插口即可
4、硬件整體實物圖
二、軟件方案
1、設(shè)計思路
本工程設(shè)計采用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);//設(shè)置中斷優(yōu)先級分組為組2:2位搶占優(yōu)先級,2位響應(yīng)優(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,"姚學(xué)峰 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;//設(shè)置字體為藍(lán)色
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); //顯示負(fù)號
temperature=-temperature; //轉(zhuǎn)為正數(shù)
}else LCD_ShowChar(120+40,150,' ',16,0); //去掉負(fù)號
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ā)板上電后進行所有模塊及內(nèi)存進行初始化,初始化后開始進行DSI820溫度傳感器的檢測,采用0.1秒的檢測時間間隔,每次采集的數(shù)據(jù)輸入到內(nèi)存ROM中作進一步調(diào)整,并與固定的值相比較,將比較結(jié)果產(chǎn)生的電平通過數(shù)據(jù)總線輸出到相應(yīng)的串口控制蜂鳴器和LED指示燈的工作狀態(tài),同時調(diào)整結(jié)束后得到一個十位和個位的非整數(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的回應(yīng)
//返回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);
}
}
}
//開始溫度轉(zhuǎn)換
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; //溫度為負(fù)
}else temp=1; //溫度為正
tem=TH; //獲得高八位
tem<<=8;
tem+=TL; //獲得底八位
tem=(float)tem*0.625; //轉(zhuǎn)換
if(temp)return tem; //返回溫度值
else return -tem;
}
子程序簡要說明:
由于傳輸線只有一根,即(DQ),系統(tǒng)經(jīng)歷了一段至少420us的低電平(ds1820溫度傳稿器端輸出信息至MCU),釋放總線并初始化,MCU形成了一個最少為15us-60us的上升沿脈沖輸出至傳感器,此時DS1820溫度傳感器處于相應(yīng)MCU輸出信號的狀態(tài),若DS1820工作模式正常,便會產(chǎn)生一個60~240us級的低電平信號,并發(fā)送至MCU,此過程便是兩端通信的建立過程。
當(dāng)接收建立后,由溫度傳感器進行間隔0.1秒的動態(tài)讀取數(shù)據(jù),并串行輸入至MCU的內(nèi)存中,經(jīng)過按位取或的移位操作,將串行數(shù)據(jù)變?yōu)?6位二進制數(shù)儲存在TH,TL寄存器中,當(dāng)TH高5位出現(xiàn)1時,判定為負(fù)數(shù),取反,未出現(xiàn)1,判定為正數(shù)并將TH及高八位賦給tem。將得到的tem值進行擴展,移位展寬成16位的二進制數(shù)后,通過乘與0.625完成16進制到10進制的轉(zhuǎn)換。
|
|