Giải thuật led quay
1. Phương pháp ý hiện chữ:
Dựa vào nguyên lý ma trận, các chữ được quét theo từng cột, các led nối anot chung. Led được dung loại
siêu sáng , dòng qua led 10mA, điện áp ~3V. khi xuất dữ liệu ra dạng xung nên nối các chân- vào các port
,chân + nối lên vcc, tín hiệu xung làm giảm điện áp ra và dòng vđk 89s52 hút vào chịu đc 10mA nên các led sẽ
hoạt động bình thường.
Trên 1 vòng quay, vị trí ngắt là cột đầu tiên, tại vị trí này thì cho hiện ký tự của địa chỉ add, sau khi hiện hết 10
cột thì địa chỉ tăng lên 1 và tiếp tục hiển thị chữ tiếp theo. Để chữ dịch chuyển thì sau mỗi vòng cho địa chỉ
tăng lên 1 hoặc nhiều đơn vị thì các chữ phía sau tự độgn dịch theo.
2. Phương pháp tạo mã chữ:
Dùng phần mềm sau tạo mã hex cho các ký tự:
Xuất ra bảng mã 8 bit, 1 ký tự gồm 10 cột, 16 hàng.
3. Phương pháp đọc dữ liệu
Mỗi ký tự có 1 bảng mã hex riêg và 1 địa chỉ riêng, khi được gọi đúng địa chỉ,lần lượt các byte trong mảng sẽ
được đọc ra để xuất ra các port
4. Phương pháp thực hiện hiệu ứng
Khi thực hiện nhiều hiệu ứng thì sau mỗi hiệu ứng sẽ được data0 và data1, sau đó dung dung phép
toán OR các data lại với nhau rồi xuất ra port
5. Thành phần mạch
Mạch gồm: cụm mạch 89s52, cụm mạch xử lý ngắt cảm biến từ, cụm mạch nguồn 12 sang 5v,mạch
remote,mạch thời gian thực.
6. Tính toán tốc độ
Theo nguyên lý để mắt nhìn thấy ảnh thì hình phải xuất hiện với tần số tối thiểu 24hình/s. mỗi vong quay sẽ
hiện 1 hình như vậy tốc độ động cơ = 24vòng/s, tươgn đương 24x60 = 1440 vòng/min. vậy chọn loại độgn cơ
có tốc độ khoảng 1500vòng/min.
Với tốc độ 24vong/s => thời gian 1 vòng = 1/24 = 0.0416 s ~ 42ms. Trên vòng quay chia làm 250 cột thì
khoảng cách giữa mỗi cột = 42/250 = 0.168 ms ~ 168us. Đây là thời gian delay giữa 2 lần xuất dữ liệu ra.
Giải thích phần mềm
#include //chèn file biên dịch cho 89s52
#include //chèn file chứa bảng mã và địa chỉ các ký tự
#define bd P3_6//khai báo led viền ngoài cùng
unsigned int colmax = 250;
//khai bao biến số cột tối đa
unsigned int colpre = 0;
//số cột đang hiển thị
unsigned char time1 = 0;
//thời gian delay giữa 2 cột
unsigned char nint = 0;
//đếm số lần ngắt để thay đổi hiệu ứng
unsigned int add1 = 0;
//địa chỉ hiển thị của ácc ký tự, khi địa chỉ này bằng địa chỉ của
mỗi ký tự thì ký tự đó được hiện ra
unsigned int cir = 0; //đếm số vòng quay
unsigned int cir_set = 0;
//số vòng quay để thực hiện các hiệu ứng
unsigned char kieu = 0;
//biến chọn kiểu hiệu ứng
unsigned char temp1 = 0;
//biến chọn dữ liệu cho từng kiểu hiệu ứng
unsigned char count_move = 0;
//biến cho phép chữ dịch chuyển
unsigned char move_high = 0;
//biến đếm cho chữ dịch từ trên xuống
unsigned char code and[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0
,0x0,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x0};
//bảng mã để OR với dữ liệu đầu ra tạo hiệu ứng chữ đi từ trên xuống
//khai báo các bít
bit move = 0;
bit dis = 0;
bit play = 0;
bit endis = 0;
//khai báo các hàm sử dụng
void out_port(unsigned char data0,unsigned char data1);
void start();
void display();
void delay(unsigned char temp);
void chop(unsigned char data0, unsigned char data1);
void delay(unsigned char temp){while(temp--);}//hàm delay, mỗi đơn vị là 1 chu kỳ máy
void main(){
//chương trình chính
colmax
= 250;
//gán giá trị ban đầu cho số cột
time1 = index[index[0]+1];
//đọc thời gian delay trong bj nhớ
kieu = 5;
TMOD = 0;
//khai báo thanh ghi điều khiển các timer
EA = 1;
//cho phéo ngắt toàn cục
ET0=1;TR0=1;
//khai bao ngat timer0 và cho timer0 chạy
TH0 = 0;
TL0 = 0;// nạp giá trị vào các thanh ghi của timer0
IT0 = 1;EX0 = 1;
//khai báo ngắt ngoài, tín hiệu từ hồng ngoại báo vị trí cột đàu tiên
add1 = 1;
//địa chỉ cho các ký tự hiển thị
start();//gọi hàm cho các led sáng từ ngoài vào trong
while(1){if(play == 1){play = 0;
endis = 1;
display();}}
//hàm gọi chương trình hiển thị led
khi ngắt hông ngoại tác động
}
void ngat0(void)interrupt 0 using 0{//hàm phục vụ ngắt ngoài
endis = 0;
//không cho xuất dữ liệu ra nữa
TR0 = 1;//cho timer0 chạy, khi timer0 ngắt thì cho phép gọi chương trình hiển thị sau mỗi vòng quay
}
void int_timer0(void) interrupt 1 {//hàm phục vụ ngắt timer0
TH0 = 0xc0;//nạp lại giá trị cho các thanh ghi
TL0 = 0;
TR0 = 0;//cho timer0 ngừng chạy
play = 1;
//cho phép gọi chương trình hiển thị ở hàm main
bd = 0;
//hiện led viền
}
void display(){//chương trình hiển thị các chữ
unsigned char x,data0,data1,index_location;//khai báo các biến tạm thời
unsigned int add2 = 0,add3 = 0;
cir++; colpre = 0;//set lại giá trị ban đầu sau mỗi vòng quay
if(cir >= 10*cir_set){//kiểm tra nếu quay đủ số vòng thì chuyển sang hiệu ứng mới
cir = 0 ;
if (kieu == 1){
// cho chu dich binh thuong
temp1 = 1;
move = 1;
nint = 1;
cir_set = (index[0] - 1);
kieu = 2;
}else if(kieu == 2){
//chu di xuong
temp1 = 2;
move = 0; add1 = 1; move_high = 0;
nint = 1;
cir_set = 20; kieu =3;
}else if(kieu == 3){
out_port(0xff,0xff);
//chu chop tai cho
temp1 = 3;
move = 0;
dis = 0;
cir_set = 10; kieu = 4;
}else if (kieu == 4){
//hieu ung start
kieu = 5;
temp1 = 4;
cir_set=0;
start();
}else if(kieu == 5){
temp1 = 1;
cir_set = 50;
}
//cho chu di ra
move = 0;
add1 = 1;
kieu = 1;
nint = 1;
colmax = 1;
}
//ket thuc chon kieu hieu ung
if(temp1 == 2){//tùy theo hiệu ứng mà cho dữ liệu ra khác nhau
if (count_move >= 10){
if(move_high < 15){move_high++;
count_move = 0;}
else{out_port(0xff,0xff);
count_move = 0;}
}else{count_move++;}
}else if(temp1 == 3){
if (count_move >= 4){
count_move = 0;
dis = !dis;
}else{count_move++;}
}
if(move == 1){
if(nint < symbol[index[add1]][20] - 1){nint++;}
else{
nint = 0;
if (add1 < index[0]){add1++;}
else{add1 = 1;}
}
}
//ket thuc chon che do du lieu tuong ung voi tung hieu ung
index_location = index[add1]; //tham chieu địa chỉ của ký tự đến bảng mã hex
for(x = nint;
x < symbol[index[add1]][20]; x++){
//cho hiển thị các cột của ký tự đầu tiên
colpre++; //sau khi hiện thì số cột tăng lên 1
if(temp1 == 1){//tùy theo kiểu hiệu ứng mà dữ liệu được kết hợp khác nhau
data0 = symbol[index_location][x];
data1 = symbol[index_location][x + 10];
}else if(temp1 == 2){
data0= symbol[index_location][x] | and[move_high];
data1 = symbol[index_location][x + 10] | and[move_high + 16];
}else if(temp1 == 3 && dis == 1){
data0 = symbol[index_location][x];
data1 = symbol[index_location][x + 10];
}else{
data0 = 0xff;
data1 = 0xff;
}
chop(data0,data1);
}
// ket thuc doc du lieu hien ky tu dau tien
add3 = add1; //sao chép địa chỉ ký tự đã hiển thị để hiện các ký tự khác trên 1 vòng quay
while(colpre < colmax && endis == 1){
add2++;//hiện các ký tự còn lại cho đến khi hết các cột
hoặc khi có ngắt hồng ngoài xảy ra
if ( add3 + add2 <= index[0] ){
index_location = index[add3 + add2];
for( x = 0;
x < symbol[index[add3 + add2]][20]; x++ ){ //hiện các cột của các ký tự
tiếp theo
if( colpre < colmax){
if(temp1 == 1){
data0 = symbol[index_location][x];
data1 = symbol[index_location][x + 10];
}else if(temp1 == 2){
data0= symbol[index_location][x] | and[move_high];
data1 = symbol[index_location][x + 10] | and[move_high + 16];
}else if(temp1 == 3 && dis == 1){
data0 = symbol[index_location][x];
data1 = symbol[index_location][x + 10];
}else{
data0 = 0xff;
data1 = 0xff;
}
chop(data0,data1);
}else{break;}
colpre++;
}
}
}
if(endis == 0){colmax--;}//sau khi hiển thị hết số cột nếu chưa xảy ra ngắt thì tăng số cột max thêm 1
else{colmax++;}
}
void start(){//hàm cho các led sáng từ ngoài vào trong
unsigned char i,data0,data1;
unsigned int j;
EX0 = 0;
out_port(0xff,0xff);
bd =0;
for(j =0; j< 500; j++){delay(155);}
/////////////////////////////////////////
data0 = 0xfe;
out_port(data0,0xff);
for(j =0; j< 500; j++){delay(155);}
for(i = 1;
i < 8; i++){
data0 = data0<<1;
out_port(data0,0xff);
for(j =0; j< 500; j++){delay(155);}
}
/////////////////////////////////////////
data1 = 0xfe;
out_port(data0,data1);
for(j =0; j< 500; j++){delay(155);}
for(i = 1;
i < 8; i++){
data1 = data1<<1;
out_port(data0,data1);
for(j =0; j< 500; j++){delay(155);}
}
/////////////////////////////////////////////
for(i = 1;
i < 2; i++){
out_port(0xff,0xff);
bd = 0;
for(j =0; j< 500; j++){delay(155);}
out_port(0,0);
bd = 1;
for(j =0; j< 500; j++){delay(155);}
}
/////////////////////////////////////////////
out_port(0xff,0xff);
bd = 1; EX0 = 1;
}
void chop(unsigned char data0, unsigned char data1){//hàm cho các led chớp tắt tạo chữ mịn hơn
out_port(data0,data1);
bd = 0;
delay(time1);
out_port(0xff,0xff);
bd = 1;
delay(time1);
out_port(data0,data1);
bd = 0;
delay(time1);
out_port(0xff,0xff);
bd = 1;
}
void out_port(unsigned char data0,unsigned char data1){P0 = data0;
các port
P1 = data1;}//hàm xuất dữ liệu ra
unsigned char code index[]={//mảng chứa địa chỉ các ký tự hiện thị
53,0,1,2,0,3,4,5,0,6,7,8,9,7,0,10,11,12,0,13,0,14,15,16,17,18,19,0,13,0,20,5,21,9,0,6,22,0,23,23,24,24,24,24
,24,24,24,24,24,24,24,24,24,24,5
};
unsigned char code symbol[][21]={//bảng mã hex cho các ký tự trên
/*32*/{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xff,0x5},
/*83*/{0xFF,0xCF,0x87,0x3,0x33,0x73,0xF3,0xC3,0xC7,0xCF,0xFF,0xF3,0xE3,0xC3,0xCE,0xCE,0xCC,0xC0,
0xE1,0xF3,0xa},
/*86*/{0xFF,0x03,0x03,0x03,0xFF,0xFF,0xFF,0x03,0x03,0x03,0xFF,0xFC,0xF8,0xF0,0xE3,0xC7,0xE3,0xF0,0
xF8,0xFC,0xa},
/*66*/{0xFF,0x03,0x03,0x03,0x73,0x73,0x73,0x03,0x07,0x8F,0xFF,0xC0,0xC0,0xC0,0xCE,0xCE,0xCE,0xC0,
0xE0,0xF1,0xa},
/*239*/{0xFF,0x7F,0x7B,0x73,0xE7,0xEF,0x7F,0x7F,0x7F,0xFF,0xFF,0xF0,0xE0,0xC0,0xCF,0xCF,0xE0,0xC
0,0xC0,0xFF,0x9},
/*105*/{0xFF,0x3F,0x3F,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC1,0xC1,0xC1,0xFF,0xFF,0xFF,0xF
F,0xFF,0xFF,0x4},
/*84*/{0xFF,0xE3,0xF3,0xF3,0x03,0x03,0x03,0xF3,0xF3,0xE3,0xFF,0xFF,0xFF,0xDF,0xC0,0xC0,0xC0,0xDF,
0xFF,0xFF,0xa},
/*104*/{0xFF,0x03,0x03,0x03,0xFF,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xFC,0xFE,0xC0,0xC
0,0xC1,0xFF,0x9},
/*97*/{0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0xFF,0x7F,0x7F,0xFF,0xFF,0xF1,0xE0,0xC0,0xCE,0xCE,0xE0,0xC0,
0xC0,0xFF,0x9},
/*110*/{0xFF,0x7F,0x7F,0x7F,0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xC0,0xC0,0xC0,0xFC,0xFE,0xFE,0xC
0,0xC0,0xC1,0xa},
/*72*/{0xFF,0x03,0x03,0x03,0x7F,0x7F,0x7F,0x03,0x03,0x03,0xFF,0xC0,0xC0,0xC0,0xFE,0xFE,0xFE,0xC0,0
xC0,0xC0,0xa},
/*203*/{0xFF,0xFF,0xDF,0x6F,0x67,0x67,0xEF,0x5F,0x7F,0xFF,0xFF,0xF1,0xE0,0xC0,0x4E,0x4E,0xE0,0xC0
,0xC0,0xFF,0x9},
/*117*/{0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0xF0,0xE0,0xC0,0xCF,0xCF,0xE0,0xC
0,0xC0,0xFF,0x9},
/*45*/{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xF
F,0xFF,0xFF,0x7},
/*76*/{0xFF,0xFB,0x03,0x03,0x03,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xC0,0xC0,0xC0,0xCF,0xCF,0xCF
,0xC7,0xC3,0xa},
/*237*/{0xFF,0xFF,0xFF,0x7F,0x77,
0x73,0x29,0x8D,0xDF,0xFF,0xFF,0xF1,0xE0,0xC0,0xCE,0xCE,0xC0,0xE0,0xF1,0xFF,0x9},
/*112*/{0xFF,0x7F,0x7F,0x7F,0xFF,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0xE4,0xE6,0xE0,0xF0,
0xF9,0xFF,0x9},
/*58*/{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,0xCC,0xCC,0xFF,0xFF,0xFF,0xF
F,0xFF,0xFF,0x4},
/*67*/{0xFF,0x0F,0x07,0x03,0xF3,0xF3,0xF3,0xC3,0xC7,0xCF,0xFF,0xF0,0xE0,0xC0,0xCF,0xCF,0xCF,0xC3,
0xE3,0xF3,0xa},
/*254*/{0xFF,0x7B,0x03,0x03,0x03,0x73,0xF3,0x03,0x07,0x0F,0xFF,0xDE,0xC0,0xC0,0xC0,0xCE,0xCF,0xC
0,0xE0,0xF0,0xa},
/*254*/{0xFF,0x7B,0x03,0x03,0x03,0x73,0xF3,0x03,0x07,0x0F,0xFF,0xDE,0xC0,0xC0,0xC0,0xCE,0xCF,0xC
0,0xE0,0xF0,0xa},
/*214*/{0xFF,0xFF,0xDF,0x4F,0x67,0x67,0x4F,0xDF,0xFF,0xFF,0xFF,0xF1,0xE0,0xC0,0x4A,0x4A,0xC8,0xE
C,0xFF,0xFF,0x8},
/*246*/{0x7F,0x7F,0x7F,0xEB,0xE3,0x77,0x7F,0x2F,0x8F,0xDF,0xF0,0xE0,0xC0,0xCF,0xCF,0xE0,0xC0,0xC
0,0xFF,0xFF,0xa},
/*51*/{0xFF,0xCF,0x47,0x63,0x73,0x73,0x03,0x07,0x8F,0xFF,0xFF,0xF3,0xE2,0xC6,0xCE,0xCE,0xC0,0xE0,
0xF1,0xFF,0x9},
/*60*/{0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFB,0xF1,0xE0,0xC4,0xCE,0xDF,0xFF,
0xFF,0xFF,0x7},
};
- Xem thêm -