Mục lục:

Màn hình nhiệt độ và mức độ ánh sáng với hiển thị trên màn hình LCD NOKIA 5110: 4 bước
Màn hình nhiệt độ và mức độ ánh sáng với hiển thị trên màn hình LCD NOKIA 5110: 4 bước

Video: Màn hình nhiệt độ và mức độ ánh sáng với hiển thị trên màn hình LCD NOKIA 5110: 4 bước

Video: Màn hình nhiệt độ và mức độ ánh sáng với hiển thị trên màn hình LCD NOKIA 5110: 4 bước
Video: OLED LCD SSD1306 128x64 I2C Tutorial: Hướng dẫn sử dụng màn hình LCD SSD1306 - Robot cho mọi người 2024, Tháng bảy
Anonim
Image
Image

Chào mọi người!

Trong phần này, chúng tôi thực hiện một thiết bị điện tử đơn giản để theo dõi nhiệt độ và mức độ ánh sáng. Các phép đo của các thông số này được hiển thị trên LCD NOKIA 5110. Thiết bị dựa trên vi điều khiển AVR ATMEGA328P. Thiết bị giám sát được trang bị nhiệt kế kỹ thuật số DS18B20 và điện trở quang để đo mức độ ánh sáng.

Bước 1: Các thành phần mô tả

Các thành phần mô tả
Các thành phần mô tả
Các thành phần mô tả
Các thành phần mô tả

Các thành phần cơ bản của thiết bị giám sát:

  • Bộ vi điều khiển AVR «ATMEGA328P»
  • Màn hình LCD đồ họa đơn sắc «NOKIA 5110»
  • Nhiệt kế kỹ thuật số 1 dây có độ phân giải có thể lập trình «DS18B20»
  • Điện trở phụ thuộc ánh sáng
  • Dây điện

Bộ vi điều khiển AVR «ATMEGA328P»

Thiết bị giám sát sử dụng các tính năng ngoại vi sau của vi điều khiển:

  1. Ngắt bộ định thời / bộ đếm 16 bit
  2. 8-kênh 10-bit ADC
  3. Giao diện nối tiếp SPI chính / phụ

Màn hình LCD đồ họa đơn sắc «NOKIA 5110»

Thông số kỹ thuật:

  1. Màn hình LCD 48 x 84 chấm
  2. Giao diện Bus nối tiếp với tốc độ cao tối đa 4 Mbits / S
  3. Bộ điều khiển / Trình điều khiển nội bộ «PCD8544»
  4. Đèn nền LED
  5. Chạy ở điện áp 2,7-5 Volt
  6. Sự tiêu thụ ít điện năng; nó phù hợp cho các ứng dụng pin
  7. Phạm vi nhiệt độ từ -25˚C đến + 70˚C
  8. Hỗ trợ đầu vào CMOS tín hiệu

Xử lý Địa chỉ LCD (Định địa chỉ):

Sự sắp xếp địa chỉ của bộ nhớ được hiển thị trên Màn hình LCD (DDRAM) là Ma trận bao gồm 6 hàng (Địa chỉ Y) từ Y-Address 0 đến Y-Address 5 và 84 cột (X Address) từ X-Address 0 đến X- Địa chỉ 83. Nếu người dùng muốn truy cập vào vị trí hiển thị kết quả trên Màn hình LCD, phải tham khảo mối quan hệ giữa Địa chỉ X và Địa chỉ Y.

Dữ liệu sẽ được gửi đến hiển thị là 8 bit (1 Byte) và nó sẽ được sắp xếp theo hàng dọc; trong trường hợp này, Bit MSB sẽ thấp hơn và Bit LSB sẽ ở trên như trong hình.

Nhiệt kế kỹ thuật số 1 dây có độ phân giải lập trình được DALLAS «DS18B20»

Đặc trưng:

  1. Giao diện 1-Wire® duy nhất chỉ yêu cầu một chân cổng để giao tiếp
  2. Giảm số lượng thành phần với cảm biến nhiệt độ tích hợp và EEPROM
  3. Đo Nhiệt độ từ -55 ° C đến + 125 ° C (-67 ° F đến + 257 ° F)
  4. ± 0,5 ° C Độ chính xác từ -10 ° C đến + 85 ° C
  5. Độ phân giải có thể lập trình từ 9 bit đến 12 bit
  6. Không yêu cầu thành phần bên ngoài
  7. Chế độ nguồn ký sinh chỉ yêu cầu 2 chân để hoạt động (DQ và GND)
  8. Đơn giản hóa các ứng dụng cảm biến nhiệt độ phân tán với khả năng đa nước
  9. Mỗi thiết bị có một mã sê-ri 64-bit duy nhất được lưu trữ trong ROM trên bo mạch
  10. Cài đặt cảnh báo không biến động (NV) linh hoạt do người dùng xác định với lệnh tìm kiếm cảnh báo xác định thiết bị có nhiệt độ nằm ngoài giới hạn được lập trình

Các ứng dụng:

  1. Điều khiển nhiệt
  2. Hệ thống công nghiệp
  3. Sản phẩm tiêu dùng
  4. Nhiệt kế
  5. Hệ thống nhạy cảm nhiệt

Điện trở phụ thuộc ánh sáng

Điện trở phụ thuộc ánh sáng (LDR) là một bộ chuyển đổi thay đổi điện trở của nó khi ánh sáng chiếu xuống bề mặt của nó thay đổi.

Thông thường, một LDR sẽ có từ một megaOhms đến hai megaOhms ở tổng mức tối, từ 10 đến 20 kiloOhms ở mười LUX, từ hai đến năm kilohms ở 100 LUX. Điện trở giữa hai tiếp điểm của cảm biến giảm khi cường độ ánh sáng hoặc độ dẫn giữa hai tiếp điểm của cảm biến tăng lên.

Sử dụng mạch phân áp để biến đổi sự thay đổi của điện trở thành sự thay đổi của điện áp.

Bước 2: Mã phần mềm vi điều khiển

#ifndef F_CPU # define F_CPU 16000000UL // cho biết tần số tinh thể của bộ điều khiển (16 MHz AVR ATMega328P) #endif

// ĐỊNH NGHĨA GIAO DIỆN SPI # xác định MOSI 3 // MOSI đó là CỔNG B, PIN 3 # xác định MISO 4 // MISO đó là CỔNG B, mã PIN 4 # xác định SCK 5 // SCK đó là CỔNG B, PIN 5 #define SS 2 // SS đó là PORT B, PIN 2

// ĐẶT LẠI MÀN HÌNH #define RST 0 // ĐẶT LẠI CỔNG B, PIN 0

// CHỌN CHẾ ĐỘ HIỂN THỊ - Đầu vào để chọn lệnh / địa chỉ hoặc đầu vào dữ liệu. #define DC 1 // DC đó là CỔNG B, mã PIN 1

// mã mảng ký hiệu âm const unsigned char neg [4] = {0x30, 0x30, 0x30, 0x30};

// mã mảng các chữ số [0..9] static const unsigned char font6x8 [10] [16] = {{0xFC, 0xFE, 0xFE, 0x06, 0x06, 0xFE, 0xFE, 0xFC, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 0 {0x00, 0x00, 0x18, 0x1C, 0xFE, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00}, // 1 { 0x0C, 0x8E, 0xCE, 0xE6, 0xE6, 0xBE, 0x9E, 0x0C, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 2 {0x00, 0x04, 0x06, 0xDExFE, 0x76, 0x76, 0x26xFE, 0x76, 0x8C, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 3 {0x3C, 0x3E, 0x7C, 0x60, 0x60, 0xFC, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01}, // 4 {0x1C, 0x3E, 0x3E, 0x36, 0x36, 0xF6, 0xF6, 0xE4, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 5 {0xFC, 0xFE, 0xFE, 0x36, 0x36, 0xF6, 0xF6, 0xE4, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01}, // 6 {0x04, 0x06, 0x06, 0x86, 0xE6, 0xFE, 0x1C7E, 0x1C, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00}, // 7 {0xCC, 0xFE, 0xFE, 0x36, 0x36, 0xFE, 0xFE, 0xCC, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0 3, 0x01}, // 8 {0x3C, 0x7E, 0x7E, 0x66, 0x66, 0xFE, 0xFE, 0xFC, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01} // 9};

// mã mảng của từ "TEMP:" static const unsigned char TEMP_1 [165] = {0x02, 0x06, 0x06, 0xFE, 0xFE, 0xFE, 0x06, 0x06, 0x02, 0x00, 0xFC, 0xFE, 0xFE, 0x26, 0x26, 0x24, 0x00, 0xFC, 0xFE, 0xFE, 0x1C, 0x38, 0x70, 0x38, 0x1C, 0xFE, 0xFE, 0xFC, 0x00, 0xFC, 0xFE, 0xFE, 0x66, 0x66, 0x7E, 0x7E, 0x3C, 0x00, 0x8C, 0x00 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0C, 0x1E, 0x33, 0x33, 0x1E, 0x0C, 0x00, 0xF8, 0x00, 0xF8 0x9C, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x01,};

// mảng mã của từ "LUX:" const unsigned char TEMP_2 [60] = {0xFC, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFE, 0xFC, 0x00, 0x00, 0xFC, 0xFE, 0xFC, 0x00, 0x04, 0x8E, 0xDE, 0xFC, 0xF8, 0xFC, 0xDE, 0x8E, 0x04, 0x00, 0x8C, 0x8C, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x01, 0x01};

#bao gồm

#include #include

// Khởi tạo cổng, tránh Port_Init () {DDRB = (1 << MOSI) | (1 << SCK) | (1 << SS) | (1 << RST) | (1 << DC); // Đặt MOSI, SCK, SS, RST, DC làm đầu ra, tất cả các đầu vào khác PORTB | = (1 << RST); // Đặt chân RST là cao PORTB | = (1 << SS); // Đặt chân SS là cao - Hiển thị là Tắt DDRC = 0xFFu; // Đặt tất cả các chân của PORTC làm đầu ra. DDRC & = ~ (1 << 0); // Đặt chân đầu tiên của PORTC làm Đầu vào PORTC = 0x00u; // Đặt tất cả các chân của PORTC ở mức thấp để tắt nó. }

// Khởi tạo ADC void ADC_init () {// Bật ADC, lấy mẫu freq = osc_freq / 128 đặt prescaler thành giá trị lớn nhất, 128 ADCSRA | = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); ADMUX = (1 << REFS0); // Chọn tham chiếu điện áp cho ADC // Chọn kênh 0 theo mặc định bằng thanh ghi Chọn bộ ghép kênh ADC (ADC0). }

// Hàm đọc kết quả chuyển từ analog sang digital uint16_t get_LightLevel () {_delay_ms (10); // Chờ một lúc để kênh được chọn ADCSRA | = (1 << ADSC); // Bắt đầu chuyển đổi ADC bằng cách thiết lập bit ADSC. ghi 1 vào ADSC while (ADCSRA & (1 << ADSC)); // đợi quá trình chuyển đổi hoàn tất // ADSC lại trở thành 0 cho đến lúc đó, chạy lặp liên tục _delay_ms (10); trở lại (ADC); // Trả về kết quả 10 bit}

// Khởi tạo SPI void SPI_Init () {SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); // Kích hoạt SPI, Đặt làm Master, Đặt Prescaler là Fosc / 16 trong điều khiển SPI Đăng ký }

// khởi tạo Timer1 16 bit, ngắt và biến void TIMER1_init () {// thiết lập timer với prescaler = 256 và chế độ CTC TCCR1B | = (1 << WGM12) | (1 << CS12); // khởi tạo bộ đếm TCNT1 = 0; // khởi tạo giá trị so sánh - 1 giây OCR1A = 62500; // kích hoạt ngắt so sánh TIMSK1 | = (1 << OCIE1A); // cho phép ngắt toàn cục sei (); }

// Kích hoạt hiển thị void SPI_SS_Enable () {PORTB & = ~ (1 << SS); // Bật chân SS thành logic 0}

// Hiển thị Disable void SPI_SS_Disable () {PORTB | = (1 << SS); // Vô hiệu hóa chân SS thành logic 1}

// Hàm gửi dữ liệu vào vùng đệm hiển thị void SPI_Tranceiver (unsigned char data) {SPDR = data; // Nạp dữ liệu vào bộ đệm while (! (SPSR & (1 << SPIF))); // Chờ cho đến khi quá trình truyền hoàn tất}

// Đặt lại Hiển thị khi bắt đầu khởi tạo void Display_Reset () {PORTB & = ~ (1 << RST); _delay_ms (100); PORTB | = (1 << RST); }

// Hàm ghi lệnh void Display_Cmnd (unsigned char data) {PORTB & = ~ (1 << DC); // tạo chân DC thành logic 0 cho hoạt động lệnh SPI_Tranceiver (data); // gửi dữ liệu trên thanh ghi dữ liệu PORTB | = (1 << DC); // làm cho chân DC thành mức logic cao để vận hành dữ liệu}

// Khởi tạo Hiển thị void Display_init () {Display_Reset (); // thiết lập lại hiển thị Display_Cmnd (0x21); // lệnh đặt ở chế độ cộng Display_Cmnd (0xC0); // đặt điện áp bằng cách gửi C0 nghĩa là VOP = 5V Display_Cmnd (0x07); // thiết lập nhiệt độ. hệ số thành 3 Display_Cmnd (0x13); // thiết lập giá trị của Voltage Bias System Display_Cmnd (0x20); // lệnh đặt ở chế độ cơ bản Display_Cmnd (0x0C); // hiển thị kết quả ở chế độ bình thường}

// Xoá Hiển thị void Display_Clear () {PORTB | = (1 << DC); // đặt chân DC thành mức logic cao để vận hành dữ liệu cho (int k = 0; k <= 503; k ++) {SPI_Tranceiver (0x00);} PORTB & = ~ (1 << DC); // đặt chân DC thành logic số không cho hoạt động lệnh}

// đặt cột và hàng đến vị trí hiển thị kết quả trên LCD Display void Display_SetXY (unsigned char x, unsigned char y) {Display_Cmnd (0x80 | x); // cột (0-83) Display_Cmnd (0x40 | y); // hàng (0-5)}

// Hàm hiển thị dấu âm void Display_Neg (unsigned char neg) {Display_SetXY (41, 0); // Đặt địa chỉ của vị trí trên màn hình for (int index = 0; index0) {SPDR = 0x30;} // Nạp dữ liệu vào vùng đệm của màn hình (hiển thị dấu âm) else {SPDR = 0x00;} // Nạp dữ liệu vào bộ đệm của màn hình (dấu âm rõ ràng) while (! (SPSR & (1 << SPIF))); // Chờ cho đến khi quá trình truyền hoàn tất _delay_ms (100); }}

// Hàm xóa dấu số void Off_Dig (unsigned char x, unsigned char y) {Display_SetXY (x, y); // Đặt địa chỉ của vị trí trên màn hình (hàng trên cùng) for (int index = 0; index <8; index ++) {SPI_Tranceiver (0);} // Nạp dữ liệu vào bộ đệm của màn hình (xóa phần trên cùng của ký số) y ++; Display_SetXY (x, y); // Đặt địa chỉ của vị trí trên màn hình (hàng dưới cùng) for (int index = 0; index <8; index ++) {SPI_Tranceiver (0);} // Nạp dữ liệu vào vùng đệm của màn hình (rõ ràng phần dưới cùng của ký số)}

// Hàm hiển thị dấu số void Display_Dig (int dig, unsigned char x, unsigned char y) {Display_SetXY (x, y); // Đặt địa chỉ vị trí trên màn hình (hàng trên cùng) for (int index = 0; index <16; index ++) {if (index == 8) {y ++; Display_SetXY (x, y);} // Đặt địa chỉ của vị trí trên màn hình (hàng dưới cùng) SPI_Tranceiver (font6x8 [dig] [index]); // Nạp mã mảng dữ liệu chữ số vào vùng đệm của display _delay_ms (10); }}

// Khởi tạo DS18B20 unsigned char DS18B20_init () {DDRD | = (1 << 2); // Đặt chân PD2 của PORTD làm đầu ra PORTD & = ~ (1 << 2); // Đặt chân PD2 ở mức thấp _delay_us (490); // Thời gian khởi tạo DDRD & = ~ (1 << 2); // Đặt chân PD2 của PORTD làm đầu vào _delay_us (68); // Định thời gian OK_Flag = (PIND & (1 << 2)); // lấy xung cảm biến _delay_us (422); trả về OK_Flag; // return 0-ok sensor is plug, 1-error sensor is unplug}

// Hàm đọc byte từ DS18B20 unsigned char read_18b20 () {unsigned char i, data = 0; for (i = 0; i <8; i ++) {DDRD | = (1 << 2); // Đặt chân PD2 của PORTD làm đầu ra _delay_us (2); // Định thời gian DDRD & = ~ (1 1; // Bit tiếp theo if (PIND & (1 << 2)) data | = 0x80; // đưa bit vào byte _delay_us (62);} trả về dữ liệu;}

// Hàm ghi byte vào DS18B20 void write_18b20 (unsigned char data) {unsigned char i; for (i = 0; i <8; i ++) {DDRD | = (1 << 2); // Đặt chân PD2 của PORTD làm đầu ra _delay_us (2); // Định thời if (data & 0x01) DDRD & = ~ (1 << 2); // nếu chúng ta muốn ghi 1, hãy giải phóng dòng khác DDRD | = (1 1; // Bit tiếp theo _delay_us (62); // Định thời gian DDRD & = ~ (1 << 2); // Đặt chân PD2 của PORTD dưới dạng đầu vào _delay_us (2);}}

// Hàm hiển thị mức sáng void Read_Lux () {uint16_t buffer; unsigned int temp_int_1, temp_int_2, temp_int_3, temp_int_0; // chữ số đơn, chữ số đôi, chữ số ba, chữ số phần tư buffer = get_LightLevel (); // đọc kết quả chuyển đổi mức sáng tương tự sang số temp_int_0 = buffer% 10000/1000; // một phần tư chữ số temp_int_1 = đệm% 1000/100; // ba chữ số temp_int_2 = đệm% 100/10; // hai chữ số temp_int_3 = đệm% 10; // một chữ số if (temp_int_0> 0) // nếu kết quả là một phần tư chữ số {Display_Dig (temp_int_0, 32, 2); // hiển thị 1 chữ số mức sáng Display_Dig (temp_int_1, 41, 2); // hiển thị 2 chữ số của mức sáng Display_Dig (temp_int_2, 50, 2); // hiển thị 3 chữ số của mức sáng Display_Dig (temp_int_3, 59, 2); // hiển thị 4 chữ số của mức sáng} else {if (temp_int_1> 0) // if kết quả là số có ba chữ số {Off_Dig (32, 2); // xóa 1 dấu của số Display_Dig (temp_int_1, 41, 2); // hiển thị 1 chữ số mức sáng Display_Dig (temp_int_2, 50, 2); // hiển thị 2 chữ số của mức sáng Display_Dig (temp_int_3, 59, 2); // hiển thị 3 chữ số của mức độ sáng} else {if (temp_int_2> 0) // if kết quả là số có hai chữ số {Off_Dig (32, 2); // xóa 1 dấu của số Off_Dig (41, 2); // xóa 2 dấu của số Display_Dig (temp_int_2, 50, 2); // hiển thị 1 chữ số của mức sáng Display_Dig (temp_int_3, 59, 2); // hiển thị 2 chữ số của mức sáng} else // nếu kết quả là số có một chữ số {Off_Dig (32, 2); // xóa 1 dấu của số Off_Dig (41, 2); // xóa 2 dấu của số Off_Dig (50, 2); // xóa dấu 3 của số Display_Dig (temp_int_3, 59, 2); // hiển thị 1 chữ số của mức độ ánh sáng}}}}

// Hàm hiển thị nhiệt độ void Read_Temp () {unsigned int buffer; unsigned int temp_int_1, temp_int_2, temp_int_3; // chữ số đơn, chữ số đôi, chữ số ba, chữ số phần tư không dấu char Temp_H, Temp_L, OK_Flag, temp_flag; DS18B20_init (); // Khởi tạo DS18B20 write_18b20 (0xCC); // Kiểm tra mã cảm biến write_18b20 (0x44); // Bắt đầu chuyển đổi nhiệt độ _delay_ms (1000); // Độ trễ thăm dò của cảm biến DS18B20_init (); // Khởi tạo DS18B20 write_18b20 (0xCC); // Kiểm tra mã cảm biến write_18b20 (0xBE); // Lệnh đọc nội dung của Sensor RAM Temp_L = read_18b20 (); // Đọc hai byte đầu tiên Temp_H = read_18b20 (); temp_flag = 1; // Nhiệt độ 1 dương, nhiệt độ 0 âm // Lấy nhiệt độ âm if (Temp_H & (1 << 3)) // Kiểm tra bit dấu (nếu bit được đặt - nhiệt độ âm) {sign int temp; temp_flag = 0; // cờ được đặt 0 - nhiệt độ âm temp = (Temp_H << 8) | Temp_L; temp = -temp; // Chuyển đổi mã bổ sung trong trực tiếp Temp_L = temp; Temp_H = temp >> 8; } buffer = ((Temp_H 4); temp_int_1 = buffer% 1000/100; // ba chữ số temp_int_2 = buffer% 100/10; // hai chữ số temp_int_3 = buffer% 10; // một chữ số

// Nếu nhiệt độ là âm thì hiển thị dấu hiệu của nhiệt độ, còn lại thì rõ ràng

if (temp_flag == 0) {Display_Neg (1);} else {Display_Neg (0);} if (temp_int_1> 0) // nếu kết quả là số có ba chữ số {Display_Dig (temp_int_1, 45, 0); // hiển thị 1 chữ số nhiệt độ Display_Dig (temp_int_2, 54, 0); // hiển thị 2 chữ số nhiệt độ Display_Dig (temp_int_3, 63, 0); // hiển thị 3 chữ số của nhiệt độ} else {if (temp_int_2> 0) // if kết quả là số có hai chữ số {Off_Dig (45, 0); // xóa 1 dấu của số Display_Dig (temp_int_2, 54, 0); // hiển thị 1 chữ số nhiệt độ Display_Dig (temp_int_3, 63, 0); // hiển thị 2 chữ số của nhiệt độ} else // nếu kết quả là số có một chữ số {Off_Dig (45, 0); // xóa 1 dấu của số Off_Dig (54, 0); // xóa 2 dấu của số Display_Dig (temp_int_3, 63, 0); // hiển thị 1 chữ số nhiệt độ}}}

// ISR này được kích hoạt bất cứ khi nào có sự trùng khớp của đếm bộ đếm thời gian với giá trị so sánh (mỗi 1 giây) ISR (TIMER1_COMPA_vect) {// Đọc, hiển thị nhiệt độ và mức độ ánh sáng Read_Temp (); Read_Lux (); }

// Hàm hiển thị từ "TEMP" và "LUX" void Display_label () {// Word "TEMP" Display_SetXY (0, 0); // Đặt địa chỉ của vị trí trên màn hình (lên hàng) for (int index = 0; index <105; index ++) {if (index == 40) {Display_SetXY (0, 1);} // Đặt địa chỉ của vị trí on display (hàng dưới) if (index == 80) {Display_SetXY (72, 0);} // Đặt địa chỉ của vị trí trên màn hình (hàng lên) if (index == 92) {Display_SetXY (72, 1); } // Đặt địa chỉ của vị trí trên màn hình (hàng dưới cùng) SPDR = TEMP_1 [index]; // Nạp dữ liệu mảng mã vào vùng đệm của màn hình while (! (SPSR & (1 << SPIF))); // Chờ cho đến khi quá trình truyền hoàn tất _delay_ms (10); } // Từ "LUX" Display_SetXY (0, 2); // Đặt địa chỉ của vị trí trên màn hình (lên hàng) for (int index = 0; index <60; index ++) {if (index == 30) {Display_SetXY (0, 3);} // Đặt địa chỉ của vị trí trên màn hình (hàng dưới cùng) SPDR = TEMP_2 [chỉ mục]; // Nạp dữ liệu mảng mã vào vùng đệm của màn hình while (! (SPSR & (1 << SPIF))); // Chờ cho đến khi quá trình truyền hoàn tất _delay_ms (10); }}

int main (void)

{Port_Init (); // Khởi tạo cổng ADC_init (); // Khởi tạo ADC SPI_Init (); // Khởi tạo SPI SPI_SS_Enable (); // Kích hoạt hiển thị DS18B20_init (); // Khởi tạo DS18B20 Display_init (); // Hiển thị khởi tạo Display_Clear (); // Hiển thị rõ ràng Display_label (); // Hiển thị các từ "TEMP" và "LUX" TIMER1_init (); // Khởi tạo Timer1. Bắt đầu giám sát. Nhận thông số mỗi giây một lần. // Vòng lặp vô cực while (1) {}}

Bước 3: Nhấp nháy Firmware sang Vi điều khiển

Tải lên tệp HEX vào bộ nhớ flash của vi điều khiển. Xem video mô tả chi tiết quá trình ghi bộ nhớ flash vi điều khiển: Ghi bộ nhớ flash vi điều khiển…

Bước 4: Lắp ráp mạch thiết bị giám sát

Lắp ráp mạch thiết bị giám sát
Lắp ráp mạch thiết bị giám sát
Lắp ráp mạch thiết bị giám sát
Lắp ráp mạch thiết bị giám sát

Kết nối các thành phần phù hợp với sơ đồ.

Cắm điện và nó đang hoạt động!

Đề xuất: