Tải bản đầy đủ (.docx) (64 trang)

(TIỂU LUẬN) báo cáo môn hệ THỐNG điều KHIỂN NHÚNG đo nhiệt độ bằng LM35 hiển thị trên mà hình LCD sử dụng vdk pic16f877a

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.3 MB, 64 trang )

TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI
KHOA ĐIỆN ĐIỆN TỬ
BỘ MÔN ĐIỀU KHIỂN HỌC

***********

BÁO CÁO MÔN: HỆ THỐNG ĐIỀU KHIỂN
NHÚNG

1


TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI

BÁO CÁO TỔNG KẾT
HỆ THỐNG ĐIỀU KHIỂN NHÚNG
NHÓM 1

Thuộc lĩnh vực khoa học và công nghệ: Điện - Điện tử
Sinh viên thực hiện:
1.Lưu Minh Lâm
2.Nguyễn Việt Tuấn
3.Nguyễn Quang Hưng
4.Nguyễn Xuân Tùng(1408989)
5.Nguyễn Xuân Tùng(1408988)
6.Nguyễn Minh Thành Long

7.Phạm Khắc Hải
8.Hoàng Văn Hải
9.Nguyễn Văn Khanh
10.Nguyên Bá Hùng


11.Nguyễn Văn Hiểu
12.Đỗ Văn Đơng

Lớp: Tự động hóa - điều khiển K55
Năm thứ: 3/Số năm đào tạo: 4.5
Ngành học: Kỹ thuật điều khiển và tự động hóa

Khoa: Điện - Điện Tử

Hà Nội, 26/03/2017
2


Mục lục
Phần 1: khái quát về VXL PIC16f877a.............................................................................. 4
Phần 2:CODE-Mô phỏng các bài lập trình……………………………………..8
❖ Bài 1: Đo nhiệt độ bằng LM35 hiển thị trên mà hình LCD sử dụng vdk

pic16f877a……………………………………………………………….8

❖ Bài 2: Đo nhiệt độ bằng LM35 khi nhiệt độ lớn hơn 40 thì đóng quạt chạy làm

mát……………………………………………………………………….16

❖ BÀI 3: ĐO TỐC ĐỘ ĐỘNG CƠ BẰNG ENCODER SỬ DỤNG NGẮT NGOÀI

VÀ TIMER1 CỦA VĐK PIC16F877A………………………………….22
❖ Bài 4:Đo khoảng Cách sử dụng cảm biến siêu âm SRF05 hiển thị trên
LCD16x02…………………………………………………………….....28


❖ Bài 5:Gửi chuỗi kí tự qua UART………………………………………..35
❖ Bài 6: Truyền thông I2C………………………………………………...51
❖ Bài 7: Đảo chiều, dừng động cơ sử dụng L298 kết hợp đo tốc độ và truyền tốc độ

qua UART……………………………………………………………….57

3


Phần I: Khái quát về VXL PIC16F877A
SƠ ĐỒ NỐI CHÂN CỦA PIC16F877A

Chức năng các chân của PORTA
4


1. Chân RA0/AN0
-

RA0: xuất/ nhập số - bit thứ 0 của port A.

-

AN0: ngõ vào tương tự của kênh thứ 0.

2. Chân RA1/AN1
-

RA1: xuất/nhập số - bit thứ 1 của port A.


-

AN1: ngõ vào tương tự của kênh thứ 1.

3. Chân RA2/AN2/VREF-/CVREF
-

RA2: xuất/nhập số - bit thứ 2 của port A.

-

AN2: ngõ vào tương tự của kênh thứ 2.

-

VREF-: ngõ vào điện áp chuẩn (thấp) của bộ ADC.

-

CVREF: điện áp tham chiếu VREF ngõ vào bộ so sánh.

4. Chân RA3/AN3/VREF+
-

RA3: xuất/nhập số - bit thứ 3 của port A.

-

AN3: ngõ vào tương tự kênh thứ 3.


-

VREF+: ngõ vào điện áp chuẩn (cao) của bộ A/D.

-

RA4: xuất/nhập số – bit thứ 4 của port A.

-

TOCKI: ngõ vào xung clock từ bên ngoài cho Timer0.

-

C1OUT: ngõ ra bộ so sánh 1.

-

RA5: xuất/nhập số – bit thứ 5 của port A.

-

AN4: ngõ vào tương tự kênh thứ 4.

-

SS : ngõ vào chọn lựa SPI tớ (Slave SPI device).

-


C2OUT: ngõ ra bộ so sánh 2.

-

Chức năng các chân của PORTB
5


1 Chân RB0/INT
RB0: xuất/nhập số – bit thứ 0 của port B.
- INT: ngõ vào nhận tín hiệu ngắt ngồi.
2. Chân RB1
-

RB1: xuất/nhập số – bit thứ 1 của port B.
3. Chân RB2
- RB2: xuất/nhập số – bit thứ 2 của port B.
4. Chân RB3
- RB3: xuất/nhập số – bit thứ 3 của port B.
5. Chân RB4
- RB4: xuất/nhập số – bit thứ 4 của port B.
6. Chân RB5
- RB5: xuất/nhập số – bit thứ 5 của port B.
7.Chân RB6
- RB6: xuất/nhập số.
-

RB7: xuất/nhập số.

-


Chức năng các chân của PORTC

Chân RC0/T1OSO/T1CKI (15): có 3 chức
năng: - RC0: xuất/nhập số – bit thứ 0 của port C.
- T1OSO: ngõ ra của bộ dao động Timer1.
- T1CKI: ngõ vào xung clock từ bên ngồi Timer1.
2. Chân RC1/T1OSI/CCP2 (16): có 3 chức năng:
- RC1: xuất/nhập số – bit thứ 1 của port C.
- T1OSI: ngõ vào của bộ dao động Timer1.
- CCP2: ngõ vào Capture2, ngõ ra compare2, ngõ ra PWM2.
3. Chân RC2 /P1A/CCP1 (17): có 3 chức năng:
- RC2: xuất/nhập số – bit thứ 2 của port C.
- P1A: ngõ ra PWM.
- CCP1: ngõ vào Capture1, ngõ ra compare1, ngõ ra PWM1 .
4. Chân RC3/SCK/SCL (18): có 3 chức năng:
- RC3: xuất/nhập số – bit thứ 3 của port C.
- SCK: ngõ vào xung clock nối tiếp đồng bộ/ngõ ra của chế độ SPI.
- SCL: ngõ vào xung clock nối tiếp đồng bộ/ngõ ra của chế độ I2C.
5. Chân RC4/SDI/SDA (23): có 3 chức năng:
1.

6


RC4: xuất/nhập số – bit thứ 4 của port C.
- SDI: ngõ vào dữ liệu trong truyền dữ liệu kiểu SPI.
- SDA: xuất/nhập dữ liệu I2C.
6. Chân RC5/SDO (24): có 2 chức năng:
- RC5: xuất/nhập số – bit thứ 5 của port C.

- SDO: ngõ xuất dữ liệu trong truyền dữ liệu kiểu SPI.
7. Chân RC6/TX/CK (25): có 3 chức năng:
- RC6: xuất/nhập số – bit thứ 6 của port C.
- TX: ngõ ra phát dữ liệu trong chế độ truyền bất đồng bộ USART.
- CK: ngõ ra cấp xung clock trong chế độ truyền đồng bộ USART.
8. Chân RC7/RX/DT
- RC7: xuất/nhập số – bit thứ 7 của port C.
- RX: ngõ vào nhận dữ liệu trong chế độ truyền bất đồng bộ EUSART.
- DT: ngõ phát và nhận dữ liệu ở chế độ truyền đồng bộ EUSART.
-

-

Chức năng các chân của PORTD

1. Chân RD0
- RD0: xuất/nhập số – bit thứ 0 của port D.
- Chân RD1
2.RD1: xuất/nhập số – bit thứ 1 của port D.
3. Chân RD2
- RD2: xuất/nhập số – bit thứ 2 của port D.
4.Chân RD3
- RD3: xuất/nhập số – bit thứ 3 của port D.
5. Chân RD4
- RD4: xuất/nhập số – bit thứ 4 của port D.
6. Chân RD5
- RD5: xuất/nhập số – bit thứ 5 của port D.
- ngõ ra PWM.
RD6: xuất/nhập số – bit thứ 6 của port D.
8. Chân RD7

- RD7: xuất/nhập số – bit thứ 7 của port D.
-

-

Chức năng các chân của PORTE

1 Chân RE0/AN5 (8): có 2 chức năng:

7


RE0: xuất/nhập số.
- AN5: ngõ vào tương tự 5.
2.Chân RE1/AN6 (9): có 2 chức năng:
- RE1: xuất/nhập số.
- AN6: ngõ vào tương tự kênh thứ 6.
3. Chân RE2/AN7 (10): có 2 chức
năng: - RE2: xuất/nhập số.
- AN7: ngõ vào tương tự kênh thứ 7.
-

Phần II: CODE – Mô Phỏng Các Bài Lập Trình
Nhúng.
Bài 1 :ĐO NHIỆT ĐỘ BẰNG CẢM BIẾN LM35 HIỂN THỊ
LÊN LCD SỬ DỤNG VĐK 16F877A


Ngun lý: Tín hiệu của các đại lượng vật lý cần đo là nhiệt độ được biến đổi
thành tín hiệu điện thơng qua các cảm biến nhiệt độ LM35. Tín hiệu này được

đưa vào vi điều khiển. Ở trong vi điều khiển PIC16F877A có tích hợp sẵn bộ
chuyển đổi ADC. Ở bài này chúng ta chỉ sử dụng để đo nhiệt độ nên chỉ cần sử
dụng 1 trong 8 kênh đo ADC của vi điều khiển. Module ADC của vi điều khiển
PIC16F877A gồm có 4 thanh ghi ADRESH, ADRESL, ADCON0, ADCON1.
Giá trị sau khi được chuyển đổi chúng ta sẽ lấy giá trị 10 bit đó tính tốn và
chuyển thành nhiệt độ tương ứng rồi hiển thị lên LCD16x2. Nếu nhiệt độ đo
được lớn hơn 40 độ sẽ có thơng báo hiển thị lên LCD và loa kêu lên. Bây giờ
chúng ta sẽ đi tìm hiểu từng thanh ghi ADC của vi điều khiển.


ADCON0:

Bit 7-6 ADCS1:ADCS0: bit này kết hợp với bit ADCS2 của thanh ghi
ADCON1 dùng để cài đặt tần số chuyển đổi ADC

8


Bit 5 - 3 CH2:CH0: là các bit lựa chọn các kênh analog của module ADC
000 = Channel 0 (AN0)
001 = Channel 1 (AN1)
010 = Channel 2 (AN2)
011 = Channel 3 (AN3)
100 = Channel 4 (AN4)
101 = Channel 5 (AN5)
110 = Channel 6 (AN6)
111 = Channel 7 (AN7)
Bit 2 Go/Done: là bit trạng thái chuyển đổi ADC.
1: Quá trình đọc ADC thực hiện xong.
2: trình đọc ADC đang tiến hành và khi thực hiện xong bit này bị


xóa và bằng 0
Bit 0 ADON:

1: module ADC bị tắt.
2: module ADC được kích hoạt.


ADCON1:

Bit 7 ADFM: bit này dùng để cài đặt việc lưu giá trị ADC đọc được
trong 2 thanh ghi.
1: 6 bit thấp của thanh ghi ADRESL không dùng. 10bit ADC được

lưu vào các bit còn lại trên 2 thanh ghi

2: 6 bit cao của thanh ghi ADRESH không dùng. 10bit ADC được

lưu vào các bit còn lại trên 2 thanh ghi

9


Bit 3-0 PCFG3:PCFG0: Bit này để cài đặt các kênh ADC




ADRESH và ADRESL: Chứa 10 bit của ADC sau khi đã chuyển
đổi xong.

LM35: Nhiệt độ được xác địnho bằng cách đo hiệu điện thế ngõ ra
của LM35.
o Đơn vị nhiệt độ là C. Nhiệt độ thay đổi tuyến tính là
10mV/ C . Độ chính xác thực tế: 1/4°C ở nhiệt độ phịng và 3/4°C
ngồi trời.Nhiệt độ đo được trong khoảng -55°C tới 150°C . LM35
có hiệu năng cao, cơng suất tiêu thụ là 60uA . Như vậy, bằng cách
đưa vào chân bên trái của cảm biến LM35 hiệu điện thế 5V, chân
phải nối đất, đo hiệu điện thế ở chân giữa bằng chân RA0/AN0
bạn sẽ có được nhiệt độ (0-150ºC) bằng công thức:
Nhiệt độ = (5000.0f) /1023*giá trị ADC đọc được/10

Hình ảnh thực tế

10




Đặc điểm chính của cảm biến LM35
+ Điện áp đầu vào từ 4V đến 30V
+ Độ phân giải điện áp đầu ra là 10mV/oC
+ Độ chính xác cao ở 25 C là 0.5 C
+ Trở kháng đầu ra thấp 0.1 cho 1mA tải
Dải nhiệt độ đo được của LM35 là từ -55 C - 150 C với các mức điện áp ra
khác nhau. Xét một số mức điện áp sau :
- Nhiệt độ -55 C điện áp đầu ra -550mV
- Nhiệt độ 25 C điện áp đầu ra 250mV
- Nhiệt độ 150 C điện áp đầu ra 1500mV
Tùy theo cách mắc của LM35 để ta đo các giải nhiệt độ phù hợp. Đối với hệ
thống này thì đo từ 0 đến 150. Chi tiết các bạn có thể xem trong datasheet

của nó

#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 8000000
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
11


#define D7 RD7
#include <xc.h>
#include "lcd.h"
// CONFIG
// Oscillator Selection bits (HS oscillator)

#pragma config FOSC = HS

#pragma config WDTE = OFF

// Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = OFF

// Power-up Timer Enable bit (PWRT disabled)

#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
(Code protection off)

// Flash Program Memory Code Protection bit

void ADCinit (void);
unsigned int ReadADC (void);

unsigned int ADCvalue = 0;
float f;
unsigned int voltage;
void main(void)
{
ADCinit();
char s[20];
int c = 33;
TRISD = 0x00;
12



RA0 = 1;
TRISA0 = 1;
Lcd_Init();
while(1)
{
ADCvalue = ReadADC();
voltage = 5000.0f / 1023 * ADCvalue;
f = voltage / 10;
sprintf(s, "NHIET DO = %g ", f);
Lcd_Set_Cursor(1,1);
Lcd_Write_String(s);
Lcd_Write_Char(223);
Lcd_Write_String("C");
sprintf(s, "MSSV IS = %u ", c);
Lcd_Set_Cursor(2,1);
Lcd_Write_String(s);
}
}
void ADCinit (void)// adc
{
// chon tan so clock cho bo adc
ADCON1bits.ADCS2 = 0, ADCON0bits.ADCS1 = 0,ADCON0bits.ADCS0 = 1;
// chon kenh adc la kenh an0
ADCON0bits.CHS2 = 0, ADCON0bits.CHS1 = 0, ADCON0bits.CHS0 = 0;
/ chon cach luu data

ADCON1bits.ADFM = 1;
/ cau hinh cong vao
13



ADCON1bits.PCFG3 = 1, ADCON1bits.PCFG2 = 1, ADCON1bits.PCFG1 = 1,
ADCON1bits.PCFG0 = 0;
/ cap nguon cho khoi adc

ADCON0bits.ADON = 1;

}
unsigned int ReadADC (void)// doc len 7 doan
{
unsigned int TempValue = 0;
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
TempValue = ADRESH*256 + ADRESL;
return (TempValue);
}

14


15


Bài 2:Đo nhiệt độ bằng cảm biến LM35 khi nhiệt độ lớn hơn 40
độ thì chạy quạt làm mát đóng điện chạy động cơ quạt qua
relay,hiển thị nhiệt độ qua LED 7 thanh hoặc LCD
/*
* File: newmain.c
* Author: minhlam


*
* Created on February 8, 2017, 12:42 AM

*/
/ CONFIG

// Oscillator Selection bits (HS oscillator)

#pragma config FOSC = HS

#pragma config WDTE = OFF

// Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = OFF
#pragma config BOREN = OFF

// Power-up Timer Enable bit (PWRT disabled)
// Brown-out Reset Enable bit (BOR disabled)

#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

(Code protection off)

// Flash Program Memory Code Protection bit

/ #pragma config statements should precede project file includes.
/ Use project enums instead of #define for ON and OFF.

#include <xc.h>
16


#include
#include
#include "74ls138.h"
#include "lcd4bit.h"
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 20000000
void ADCinit(void);
unsigned int read_adc(void);
unsigned int giatri = 0;
float f;
unsigned int voltage;
int i;
//unsigned char Code7Seg[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41,
0x1f, 0x01, 0x09};
//unsigned int chuc, donvi, nghin, tram;
//unsigned int i, j;
//unsigned int mang[4] = {0X0C, 0X10, 0X14, 0X18}; //quet 74ls138


void port_init() {

TRISD = 0X00;
TRISB=0x00;
PORTD=0x00;
PORTB=0x00;
}

17


void ADCinit(void)// adc
{// chon tan so clock cho bo adc
ADCON1bits.ADCS2 = 1, ADCON0bits.ADCS1 = 1, ADCON0bits.ADCS0 = 0;
// chon kenh adc la kenh an0
ADCON0bits.CHS2 = 0, ADCON0bits.CHS1 = 0, ADCON0bits.CHS0 = 0;
/ chon cach luu data

ADCON1bits.ADFM = 1;
/ cau hinh cong vao

ADCON1bits.PCFG3 = 1, ADCON1bits.PCFG2 = 1, ADCON1bits.PCFG1 = 1,
ADCON1bits.PCFG0 = 0;
/ cap nguon cho khoi adc

ADCON0bits.ADON = 1;

}

unsigned int read_adc(void)// doc len 7

doan {
unsigned int TempValue = 0;
ADCON0bits.GO_nDONE = 1; while
(ADCON0bits.GO_nDONE); TempValue
= ADRESH * 256 + ADRESL; return
(TempValue);

}
//unsigned int read_adc(void) {
/

ADCON0bits.GO_DONE = 1;

/

while (ADCON0bits.GO_DONE);

/

return (((ADRESH & 0x03) << 8) + ADRESL); // d?ch tr?i khi ADFM =1
18


//}

//void hienthi_sothuc(unsigned int f) {
/

char s[20];


/

sprintf(s, "Nhiet Do = %g", f);

/

LCD_Puts(s);

//
//}

//void display(long count) {
/

nghin = count / 1000;

/

tram = (count - nghin * 1000) / 100;

/

chuc = (count - nghin * 1000 - tram * 100) / 10;

/

donvi = count - nghin * 1000 - tram * 100 - chuc * 10;
/

/


PORTA = mang[0];

/

PORTD = Code7Seg[nghin];

/

__delay_ms(5);

//
//
/

PORTA = mang[1];

/

PORTD = Code7Seg[tram];

/

__delay_ms(5);

//
//
// PORTA = mang[2];
19



/

PORTD = Code7Seg[chuc];

/

__delay_ms(5);

//
//
/

PORTA = mang[3];

/

PORTD = Code7Seg[donvi];

/

__delay_ms(5);

//
//}

void main(void) {
port_init();
ADCinit();
LCD_Init();

char s[20];
while (1) {

LCD_Gotoxy(0, 0);
LCD_Puts("Do nhiet do");
giatri = read_adc();
voltage = 5000.0f / 1023 * giatri;//cong thuc tinh adc
f = voltage / 10;
sprintf(s, "NHIET DO = %2.2f ", f);
LCD_Gotoxy(1, 0);
__delay_ms(500);
LCD_Puts(s);
LCD_PutChar(223);
20


LCD_Puts("C");
__delay_ms(100);
if(f>=40)
{
RB0=1;
}
else
RB0=0;

}
}

21



BÀI 3: ĐO TỐC ĐỘ ĐỘNG CƠ BẰNG ENCODER SỬ DỤNG
NGẮT NGỒI VÀ TIMER1 CỦA VĐK PIC16F877A


Sử dụng ngắt ngồi để đếm số xung và sử dụng timer1 để cài thời gian trích
mẫu là 10ms tốc độ động cơ được tính theo cơng thức
Tốc độ={(tổng số xung/thời gian trích mẫu)*60)/độ phần giải của động cơ

❖ Nguyên lý hoạt động của ngắt ngồi


Ta sử dụng các thanh ghi INTCON và OPTION_REG để cài đặt cho ngắt ngoài.

Bit 6 INTEDG:
1: Cho phép chân ngắt tích cực cạnh xuống.
2: Cho phép chân ngắt tích cực cạnh lên.

Bit 7 GIE:
1: Cấm tất cả các nguồn ngắt.
2: Cho phép tất cả các nguồn ngắt.
Bit 4 INTE:
1: Khơng cho phép ngắt ngồi.
2: Cho phép ngắt ngồi.

/*
* File: main.c
* Author: minhlam

*

22


* Created on March 19, 2017, 10:58 PM

*/
#define _XTAL_FREQ 20000000

#define RS RD1
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7

#include <xc.h>
#include<stdio.h>
#include "lcd.h"
#include
// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // 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)

23


#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code
protection off)
//END CONFIG
float dem=0;

float Soxungdem=0;
float tongsoxung=0;
float count;
void _KhoiTaoTIMER1(void)
{

T1CONbits.TMR1CS = 0;
T1CONbits.T1CKPS1 = 1;
T1CONbits.T1CKPS0 = 1;//ti le chia 1:8
TMR1=59286;
T1CONbits.TMR1ON = 1;
PIE1bits.TMR1IE=1; //cho phep ngat timer1
}
void _KhoiTaoNgatNgoai(void)
{
TRISBbits.TRISB0=1;
INTCONbits.PEIE=1;//ngat ngoai vi
INTCONbits.INTE=1; //ngat RB0
OPTION_REGbits.INTEDG=1; //ngat canh xuong
INTCONbits.INTF=0;

}
void main(void) {
24


//khai bao bien cuc bo o day
float TocDo;

TRISD=0x00;
PORTDbits.RD2=0;
unsigned char s[20];
_KhoiTaoTIMER1();
_KhoiTaoNgatNgoai();
INTCONbits.GIE=1;// ngat toan cuc
Lcd_Init();
while(1)
{

if(INTCONbits.INTF)
{

Soxungdem=Soxungdem+1;
INTCONbits.INTF=0;
}

if(PIR1bits.TMR1IF)
{

INTCONbits.INTE=0;// ko cho ngat RB0
T1CONbits.TMR1ON=0;

tongsoxung=Soxungdem;
25


×