Phương pháp trao đổi tin song song theo chương trình~
CPU muốn trao đổi dữ liệu với các TBNV thì có thể thực hiện bằng các lệnh IN và OUT trong chương trình vào ra. Các lệnh có cú pháp như sau: IN A cc , Port#; Đưa dữ liệu vào thanh ghi chứa A cc từ cổng Port# OUT Port#,A cc ; ...
CPU muốn trao đổi dữ liệu với các TBNV thì có thể thực hiện bằng các lệnh IN và OUT trong chương trình vào ra. Các lệnh có cú pháp như sau:
IN Acc, Port#; Đưa dữ liệu vào thanh ghi chứa Acc từ cổng Port#
OUT Port#,Acc; Đưa dữ liệu từ thanh ghi chứa Acc ra cổng Port#
Vào ra có điều kiện và không có điều kiện
Vào ra không điều kiện
Trao đổi tin không điều kiện,các TBNV luôn ở trạng thái của các thiết bị ngoại vi khác. Nếu thiết bị ngoại vi sẵn sàng thì mới tiến hành trao đổi dữ liệu,cpu chủ động pháp tín hiệu trao đổi.
Trao đổi tin có điều kiện
Trao đổi dữ liệuTrao đổi dữ liệuTBNV sẵn sàng a) Không điều kiện b ) có điều kiệnHình 2-10: Vào ra có điều kiện và không có điều kiệnsaiđúng Trước khi CPU muốn trao đổi dữ liệu,thì nó cần phải kiểm tra trạng thái của TBNV. Nếu TBNV sẵn sàng thì mới tiến hành trao đổi tin
Trong trường hợp có nhiều thiết bị ngoại vi thì khi đó CPU sẽ tiến hành kiểm tra lần lược các trạng thái của từng thiết bị
Khối ghép nối song song
Hình 2-11: Sơ đồ nguyên lý cổng song song một chiều
Các thành phần bao gồm:
1.Hệ thống trung tâm:Điều khiển hoạt dộng của hệ
2. Giải mã địa chỉ từ hệ trung tâm,tạo tín hiệu CS (chip select) kết hợp với IOW điều khiển mạch chốt (C).
3. Mạch chốt cho phép ghi số liệu
4. Triger RS(Flip-Flop)
5. cổng vào ra các thiết bị ngoại vi
6. cổng XOR
7 cổng OR
8 chốt ba trạng thái
9 Phủ định Not
* nhận xét:
Khi trao đổi song song giữa máy tính và TBNV: Các đường dữ liệu được nối trực tiếp với thiết bị ngoại vi.Các đường được giải mã địa chỉ có các giá trị cụ thể kết hợp với tín hiệu điều khiển =>cho biết lúc nào cần đọc cần ghi.
Vi mạch vào ra theo chương trình
Các hệ vi xử lí trước 8086 sử dụng vi mạch vào ra theo chương trình PPI 8255 loại vi mạch nay có các dặc điểm sau:
- Có bộ nhớ (256*8bit), timer 14 bit theo chương trình.
- Không có chế độ khác nhau, khả năng lập xoá các bit của C đối thoại 8255A. Loại vi mạch này cho phép lập xoá các bit của các cổng C cho đối thoại
1 40PPI 8255A20 21Hình 2-12:Sơ đồ chân của PPI 8255Sơ đồ chân của PPI 8255A
1 4 các chân (PA3PA0) Lối ra cổng A
5: tín hiệu điêu khiển đọc ghi RD
6 :Tín hiệu chọn chip CS(chip select)
7: chân tín hịêu nối đất GND (Ground)
89 : các chân địa chỉ A0A1
1013:các chân (PC7PC4) nối ra cổng C
1417:các chân (PC3PC0) Lối ra cổng C
1825: các chân (PB7PB0) Lối ra cổng B
26 nguồn Vcc
2734: các chân dữ liệu (D0D7)
35: chân Reset
36 Tín hiệu điều khiển WR
3740 các chân (PA7PA4) Lối ra cổng A
Sơ đồ cấu trúc của PPI 8255A
Hình 2-13: Sơ đồ khối của PPI-8255A
- Gồm các thành phần sau
Phần nối với VXL có:
- Đệm số liệu: Trao đổi tin hai chiều (vào/ra) giữa đường dây MVT và đường dây nội (Interal Bus)
- Bộ điều khiển: Giải mã địa chỉ lệnh cho các thanh ghi đêm và các thanh ghi điều khiển.
Phần ghép nối với TBNV gồm:
- Cổng A: Thanh ghi đệm số liệu 8 bit vào ra tuỳ ý chương trình khởi dộng
- Cổng B: Thanh ghi đệm số liệu 8 bit vào ra tuỳ ý chương trình khởi dộng
- Cổng C cao : nửa cao 4 bit
- Cổng C thấp: nửa thấp 4 bit
- Địa chỉ các cổng 8 bít của 8255A trong một máy vi tính cá nhân tương thích IBM như sau: Cổng A: 60h; Cổng B: 61h; Cổng C:62h thanh ghi điều khiển 63 h
Các mạch địa chỉ nội bộ gồm các khối điều khiển,các cổng A,B,C..
A1 | A0 | CS | RD | WR | Lệnh của VXL | Chiều di chuyển |
0 | 0 | 0 | 0 | 1 | đọc cổng A | cổng A→ D0D7 |
0 | 1 | 0 | 0 | 1 | đọc cổng B | cổng B→ D0D7 |
1 | 0 | 0 | 0 | 1 | đọc cổng C | cổng C→ D0D7 |
1 | 1 | 0 | 0 | 1 | không có giá trị | |
0 | 0 | 0 | 1 | 0 | Ghi cổng A | D0D7→cổng A |
0 | 1 | 0 | 1 | 0 | Ghi cổng B | D0D7→cổng B |
1 | 0 | 0 | 1 | 0 | Ghi cổng C | D0D7→cổng C |
1 | 1 | 0 | 1 | 0 | Ghi thanh từ Điều khiển | D0D7→T/ghi từ đ/khiển |
X | X | 1 | x | x | Trạng thái điện trở cao | Không trao đổi dữ liệu |
Từ điều khiển chế độ (Định nghĩa cấu hình)
D7 D6 D5 D4 D3 D2 D1 D0
1 | MA1 | MA0 | A | CA | MB | B | CB |
Bit D7 =1:chế độ định nghĩa cấu hình các cổng nhóm A
nhóm A:
(D6D7) MA1,MA0:Chọn chế độ nhóm A (Mode of group A)
= 00: chế độ 0
= 01:Chế độ 1
=10 hay 11 chế độ 2
(D4) A port: định nghĩa nhiều cổng A
= 0 ra cổng A
= 1 vào cổng A
(D3) CA (port C,group A ):định nghiã chiều cổng C trong nhóm cổng A
=0 Ra cổng C cao
=1 vào cổng C cao
Nhóm B:
MB: Chế độ chọn nhóm B (Mode of group B)
=0 chế độ 0
= 1 chế độ 1
CB ( port C,group B ) định nghĩa chiều của cổng c trong nhóm B
=0 Ra cổng C thấp
=1 vào cổng C thấp
Ví dụ tìm từ điều khiển cổng A vào,B ra CH ra.CL ra sử dụng chế độ 0
1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Các chế độ chọn của 8255A.
- Chế độ 0 chế độ vào ra cơ sở
trong chế độ này các cổng A,B,CH,CL có thể lập trình vào ra, nghiã là, tất cả các bít có thể vào hoặc ra.
- Chế độ 1: Cổng A cổng B có thể vào hoặc ra tín hiệu trao đổi (hand Shacking) được cung cấp bởi cổng C
- Chế độ 2 Cổng A có thể sử dụng điều khiển vào hoặc ra với tín hiệu trao đổi được cung cấp từ cổng C Cổng B hoặc sử dụng ở chế độ đơn giản hoặc được sử dụng ở chế độ cao vào /ra.
Chế độ BSR(bit set/reset) xác lập hoặc xoá bỏ từng bit cổng C: thiết lập với các bit cổng C (C0 C7). Khi đó từ điều khiển như sau:
D7 D6 D5 D4 D3 D2 D1 D0
0 | X | x | x | CC2 | CC1 | CC0 | S/R |
= 0 Reset
= 1 Set
xác định bit cổng C | |||
0 | 0 | 0 | PC0 |
0 | 0 | 1 | PC1 |
0 | 1 | 0 | PC2 |
0 | 1 | 1 | PC3 |
1 | 0 | 0 | PC4 |
1 | 0 | 1 | PC5 |
1 | 1 | 0 | PC6 |
1 | 1 | 1 | PC7 |
không sử dụng
Hình 2-14: Chế độ xác lập xoá bit cổng C
Căn cứ vào các bit cổng C, Ta có thể điều chỉnh quá trình xuất,nhập thông tin qua vi mạch 8255A -> gọi là quá tình điều khiển nhờ xác lập bit và có thẻ xác lập thông qua thông tin này.
Ghép nối máy tính và thiết bị ngoại vi
Hình 2-15: Sơ đồ ghép nối PPI-8255A với máy vi tính
Phần ghép nối với máy vi tính
+ D0 D7,A0,A1,RD,Wr nối trực tiếp với các đầu ra tương ứng trong cpu
+ Reset nối từ cpu qua mạch đảo tới 8255A
+ CS nối với bộ giải mã các tín hiệu từ các chân địa chỉ (A2An) của cpu
+ Phần gép nối với thiết bị ngoại vi:
Tuỳ thuộc loại thiết bị ngoại vi (vào hoặc ra),số bit đường dây,phương thức trao đổi tin và chế độ trao đổi tin mà có các cách mắt khác nhau.
- Lập trình cho PPI trong trường hợp chế độ chọn đều bằng 0
- Bước1: Phân tích tìm giá trị cho từ điều khiển chế độ
- Bước 2 ; lập trình
+ Đưa giá trị cấu hình ra thanh ghi từ điều khiển
Mov Al,<giá trị cấu hình>
OUT <thanh ghi điều khiển >,Al
+ Đưa dữ liệu vào
IN AL,60h
+ Xuất dữ liệu
OUT 61h,AL
Ví dụ: lập trình nhập dữ liệu từ cổng PB và đưa ra cổng PA và PC với giả thiết chế độ chọn cổng A và B đều là 0
Giải
Bước 1 Phân tích tìm giá trị cấu hình
- Chế độ định cấu hình các cổng => bit D7=0
- chế độ chọn bằng 0 => D6=D5=D2=0
- cổng B vào => D1=1
- cổng A Và C ra => D4=D3=D0=0
cw= A2h1 0 0 0 0 0 1 0
Bước 2 lập trình bằng ASSEMBLY
TITLE Chuong_trinh_PI
.Model Small
.Stack 100h
.Data
PA EQU 60h;dia chi cong A
PB EQU 61h;dia chi cong B
PC EQU 62h;dia chi cong A
CWR EQU 63h;dia chi tu dieu khien
CW EQU A2h;dia chi tu dieu khien
.Code
MAIN PROC
MOV AX, @Data ;Chuyen du lieu qua thanh ghi Ax
MOV DS, AX ;sau do chuyen cho DS
MOV AL, CW ; Gia tri tu dieun khien trong AL
OUT CWR,AL ;chuyen ra tu dieu khien du
IN AL, PB ;du lieu vao qua cong B
OUT PA, AL ;dua ra cong A
OUT PC,AL ;va cong C
MOV AH,4CH ;chuan bi
INT 21h ;ve DOS
MAIN ENDP
END MAIN
Ví dụ: Viết một chương trình bằng C cho PPI8255A
/* This is the QC program for 8255/8253 I/O CARD
Author : Johnny Tseng
Date : 1999/10/02 */
#include <dos.h>
#include <stdio.h>
#include <conio.h>
/* set default value for ioport, CNTR */
unsigned int ioport = 0;
void test8255loopback (void)
{
int loop, i, c, step = 0;
unsigned char x1, x2, x3, y1, y2, y3, z1, z2, z3;
unsigned long x;
unsigned long y;
unsigned duration = 64;
if (!ioport)
return;
gotoxy (10, 16);
outportb (ioport + 3, 0x80);
outportb (ioport + 7, 0x9b);
for (loop = 0; loop < 100; loop ++) {
for (i = 0; i < 24; i++) {
x = (unsigned long)1 << i;
x1 = x & 0x00ff;
x2 = (x >> 8) & 0x00ff;
x3 = (x >> 16) & 0x00ff;
y = 0x00800000 >> i;
y1 = y & 0x00ff;
y2 = y >> 8;
y3 = y >> 16;
outportb (ioport, x1);
outportb (ioport + 1, x2);
outportb (ioport + 2, x3);
delay (duration);
z1 = inportb (ioport + 4);
z2 = inportb (ioport + 5);
z3 = inportb (ioport + 6);
gotoxy (3, 16);
cprintf("Loop: %3d Testing Pin:%2d Output: %02X%02X%02X,input:%02X%02X%02X Correct:%02X%02X%02X", loop + 1, i, x3, x2, x1, z3, z2, z1, y3, y2, y1);
if (z1 != y1 || z2 != y2 || z3 != y3) {
cputs (" Error ");
c = getch ();
if (c == 27)
break;
}
else {
cputs (" OK ");
//c = getch ();
}
if (kbhit () || step) {
c = getch ();
if (c == 27)
break;
else if (c == ' ')
step = !step;
else if (c == '+') {
if (duration > 1)
duration >>= 1;
}
else if (c == '-') {
if (duration < 512)
duration <<= 1;
}
else if (!step)
getch ();
}
}
if (c == 27)
break;
}
gotoxy (3, 17);
cputs("Press any key when ready");
if (kbhit ())
getch();
}
void dumpbits (unsigned long x)
{
int i;
for (i = 0; i < 24; i++) {
putch (((0x00800000 >> i) & x)? '1' : '0');
}
}
void test8255output (void)
{
unsigned long x, loop = 0L;
int i, flag, iop, step = 0;
unsigned char x1, x2, x3, c = 0;
unsigned duration = 64;
outportb (ioport + 3, 0x80);
outportb (ioport + 7, 0x80);
outportb (ioport, 0);
outportb (ioport + 1, 0);
outportb (ioport + 2, 0);
outportb (ioport + 4, 0);
outportb (ioport + 5, 0);
outportb (ioport + 6, 0);
for (flag = 0;;flag = !flag) {
outportb (iop, 0);
outportb (iop + 1, 0);
outportb (iop + 2, 0);
if (flag) {
iop = ioport + 4;
} else {
iop = ioport;
}
for (i = 0, x = (unsigned long)1; i < 24; i++, x <<= 1,
loop++) {
x1 = x & 0x00ff;
x2 = (x >> 8) & 0x00ff;
x3 = (x >> 16) & 0x00ff;
outportb (iop, x1);
outportb (iop + 1, x2);
outportb (iop + 2, x3);
gotoxy (3, 16);
cprintf("Loop: %8ld : ", loop);
if (flag) {
dumpbits (x);
dumpbits (0);
} else {
dumpbits (0);
dumpbits (x);
}
delay (duration);
if (kbhit () || step) {
c = getch ();
if (c == 27)
break;
else if (c == ' ')
step = !step;
else if (c == '+') {
if (duration > 1)
duration >>= 1;
}
else if (c == '-') {
if (duration < 512)
duration <<= 1;
}
else if (!step)
getch ();
}
} // for (i)
if (c == 27)
break;
} // for (flag)
if (kbhit ())
getch ();
}
void test8255input (void)
{
unsigned long x, y, loop = 0L;
unsigned char c;
outportb (ioport + 3, 0x9b);
outportb (ioport + 7, 0x9b);
for (loop = 0;;loop++) {
x = inportb (ioport + 2);
x = (x << 8) | inportb (ioport + 1);
x = (x << 8) | inportb (ioport);
y = inportb (ioport + 6);
y = (y << 8) | inportb (ioport + 5);
y = (y << 8) | inportb (ioport + 4);
gotoxy (3, 16);
cprintf("Loop: %8ld : ", loop);
dumpbits (y);
dumpbits (x);
if (kbhit ()) {
c = getch ();
if (c == 27)
break;
} // for (i)
} // for (flag)
if (kbhit ())
getch ();
}
void test8253 (void)
{
unsigned long loop = 0L;
unsigned duration = 4;
int step = 0;
int i, j;
unsigned char c;
outportb (ioport + 3, 0x9b); //All input
outportb (ioport + 7, 0x89); //Port A, B output and Port C input
outportb (ioport + 11, 0x36); //Counter 0: Mode 3, LSB + MSB
outportb (ioport + 8, 10);
outportb (ioport + 8, 0);
outportb (ioport + 11, 0x76); //Counter 1: Mode 3, LSB + MSB
outportb (ioport + 9, 10);
outportb (ioport + 9, 0);
outportb (ioport + 11, 0xb6); //Counter 2: Mode 3, LSB + MSB
outportb (ioport + 10, 10);
outportb (ioport + 10, 0);
gotoxy (3, 17);
cprintf ("Please use probe to check if OUT0, OUT1, and OUT2 are blinking.");
for (loop = 0;;loop++) {
for (i = 0; i < 10; i++) {
outportb (ioport + 5, 0x2a);
for (j = 0; j <10; j++);
outportb (ioport + 5, 0x3f);
for (j = 0; j <10; j++);
}
gotoxy (3, 16);
cprintf("Loop: %8ld : ", loop);
delay (duration);
if (kbhit () || step) {
c = getch ();
if (c == 27)
break;
else if (c == ' ')
step = !step;
else if (c == '+') {
if (duration > 1)
duration >>= 1;
}
else if (c == '-') {
if (duration < 512)
duration <<= 1;
}
else if (!step)
getch ();
} //if
if (c == 27)
break;
} // for (flag)
if (kbhit ())
getch ();
}
void main()
{
int r;
int flag = 1;
char ch;
ioport = 0x1b0;
while (flag) {
clrscr();
cputs (" ");
cputs (" 8255/8253 I/O CARD Q.C. Program V1.2 ");
cputs ("==================================== ");
cputs (" ");
cprintf (" I/O Address: %04X ",
ioport);
cputs (" ");
cputs (" (0): Change I/O setting ");
cputs (" (1): 8255 Loopback test ");
cputs (" (2): Output Test ");
cputs (" (3): Input Test ");
cputs (" (4): Counter Test (8253) ");
cputs (" ESC: EXIT ");
cputs (" Choose:");
do {
ch = getch();
} while (ch != '0' && ch != '1' && ch != '2' && ch != '3' &&
ch != '4' && ch != 27);
switch (ch) {
case 27:
flag = 0;
break;
case '0':
if (ioport == 0x1b0)
ioport = 0x300;
else if (ioport == 0x300)
ioport = 0x360;
else if (ioport == 0x360)
ioport = 0x1b8;
else
ioport = 0x1b0;
break;
case '1':
test8255loopback ();
break;
case '2':
test8255output ();
break;
case '3':
test8255input ();
break;
case '4':
test8253 ();
break;
}
}
} /* end of main */