24/05/2018, 16:02

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 (PA3PA0) 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)

89 : các chân địa chỉ A0A1

1013:các chân (PC7PC4) nối ra cổng C

1417:các chân (PC3PC0) Lối ra cổng C

1825: các chân (PB7PB0) Lối ra cổng B

26 nguồn Vcc

2734: các chân dữ liệu (D0D7)

35: chân Reset

36 Tín hiệu điều khiển WR

3740 các chân (PA7PA4) 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→ D0D7
0 1 0 0 1 đọc cổng B cổng B→ D0D7
1 0 0 0 1 đọc cổng C cổng C→ D0D7
1 1 0 0 1 không có giá trị
0 0 0 1 0 Ghi cổng A D0D7→cổng A
0 1 0 1 0 Ghi cổng B D0D7→cổng B
1 0 0 1 0 Ghi cổng C D0D7→cổng C
1 1 0 1 0 Ghi thanh từ Điều khiển D0D7→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

10010000
CW = 90h

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ỉ (A2An) 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
  • 10000010
    cw= A2h

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 */

0