#define LCD_RS_PIN PIN_E0
#define LCD_RW_PIN PIN_E1
#define LCD_ENABLE_PIN PIN_E2
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#define BUTTON_UP PIN_C0 // nút nh?n
#define BUTTON_DOWN PIN_C1 // nút nh?n
#define VIEW_BUTTON PIN_C3 // Đ?nh ngh?a chân C3 là nút xem
#define BUZZER_PIN PIN_C2 // loa
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#include <lcd.c>
#use fast_io(B)
int set_temp = 25; // kho?ng cách thi?t l?p m?c đ?nh
int8 check;
unsigned int16 i, distance;
unsigned int16 saved_distance; // bi?n lưu kho?ng cách đo đư?c
unsigned int16 save_timer; // bi?n đ?m th?i gian lưu
#define NUM_SAVED_DISTANCES 20
unsigned int16 saved_distances[NUM_SAVED_DISTANCES]; // m?ng lưu 20 l?n đo cu?i cùng
int current_index = 0; // ch? s? hi?n t?i trong m?ng
void save_distance(unsigned int16 distance) {
saved_distances[current_index] = distance;
current_index++;
if (current_index >= NUM_SAVED_DISTANCES) {
current_index = 0; // v?ng l?i đ?u m?ng
void view_saved_distances() {
for (int j = 0; j < NUM_SAVED_DISTANCES; j++) {
lcd_putc('\f'); // xóa màn h?nh
lcd_gotoxy(3, 1);
lcd_putc("NHUNG LAN DO");
lcd_gotoxy(1, 2); // hi?n th? ? d?ng th? 2
printf(lcd_putc, "LAN %2u : %3Lu CM", j + 1, saved_distances[j]); // s?a l?i đ?nh d?ng
delay_ms(1000); // hi?n th? trong 1 giây
lcd_putc('\f'); // xóa màn h?nh sau khi hi?n th? h?t
lcd_gotoxy(1, 1);
lcd_putc("DISTANCE:"); // tr? v? tr?ng thái b?nh thư?ng
void main() {
output_b(0);
set_tris_b(2);
lcd_init();
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_2); // chia 2
set_timer1(0);
lcd_putc('\f');
lcd_gotoxy(1, 1);
lcd_putc("DISTANCE:"); // kho?ng cách
save_timer = 0; // kh?i t?o b? đ?m th?i gian lưu
while(TRUE) {
// X? l? nút b?m
if(input(BUTTON_UP) == 0) {
set_temp++;
delay_ms(100); // ch?ng nhi?u khi nh?n nút
if(input(BUTTON_DOWN) == 0) {
set_temp--;
delay_ms(100);
// Hi?n th? thi?t l?p kho?ng cách
lcd_gotoxy(1,2);
printf(lcd_putc, "THIET LAP: %d CM ", set_temp);
check = 0;
i = 0;
output_high(PIN_B0);
delay_us(10);
output_low(PIN_B0);
set_timer1(0);
while(!input(PIN_B1) && (get_timer1() < 1000));
if(get_timer1() > 990)
check = 1;
set_timer1(0);
while(input(PIN_B1) && (i < 25000))
i = get_timer1();
if(i > 24990)
check = 2;
//! if(check == 2) {
//!
//! lcd_gotoxy(3, 2);
//! lcd_putc("NGOAI PHAM VI "); // 430cm vuot quá ph?m vi kho?ng cách
//!
//! }
else {
distance = i / 58;
lcd_gotoxy(14, 1);
lcd_putc("CM");
lcd_gotoxy(10, 1);
printf(lcd_putc, " %3Lu", distance);
// Thi?t l?p loa
if(set_temp > distance) {
output_high(BUZZER_PIN); // Kích ho?t loa buzzer
} else {
output_low(BUZZER_PIN);
delay_ms(100); // c?p nh?t kho?ng cách sau 100ms
// Tăng b? đ?m th?i gian lưu
save_timer += 100; // tăng lên 100ms
// Ki?m tra n?u đ? qua 5 giây
if(save_timer >= 5000) {
save_timer = 0; // đ?t l?i b? đ?m th?i gian
saved_distance = distance; // lưu kho?ng cách hi?n t?i
save_distance(saved_distance); // g?i hàm lưu kho?ng cách vào m?ng
// Kích ho?t loa báo hi?u đ? lưu
output_high(BUZZER_PIN);
delay_ms(100); // th?i gian kêu
output_low(BUZZER_PIN);
// Ki?m tra nút xem
if(input(VIEW_BUTTON) == 0) {
delay_ms(100); // ch?ng nhi?u khi nh?n nút
view_saved_distances(); // g?i hàm hi?n th? 20 l?n đo cu?i cùng