Màn hình quảng cáo ở chế độ văn bản sử dụng ma trận LED 5x7 có điều khiển máy tính
Trang 1chơ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ầucủ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ổngsong 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, thanhghi 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ỉ
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 (D0 D7) 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ừ D0
đến D3) và địa chỉ cột (3 bit tiếp theo, từ D4 đến D6), tức là cần 7 bit địa chỉ D0 D6, bit thứ 8 làD7 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ì địachỉ 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 (D0 D5) để 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:
Trang 2Thanh ghi trạng thái có 8 bit (S0 S7), dùng để thu nhận những thông tin từ mạch bênngoà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 ứngtrên thanh ghi
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 S4 ở mức logic 1 khi mạch ngoài đã đóng công tắcnguồ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 đóngcha thông qua việc đọc dữ liệu từ thanh ghi trạng thái và kiểm tra bit S4 có ở trạng thái 1 khôngbằng các lệnh:
result = inportb(StatusReg);
k = result & 16; // Phép AND giữa result và 16Số 16 biểu diễn dới dạng nhị phân là: 00010000 Khi k 0 thì S4 = 1.
Trớc khi ghi dữ liệu lên RAM phải kiểm tra xem bit S6 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ếuchâ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 (C0 C7) dùng để gửi thông tin điều khiển từ máy tínhra 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:
Bit tơng ứngtrên thanh ghi
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.
Sau khi địa chỉ và dữ liệu đã đa tới RAM, chơngtrình sẽ làm cho chân này chuyển xuống mức logic0 để tạo ra tín hiệu ghi vào RAM.
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ơngtrình sẽ gửi một mức logic 0 ra chân này để tạo ratín hiệu cấp nguồn cho mạch.
Trang 3ch¬ng ii: m nguån· 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 0x37Avoid Initialize();
void Interfacing();
void Print_Code(int code);
Trang 4void 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{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
Trang 5{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-#{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];
Trang 6int 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(;;)
{
{
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) {
column=16;
Trang 7row ; }
else column=1; }
column ; }
break;
case 77: //Right Arrow
if(power==1) {
if(pos<127) pos++; column++;
if(column>15) {
if(row<7) {
column=0; row++; }
else column=15; }
}
break;
case 72: //Up Arrow
if(power==1) {
if(row>0) {
pos=pos-16; row ;
} }
break;
case 80: //Down Arrow
if(power==1) {
if(row<7) {
pos=pos+16; row++;
Trang 8} }
break;
} // for switch(ch)
} // for if((scan=getch())==0)else
{
ch=scan; switch(ch) {
pos=pos+(16-column); row++;
column=0; }
break; default:
if((isprint(ch))&&(power==1)) {
ch=toupper(ch); for(i=0;i<64;i++)
if(character[i][5]==ch) {
Print_Character(column,row,ch); if(Out_Char(column,row,i)==0) {
textbackground(LIGHTGRAY); textcolor(RED);
window(4,25,30,25);clrscr();
cprintf("Khong gui duoc ky tu !"); }
else {
Trang 9textbackground(LIGHTGRAY); window(4,25,30,25);clrscr(); }
matrix[pos]=i; break;
}
if(pos<127) pos++; if(column==15)
{
if(row<7) {
column=-1; row++; }
else column=14; }
// -void Initialize() {
//Dong mach ngoai: chan 17,bit3=1
outportb(ControlReg,8); // 8 = 00001000b
power=0; //Chua cho phep chuong trinh hoat dong
textbackground(BLACK); textcolor(WHITE);
window(16,20,18,20);clrscr(); printf("OFF");
}
// -void Power() {
unsigned char result;
Trang 10if(power==0) {
//Kiem tra xem chan 13 co o muc cao (bit4=1)
result=inportb(StatusReg);if(result&16 !=0) // 16=10000b
//Dua ra tin hieu dong mach ngoai (chan 17,bit3=0)
//va thiet lap trang thai ban dau: dong bo dem 74244(chan //1,bit0=0),khong cho phep ghi vao RAM(chan 14,bit1=1)
outportb(ControlReg,2); // 2 = 00000010b }
else {
textbackground(LIGHTGRAY); textcolor(RED);
window(4,25,30,25);clrscr();
cprintf("Chua dong nguon cho mach!"); }
} else {
//Khong cho phep chuong trinh hoat dong
//Dua ra tin hieu tat mach ngoai (chan 17,bit3=1)
outportb(ControlReg,8); // 8 = 00001000b
} }
// -void Interfacing() {
Trang 11textmode(C40);
textbackground(BLUE);window(0,0,40,25);clrscr(); textbackground(BLACK);window(5,2,37,25);clrscr(); textcolor(BLUE);
textbackground(LIGHTGRAY);window(4,1,36,17);clrscr(); textcolor(LIGHTGRAY);
textbackground(BLACK);window(5,2,35,17);clrscr(); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ");
cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ "); cprintf("ÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄÅÄ"); cprintf(" ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ \r");
textbackground(LIGHTGRAY);window(5,17,35,17);clrscr();
window(19,18,36,25);clrscr();
textbackground(BLACK);window(31,18,35,24);clrscr(); textcolor(BLUE);textbackground(LIGHTGRAY);
window(20,19,30,19);clrscr();cprintf("Column:"); window(20,21,30,21);clrscr();cprintf("Row:"); window(20,23,30,23);clrscr();cprintf("Code:"); window(4,19,17,23);clrscr();
window(4,25,30,25);clrscr();
window(6,20,17,21);clrscr();cprintf("F1 - Power"); window(6,21,17,22);clrscr();cprintf("F2 - Reset"); window(5,22,17,23);clrscr();cprintf("ESC - Exit");
}
// -void ItoSofB(int i,char up[],char down[])//Chuyen so nguyen
// sang chuoi cac so nhiphan
Trang 12{
int j=0,k=0; do
{
if(i%2==0) up[j]='0'; else up[j]='1';
j++; i=i/2;
} while(i!=0); up[j]='\0';
do {
down[k]=up[j-1]; k++;j ;
} while(j>=0); down[k-1]='\0'; }
// -void Print_Code(int code) {
char up[7]; char down[7];
textcolor(RED);textbackground(LIGHTGRAY); window(27,23,30,23);clrscr();
itoa(code,up,10);cprintf("%s",up); window(22,24,30,24);clrscr();
ItoSofB(code,up,down);cprintf("%sB",down); }
// -void Print_Column(int column) {
char up[7],down[7];
textcolor(RED);textbackground(LIGHTGRAY); window(27,19,30,19);clrscr();
itoa(column,up,10);cprintf("%s",up); window(22,20,30,20);clrscr();
ItoSofB(column,up,down);cprintf("%sB",down); }
Trang 13// -void Print_Row(int row) {
char up[7],down[7];
textcolor(RED);textbackground(LIGHTGRAY); window(27,21,30,21);clrscr();
itoa(row,up,10);cprintf("%s",up); window(22,22,30,22);clrscr();
ItoSofB(row,up,down);cprintf("%sB",down); }
// -void Print_Cell(int column,int row,char value) {
if(value=='0')
textbackground(BLACK); else
textbackground(RED); textcolor(WHITE);
window(31+column,18+row,31+column,18+row);clrscr(); printf("%c",value);
}
// -void Print_Matrix(int code) {
int i,j,k,len; char up[9]; char down[9]; for(i=0;i<5;i++) {
k=0;
ItoSofB(character[code][i],up,down); len=strlen(up);
while(k<8-len) {
up[len+k]='0'; k++;
}
Trang 14for(j=0;j<7;j++)
Print_Cell(i,j,up[j]); }
}
// -void Print_Character(int column,int row,int code) {
textcolor(RED);textbackground(BLACK);
window(5+column*2,2+row*2,5+column*2,2+row*2);clrscr(); printf("%c",code);
}
// -int Out_Char(// -int column,// -int row,// -int code) //Dua ky tu co ma
// code ra cong songsong
add=row|column; //Dia chi o nho cua RAM
for(i=0;i<1000;i++) //Hoi vong
{
result=inportb(StatusReg); //Doc trang thai vao
if(result&64==0) //Kiem tra xem chan 10 co o muc thap
//(bit7=0)
{ //64 = 01000000b
//Dua dia chi ra cong song song
outportb(DataReg,add);//Ghi du lieu vao thanh ghi du lieu
//Dua ra tin hieu chot dia chi 74373 //va mo bo dem 74244 (chan 1,bit0=1)
outportb(ControlReg,3);//Ghi du lieu vao thanh ghi dieu
// khien // 3 = 00000011b //Dua ma ky tu ra cong song song
Trang 15// va khong cho ghi vao RAM (bit1=1) outportb(ControlReg,2); // 2 = 00000010b
return 1; // Ket thuc ghi vao RAM
} }
return 0; }
// -void Reset() {
Trang 16Phần chính của giao diện là một ma trận các ô gồm 8 hàng x 16 cột mô phỏng ma trậnđèn quảng cáo của mạch thực Mỗi ô là nơi để hiển thị ký tự mà ngời dùng nhập vào ở góc dớibên phải giao diện là các thông số của ô chữ tại vị trí con trỏ màn hình xuất hiện gồm có: + Column (cột): chỉ số thứ tự của cột (từ 0 đến 15) mà con trỏ màn hình xuất hiện.
+ Row (hàng): chỉ số thứ tự của hàng (từ 0 đến 7) mà con trỏ màn hình xuất hiện.+ Code (mã): chỉ mã của ký tự (theo bảng mã qui ớc của chúng tôi đã đợc đa ra ở ch-ơng I của phần này) xuất hiện tại vị trí con trỏ màn hình.
Bên cạnh đó là ma trận 5x7 các ô vuông biểu thị các bit 1 (đèn LED sáng) và bit 0 (đèn LEDtắt) của ma trận 5x7 LED ứng với ký tự hiển thị.
ở góc dới bên trái giao diện là bảng chỉ dẫn các phím chức năng:
+ F1 – Power: Bật / tắt chơng trình Lúc này, chơng trình cha đợc bật nên bên cạnhđó là chữ OFF (tắt) Khi nhấn F1, chơng trình sẽ kiểm tra qua cổng song song xem mạch ngoàiđã đợc cấp nguồn hay cha Nếu mạch ngoài đã đợc cấp nguồn thì chơng trình sẽ gửi tín hiệu racổng song song cho phép mạch ngoài hoạt động, đồng thời cho phép chơng trình hoạt động Lúcđó, chữ OFF sẽ chuyển thành ON Nếu mạch ngoài cha đợc cấp nguồn thì chơng trình sẽ hiệnra thông báo là: "Cha đóng nguồn cho mạch ngoài !" Khi chơng trình đang đợc bật mà nhấn F1thì chơng trình sẽ gửi tín hiệu ra cổng song song không cho phép mạch ngoài hoạt động, đồngthời tắt chơng trình.
+ F2 – Reset: Thiết lập lại Khi chơng trình đang đợc bật mà nhấn F2 thì chơng trìnhsẽ gửi tín hiệu ra cổng song song cắt nguồn cấp cho mạch ngoài khoảng 0.5 s, sau đó đóng lạinhằm thiết lập lại hệ thống trở về trạng thái ban đầu Đồng thời sẽ xoá toàn bộ ma trận các ô kýtự thành ký tự trắng (mã 63).
+ ESC – exit: Thoát Khi nhấn phím ESC sẽ thoát khỏi chơng trình điều khiển Trớckhi thoát, chơng trình sẽ gửi tín hiệu ra cổng song song để cắt cắt nguồn cấp cho mạch ngoài.
Khi chơng trình đã đợc bật, ta có thể dùng các phím mũi tên (, , , ) để di chuyểncon trỏ đến vị trí bất kỳ trên trang màn hình để nhập ký tự cần hiển thị Khi ký tự đợc nhập vào,nó hiển thị tại vị trí con trỏ màn hình vừa đứng, sau đó, con trỏ tự động nhảy sang vị trí bêncạnh Chơng trình sẽ gửi thông tin về ký tự vừa nhập ra cổng song song để mạch ngoài hiển thị,nếu không thành công thì sẽ có thông báo: "Không gửi đợc ký tự !"
Hình III.2 là hình ảnh của chơng trình khi đã đợc bật và nhập các ký tự Lúc này, contrỏ màn hình đã đợc dịch chuyển đến cột 2, hàng 2, ký tự tại ô này là "L", có mã là 11 Thôngtin của ký tự đó có thể thấy ở góc dới bên phải bằng cả số thập phân và số nhị phân.