• Temperature Measurement using LM35 and AVR Microcontroller - Đo nhiệt độ sử dụng LM35 và Vi điều khiển AVR

QC

Temperature Measurement using LM35 and AVR Microcontroller - Đo nhiệt độ sử dụng LM35 và Vi điều khiển AVR

  Temperature Measurement using LM35 and AVR Microcontroller - Đo nhiệt độ sử dụng LM35 và Vi điều khiển AVR


Trong dự án này, chúng tôi sẽ thiết kế một mạch để đo nhiệt độ. Mạch này được phát triển bằng cách sử dụng “LM35”, một cảm biến điện áp tuyến tính. Nhiệt độ thường được đo bằng “Centigrade” hoặc “Faraheite”. Cảm biến “LM35” cung cấp đầu ra dựa trên quy mô độ phân giải.


LM35 là thiết bị bóng bán dẫn ba chân giống như thiết bị. Nó có VCC, GND và OUTPUT. Cảm biến này cung cấp điện áp thay đổi ở đầu ra dựa trên nhiệt độ.



Như thể hiện trong hình trên, cứ mỗi độ tăng nhiệt độ +1 độ C sẽ có đầu ra cao hơn + 10mV. Vì vậy, nếu nhiệt độ là 0 độ C đầu ra của cảm biến sẽ là 0V, nếu nhiệt độ là 10 độ C đầu ra của cảm biến sẽ là + 100mV, nếu nhiệt độ là 25 độ C đầu ra của cảm biến sẽ là + 250mV.


Vì vậy, bây giờ với LM35, chúng tôi nhận được nhiệt độ ở dạng điện áp thay đổi. Điện áp phụ thuộc vào nhiệt độ này được cung cấp làm đầu vào cho ADC (Bộ chuyển đổi tương tự sang kỹ thuật số) của ATMEGA32A. Giá trị kỹ thuật số sau khi chuyển đổi thu được được hiển thị trên màn hình LCD 16x2 dưới dạng nhiệt độ.


Components Required

Hardware: ATMEGA32 Microcontroller, power supply (5v), AVR-ISP PROGRAMMER, JHD_162ALCD (16x2LCD), 100uF capacitor (two pieces), 100nF capacitor, LM35 Temperature Sensor.

Software: Atmel studio 6.1, progisp or flash magic.

Circuit Diagram and Explanation



Trong mạch, PORTB của ATMEGA32 được kết nối với cổng dữ liệu của LCD. Ở đây, người ta nên nhớ vô hiệu hóa giao tiếp JTAG trong PORTC ot ATMEGA bằng cách thay đổi các byte cầu chì, nếu người ta muốn sử dụng PORTC như một cổng giao tiếp thông thường. Trong LCD 16x2 có 16 chân trên tất cả nếu có đèn nền, nếu không có đèn nền sẽ có 14 chân. Người ta có thể cấp nguồn hoặc để lại các chân đèn phía sau. Bây giờ trong 14 chân có 8 chân dữ liệu (7-14 hoặc D0-D7), 2 chân cấp nguồn (1 & 2 hoặc VSS & VDD hoặc gnd & + 5v), chân thứ 3 để điều khiển độ tương phản (VEE-điều khiển độ dày của các ký tự sẽ được hiển thị ), 3 chân điều khiển (RS & RW & E).


Trong mạch, bạn có thể quan sát tôi chỉ lấy hai chân điều khiển vì điều này cho phép hiểu rõ hơn về tính linh hoạt. Bit tương phản và READ / WRITE không thường xuyên được sử dụng để chúng có thể được nối đất. Điều này đặt màn hình LCD ở chế độ đọc và độ tương phản cao nhất. Chúng ta chỉ cần điều khiển các chân ENABLE và RS để gửi các ký tự và dữ liệu cho phù hợp.


Các kết nối được thực hiện cho LCD được đưa ra dưới đây:


PIN1 hoặc VSS ------------------ mặt đất


PIN2 hoặc VDD hoặc VCC ------------ Nguồn + 5v


PIN3 hoặc VEE --------------- mặt đất (mang lại độ tương phản tối đa tốt nhất cho người mới bắt đầu)


PIN4 hoặc RS (Lựa chọn đăng ký) --------------- PD6 của uC


PIN5 hoặc RW (Đọc / Ghi) ----------------- mặt đất (đặt màn hình LCD ở chế độ đọc giúp giảm bớt giao tiếp cho người dùng)


PIN6 hoặc E (Bật) ------------------- PD5 của uC


PIN7 hoặc D0 ----------------------------- PB0 của uC


PIN8 hoặc D1 ----------------------------- PB1 của uC


PIN9 hoặc D2 ----------------------------- PB2 của uC


PIN10 hoặc D3 ----------------------------- PB3 của uC


PIN11 hoặc D4 ----------------------------- PB4 của uC


PIN12 hoặc D5 ----------------------------- PB5 của uC


PIN13 hoặc D6 ----------------------------- PB6 của uC


PIN14 hoặc D7 ----------------------------- PB7 của uC


Trong mạch các bạn có thể thấy chúng ta đã sử dụng giao tiếp 8bit (D0-D7) tuy nhiên đây không phải là điều bắt buộc, chúng ta có thể sử dụng giao tiếp 4bit (D4-D7) nhưng với 4 bit chương trình giao tiếp hơi phức tạp nên mình đã chọn 8 bit. liên lạc.


Vì vậy, từ quan sát đơn thuần từ bảng trên, chúng ta đang kết nối 10 chân của LCD với bộ điều khiển, trong đó 8 chân là chân dữ liệu và 2 chân để điều khiển. Đầu ra điện áp được cung cấp bởi cảm biến không hoàn toàn tuyến tính; nó sẽ là một trong những ồn ào. Để lọc tiếng ồn, một tụ điện cần được đặt ở đầu ra của cảm biến như trong hình.


Trước khi tiếp tục, chúng ta cần nói về ADC của ATMEGA32A. Trong ATMEGA32A, chúng tôi có thể cung cấp đầu vào Analog cho bất kỳ kênh nào trong số tám kênh của PORTA, không quan trọng chúng tôi chọn kênh nào vì tất cả đều giống nhau. Chúng tôi sẽ chọn kênh 0 hoặc mã PIN0 của PORTA. Trong ATMEGA32A, ADC có độ phân giải 10 bit, vì vậy bộ điều khiển có thể phát hiện ra sự thay đổi tối thiểu của Vref / 2 ^ 10, vì vậy nếu điện áp tham chiếu là 5V, chúng tôi nhận được mức tăng đầu ra kỹ thuật số cho mỗi 5/2 ^ 10 = 5mV . Vì vậy, với mỗi mức tăng 5mV ở đầu vào, chúng ta sẽ có mức tăng là một ở đầu ra kỹ thuật số.


Bây giờ chúng ta cần thiết lập sổ đăng ký ADC dựa trên các điều khoản sau:


1. Trước hết chúng ta cần kích hoạt tính năng ADC trong ADC.


2. Vì chúng tôi đang đo nhiệt độ phòng, chúng tôi không thực sự cần các giá trị vượt quá hàng trăm độ (đầu ra 1000mV của LM35). Vì vậy, chúng tôi có thể thiết lập giá trị lớn nhất hoặc tham chiếu của ADC đến 2,5V.


3. Bộ điều khiển có tính năng chuyển đổi trình kích hoạt, có nghĩa là chuyển đổi ADC chỉ diễn ra sau trình kích hoạt bên ngoài, vì chúng tôi không muốn rằng chúng tôi cần đặt các đăng ký để ADC chạy ở chế độ chạy tự do liên tục.


4. Đối với bất kỳ bộ ADC nào, tần số chuyển đổi (giá trị Tương tự sang giá trị Kỹ thuật số) và độ chính xác của đầu ra kỹ thuật số tỷ lệ nghịch. Vì vậy, để có độ chính xác tốt hơn của đầu ra kỹ thuật số, chúng ta phải chọn tần số thấp hơn. Đối với đồng hồ ADC nhỏ hơn, chúng tôi đang đặt giá trị đặt trước của ADC thành giá trị lớn nhất (128). Vì chúng tôi đang sử dụng đồng hồ bên trong 1MHZ, đồng hồ của ADC sẽ là (1000000/128).


Đây là bốn điều duy nhất chúng ta cần biết để bắt đầu với ADC. Tất cả bốn tính năng trên được thiết lập bởi hai thanh ghi.



ĐỎ (ADEN): Bit này phải được đặt để kích hoạt tính năng ADC của ATMEGA.


BLUE (REFS1, REFS0): Hai bit này được sử dụng để đặt điện áp tham chiếu (hoặc điện áp đầu vào tối đa mà chúng tôi sẽ cung cấp). Vì chúng ta muốn có điện áp tham chiếu 2,56V, nên cả hai REFS0 và REFS1 đều phải được đặt theo bảng.



LIGHT GREEN (ADATE): Bit này phải được thiết lập để ADC chạy liên tục (chế độ chạy tự do).


PINK (MUX0-MUX4): Năm bit này dùng để báo cho kênh đầu vào. Vì chúng ta sẽ sử dụng ADC0 hoặc PIN0, chúng ta không cần đặt bất kỳ bit nào như trên bảng.




BROWN (ADPS0-ADPS2): ba bit này dùng để thiết lập bảng điều khiển trước cho ADC. Sice mà chúng ta đang sử dụng một phương pháp đặt trước là 128, chúng ta phải đặt tất cả ba bit.



DARK GREEN (ADSC): bit này được thiết lập để ADC bắt đầu chuyển đổi. Bit này có thể bị vô hiệu hóa trong chương trình khi chúng ta cần dừng chuyển đổi.

Programming Explanation

Hoạt động của ĐO NHIỆT ĐỘ được giải thích tốt nhất theo từng bước của mã C được đưa ra dưới đây:

#include <avr/io.h> //header to enable data flow control over pins

#define F_CPU 1000000  //telling controller crystal frequency attached

#include <util/delay.h> //header to enable delay function in program

#define    E   5 //giving name “enable”  to 5th pin of PORTD, since it Is connected to LCD enable pin

#define RS  6 //giving name “registerselection” to 6th pin of PORTD, since is connected to LCD RS pin

void send_a_command(unsigned char command);

void send_a_character(unsigned char character);

void send_a_string(char *string_of_characters);    

int main(void)

{

DDRB = 0xFF; //putting portB and portD as output pins

DDRD = 0xFF;

_delay_ms(50);//giving delay of 50ms

DDRA = 0;//Taking portA as input.

ADMUX |=(1<<REFS0)|(1<<REFS1);//setting the reference of ADC

ADCSRA |=(1<<ADEN)|(1<<ADATE)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);

//enabling the ADC, setting free running mode, setting prescalar 128

int16_t COUNTA = 0;//storing digital output

char SHOWA [3];//displaying digital output as temperature in 16*2 lcd

send_a_command(0x01); //Clear Screen 0x01 = 00000001

_delay_ms(50);

send_a_command(0x38);//telling lcd we are using 8bit command /data mode

_delay_ms(50);

send_a_command(0b00001111);//LCD SCREEN ON and courser blinking

ADCSRA |=(1<<ADSC);//starting the ADC conversion

while(1)

{

COUNTA = ADC/4; //since the resolution (2.56/2^10 = 0.0025) is 2.5mV there will be an increment of 4 for every 10mV input, that means for every degree raise there will be increment of 4 in digital value. So to get the temperature we have to divide ADC output by four.

send_a_string ("CIRCUIT DIGEST ");//displaying name

send_a_command(0x80 + 0x40 + 0); // shifting cursor  to 1st  shell  of second line

send_a_string ("Temp(C)=");// displaying name

send_a_command(0x80 + 0x40 + 8); // shifting cursor  to 9st  shell  of second line

itoa(COUNTA,SHOWA,10); //command for putting variable number in LCD(variable number, in which character to replace, which base is variable(ten here as we are counting number in base10))

send_a_string(SHOWA); //telling the display to show character(replaced by variable number) of first person after positioning the courser on LCD

send_a_string ("      ");

send_a_command(0x80 + 0);//retuning to first line first shell

}

}

void send_a_command(unsigned char command)

{

PORTA = command;

PORTD &= ~ (1<<RS); //putting 0 in RS to tell lcd we are sending command

PORTD |= 1<<E; //telling lcd to receive command /data at the port

 _delay_ms(50);

PORTD &= ~1<<E;//telling lcd we completed sending data

PORTA= 0;

}

void send_a_character(unsigned char character)

{

PORTA= character;

PORTD |= 1<<RS;//telling LCD we are sending data not commands

PORTD |= 1<<E;//telling LCD to start receiving command/data

_delay_ms(50);

PORTD &= ~1<<E;//telling lcd we completed sending data/command

PORTA = 0;

}

void send_a_string(char *string_of_characters)

{

while(*string_of_characters > 0)

{

send_a_character(*string_of_characters++);

}

}



#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>
#include <stdlib.h>

#define enable            5
#define registerselection 6

void send_a_command(unsigned char command);
void send_a_character(unsigned char character);
void send_a_string(char *string_of_characters);

int main(void)
{
    DDRB = 0xFF;
    DDRA = 0;
    DDRD = 0xFF;
    _delay_ms(50);
    
    ADMUX |=(1<<REFS0)|(1<<REFS1);
    ADCSRA |=(1<<ADEN)|(1<<ADATE)|(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2);
    
    int16_t COUNTA = 0;
    char SHOWA [3];
     

    send_a_command(0x01); //Clear Screen 0x01 = 00000001
    _delay_ms(50);
    send_a_command(0x38);
    _delay_ms(50);
    send_a_command(0b00001111);
    _delay_ms(50);
    
    ADCSRA |=(1<<ADSC);
    while(1)
    {
        COUNTA = ADC/4;
        send_a_string ("CIRCUIT DIGEST");
        send_a_command(0x80 + 0x40 + 0);
        send_a_string ("Temp(C)=");
        send_a_command(0x80 + 0x40 + 8);
        itoa(COUNTA,SHOWA,10);
        send_a_string(SHOWA);
        send_a_string ("      ");
        send_a_command(0x80 + 0);
        
    }    
}

void send_a_command(unsigned char command)
{
    PORTB = command;
    PORTD &= ~ (1<<registerselection);
    PORTD |= 1<<enable;
    _delay_ms(20);
    PORTD &= ~1<<enable;
    PORTB = 0;
}

void send_a_character(unsigned char character)
{
    PORTB = character;
    PORTD |= 1<<registerselection;
    PORTD |= 1<<enable;
    _delay_ms(20);
    PORTD &= ~1<<enable;
    PORTB = 0;
}
void send_a_string(char *string_of_characters)
{
    while(*string_of_characters > 0)
    {
        send_a_character(*string_of_characters++);
    }
}






Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...