1. Trang chủ
  2. » Giáo án - Bài giảng

Thực hành lập trình PIC16F877A CCS

176 270 2

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 176
Dung lượng 7,14 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

BÀI 4 : GIAO TIẾP VỚI NÚT NHẤNPIC16F877A CCS P2 7:07:00 AM CCS PIC16F877A CCSChào các bạn trong bài 3 mình đã giới thiệu với các bạn về cách giao tiếp với nút nhấn rồi bạn nào chưa xem t

Trang 1

BÀI 1 : CHỚP TẮT LED PIC16F877A CCS

7:59:00 AM CCS PIC16F877A CCSChào các bạn trong bài đăng này mình sẽ hướng dẫn các bạn về I/O của PIC16F877A cụ thể là chớp tắt led

- Dưới đây là ảnh mô phỏng Protues

- Đây là code chương trình

set_tris_b(0x00); // portb la output

output_b(0); // off all led

while(true)

Trang 2

delay_ms(1000);output_b(0xff);delay_ms(1000);output_b(0x00);}

}

Trang 3

BÀI 2 : HIỆU ỨNG LED PIC16F877A CCS

Trang 5

// sang dan and tat dan

for(i=0;i<9;i++)

{

Trang 6

delay_ms(100);

PORTB = PORTB<<1;

}

/////////

X=0X00000000; for(I=0;I<8;I++)

Trang 7

PORTB = (Y);delay_ms(100);

D=0X03;

for(I=0;I<J;I++)

{

Y=CD+D;

PORTB = (Y);delay_ms(100);

D=(D<<2);

}

CD=Y;

}

Trang 8

}}

Trang 9

BÀI 3 : GIAO TIẾP VỚI NÚT NHẤN

Trang 11

BÀI 4 : GIAO TIẾP VỚI NÚT NHẤN

PIC16F877A CCS (P2)

7:07:00 AM CCS PIC16F877A CCSChào các bạn trong bài 3 mình đã giới thiệu với các bạn về cách giao tiếp với nút nhấn rồi bạn nào chưa xem thì xem lại tại đây để hiểu rõ hơn về cấu tạo và phân loại của nó nha ! Còn trong bài đăng này mình sẽ hướng dẫn các bạn thêm 1 phần nữa cũng là giao tiếp với nhút nhấn nhưng nó sẽ khó hơn bài trước vì trong bài trước chúng ta chỉ dùng lại ở việc giao tiếp thôi còn trong bài này thì chúng ta sẽ ứng dụng nó vào bài này để chuyển đổi hiệuứng LED dùng 1 nút nhấn cụ thể là khi chúng ta không nhấn nút thì chương trình sẽ chạy bình thường còn nếu chúng ta nhấn nút thì nó sẽ chuyển sang hiệu ứng khác cho chúng ta ngay lập tức ! Chúng ta sẽ có đoạn chương trình như sau !

unsigned char KiemTraPhim()

Trang 12

return 0;

}

- Đoạn chương trình trên dùng để delay và kiểm tra nút nhấn của chúng ta cụ thể là khi nhấn nút thì nó sẽ kiểm tra cái bit check của chúng ta nếu mà bit check = 1 thì có nghĩa nút nhấn của chúng ta được nhấn nó sẽ return 1 còn nếu không nhấn thì nó sẽ return 0

Và đoạn chương trình trong void main (void) được viết như sau :

Trang 13

}

}

- Giải thích đoạn chương trình trên như sau : Mỗi hiệu ứng LED bình thường chúng ta sẽ cho nó chạy 20 lần nếu như chúng ta nút nhấn nó sẽ lặp tức thoát khỏi chương trình đang thực thi và nhảy vào chương trình tiếp theo !

Trang 15

{

if(KiemTraPhim()) break; delay_ms(1000);

LED = ~LED;

}

}

}

Trang 16

BÀI 5 : HIỂN THỊ SỐ 2015 LÊN LED 7

ĐOẠN CCS

11:17:00 PM CCS PIC16F877A CCS

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 18

rc3=1;}}

Trang 19

BÀI 6 : ĐẾM TỪ 0 ĐẾN 9 PIC16F877A

CCS

5:04:00 AM CCS PIC16F877A CCS

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 20

void main (void){

Trang 21

BÀI 7 : ĐẾM TỪ 0 ĐẾN 99 PIC16F877A

CCS

9:56:00 PM CCS PIC16F877A CCSChào các bạn trong bài đăng trước mình đã hướng dẫn các bạn giao tiếp với LED 7 SEG

cụ thể là đếm từ 0 đến 9 còn trong bài đăng này mình sẽ hướng dẫn các bạn đếm từ 0 – 99

sử dụng PIC16F877A và trình biên dịch MPLAB XC8 để viết code

Đếm từ 0 - 9 thì chỉ có 1 LED còn đếm từ 0 - 99 thì có 2 LED nên trong cùng 1 thời điểm PORTX của con PIC không thể xuất dữ liệu ra 2 LED được nên buộc chúng ta phải sử dụng 2 chân của LED để bật, tắt phù hợp để dữ liệu có thể xuất ra 2 LED của chúng ta

Và giải thuật được viết như sau :

Trang 22

- Đây là code chương trình.

Trang 23

delay_ms(40);

ra1=1;

// -hiển thị số hàng đơn vị -\\dem++;

Trang 24

BÀI 8 : ĐẾM TỪ 0 ĐẾN 9999 PIC16F877A

CCS

3:50:00 AM CCS PIC16F877A CCSChào các bạn trong bài đăng trước mình đã hướng dẫn các bạn giao tiếp với LED 7 SEG

cụ thể là đếm từ 0 đến 99 còn trong bài đăng này mình sẽ hướng dẫn các bạn đếm từ 0 –

9999 sử dụng PIC16F877A và trình biên dịch MPLAB XC8 để viết code

Đếm từ 0 - 99 thì chỉ có 1 LED còn đếm từ 0 - 9999 thì có 4 LED nên trong cùng 1 thời điểm PORTX của con PIC không thể xuất dữ liệu ra 4 LED được nên buộc chúng ta phải

sử dụng 4 chân của LED để bật, tắt phù hợp để dữ liệu có thể xuất ra 4 LED của chúng ta

Và giải thuật được viết như sau :

Và khi đếm chúng ta phải xác định LED nào là LED hàng nghin,tram,chuc,donvi và chúng

ta có công thức tính như sau :

nghin = dem/1000;

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

Trang 25

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

donvi = dem - nghin*1000 - tram*100 - chuc*10;

Hai phần mình nói ở trên cũng chính là 2 phần quan trọng để các bạn làm được bài này và các bạn có thể phát triển PROJECT của mình lên từ 2 LED có thể lên 6 hoặc 8 LED

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 26

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

chuc=(dem - nghin*1000 - tram*100)/10;donvi=dem - nghin*1000 - tram*100 - chuc*10;// phan tach so \\

Trang 27

dem=0;

}

}

}

Trang 28

BÀI 9 : ĐẾM TỪ 9999 VỀ 0 PIC16F877A

CCS

8:42:00 PM CCS PIC16F877A CCSChào các bạn trong bài đăng trước mình đã hướng dẫn các bạn giao tiếp với LED 7 SEG

cụ thể là đếm từ 0 đến 9999 còn trong bài đăng này mình sẽ hướng dẫn các bạn đếm từ

9999 – 0000 sử dụng PIC16F877A và trình biên dịch CCS để viết code

Trong bài này chúng ta đếm lùi từ 9999 - 0 nên code giống với đếm từ 0 - 9999 nhưng chỉ thay đổi chỗ count ++ thành count để đếm lùi

Và giải thuật được viết như sau :

Và khi đếm chúng ta phải xác định LED nào là LED hàng nghin,tram,chuc,donvi và chúng

ta có công thức tính như sau :

nghin = dem/1000;

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

Trang 29

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

donvi = dem - nghin*1000 - tram*100 - chuc*10;

Và muốn đếm lùi thì các bạn có cách làm như sau đầu tiên gắn biến dem=xxxx sau đó :dem ;

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 30

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

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

donvi=dem - nghin*1000 - tram*100 - chuc*10;

// phan tach so \\

Trang 32

BÀI 10 : TIMER 0 PIC16F877A CCS

1:20:00 AM CCS PIC16F877A CCSChào các bạn trong bài đăng này mình sẽ hướng dẫn về timer của PIC16F877A Các bạn chú ý đây là 1 trong các modun của PIC16F877A và nó cũng rất quan trọng và được sử dụng rất nhiều nên các bạn phải chú ý để nắm rõ về nó

Về phần lý thuyết các bạn đọc Datasheet hoặc lên mạng tìm hoặc qua bên TUT về

- 256 vì đây là Timer 8 bit

Trang 33

- Đây là code chương trình.

Trang 35

BÀI 11 : TIMER 1 PIC16F877A CCS

1:47:00 AM CCS PIC16F877A CCSChào các bạn trong bài đăng trước mình đã hướng dẫn các bạn về timer0 và trong bài đăng này mình sẽ tiếp tục hướng dẫn các ban về timer1 của PIC16F877A Timer 1 và 0 là 2loại timer mà chúng ta rất hay sử dụng vì vậy các bạn phải nắm chất về 2 bộ timer này nha

Ok bây giờ mình sẽ đi vào vấn đề chính ngay

Về phần lý thuyết các bạn đọc Datasheet hoặc lên mạng tìm hoặc qua bên TUT về

PIC16F877A XC8 tìm đọc nha !

Chúng ta sẽ tính toán các thông số để cài đặt cho Timer 1 theo công thức sau : Ví dụ muốnđịnh thời 50ms = 50000us sử dụng prescaler 1:8, Fosc = 4 Mhz thì ta có công thức tính như sau :

GT = 65536 - Tdelay.Fosc/(4.Kprescaler)

Từ công thức trên thay số vào ta được như sau :

GT = 65536 - 50.10^-3.4.10^6.(4/8) = 59286

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 37

BÀI 12 : EEPROM PIC16F877A CCS

có hỗ trợ hai hàm đọc và viết dữ liệu EEPROM

- Hàm viết dữ liệu data vào địa chỉ addr:

- Hàm viết một chuỗi kí tự vào địa chỉ addr

void eeprom_write_string(unsigned int8 addr,unsigned char*str)

- Hàm đọc len kí tự từ eeprom bắt đầu từ địa chỉ addr

void eeprom_read_string(unsigned int8 addr, unsigned char* str,unsigned int8 len)

{

unsigned int8 i;

Trang 38

- Đây là ảnh mô phỏng protues.

- Đây là code chương trình

Trang 40

Để delay 1s thì chương trình con ngắt 100ms phải thực hiện 10 lần, mỗi lần ngắt 100ms thì tăng biến đếm ngắt BDN lên 1 đơn vị, kiểm tra nếu bằng 10 thì cho bằng 0 và đảo trạng thái của led, nếu chưa bằng 10 thì thoát và thực hiện tiếp chương trình chính Ý nghĩa của việc dùng TIMER 1 để delay 1s chính xác hơn khi chúng ta sử dụng lệnh delay_ms().

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

#INCLUDE <16F877a.H>

#FUSES NOWDT, PUT, HS, NOPROTECT, NOLVP

Trang 42

BÀI 14 : GIAO TIẾP UART PIC16F877A

Để bắt đầu cho việc truyền dữ liệu bằng UART, một START bit được gửi đi, sau đó là cácbit dữ liệu và kết thúc quá trình truyền là STOP bit

Như hình các bạn có thể thấy Khi ở trạng thái chờ mức điện thế ở mức 1 (high) Khi bắtđầu truyền START bit sẻ chuyển từ 1 xuống 0 để báo hiệu cho bộ nhận là quá trình truyền

dữ liệu sắp xảy ra Sau START bit là đến các bit dữ liệu D0-D7 (Theo hình vẽ các bit này cóthể ở mức High or Low tùy theo dữ liệu) Sau khi truyền hết dữ liệu thì đến Bit Parity để bộnhận kiểm tra tính đúng đắn của dữ liệu truyền (vấn đề này mình sẽ giải thích rõ hơn trong

Trang 43

tài liệu CRC trong thời gian tới) Cuối cùng là STOP bit là 1 báo cho thiết bị rằng các bit đãđược gửi xong Thiết bị nhận sẽ tiến hành kiểm tra khung truyền nhằm đảm báo tính đúngđắn của dữ liệu.

Các thông số cơ bản trong truyền nhận UART:

- Baund rate (tốc độ baund ): Khoảng thời gian dành cho 1 bit được truyền Phải

- Frame (khung truyền ): Khung truyền quy định về số bit trong mỗi lần truyền

- Start bit : là bit đầu tiên được truyền trong 1 Frame Báo hiệu cho thiết bị nhận

có một gói dữ liệu sắp đc truyền đến Bit bắt buộc

- Data : dữ liệu cần truyền Bit có trọng số nhỏ nhất LSB được truyền trước sau đó đến bitMSB

- Parity bit : kiểm tra dữ liệu truyền có đúng không

- Stop bit : là 1 hoặc các bit báo cho thiết bị rằng các bit đã được gửi xong Thiết

bị nhận sẽ tiến hành kiểm tra khung truyền nhằm đảm bảo tính đúng đắn của dữliệu Bit bắt buộc

2 Tổng quan về truyền nhận dữ liệu bằng UART trong PIC16F877A Truyền

Sơ đồ khối bộ truyền UART:

Nguyên tắc hoạt động:

1 Dữ liệu cần truyền được đặt vào thanh ghi TXREG, baund rate được tạo ra, khi TXEN gán bằng 1

Trang 44

dữ liệu từ thanh ghi TXREG đưa vào thanh ghi TSR đồng thời baund rate tác động đến TSR, đẩy

dữ liệu cần truyền ra bộ đệm sau đó xuất ra chân TX

2 Bit TXIF dùng để báo trạng thái trong thanh ghi TXREG, nếu có dữ liệu trong TXREG thì TXIF =

1 Nếu dữ liệu được truyền xuống thanh TSR thì TXIF = 0 Tương tự bit TRMT dùng để báo trạng

thái thanh ghi TSR

Như vậy các bước cho quá trình gửi dữ liệu bao gồm:

1 Khởi tạo baund rate: ở thanh ghi SPBRG

Cho phép quá trình truyền thông không đồng bộ bằng cách thiết lập SPEN = 1; SYNC = 0;

2 Cho phép truyền dữ liệu bằng cách thiết lập bit TXEN = 1;

3 Khi cần truyền dữ liệu thì cần set dữ liệu đó lên TXREG

Thanh ghi quy định chế độ truyền.

- CSRC:

- TX9: Cho phép truyền nhận chế độ 9 bit

- TX9 = 1; // Hoạt động với chế độ 9 bit.- TX9 = 0; // Hoạt động với chế độ 8 bit.- TXEN: Cho phép truyền UART

- TXEN = 1; // Cho phép- TXEN = 0; // Không cho phép- SYNC: Cho phép chế độ đồngbộ

- SYNC = 1; // Truyền chế độ đồng bộ.- SYNC = 0; // Truyền chế độ bất đồng bộ.- BRGH: Chọn chế độ baund rate

- BRGH = 1; // Tốc độ cao (bất đồng bộ).- BRGH = 0; // Tốc độ thấp (bất đồng bộ).- TRMT: Trạng thái thanh ghi truyền

- TRMT = 1; // Thanh ghi TSR trống- TRMT = 0; // Thanh ghi TSR có dữ liệu.- TX9D:

Dữ liệu bit thứ 9 trong chế độ truyền 9 bit

Trang 45

ngắt và PIC sẽ tạm dừng chương trình hiện thời để xử lý dữ liệu vừa nhận được.

Như vậy các bước cho quá trình nhận dữ liệu bao gồm:

1 Khởi tạo baund rate: ở thanh ghi SPBRG

Cho phép quá trình truyền thông không đồng bộ bằng cách thiết lập SPEN = 1; SYNC = 0;

2 Cho phép ngắt quá trình nhận dữ liệu CREN = 1;

3 Cho phép ngắt toàn cục: CIE = 1; PEIE = 1;

Trang 46

4 Xử lý các phần khác của chương trình khi có ngắt xảy ra thì xử lý dữ liệu.

Thanh ghi quy định chế độ nhận:

- SPEN: Khởi tạo cổng nối tiếp

- SPEN = 1; // Cho phép cổng nối tiếp- SPEN = 0; // Không cho phép- RX9: Cho phép nhận 9bit

- RX9 = 1; // Cho phép nhận 9bit- RX9 = 0; // Nhan 8bit- CREN: Cho phép nhận liên tục

- CREN = 1; // Cho phép- CREN = 0; // Không cho phép- ADDEN: Bit cho phép phát hiện địa chỉ (sử dụng ở chế độ truyền nhận bất đồng bộ 9 bit )

- ADDEN = 1; // Cho phép phát hiện địa chỉ , cho phép ngắt và tải bộ đệm nhận khi RSR<8> được set.- ADDEN = 0; // Không cho phép phát hiện địa chỉ , tất cả byte được nhận và bit thứ 9 dùng làm bit parity.- FERR: Bit báo lỗi frame

- FERR == 1; // Có lỗi.- FERR == 0; // Không có lỗi.- OERR: Lỗi OVERRUN

- OEER == 1 ; // Có lỗi- OEER == 0; // Không lỗi- RX9D: Lưu dữ liệu nhân của bit thứ 9

- Thanh ghi TXREG: Dùng để chứa dữ liệu truyền đi

- Thanh ghi RCREG: Dùng để lưu dữ liệu từ ngoài vào

- Thanh ghi SPBRG: Thiết lập baud rate của PIC

4 BaudRate và Công thức tính Baud Rate

Như mình đã nêu trên, UART khác với I2C ở điểm là nó không có dây CLK Vậy để 2 thiết bị truyền

và nhận dữ liệu hiểu được độ dài của mỗi bit tín hiệu để gửi và nhận chính xác tín hiệu thì ta cần phải

thiết lập được độ dài của bit tín hiệu Ta có thể hiểu nó là baund rate

Công thức tính:

Trang 47

- Đây là ảnh mô phỏng protues.

- Đây là code chương trình Master

#include <16F877a.h>

#FUSES NOWDT, HS, PUT, NOPROTECT,

#use DELAY(clock=16000000)

Trang 48

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7) int8 TDATA;

Trang 49

BÀI 15 : GIAO TIẾP UART PIC16F877A

CCS (P2)

4:54:00 AM CCS PIC16F877A CCSChào các bạn hôm nay mình sẽ hướng dẫn các bạn tiếp phần UART nha Trong BÀI

14 mình đã hướng dẫn lý thuyết và đã làm 1 ví dụ nhỏ về giao tiếp UART nên bạn nào chưa xem bài trước thì xem lại bài 14 nha ! Bài hôm bữa chúng ta chỉ dừng lại ở việc giao tiếp giữa 2 con Vi Điều Khiển con Master sẽ gửi lệnh sang con Slave của chúng ta sẽ nhận lệnh và thực hiện nhưng hôm bữa chúng ta chỉ dừng lại ở giao tiếp với LED thôi hôm nay

sẽ thêm nút nhấn nữa ! OK

- Đây là ảnh mô phỏng proteus

- Đây là code chương trinh Master

Trang 50

void main()

{

SET_TRIS_D(0x00);

output_d(0);

Trang 51

}

Trang 52

BÀI 16 : GIAO TIẾP VỚI LCD 16X02

PIC16F877A CCS

5:17:00 AM CCS PIC16F877A CCSTrong hướng dẫn này chúng ta sẽ thấy như thế nào để giao tiếp một LCD 16 × 2 Module với PIC 16F877A Vi điều khiển sử dụng CCS C Compiler LCD 16 × 2 là màn hình LCD module rất thường được sử dụng trong các dự án điện tử và các sản phẩm 16 × 2 có nghĩa là nó có thể hiển thị 2 dòng 16 ký tự Nó là một mô-đun chi phí rất cơ bản và thấp Biến thể khác của nó như 16 × 1, 20 × 4 có sẵn trên thị trường Trong các màn hình này mỗi ký tự được hiển thị bằng cách sử dụng 5 × 8 hoặc 5 × 10 dot matrix Những màn hình LCD thường sử dụng các bộ điều khiển tương thích HD44780 cho hoạt động của mình

Trong bài này mình cũng có sử dụng 1 số lệnh cơ bản để điều khiển LCD

- Ảnh mô phỏng protues

Trang 53

- Đây là code chương trình.

Trang 54

LCD_PutChar("chiasedientu.blogspot.com");for(i=0;i<20;i++)

Trang 55

BÀI 17 : ĐỌC GIÁ TRỊ ADC XUẤT RA

LED VÀ LCD PIC16F877A CCS

6:26:00 PM CCS PIC16F877A CCS

Về phần lý thuyết các bạn đọc Datasheet hoặc lên mạng tìm hoặc qua bên TUT về PIC16F877A XC8 tìm đọc nha !

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 56

delay_us(100);

}

Trang 57

BÀI 18 : ĐO GIÁ TRỊ ĐIỆN ÁP TỪ 0 ĐẾN

5V PIC16F877A CCS

5:55:00 AM CCS PIC16F877A CCSChào các bạn trong BÀI 17 mình đã hướng dẫn các bạn lý thuyết về ADC trong

PIC16F877A và đã làm 1 ví dụ nhỏ về ADC Trong bài này chúng ta sẽ ứng dụng ADC để làm 1 số ứng dụng nhỏ cụ thể trong bài này chúng ta sẽ đo giá trị điện áp từ 0 đến 5V và hiển thị kết quả lên LCD 16x02

Công thức tính giá trị điện áp như sau :

x = 5 * read_ADC() / 1023;

Với công thức trên thì giá trị điện áp Max sẽ là 5V tương ứng với giá trị ADC là 1023 và 0V

sẽ tương ứng với giá trị ADC là 0

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Trang 58

delay_us(100);

}

Trang 59

BÀI 19 : ĐO NHIỆT ĐỘ LM35 HIỂN THỊ

LCD PIC16F877A CCS

8:16:00 PM CCS PIC16F877A CCSXem lý thuyết về LM35 bên PIC16F877A XC8 nha !

- Đây là ảnh mô phỏng protues

- Đây là code chương trình

Ngày đăng: 16/12/2019, 17:06

TỪ KHÓA LIÊN QUAN

w