CHƯƠNG 5: PORT XUẤT NHẬP CỦA VĐK PIC 16F8XX 8BIT

Một phần của tài liệu Bài giảng lý thuyết vi xử lý kỹ thuật vi xử lý cd rom (Trang 58 - 82)

VI. VI XỬ LÝ VÀ VI ĐIỀU KHIỂN Về cấu trúc phần cứng:

CHƯƠNG 5: PORT XUẤT NHẬP CỦA VĐK PIC 16F8XX 8BIT

- Trình bày được cấu trúc và tập lệnh của VĐK PIC và các thanh ghi lien quan đến các PORT. - Trình bày được qui trình phân tích, thiết kế các hệ mạch ứng dụng hệ VĐK với ngoại vi qua các PORT.

- Phân tích, thiết kế các hệ mạch ứng dụng hệ VĐK với ngoại vi qua các port.

- Thiết kế lưu đồ giải thuật và lập trình ứng dụng cho các mạch điều khiển xuất nhập cơ bản sử dụng (LED đơn, LED 7 đoạn, LED ma trận, LCD,…).

- Vẽ được sơ đồ nguyên lý mạch điều khiển xuất nhập cơ bản sử dụng (LED đơn, LED 7 đoạn, LED ma trận, LCD,…).

5.1. Giới thiệu

+ Vi điều khiển là một chip rất linh hoạt và có thể được lập trình để hoạt động trong một số cấu hình khác nhau. PIC 16F877A có 33 đường I/O.

+ Cụ thể: 16F877A có 5 port: port A là port 6 bit nó có 6 đường I/O, port B có 8 đường I/O, port C có 8 đường I/O, port D có 8 đường I/O, và port E có 3 đường I/O.

5.2. Chức năng

+ PortA là port 2 chiều, 6 bit. Thanh ghi định hướng dữ liệu tương ứng và TRISA. Bật các bit TRISA (=1) sẽ làm cho các chân portA tương ứng là ngõ vào (input) (nghĩa là đặt bộ điều khiển (driver) ngõ tương ứng trong chế độ tổng trở cao Hi-Z). Xóa bit TRISA (=0) sẽ làm cho chân portA tương ứng là ngõ ra (output) (nghĩa là đặt nội dung của mạch cài ngõ ra trên chân được chọn).

+ Tương tự, PortB là port 2 chiều, 8 bit. Thanh ghi định hướng dữ liệu tương ứng là TRISB. + Tương tự, PortC là port 2 chiều, 8 bit. Thanh ghi định hướng dữ liệu tương ứng là TRISC. + PortD là port 8 bit với đệm ngõ vào Schmitt-trigger. Thanh ghi định hướng dữ liệu tương ứng là TRISD.

+ PortE có 3 chân (RE0/RD/AN5, RE1/WR/AN6, RE2/CS/AN7) mà có thể được cấu hình riêng biệt như là ngõ vào hay ngõ ra. Thanh ghi định hướng dữ liệu tương ứng là TRISE. Chú ý thêm đối với PORTE, đảm bảo rằng thanh ghi ADCON được cấu hình cho I/O số. Trong chế độ này, bộ đệm ngõ vào là TTL.

5.3 Tập các thanh ghi liên quan

+ Trong Chương nhập/xuất các PORT, ta chỉ quan tâm đến chức năng các port là digital I/O. Các chức năng đặc biệt khác sẽ trình bày tuần tự trong các phần kế tiếp.

58

+ Để điều khiển I/O, sử dụng thanh ghi tên TRIS tương ứng với Port cần dùng (đã trình bày ở 5.2). Như vậy, có các cặp thanh ghi tương ứng: PORTA-TRISA; PORTB-TRISB; PORTC-TRISC; PORTD- TRISD và PORTE-TRISE.

5.4. Lập trình điều khiển các chức năng xuất nhập

+ Thanh ghi PIC gồm có 4 BANK độc lập. Khi sử dụng thanh ghi nào, trước hết ta cần chọn BANK chứa thanh ghi tương ứng. Trong ngôn ngữ ASM, câu lệnh BANKSEL <tên thanh ghi> cần được thực hiện trước khi dùng thanh ghi. Tuy nhiên trong ngôn ngữ Hitech-C, người lập trình không cần quan tâm đến các BANK thanh ghi, nó sẽ được thực hiện tự động.

+ Có 2 trường hợp đưa dữ liệu vào/ra Port: theo từng bit và theo 1 Byte. 5.5 Ứng dụng ghép nối với ngoại vi

+ Do những ưu điểm vượt bậc của ngôn ngữ C so với ASM, tác giả chỉ chú trọng sử dụng ngôn ngữ C cho tất cả các ví dụ trong bài giảng.

Ví dụ 1:

Thực hiện điều khiển đồng thời tắt, mở các led ở PORTB theo Ton=Toff=500 ms.

#define _XTAL_FREQ 4000000 #include <htc.h>

void delay_for_500ms(void); // Khai báo chương trình con __CONFIG(0x3FFA);

void main(void) {

59

PORTB = 0x00; // Cho 8 chân PORTB xuống mức 0 – các Led OFF while(1) // Chạy vòng lặp mãi mãi

{

PORTB = 0xFF; // Cho 8 chân PORTB xuống mức 0 – các Led ON delay_for_500ms(); // Gọi chương trình con tạo trễ 500ms

PORTB = 0x00; // Cho 8 chân PORTB xuống mức 0 – các Led OFF delay_for_500ms(); // Gọi chương trình con tạo trễ 500ms

} }

void interrupt isr(void) // Chương trình con ngắt – không dùng tới { } (adsbygoogle = window.adsbygoogle || []).push({});

void delay_for_500ms(void) // Chương trình con tạo trễ 500ms {

unsigned char count1, count2, i; for (count2=10; count2>0; count2--)

{

for (count1=50; count1>0; count1--) {

for (i=0; i<100; i++) {

} // chú ý: tạo trễ dạng này không được chính xác }

} }

Ví dụ 2:

Thực hiện điều khiển tắt, mở các led ở PORTB từ chân PORTB.0 đến PORTB.7 theo chu kỳ lặp lại với Ton=Toff=500 ms. #define _XTAL_FREQ 4000000 #include <htc.h> __CONFIG(0x3FFA); void main(void) {

TRISB = 0x00; // PORTB là Output

PORTB = 0b00000001; // Led ON tại chân PORTB.0 while(1)

{ __delay_ms(500); // Tạo trễ chính xác 500ms, dùng thư viện của Hitech-C PORTB = PORTB<<1; // Dịch các bit của PORTB sang trái 1 đơn vị

if (PORTB == 0x00) // Kiểm tra đã dịch trái 8 đơn vị hay không {PORTB = 0b00000001;} //nếu đúng thì gán lại giá trị cho PORTB }

60 Ví dụ 3:

Thực hiện hiển thị Led 7 đoạn anode chung các số từ 0 đến 9. Thời gian hiển thị mõi số là 1s.

Dựa vào kết nối từ sơ đố mạch, ta xây dựng bảng mã cho Led 7 đoạn. Chú ý, Led 7 đoạn cực dương chung, và segment-a nối với chân trọng số thấp nhất (PORTB.0), segment-dp nối với chân trọng số cao nhất (PORTB.7).

#define _XTAL_FREQ 4000000 #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #include <htc.h>

__CONFIG(0x3FFA);

const uchar seg7led[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; uchar val=0;

61 //*************** main ******************** void main(void) { TRISB=0x00; PORTB=0xFF; while(1) { if (val==10) { val=0; } else { PORTB = seg7led[val]; __delay_ms(1000); val ++; } } } Ví dụ 4:

Thực hiện hiển thị đồng thời 2 Led 7 đoạn anode chung các số từ 00 đến 59. Thời gian hiển thị mỗi số là 1s. Tần số lưu ảnh của mắt: 25 hình/s  với 2 led thì mỗi led sẽ sáng trong 20ms. #define _XTAL_FREQ 4000000

#define uchar unsigned char #define uint unsigned int #define ulong unsigned long #include <htc.h>

__CONFIG(0x3FFA);

const uchar seg7led[]={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 }; uchar val1=0; uchar val2=0; //*************** main ******************** void main(void) { TRISB=0x00; PORTB=0xFF; TRISC1 = 0; TRISC2 = 0; while(1) {

62 {

for (val2=0 ; val2<10 ; val2++) {

for (uchar count=25; count>0; count--) { PORTB = seg7led[val1]; RC1 = 0; RC2 = 1; __delay_ms(20); RC1 = 1; RC2 = 1; PORTB = seg7led[val2]; RC1 = 1; RC2 = 0; __delay_ms(20); RC1 = 1; RC2 = 1; } } } } } Ví dụ 5:

Thực hiện lại ví dụ 3 khi Led 7 đoạn dùng thêm IC chốt song song (74LS373; 74LS374)

Do có IC chốt song song, dữ liệu từng Led 7 đoạn sẽ được chốt vào từng Led tương ứng mà không cần phải quét các led theo chu kỳ để lưu ảnh. Phương pháp dùng IC chốt có ưu điểm cho Led sáng không nhấp nhấy, ổn định và lập trình cho vi điều khiển nhẹ nhàng hơn.

63 for (val1=0 ; val1<6 ; val1++) (adsbygoogle = window.adsbygoogle || []).push({});

{

for (val2=0 ; val2<10 ; val2++) {

PORTB = seg7led[val1]; RC1 = 1;

RC1 = 0; // Chốt giá trị val1 cho Led 1 PORTB = seg7led[val2];

RC2 = 1;

RC2 = 0; // Chốt giá trị val2 cho Led 2 __delay_ms(1000);

} }

Ví dụ 6:

Hiển thị ký tự A lên Led ma trận.

+ Trước hết, chúng ta phải xem xét kết nối port anode và port cathode của Led ma trận với vi điều khiển. Port anode (dương chung) kết nối đến port C, Port cathode (âm chung) kết nối đến port B. Như vậy, Port C dùng để xuất tuần tự dữ liệu cột, và Port B dùng cho việc chọn cột dữ liệu đồng bộ với dữ liệu của Port C.

64 #define _XTAL_FREQ 4000000

#define uchar unsigned char #define uint unsigned int #define ulong unsigned long #include <htc.h>

__CONFIG(0x3FFA);

const uchar seg7led[]={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90 }; const uchar A[8][8]={ {0,0,0,1,1,0,0,0},

{0,0,1,0,0,1,0,0}, {0,1,0,0,0,0,1,0}, {1,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,1} }; //*************** main ******************** void main(void) {

// Configure PORTC as OUTPUT TRISC=0x00;

PORTC=0x00;

// Configure PORTB as OUTPUT TRISB=0x00;

PORTB=0x00; while(1)

{

PORTB=0b01111111; // Cột được tích cực mức 0 sẽ sáng for (uchar i=0; i<8; i++)

65 RC0=A[0][i]; RC1=A[1][i]; RC2=A[2][i]; RC3=A[3][i]; RC4=A[4][i]; RC5=A[5][i]; RC6=A[6][i]; RC7=A[7][i]; __delay_ms(5); PORTB = (PORTB >>1) + 0b10000000; // Dịch mức tích cực 0 sang phải 1 đơn vị,

// đồng thời cho cột ngoài cùng bên trái lên mức 1 vì PORTB là số không dấu nên số 0 được chèn vào trong phép dịch (còn gọi là phép dịch số học)

} }

}

Ví dụ 7:

66 + Cấu tạo và nguyên lý làm việc của LCD:

Khi sản xuất LCD, nhà sản xuất đã tích hợp chíp điều khiển (HD44780) bên trong lớp vỏ và chỉ đưa các chân giao tiếp cần thiết. Các chân này được đánh số thứ tự và đặt tên như hình trên.

+Các thanh ghi : HD44780 có 2 thanh ghi 8 bit quan trọng : Thanh ghi lệnh IR (Instructor Register) và thanh ghi dữ liệu DR (Data Register)

- Thanh ghi IR : Để điều khiển LCD, người dùng phải “ra lệnh” thông qua tám đường bus DB0- DB7. Mỗi lệnh được nhà sản xuất LCD đánh địa chỉ rõ ràng. Người dùng chỉ việc cung cấp địa chỉ lệnh bằng cách nạp vào thanh ghi IR. Nghĩa là, khi ta nạp vào thanh ghi IR một chuỗi 8 bit, chíp HD44780 sẽ tra bảng mã lệnh tại địa chỉ mà IR cung cấp và thực hiện lệnh đó. (adsbygoogle = window.adsbygoogle || []).push({});

- Thanh ghi DR : Thanh ghi DR dùng để chứa dữ liệu 8 bit để ghi vào vùng RAM DDRAM hoặc CGRAM (ở chế độ ghi) hoặc dùng để chứa dữ liệu từ 2 vùng RAM này gởi ra cho MPU (ở chế độ đọc). Nghĩa là, khi MPU ghi thông tin vào DR, mạch nội bên trong chíp sẽ tự động ghi thông tin này

Chân Ký

hiệu Mô tả

1 Vss Chân nối đất cho LCD, nối chân này với GND của mạch điều khiển 2 VDD Chân cấp nguồn cho LCD, nối chân này với VCC=5V của mạch điều khiển 3 VEE Điều chỉnh độ tương phản của LCD.

4 RS Chân chọn thanh ghi (Register Select).

+ Logic “0”: Bus DB0-DB7 sẽ nối với thanh ghi lệnh IR của LCD (ở chế độ “ghi” - write) hoặc nối với bộ đếm địa chỉ của LCD (ở chế độ “đọc” - read)

+ Logic “1”: Bus DB0-DB7 sẽ nối với thanh ghi dữ liệu DR bên trong LCD.

5 R/W Chân chọn chế độ đọc/ghi (Read/Write). Nối chân R/W với logic “0” để LCD hoạt động ở chế độ ghi, hoặc nối với logic “1” để LCD ở chế độ đọc.

6 E Chân cho phép (Enable). Sau khi các tín hiệu được đặt lên bus DB0-DB7, các lệnh chỉ được chấp nhận khi có 1 xung cho phép của chân E.

+ Ở chế độ ghi: Dữ liệu ở bus sẽ được LCD chuyển vào (chấp nhận) thanh ghi bên trong nó khi phát hiện một xung (high-to-low transition) của tín hiệu chân E. + Ở chế độ đọc: Dữ liệu sẽ được LCD xuất ra DB0-DB7 khi phát hiện cạnh lên (low-to-high transition) ở chân E và được LCD giữ ở bus đến khi nào chân E xuống mức thấp.

7 - 14 DB0 -

DB7 Tám đường của bus dữ liệu dùng để trao đổi thông tin với MPU. Có 2 chế độ sử dụng 8 đường bus này : + Chế độ 8 bit: Dữ liệu được truyền trên cả 8 đường, với bit MSB là bit DB7. + Chế độ 4 bit: Dữ liệu được truyền trên 4 đường từ DB4 tới DB7, bit MSB là DB7 15 - Nguồn dương cho đèn nền

67

vào DDRAM hoặc CGRAM. Hoặc khi thông tin về địa chỉ được ghi vào IR, dữ liệu ở địa chỉ này trong vùng RAM nội của HD44780 sẽ được chuyển ra DR để truyền cho MPU.

=> Bằng cách điều khiển chân RS và R/W chúng ta có thể chuyển qua lại giữ 2 thanh ghi này khi giao tiếp với MPU. Bảng sau đây tóm tắt lại các thiết lập đối với hai chân RS và R/W theo mục đích giao tiếp.

RS R/W Chức năng

0 0 Ghi vào thanh ghi IR để ra lệnh cho LCD

0 1 Đọc cờ bận ở DB7 và giá trị của bộ đếm địa chỉ ở DB0-DB6 1 0 Ghi vào thanh ghi DR

1 1 Đọc dữ liệu từ DR

+ Cờ báo bận BF: (Busy Flag) Khi thực hiện các hoạt động bên trong chíp, mạch nội bên trong cần một khoảng thời gian để hoàn tất. Khi đang thực thi các hoạt động bên trong chip như thế, LCD bỏ qua mọi giao tiếp với bên ngoài và bật cờ BF (thông qua chân DB7 khi có thiết lập RS=0, R/W=1) lên để báo cho MPU biết nó đang “bận”. Dĩ nhiên, khi xong việc, nó sẽ đặt cờ BF lại mức 0.

+ Vùng RAM hiển thị DDRAM : (Display Data RAM) Đây là vùng RAM dùng để hiển thị, nghĩa là ứng với một địa chỉ của RAM là một ô kí tự trên màn hình và khi bạn ghi vào vùng RAM này một mã 8 bit, LCD sẽ hiển thị tại vị trí tương ứng trên màn hình một kí tự có mã 8 bit mà bạn đã cung cấp. Hình sau đây sẽ trình bày rõ hơn mối liên hệ này :

+ Vùng ROM chứa kí tự CGROM: Character Generator ROM: Vùng ROM này dùng để chứa các mẫu kí tự loại 5x8 hoặc 5x10 điểm ảnh/kí tự, và định địa chỉ bằng 8 bit. Tuy nhiên, nó chỉ có 208 mẫu kí

68

tự 5x8 và 32 mẫu kí tự kiểu 5x10 (tổng cộng là 240 thay vì 2^8 = 256 mẫu kí tự). Người dùng không thể thay đổi vùng ROM này.

+ Vùng RAM chứa kí tự đồ họa CGRAM : (Character Generator RAM) : Như trên bảng mã kí tự, nhà sản xuất dành vùng có địa chỉ byte cao là 0000 để người dùng có thể tạo các mẫu kí tự đồ họa riêng. Tuy nhiên dung lượng vùng này rất hạn chế: Ta chỉ có thể tạo 8 kí tự loại 5x8 điểm ảnh, hoặc 4 kí tự loại 5x10 điểm ảnh.

+ Tập lệnh điều khiển LCD:

Tên lệnh Hoạt động

69

Display DBx = 0 0 0 0 0 0 0 1

Lệnh Clear Display (xóa hiển thị) sẽ ghi một khoảng trống-blank (mã hiện kí tự 20H) vào tất cả ô nhớ trong DDRAM, sau đó trả bộ đếm địa AC=0, trả lại kiểu hiển thị gốc nếu nó bị thay đổi. Nghĩa là : Tắt hiển thị, con trỏ dời về góc trái (hàng đầu tiên), chế độ tăng AC. (adsbygoogle = window.adsbygoogle || []).push({});

Return home

Mã lệnh : DBx = DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DBx = 0 0 0 0 0 0 1 *

Lệnh Return home trả bộ đếm địa chỉ AC về 0, trả lại kiểu hiển thị gốc nếu nó bị thay đổi. Nội dung của DDRAM không thay đổi.

Entry mode set

Mã lệnh : DBx = DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DBx = 0 0 0 0 0 1 [I/D] [S]

I/D : Tăng (I/D=1) hoặc giảm (I/D=0) bộ đếm địa chỉ hiển thị AC 1 đơn vị mỗi khi có hành động ghi hoặc đọc vùng DDRAM. Vị trí con trỏ cũng di chuyển theo sự tăng giảm này.

S : Khi S=1 toàn bộ nội dung hiển thị bị dịch sang phải (I/D=0) hoặc sang trái (I/D=1) mỗi khi có hành động ghi vùng DDRAM. Khi S=0: không dịch nội dung hiển thị. Nội dung hiển thị không dịch khi đọc DDRAM hoặc đọc/ghi vùng CGRAM. Display on/off control Mã lệnh : DBx = DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DBx = 0 0 0 0 1 [D] [C] [B]

D: Hiển thị màn hình khi D=1 và ngược lại. Khi tắt hiển thị, nội dung DDRAM không thay đổi.

C: Hiển thị con trỏ khi C=1 và ngược lại.

B: Nhấp nháy kí tự tại vị trí con trỏ khi B=1 và ngược lại.

Chu kì nhấp nháy khoảng 409,6ms khi mạch dao động nội LCD là 250kHz.

Cursor or display

Mã lệnh : DBx = DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DBx = 0 0 0 1 [S/C] [R/L] * *

Lệnh Cursor or display shift dịch chuyển con trỏ hay dữ liệu hiển thị sang trái mà không cần hành động ghi/đọc dữ liệu. Khi hiển thị kiểu 2 dòng, con trỏ sẽ nhảy

70

shift xuống dòng dưới khi dịch qua vị trí thứ 40 của hàng đầu tiên. Dữ liệu hàng đầu và hàng 2 dịch cùng một lúc. Chi tiết sử dụng xem bảng bên dưới:

S/C R/L Hoạt động

0 0 Dịch vị trí con trỏ sang trái (Nghĩa là giảm AC một đơn vị). 0 1 Dịch vị trí con trỏ sang phải (Tăng AC lên 1 đơn vị).

1 0 Dịch toàn bộ nội dung hiển thị sang trái, con trỏ cũng dịch theo. 1 1 Dịch toàn bộ nội dung hiển thị sang phải, con trỏ cũng dịch

theo.

Function set

Mã lệnh : DBx = DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 DBx = 0 0 1 [DL] [N] [F] * *

DL: Khi DL=1, LCD giao tiếp với MPU bằng giao thức 8 bit (từ bit DB7 đến DB0). Ngược lại, giao thức giao tiếp là 4 bit (từ bit DB7 đến bit DB0). Khi chọn giao thức 4 bit, dữ liệu được truyền/nhận 2 lần liên tiếp. với 4 bit cao gởi/nhận trước, 4 bit

Một phần của tài liệu Bài giảng lý thuyết vi xử lý kỹ thuật vi xử lý cd rom (Trang 58 - 82)