Thiết kế mạch logic số Phần III: Phần mềm điều khiển
chơng I: Phân tích chơng trình
Chơng trình điều khiển đợc viết bằng ngôn ngữ C, chạy trong môi trờng DOS.
Yêu cầu của chơng trình là phải có một giao diện thân thiện, giúp ngời dùng dễ dàng dùng máy
tính để nhập các ký tự cần hiển thị tại vị trí mong muốn trên ma trận LED bên ngoài.
Khi thực hiện, chơng trình phải thờng xuyên trao đổi dữ liệu với mạch ngoài qua
cổng song song bằng cách truy nhập vào ba thanh ghi của cổng song song là: thanh ghi dữ liệu,
thanh ghi trạng thái, thanh ghi điều khiển. Chơng trình mặc định lấy cổng song song ở đây là
LPT1 với địa chỉ các thanh ghi đợc cho (tính ở hệ đếm 16) nh sau:
Thanh ghi Địa chỉ
Dữ liệu 378h
Trạng thái 379h
Điều khiển 37Ah
Để thuận tiện, trong chơng trình ta dùng lệnh #define để định nghĩa cho các
thanh ghi: #define DataReg 0x378
#define StatusReg 0x379
#define ControlReg 0x37A
Thanh ghi dữ liệu có 8 bit (D
0
ữ D
7
) dùng để đa ra địa chỉ và mã của ký tự cần ghi vào RAM ở
mạch ngoài. Sử dụng lệnh: outportb(DataReg, dữ liệu). Địa chỉ của ký tự cần ghi vào RAM sẽ
xác định vị trí của ký tự trên bảng quảng cáo bên ngoài, nó gồm có địa chỉ cột (4 bit đầu, từ D
0
đến D
3
) và địa chỉ cột (3 bit tiếp theo, từ D
4
đến D
6
), tức là cần 7 bit địa chỉ D
0
ữ D
6
, bit thứ 8 là
D
7
không dùng. Gọi column là địa chỉ cột và row là địa chỉ hàng của ký tự cần hiển thị thì địa
chỉ của ký tự đó trong RAM là add đợc tính nh sau:
row << 4; // dịch phải 4 bit
add = row | column; // cộng đại số row và column
Mã của ký tự dùng 6 bit (D
0
ữ D
5
) để biểu diễn, tức là có thể biểu diễn đợc 64 ký tự có mã từ 0
đến 63, đợc qui ớc nh bảng dới đây:
Ký
tự
Mã
Hệ 10 Hệ 2
Ký
tự
Mã
Hệ 10 Hệ 2
Ký
tự
Mã
Hệ
10
Hệ 2
A 0
000000
X 23
010111
; 46
101110
B 1
000001
Y 24
011000
' 47
101111
C 2
000010
Z 25
011001
" 48
110000
D 3
000011
0 26
011010
( 49
110001
E 4
000100
1 27
011011
) 50
110010
F 5
000101
2 28
011100
[ 51
110011
G 6
000110
3 29
011101
] 52
110100
H 7
000111
4 30
011110
! 53
110101
I 8
001000
5 31
011111
? 54
110110
J 9
001001
6 32
100000
@ 55
110111
K 10
001010
7 33
100001
# 56
111000
L 11
001011
8 34
100010
$ 57
111001
M 12
001100
9 35
100011
% 58
111010
N 13
001101
+ 36
100100
^ 59
111011
36
Thiết kế mạch logic số Phần III: Phần mềm điều khiển
O 14
001110
- 37
100101
& 60
111100
P 15
001111
* 38
100110
\ 61
111101
Q 16
010000
/ 39
100111
| 62
111110
R 17
010001
= 40
101000
space
63
111111
S 18
010010
> 41
101001
T 19
010011
< 42
101010
U 20
010100
. 43
101011
V 21
010101
, 44
101100
W 22
010110
: 45
101101
Thanh ghi trạng thái có 8 bit (S
0
ữ S
7
), dùng để thu nhận những thông tin từ
mạch bên ngoài gửi đến qua các chân: 10 và 13. Chức năng từng chân đợc nêu nh bảng dới đây:
Chân
Bit tơng ứng
trên thanh ghi
trạng thái
Chức năng
10 S
6
Mạch ngoài gửi mức logic 1 để thông báo là đang
đọc RAM. Khi nó có mức logic 0 thì có nghĩa là
RAM đã đợc đọc xong và máy tính có thể ghi dữ
liệu lên RAM.
13 S
4
ở mức logic 1 khi mạch ngoài đã đóng công tắc
nguồn (có thể cha cấp nguồn cho mạch ngoài).
Khi bắt đầu thực hiện, chơng trình phải kiểm tra xem công tắc nguồn ở mạch ngoài đã đợc đóng
cha thông qua việc đọc dữ liệu từ thanh ghi trạng thái và kiểm tra bit S
4
có ở trạng thái 1 không
bằng các lệnh:
result = inportb(StatusReg);
k = result & 16; // Phép AND giữa result và 16
Số 16 biểu diễn dới dạng nhị phân là: 00010000. Khi k 0 thì S
4
= 1.
Trớc khi ghi dữ liệu lên RAM phải kiểm tra xem bit S
6
có ở trạng thái 0 không. Quá trình kiểm
tra đợc thực hiện ở chế độ hỏi vòng bằng cách dùng lệnh for(i=0;i<1000;i++), tức là liên tục
đọc thanh ghi trạng thái, bắt đầu từ lúc ký tự đợc nhập vào từ bàn phím. Sau một thời gian, nếu
chân 10 vẫn ở mức logic 1 thì sẽ tự thoát ra và quá trình gửi ký tự là không thành công.
Thanh ghi điều khiển có 8 bit (C
0
ữ C
7
) dùng để gửi thông tin điều khiển từ máy
tính ra mạch bên ngoài bằng các chân: 1, 14, 17. Chức năng các chân đợc cho nh bảng dới đây:
37
Thiết kế mạch logic số Phần III: Phần mềm điều khiển
Chân
Bit tơng ứng
trên thanh ghi
điều khiển
Chức năng
1 C
0
Chơng trình sẽ gửi một mức logic 1 ra chân này để
chốt địa chỉ của ký tự gửi ra trên mạch chốt 74373,
đồng thời mở bộ đệm 74244 đa địa chỉ tới RAM.
14 C
1
Sau khi địa chỉ và dữ liệu đã đa tới RAM, chơng
trình sẽ làm cho chân này chuyển xuống mức logic
0 để tạo ra tín hiệu ghi vào RAM.
17 C
3
Khi ngời dùng nhấn phím F1 để bật chơng trình,
nếu công tắc nguồn mạch ngoài đã đợc đóng, chơng
trình sẽ gửi một mức logic 0 ra chân này để tạo ra
tín hiệu cấp nguồn cho mạch.
38
ThiÕt kÕ m¹ch logic sè PhÇn III: PhÇn mÒm ®iÒu khiÓn
ch¬ng ii: m nguån·
//Chuong trinh dieu khien bang quang cao dung ma tran LED 5x7
// (Do an mon hoc: Thiet ke mach Logic)
//Nguoi viet: Le Minh Hung
// Nguyen Duc Linh
// Lop DT6-K43-DHBKHN
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#define DataReg 0x378
#define StatusReg 0x379
#define ControlReg 0x37A
void Initialize();
void Interfacing();
void Print_Code(int code);
void ItoSofB(int i,char up[],char down[]);
void Print_Character(int column,int row,int code);
void Print_Column(int column);
void Print_Row(int row);
void Print_Cell(int column,int row,char value);
void Print_Matrix(int code);
int Out_Char(int column,int row,int code);
void Reset();
void Power();
//-------------------------------------------------------------
----
int character[64][6]={
//character[x][0-4]: code of character'column
//character[x][5]: ASCII code
{126,17,17,17,126,65}, // 0-A
{127,73,73,73,54,66}, // 1-B
{62,65,65,65,34,67}, // 2-C
{127,65,65,34,28,68}, // 3-D
{127,73,73,73,65,69}, // 4-E
{127,9,9,9,1,70}, // 5-F
{62,65,73,73,58,71}, // 6-G
{127,8,8,8,127,72}, // 7-H
{0,65,127,65,0,73}, // 8-I
{32,64,65,63,1,74}, // 9-J
39
ThiÕt kÕ m¹ch logic sè PhÇn III: PhÇn mÒm ®iÒu khiÓn
{127,8,20,34,65,75}, //10-K
{127,64,64,64,64,76}, //11-L
{127,2,12,2,127,77}, //12-M
{127,4,8,16,127,78}, //13-N
{62,65,65,65,62,79}, //14-O
{127,9,9,9,6,80}, //15-P
{62,65,81,33,94,81}, //16-Q
{127,9,25,41,70,82}, //17-R
{38,73,73,73,50,83}, //18-S
{1,1,127,1,1,84}, //19-T
{63,64,64,64,63,85}, //20-U
{31,32,64,32,31,86}, //21-V
{63,64,48,64,63,87}, //22-W
{99,20,8,20,99,88}, //23-X
{7,8,120,8,7,89}, //24-Y
{97,81,73,69,67,90}, //25-Z
{62,81,73,69,62,48}, //26-0
{0,66,127,64,0,49}, //27-1
{66,97,81,73,70,50}, //28-2
{33,65,69,75,49,51}, //29-3
{24,20,18,127,16,52}, //30-4
{39,69,69,69,57,53}, //31-5
{60,74,73,73,48,54}, //32-6
{1,113,9,5,3,55}, //33-7
{54,73,73,73,54,56}, //34-8
{6,73,73,41,30,57}, //35-9
{8,8,62,8,8,43}, //36-+
{8,8,8,8,8,45}, //37--
{20,8,62,8,20,42}, //38-*
{32,16,8,4,2,47}, //39-/
{20,20,20,20,20,61}, //40-=
{0,65,34,20,8,62}, //41->
{8,20,34,65,0,60}, //42-<
{0,96,96,0,0,46}, //43-.
{0,80,48,0,0,44}, //44-,
{0,54,54,0,0,58}, //45-:
{0,86,54,0,0,59}, //46-;
{0,5,3,0,0,39}, //47-'
{0,3,0,3,0,34}, //48-"
{0,28,34,65,0,40}, //49-(
{0,65,34,28,0,41}, //50-)
{0,127,65,65,0,91}, //51-[
{0,65,65,127,0,93}, //52-]
{0,0,95,0,0,33}, //53-!
{2,1,81,9,6,63}, //54-?
{50,73,121,65,62,64}, //55-@
{20,62,20,62,20,35}, //56-#
40
ThiÕt kÕ m¹ch logic sè PhÇn III: PhÇn mÒm ®iÒu khiÓn
{36,42,127,42,18,36}, //57-$
{35,19,8,100,98,37}, //58-%
{4,2,1,2,4,94}, //59-^
{54,73,85,34,80,38}, //60-&
{2,4,8,16,32,92}, //61-\
{0,0,127,0,0,124}, //62-|
{0,0,0,0,0,32}, //63-
};
int matrix[128];
int power;
//-------------------------------------------------------------
----
void main()
{
int column=0,row=0,pos=0,i;
char scan,ch;
Interfacing();
Initialize();
for(i=0;i<128;i++)
matrix[i]=63;
for(;;)
{
Print_Column(column);
Print_Row(row);
Print_Matrix(matrix[pos]);
Print_Code(matrix[pos]);
window(5+column*2,2+row*2,5+column*2,2+row*2);
if((scan=getch())==0)
{
ch=getch();
switch(ch)
{
case 59: //F1
Power();
break;
case 60: //F2
if(power==1)
Reset();
break;
case 75: //Left Arrow
if(power==1)
{
if(pos>0) pos--;
if(column==0)
{
if(row>0)
41