發布日期:2022-10-09 點擊率:58
1、首先完成Proteus的安裝以及Arduino庫的安裝和引入。(參考此前教程)
2、新建一個 Arduino工程。點擊左上角的File——New Project,選擇Arduino 328開發板。
3、工作區中出現Arduino的原理圖。現在開始添加功能電路——添加溫度傳感器 DHT11。
點擊左側的P,選擇元件。
4、在彈出的對話框中,輸入DHT11,如下圖:
選擇右側的 DHT11,點擊右下角的OK
5、回到工作區的原理圖位置,空白處點擊鼠標左鍵,出現粉紅色的待放置元件,再次點擊左鍵。完成元件的放置。
6、完成DHT11的連線工作。(電源VDD,接地GND,數據DATA)
6.1接電源線。
左側點擊“Terminal Mode”——“Power”
在工作區,放置一個電源端子,并完成與VDD的連線。
6.2 接地。類似于電源端子的連接,“Terminal Mode”——“GROUND”。
6.3 數據接線。選擇DEFAULT端子,完成與DATA接線口的連接。如下面兩個圖。
6.4 修改DEFAULT端子的屬性。右鍵該端子,選擇編輯屬性。在String處,填寫IO2.點確定。
7、增加串口模塊。
同樣的在設備庫中(Pick Devices),搜索 COMPIM
8、放置COMPIM串口模塊,并完成連線。如下圖。
9、再放置虛擬終端,來觀察串口輸出的數據。
在左側工具欄,選擇“INSTRUMENTS”——VIRTUAL TERMINAL。
并完成連線如下圖。
10、編寫Arduino代碼。進入Source Code模式,編寫如下代碼:
11、將課堂發送給大家的DHT11的庫文件,解壓后放置在Arduino安裝目錄下的Libraris目錄下。(DHT11庫文件也可以到FTP上下載)
11.1找到自己的Arduino安裝目錄。
點擊Proteus的System——Compilers Configuration,找到Arduino AVR(Proteus)和Arduino AVR兩個。
11.2 將DHT11庫文件放到這兩個目錄的Libraries下。如下圖:(兩個都放一下)
12、開始編譯運行。
點擊左下角的三角箭頭,開始編譯仿真運行。如果代碼編譯成功,會顯示 Compiled Successfully.
13、仿真成功。顯示DHT11讀取的數據。虛擬終端會顯示從串口讀來的數據。
14、修改傳感器的值,查看讀取數據的情況。
首先要關閉仿真。點擊左下角的方塊鍵。
然后在設計圖中,右鍵DHT11傳感器,點擊“編輯屬性”Edit Properties
修改其中的Actual Humidity(濕度值)和Actual Temp(溫度值),點擊“OK”
再次仿真運行,查看結果。溫濕度傳感器仿真實驗 第1張" title="proteus濕度傳感器:Proteus 基于Arduino DHT11溫濕度傳感器仿真實驗 第1張-傳感器知識網"/>
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
使用1602顯示DHT22的溫濕度,精確到小數點的后一位
//
// DHT21使用范例
//單片機 AT89S52 或 STC89C52RC
//功能 串口發送溫濕度數據 晶振 11.0592M 波特率 9600
//硬件 P2.0口為通訊口連接DHT22,DHT22的電源和地連接單片機的電源和地,單片機串口加MAX232連接電腦
//
#include
一、傳感器概述
SHT10型傳感器屬于SHT1×系列(其他常用型號還有SHT11、SHT15),SHT1×屬于Sensirion溫濕度傳感器家族中的貼片封裝系列。傳感器將傳感元件和信號處理電路集成在一塊微型電路板上,輸出完全標定的數字信號。傳感器采用專利的CMOSens技術,確保產品具有極高的可靠性與卓越的長期穩定性。傳感器包括一個電容性聚合體測濕敏感元件、一個用能隙材料制成的測溫元件以及串行接口電路實現無縫連接。因此,該產品具有品質優越、響應迅速、抗干擾能力強、性價比高等優點。本篇博文將詳細分析傳感器的工作時序并根據時序編寫驅動程序。最終,該驅動程序將通過Proteus仿真軟件進行仿真驗證。
?
二、傳感器尺寸
?
三、接口定義及電源引腳
(一)接口定義
(二)電源引腳
SHT10的供電電壓范圍為2.3-5.5V,建議供電電壓為3.3V。在電源引腳(VDD與GND)之間必須加一個100nF的電容,用于去耦濾波(在仿真中可加可不加)
SHT10的串行接口,在傳感器信號的讀取及電源損耗方面,都做了優化處理;傳感器不能按照I2C協議進行編址,但是,如果I2C總線上沒有掛在別的原件則傳感器可以掛載到I2C總線上,但是單片機與傳感器之間的通信協議不能采用I2C協議,而是要在按照傳感器的協議進行信息交互。
?
四、傳感器電氣特性
傳感器的電氣特性(如:高/低電平、輸入/輸出電壓等)受供電電壓的影響,下表中的參數在沒有特殊說明情況下均代表在5V供電條件下的參數。
下列時序圖中,加粗的DATA線由傳感器控制,普通的DATA線由單片機控制,有效時間由SCK的時序決定。尤其要注意的是,數據讀取的有效時間為前一個切換的下降沿。
? ? ?
?
五、傳感器的通訊過程及對應的驅動程序
(一)啟動傳感器
首先,選擇供電電壓后將傳感器通電,商店速率不能低于1V/ms。通電后傳感器需要有11ms進入休眠狀態,在此之前,不允許單片機對傳感器發送任何命令。
在休眠狀態之后,要用一組“啟動傳輸”時序。來完成數據傳輸的初始化。該”啟動傳輸”時序包括:當SCK時鐘為高電平時,DATA由高電平反轉為低電平,隨后是在SCK高電平時DATA由低電平反轉為高電平。具體時序圖如下:
由上述時序圖,可以得到“啟動傳輸”的驅動程序如下:
(二)命令集及“寫一字節”程序
在啟動程序之后,后續命令包括三個地址位(目前只支持000)和五個命令位。SHT10會以下述方式表示已正確接收指令:在第八個SCK的下降沿之后將DATA下拉為低電平作為ACK位,并在第九個SCK時鐘的下降沿之后釋放DATA(恢復高電平)。SHT10的命令集如下圖所示。
根據已知命令集,即可通過單總線向傳感器發送命令。發送濕度測量命令的工作時序如下圖所示:
通過上述時序圖所展示的“發送一字節”的工作時序,在“發送一字節數據”的驅動程序中可以采取的思路為:數據線先傳送高位后傳送低位,取位的方式為mask=0x80與命令值value進行“相與”,之后通過mask<<=1配合循環操作,即可實現將命令值由高位向低位逐位取出。在每取出value的一位后,首先延時一個_op_()? (在12MHz的工作頻率下為1us),使DATA引腳能夠建立起穩定的電平,然后使sck產生上升沿并延時兩個_nop_(),使傳感器讀入DATA引腳的數據,然后再恢復sck引腳的低電平,依次循環八次,使傳感器讀入一字節的命令數據。在讀完八位數據之后,使SCK變高電平并檢測DATA引腳是否拉低,以檢測傳感器是否發出了確認信息ACK。然后,再將SCK恢復為低電平。具體驅動程序如下:
(三)“讀一字節”驅動程序
在發布完一組測量命令之后,單片機要等待測量結束,這個過程大約需要10/80/120ms,分別對應8/12/14bit測量,確切時間由內部晶振速度決定,最多有-30%的變化。SHT10通過下拉DATA至電平并進入空閑模式表示測量結束。單片機在再次觸發SCK時鐘前必須等待這個“數據備妥”信號來讀出數據。(默認溫度測量14bit,濕度測量12bit),另外,還有一字節的CRC,用于循環冗余校驗。濕度測量時序圖如下:
根據上述濕度測量時序圖可以類推溫度測量時序圖(區別在于默認情況下溫度值比濕度值多2bit),并由時序圖可寫出具體控制時序,如下:
?
六、測量結果轉換
測量結果轉換過程中使用的參數與供電電壓有關,總控制程序中的轉換代碼僅適用于5V供電時進行轉換,其他工作電壓下的轉換關系如下圖所示:
?
七、總控制程序
八、Proteus仿真圖的連接及結果
?
?
?
?
左肩理想右肩擔當,君子不怨永遠不會停下腳步!
?
?
?
?
?
?
?
?
?
?
?
我最近做項目,接觸到了sht11溫濕度傳感器,分享給大家
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
#include
void LCD_init(void)
{
delay_n10us(10);
LCD_write_command(0x38);//設置8位格式,2行,5x7
delay_n10us(10);
LCD_write_command(0x0c);//整體顯示,關光標,不閃爍
delay_n10us(10);
LCD_write_command(0x06);//設定輸入方式,增量不移位
delay_n10us(10);
LCD_write_command(0x01);//清除屏幕顯示
delay_n10us(100); //延時清屏,延時函數,延時約n個10us
}
void LCD_write_command(uchar dat)
{
delay_n10us(10);
LCD_RS=0; //指令
LCD_RW=0; //寫入
LCD_E=1; //允許
LCD_DB=dat;
delay_n10us(10); //實踐證明,我的LCD1602上,用for循環1次就能完成普通寫指令。
LCD_E=0;
delay_n10us(10); //實踐證明,我的LCD1602上,用for循環1次就能完成普通寫指令。
}
void LCD_write_data(uchar dat)
{
delay_n10us(10);
LCD_RS=1; //數據
LCD_RW=0; //寫入
LCD_E=1; //允許
LCD_DB=dat;
delay_n10us(10);
LCD_E=0;
delay_n10us(10);
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
LCD_write_data(dat);
}
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
LCD_write_command(address);
while(*str!='?')
{
LCD_write_data(*str);
str++;
}
}
void delay_n10us(uint n) //延時n個10us@12M晶振
{
uint i;
for(i=n;i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
/
void s_transstart(void); //啟動傳輸函數
void s_connectionreset(void); //連接復位函數
char s_write_byte(unsigned char value);//DHT90寫函數
char s_read_byte(unsigned char ack); //DHT90讀函數
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//測量溫濕度函數
void calc_dht90(float *p_humidity ,float *p_temperature);//溫濕度補償
void s_transstart(void)
// generates a transmission start
// _____ ________
// data: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1; SCK=0; //Initial state
_nop_();
SCK=1;
_nop_();
DATA=0;
_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();
DATA=1;
_nop_();
SCK=0;
}
void s_connectionreset(void)
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// data: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
DATA=1; SCK=0; //Initial state
for(i=0;i
char s_read_byte(unsigned char ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
DATA=1; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{ SCK=1; //clk for SENSI-BUS
if (DATA) val=(val | i); //read bit
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=0;
}
if(ack==1)DATA=0; //in case of "ack==1" pull down DATA-Line
else DATA=1; //如果是校驗(ack==0),讀取完后結束通訊
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=1; //clk #9 for ack
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
SCK=0;
_nop_();_nop_();_nop_(); //pulswith approx. 3 us
DATA=1; //release DATA-line
return val;
}
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
// makes a measurement (humidity/temperature) with checksum
{
unsigned error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i
下一篇: PLC、DCS、FCS三大控
上一篇: 電氣控制線路圖控制原