在本教程中,我們將使用 PIC 微控制器和 LM35 溫度傳感器制作數(shù)字溫度計。在本項目中,我們將使用 LM35 檢測溫度并將其顯示在 16x2 LCD 上。LM35 溫度傳感器準確且成本低廉,無需任何外部校準。輸出電壓與攝氏溫標成正比,每°C變化10mV。
所需材料
圖片套件 3
LM35 溫度傳感器
16 * 2液晶顯示器
PIC16F877A 集成電路
40 - 引腳 IC 支架
性能板
20 MHz 晶體 OSC
內螺紋和外螺紋伯格斯圖銷
33pf 電容器 - 2 個電容、100uf 和 10uf 電容。
680 歐姆、220 歐姆、10K 和 560 歐姆電阻器
電位器 10k
任何顏色的發(fā)光二極管
1 焊接套件
集成電路 7805
12V 適配器
連接線
面包板
LM35 溫度傳感器:
LM35 溫度傳感器具有零失調電壓,這意味著在 0°C 時輸出將為 0V。它可以處理的最大電壓為1.5V,這意味著它可以檢測150°C(1.5V / 10mV)的最高溫度。
引腳編號 | 功能 | 名字 |
1 | 電源電壓;5V (+35V 至 -2V) | Vcc |
2 | 輸出電壓(+6V至-1V) | 輸出 |
3 | 接地 (0V) | 地 |
我們已經(jīng)將LM35與許多其他微控制器一起使用來測量溫度:
正如我們已經(jīng)說過的,LM35 提供模擬輸出,因此首先我們需要使用 PIC 微控制器讀取該模擬值,然后我們將使用 ADC(模數(shù)轉換)將它們轉換為數(shù)字值。因此,在進一步討論之前,我們將學習PIC微控制器中的ADC。
PIC 微控制器 PIC16F877A 中的 ADC:
有許多類型的ADC可用,每種都有自己的速度和分辨率。最常見的ADC類型是閃存、逐次逼近和Σ-Δ。PIC16F877A中使用的ADC類型簡稱為逐次逼近型ADC或SAR。因此,在開始使用SAR ADC之前,讓我們先了解一下它。
逐次逼近型 ADC:SAR ADC在比較器和一些邏輯對話的幫助下工作。這種類型的ADC使用基準電壓(可變的),并使用比較器將輸入電壓與基準電壓進行比較,并從最高有效位(MSB)中保存差值(數(shù)字輸出)。比較的速度取決于PIC運行的時鐘頻率(Fosc)。
現(xiàn)在我們了解了ADC的一些基礎知識,讓我們打開數(shù)據(jù)手冊,了解如何在PIC16F877A MCU上使用ADC。我們使用的PIC具有10位8通道ADC。這意味著我們的ADC的輸出值將為0-1024(2^10),并且我們的MCU上有8個引腳(通道)可以讀取模擬電壓。值 1024 由 2^10 獲得,因為我們的 ADC 是 10 位。數(shù)據(jù)表中提到了可以讀取模擬電壓的八個引腳。讓我們看看下面的圖片。
模擬通道 AN0 到 AN7 已為您突出顯示。只有這些引腳才能讀取模擬電壓。因此,在讀取輸入電壓之前,我們必須在代碼中指定必須使用哪個通道來讀取輸入電壓。在本教程中,我們將使用帶有電位計的通道4來讀取該通道的模擬電壓。
A/D 模塊有四個寄存器,必須配置為從輸入引腳讀取數(shù)據(jù)。這些寄存器是:
? A/D 結果高寄存器 (ADRESH)
? A/D 結果低寄存器 (ADRESL)
? A/D 控制寄存器 0 (ADCON0)
? 模數(shù)控制寄存器 1 (ADCON1)
代碼和說明
最后給出了使用LM35和PIC微控制器的數(shù)字溫度計的完整代碼。該代碼是用注釋行自我解釋的,只涉及將LCD與PIC微控制器連接的概念,以及在PIC微控制器中使用ADC模塊的概念,我們已經(jīng)在之前的PIC微控制器學習教程中介紹過。
在這里,我們僅顯示從LM35讀取模擬輸出電壓然后將其轉換為溫度值的計算。因此,這里我們將LM35的ADC值轉換為電壓,然后將電壓值轉換為溫度。因此,在獲得值后,我們將每個字符分開以顯示在LCD上。
adc = (ADC_Read(4)); // Reading ADC values
volt = adc*4.88281; // Convert it into the voltage
temp=volt/10.0; // Getting the temperature values
temp1 = temp*100;
c1 = (temp1/1000)%10;
c2 = (temp1/100)%10;
c3 = (temp1/10)%10;
c4 = (temp1/1)%10;
現(xiàn)在在下面的代碼中,設置LCD光標,然后打印輸出值
Lcd_Clear();
Lcd_Set_Cursor(1,3);
Lcd_Print_String("Temperature");
Lcd_Set_Cursor(2,5);
Lcd_Print_Char(c1+'0');
Lcd_Print_Char(c2+'0');
Lcd_Print_String(".");
Lcd_Print_Char(c3+'0');
Lcd_Print_Char(c4+'0');
Lcd_Print_Char(0xDF);
Lcd_Print_String("C");
__delay_ms(3000);
數(shù)字溫度計的工作原理
將代碼上傳到PIC微控制器后,使用12v適配器為電路上電。LM35 溫度傳感器的模擬輸出被饋送到 PIC 控制器的模擬輸入通道。隨著溫度的升高,ADC值也會增加。該ADC值通過乘以4.88281進一步轉換為電壓。然后將電壓值轉換為相應的字符,以將其顯示到16 * 2 LCD中。
#define _XTAL_FREQ 20000000
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7
#include
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void ADC_Initialize()
{
ADCON0 = 0b01000001; //ADC ON and Fosc/16 is selected
ADCON1 = 0b11000000; // Internal reference voltage is selected
}
unsigned int ADC_Read(unsigned char channel)
{
ADCON0 &= 0x11000101; //Clearing the Channel Selection Bits
ADCON0 |= channel<<3; //Setting the required Bits?
__delay_ms(2); //Acquisition time to charge hold capacitor
GO_nDONE = 1; //Initializes A/D Conversion
while(GO_nDONE); //Wait for A/D Conversion to complete
return ((ADRESH<<8)+ADRESL); //Returns Result?
}
//LCD Functions Developed by Circuit Digest.
void Lcd_SetBit(char data_bit) //Based on the Hex value Set the Bits of the Data Lines
{
if(data_bit& 1)
D4 = 1;
else
D4 = 0;
if(data_bit& 2)
D5 = 1;
else
D5 = 0;
if(data_bit& 4)
D6 = 1;
else
D6 = 0;
if(data_bit& 8)
D7 = 1;
else
D7 = 0;
}
void Lcd_Cmd(char a)
{
RS = 0;
Lcd_SetBit(a); //Incoming Hex value
EN = 1;
__delay_ms(4);
EN = 0;
}
Lcd_Clear()
{
Lcd_Cmd(0); //Clear the LCD
Lcd_Cmd(1); //Move the curser to first position
}
void Lcd_Set_Cursor(char a, char b)
{
char temp,z,y;
if(a== 1)
{
temp = 0x80 + b - 1; //80H is used to move the curser
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
else if(a== 2)
{
temp = 0xC0 + b - 1;
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
}
void Lcd_Start()
{
Lcd_SetBit(0x00);
for(int i=1065244; i<=0; i--) ?NOP(); ??
Lcd_Cmd(0x03);
__delay_ms(5);
Lcd_Cmd(0x03);
__delay_ms(11);
Lcd_Cmd(0x03);
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x08); //Select Row 1
Lcd_Cmd(0x00); //Clear Row 1 Display
Lcd_Cmd(0x0C); //Select Row 2
Lcd_Cmd(0x00); //Clear Row 2 Display
Lcd_Cmd(0x06);
}
void Lcd_Print_Char(char data) //Send 8-bits through 4-bit mode
{
char Lower_Nibble,Upper_Nibble;
Lower_Nibble = data&0x0F;
Upper_Nibble = data&0xF0;
RS = 1; // => RS = 1
Lcd_SetBit(Upper_Nibble>>4); //Send upper half by shifting by 4
EN = 1;
for(int i=2130483; i<=0; i--) ?NOP(); ?
EN = 0;
Lcd_SetBit(Lower_Nibble); //Send Lower half
EN = 1;
for(int i=2130483; i<=0; i--) ?NOP();?
EN = 0;
}
void Lcd_Print_String(char *a)
{
int i;
for(i=0;a[i]!='';i++)
Lcd_Print_Char(a[i]); //Split the string using pointers and call the Char function
}
int main()
{
float adc;
float volt, temp;
int c1, c2, c3, c4, temp1;
ADC_Initialize();
unsigned int a;
TRISD = 0x00;
Lcd_Start();
while(1)
{
adc = (ADC_Read(4)); // Reading ADC values
volt = adc*4.88281; // Convert it into the voltage
temp=volt/10.0; // Getting the temperature values
temp1 = temp*100;
c1 = (temp1/1000)%10;
c2 = (temp1/100)%10;
c3 = (temp1/10)%10;
c4 = (temp1/1)%10;
Lcd_Clear();
Lcd_Set_Cursor(1,3);
Lcd_Print_String("Temperature");
Lcd_Set_Cursor(2,5);
Lcd_Print_Char(c1+'0');
Lcd_Print_Char(c2+'0');
Lcd_Print_String(".");
Lcd_Print_Char(c3+'0');
Lcd_Print_Char(c4+'0');
Lcd_Print_Char(0xDF);
Lcd_Print_String("C");
__delay_ms(3000);
}
return 0;
}
-
微控制器
+關注
關注
48文章
7559瀏覽量
151480 -
溫度傳感器
+關注
關注
48文章
2941瀏覽量
156111 -
PIC
+關注
關注
8文章
507瀏覽量
87591 -
LM35
+關注
關注
2文章
83瀏覽量
18127 -
數(shù)字溫度計
+關注
關注
3文章
108瀏覽量
21732
發(fā)布評論請先 登錄
相關推薦
評論