25
Lý thuyết về code LED sao băng bằng ASM và KeilC cho 8051 Thân chào tất cả các bạn! Hôm nay mình sẽ chỉ cho các bạn tất tần tật từ lý thuyết đến làm 1 mạch LED sao băng 32 cổng bằng vi điều khiển 8051. Nội dung mình viết sẽ gồm các phần sau: 1. Lý thuyết căn bản về PWM ( Pulse - Width - Modulation) hay còn gọi là điều chế độ rộng xung; 2. Code PWM = ASM và C đơn giản bằng vòng lặp, hình ảnh chạy thực tế và xem độ rộng xung trên proteus; 3. Code PWM = ASM và C trên ngắt timer của 8051, hình ảnh chạy thực tế và xem độ rộng xung trên proteus; 4. Code mẫu PWM = ASM và C 32 cổng bằng ngắt timer của 8051, hình ảnh chạy thực tế và xem độ rộng xung trên proteus. Phần 1: -Phần lý thuyết PWM thì có rất nhiều tài liệu trên mạng nhưng mình tóm tắt lại là: cùng 1 tần số F hay chu kỳ T không đổi nhưng khác nhau về độ rộng của sườn dương hoặc sườn âm thì điện áp trung bình trên tải sẽ khác nhau --> dòng trung bình chảy qua tải cũng sẽ thay đổi (cụ thể là dòng chảy qua LED thay đổi nên độ sáng LED cũng thay đổi theo). *Ví dụ: trong chu kỳ T=1/60(s) nếu T(+)=0.5T(s) và T(-)=0.5T(s) thì điện áp trung bình = U1(V). Nếu T(+)=0.1T(s) và T(-)=0.9T(s) thì điện áp trung bình = U2(V). Ta sẽ có U1>U2 --> I1>I2 nên cường độ sáng LED1 > LED2. - Gửi các bạn link hay về PWM: Nguyên tắc điều chế PWM - Pulse - Width-Modulation - Hội Quán Điện Tử - Hội Quán Điện Tử Phần 2: - Phần này chúng ta sẽ viết code PWM để thay đổi độ sáng của 1 led. - Để thực tế và nhanh khi thực hành thì mình sẽ cắm mạch trên test bo: nguyên liệu cần là 1-89S52, 2-LED đỏ, 3-trở 220 Ôm, 4-thạch anh 24Mhz, 5-2 tụ 22pF, 6-tụ 104(0.1uF), 7-nguồn 5V(có thể lấy từ nguồn USB) - Như đã nói là code sẽ được thực hiện trên cả ASM và C nhưng để nhanh mình sẽ viết C trước, còn code ASM mình sẽ đóng gói thành File gửi các bạn sau nha. - Đầu tiên mình sẽ xây dựng hàm delay_ms(unsigned char time) trong Keil C Code

Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

Embed Size (px)

Citation preview

Page 1: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

Lý thuyết về code LED sao băng bằng ASM và KeilC cho 8051

Thân chào tất cả các bạn!Hôm nay mình sẽ chỉ cho các bạn tất tần tật từ lý thuyết đến làm 1 mạch LED sao băng 32 cổng bằng vi điều khiển 8051.Nội dung mình viết sẽ gồm các phần sau:1. Lý thuyết căn bản về PWM ( Pulse - Width - Modulation) hay còn gọi là điều chế độ rộng xung;2. Code PWM = ASM và C đơn giản bằng vòng lặp, hình ảnh chạy thực tế và xem độ rộng xung trên proteus;3. Code PWM = ASM và C trên ngắt timer của 8051, hình ảnh chạy thực tế và xem độ rộng xung trên proteus;4. Code mẫu PWM = ASM và C 32 cổng bằng ngắt timer của 8051, hình ảnh chạy thực tế và xem độ rộng xung trên proteus.

Phần 1:-Phần lý thuyết PWM thì có rất nhiều tài liệu trên mạng nhưng mình tóm tắt lại là: cùng 1 tần số F hay chu kỳ T không đổi nhưng khác nhau về độ rộng của sườn dương hoặc sườn âm thì điện áp trung bình trên tải sẽ khác nhau --> dòng trung bình chảy qua tải cũng sẽ thay đổi (cụ thể là dòng chảy qua LED thay đổi nên độ sáng LED cũng thay đổi theo).*Ví dụ: trong chu kỳ T=1/60(s) nếu T(+)=0.5T(s) và T(-)=0.5T(s) thì điện áp trung bình = U1(V). Nếu T(+)=0.1T(s) và T(-)=0.9T(s) thì điện áp trung bình = U2(V). Ta sẽ có U1>U2 --> I1>I2 nên cường độ sáng LED1 > LED2.- Gửi các bạn link hay về PWM: Nguyên tắc điều chế PWM - Pulse - Width-Modulation - Hội Quán Điện Tử - Hội Quán Điện Tử

Phần 2:- Phần này chúng ta sẽ viết code PWM để thay đổi độ sáng của 1 led.- Để thực tế và nhanh khi thực hành thì mình sẽ cắm mạch trên test bo: nguyên liệu cần là 1-89S52, 2-LED đỏ, 3-trở 220 Ôm, 4-thạch anh 24Mhz, 5-2 tụ 22pF, 6-tụ 104(0.1uF), 7-nguồn 5V(có thể lấy từ nguồn USB)- Như đã nói là code sẽ được thực hiện trên cả ASM và C nhưng để nhanh mình sẽ viết C trước, còn code ASM mình sẽ đóng gói thành File gửi các bạn sau nha.- Đầu tiên mình sẽ xây dựng hàm delay_ms(unsigned char time) trong Keil CCodevoid delay_ms(unsigned char time){

unsigned char temp;while(time--){

temp = 250;while(temp--); temp = 62;while(temp--);

};}

Giải thích: Mình dùng thạch anh là 24Mhz nên thời gian chu kỳ máy là 1/(24/12) =1/2 (us)--> muốn delay 1s thì cần 2*10^6 chu kỳ máy --> delay 1ms cần 2000 chu kỳ máy- Chúng ta chạy debug hàm delay_ms(unsigned char time) trong ASM thì được như sauCode:5: void delay_ms(unsigned char time){ 6: unsigned char temp; 7: while(time--){ C:0x0003 AD07 MOV R5,0x07 ;2ckm

Page 2: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

C:0x0005 1F DEC R7 ;1ckmC:0x0006 ED MOV A,R5 ;1ckmC:0x0007 6012 JZ C:001B ;2ckm 8: temp = 250; C:0x0009 7EFA MOV R6,#0xFA ; 2ckm 9: while(temp--); C:0x000B AD06 MOV R5,0x06 ; 2ckmC:0x000D 1E DEC R6 ;1ckmC:0x000E ED MOV A,R5 ;1ckmC:0x000F 70FA JNZ C:000B ;2ckm 10: temp = 62; C:0x0011 7E3E MOV R6,#0x3E ;2ckm 11: while(temp--); C:0x0013 AD06 MOV R5,0x06 ;2ckmC:0x0015 1E DEC R6 ;1ckmC:0x0016 ED MOV A,R5 ;1ckmC:0x0017 60EA JZ delay_ms(C:0003) ;2ckmC:0x0019 80F8 SJMP C:0013 ;2ckm 12: };

Phân tích hàm delay_ms(1) thành ASM thì tốn số chu kỳ máy là: 6 + 2 + 250*6 + 2 + 62*8 = 2004 (ckm)Vậy là OK rồi từ nay các bạn muốn delay số ms thì dùng hàm này nhé, các bạn có thể kiểm chứng trên Proteus thử nha.Ví dụ: delay 100ms thì gọi hàm delay_ms(100);Bây giờ ta vào hàm main() để viết vòng lặp PWM cho LED nha:- Có 1 chú ý khi PWM cho LED là : tần số F luôn đảm bảo >=60 Hz thì LED sáng mịn và không có cảm giác bị giậtNếu f=60Hz --> T = 1/60 ~= 16ms.- Một điều chú ý nữa là cường độ sáng cua LED bạn muốn bao nhiêu mức.Ví dụ: Muốn có độ phân giải là 16 mức sáng khác nhau cho LED thì trong chu kỳ T=16ms ta chia ra 16 mức. Nghĩa là mỗi mức giữ 1ms ở sường dương hoặc sườn âm tùy vào thiết kế mạch kích LED.- Code mình viết sau đây sẽ sáng dần và tắt dần LED tại PORT0.0 sử dụng vòng lặp.Code:/*Thach anh su dung f=24Mhz*/#include "regx52.h"sbit led = P0^0;

void led_dimmer();

void delay_ms(unsigned char time){unsigned char temp;while(time--){

temp = 250;while(temp--); temp = 62;while(temp--);

};}

void main(){while(1){

led_dimmer();}

}

void led_dimmer(){unsigned char i,j;

Page 3: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

for(i=1;i<=16;i++){j=0;while(++j<5){ // tong time delay la 16*5 = 80 ms

led = 1;delay_ms(i);led = 0;delay_ms(16-i);

}}for(i=1;i<=16;i++){

j=0;while(++j<5){ // tong time delay la 16*5 = 80ms

led = 1;delay_ms(16-i);led = 0;delay_ms(i);

}}

}

Phần 3:- Phần này mình sẽ xây dựng: a. Code PWM cho 1 LED bởi ngắt timer 8051b. Code PWM cho 1 module LED RGB chuyển màu full color

a. Phần này sẽ gồm 3 phần:- Khởi tạo ngắt timer0 cho 89S52;- Code PWM trên timer1;- Code thay đổi PWM trong hàm main();

Để khởi tạo ngắt timer0 hoặc timer1 trong 89S52 các bạn tham khảo thanh ghi TMOD và IE trong datasheet nha:- Mình khởi tạo timer1 ở mode1 là bộ đếm 16bit: nghĩa là khi thanh ghi TH1 và TL1 chuyển từ FFFF --> 0000 thì sẽ xảy ra ngắt timer1;- Để cho phép ngắt timer1 thì phải enable bit EA và bit ET1 trong thanh ghi IE- Đây là code để khởi tạo ngắt timer1 chế độ 16bitCode:TMOD=0x10; /*timer 1 16bit*/

TR1=1;TH1=0xFE;TL1=0xB3;IE=0x88; /*Ket thuc khoi dong timer1*/

* Mình giải thích vì sao TH1=0xFE, TL1=0xB3;Như mình đã nói: 1. Muốn LED sáng mịn thì tần số PWM phải đảm bảo >=60Hz, 2. Độ phân giải cường độ sáng của LED là bao nhiêu.Vì đợt này mình thực hiện PWM trên ngắt timer nên mình sẽ tạo độ phân giải là 100 mức sáng khác nhau. Ta dùng thạch anh là 24Mhz --> 1 chu kỳ máy = 1/(24/12) = 0.5us --> F= 2000000Hz --> nếu TH1=0xFF và TL1=0xFF thì tần số ngắt timer1 là F=2000000Hz. Vậy để tần số PWM LED là 60Hz và độ phân giải là 100 mức sáng khác nhau thì giá trị nạp vào TH1 và TL1 được tính như sau:TH1TL1 = -(2000000/60/100) ~= -333(DEC) = 0xFEB3(HEX) hay TH1=0xFE, TL1=0xB3

- Đây là code PWM trên ngắt timer1 cho 1 LED tại chân P0.0Code:/*Thach anh su dung f=24Mhz*/

Page 4: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

#include "regx52.h"

typedef unsigned char uchar;typedef unsigned int uint;

sbit led = P0^0;

uchar num_pwm;uchar pwm_c;uchar delay_in_t1;void isr_timer1() interrupt 3 using 2{

TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/

TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/

led =(pwm_c>num_pwm)?1:0;

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

}void delay_ms(uchar time){

delay_in_t1 = 0;while(delay_in_t1 <= time*6);

}

void led_dim_ti();

void main(){TMOD=0x10; /*timer 1 16bit*/TR1=1;TH1=0xFE;TL1=0xB3;IE=0x88; /*Ket thuc khoi dong timer1*/

while(1){ led_dim_ti();

}}

void led_dim_ti(){ uchar i;P0 = 0;while(1){

for(i=0;i<=100;i++){pwm_c = i;num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

pwm_c = 100-i;num_pwm = 0;delay_ms(16);

}}

}

* Giải thích hàm delay_ms(uchar time) :- Vì khi sử dụng ngắt timer1 với TH1TL1 =0xFEB3(-333) có nghĩa là cứ 333 chu kỳ máy là xảy ra 1 lần ngắt trên timer1, vì thạch anh 24Mhz nên mỗi chu kỳ máy tốn 0.5us --> 333 ckm

Page 5: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

sẽ tốn 333*0.5 us --> nếu xảy ra 6 lần ngắt timer1 thì T = 333*0.5*6 = 999 us ~=1ms. Chính vì thế mà hàm delay_ms(uchar time) được xây dựng như sau:Code:void delay_ms(uchar time){

delay_in_t1 = 0;while(delay_in_t1 <= time*6); // time*6 = 1ms

}

- Còn hàm led_dim_ti() các bạn tự hiểu nha.Vì độ sáng được chia làm 100 mức nên PWM bằng ngắt timer sẽ mịn hơn khi delay với vòng lặp ở phần 2

b. Phần này tương tự phần (a) nhưng mình chỉ viết thêm hàm dimmer_GRB() để thay đổi độ sáng từng LED đỏ, xanh lá và xanh dương để phối ra được các màu khác nhau. ******Giờ chúc các bạn ngủ ngon, ai xem đá banh cuối tuần thì xem cho đã còn mình phải ngủ thôi vì mai dậy sớm có cv rùi. Mình sẽ sớm viết tiếp các phần còn lại cho các bạn. bibi*******

phần 3: LED RGB dimmer

Phần 3b:- Phần này mình dùng 1 module LED RGB .- Phần cứng thì PORT0.0 - LED ĐỎ, PORT0.1 - LED XANH LÁ, PORT0.2 - LED XANH DƯƠNG- Code thì tương tự phần 3a, mình chỉ viết thêm hàm PWM kết hợp các cổng LED RGB lại để điều chỉnh độ sáng từng LED --> cho ra màu tương ứng.Code:/*Thach anh su dung f=24Mhz*/#include "regx52.h"

typedef unsigned char uchar;typedef unsigned int uint;

sbit led_r = P0^0;sbit led_g = P0^1;sbit led_b = P0^2;

uchar num_pwm;uchar pwm_r,pwm_g,pwm_b;uint delay_in_t1;void isr_timer1() interrupt 3 using 2{

TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/

TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/

led_r =(pwm_r>num_pwm)?1:0;led_g =(pwm_g>num_pwm)?1:0;led_b =(pwm_b>num_pwm)?1:0;

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

}void delay_ms(uint time){

delay_in_t1 = 0;while(delay_in_t1 <= time*6);

Page 6: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

}

void led_dim_rgb(uchar red, uchar green, uchar blue);void full_color1(void);void full_color2(void);

void main(){TMOD=0x10; /*timer 1 16bit*/TR1=1;TH1=0xFE;TL1=0xB3;IE=0x88; /*Ket thuc khoi dong timer1*/

P0 = 0;delay_ms(3000);full_color1();while(1){

full_color2();}

}

void led_dim_rgb(uchar red, uchar green, uchar blue){pwm_r = red;pwm_g = green;pwm_b = blue;

}

void full_color2(void){uchar i;//0,0,1for(i=0;i<=100;i++){

led_dim_rgb(i,0,0);num_pwm = 0;delay_ms(16);

}//0,1,0for(i=0;i<=100;i++){

led_dim_rgb(100-i,i,0);num_pwm = 0;delay_ms(16);

}//0,1,1for(i=0;i<=100;i++){

led_dim_rgb(i,100,0);num_pwm = 0;delay_ms(16);

}//1,0,0for(i=0;i<=100;i++){

led_dim_rgb(100-i,100-i,i);num_pwm = 0;delay_ms(16);

}//1,0,1for(i=0;i<=100;i++){

led_dim_rgb(i,0,100);num_pwm = 0;delay_ms(16);

}//1,1,0for(i=0;i<=100;i++){

led_dim_rgb(100-i,i,100);num_pwm = 0;

Page 7: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

delay_ms(16);}//1,1,1for(i=0;i<=100;i++){

led_dim_rgb(i,100,100);num_pwm = 0;delay_ms(16);

}//0,0,0for(i=0;i<=100;i++){

led_dim_rgb(100-i,100-i,100-i);num_pwm = 0;delay_ms(16);

}}

void full_color1(void){uchar i;//pwm led dofor(i=0;i<=100;i++){

led_dim_rgb(i,0,0);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(100-i,0,0);num_pwm = 0;delay_ms(16);

}

//pwm led xanh lafor(i=0;i<=100;i++){

led_dim_rgb(0,i,0);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(0,100-i,0);num_pwm = 0;delay_ms(16);

}

//pwm led xanh duongfor(i=0;i<=100;i++){

led_dim_rgb(0,0,i);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(0,0,100-i);num_pwm = 0;delay_ms(16);

}

//pwm led do + xanh lafor(i=0;i<=100;i++){

led_dim_rgb(i,i,0);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(100-i,100-i,0);num_pwm = 0;delay_ms(16);

Page 8: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

}

//pwm led do + xanh duongfor(i=0;i<=100;i++){

led_dim_rgb(i,0,i);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(100-i,0,100-i);num_pwm = 0;delay_ms(16);

}

//pwm led xanh la + xanh duongfor(i=0;i<=100;i++){

led_dim_rgb(0,i,i);num_pwm = 0;delay_ms(16);

}for(i=0;i<=100;i++){

led_dim_rgb(0,100-i,100-i);num_pwm = 0;delay_ms(16);

}}

- Bạn muốn băm xung qua 595 thì cũng thế thôi. Thay vì xuất trực tiếp qua PORT thì bạn thay bằng 1 xung CLK là xong mừ.Ví dụ:Code:sbit di_595 = P0^0;sbit sck_595 = P0^1;sbit rck_595 = P0^2;uchar num_pwm;uchar pwm_r,pwm_g,pwm_b;uint delay_in_t1;void isr_timer1() interrupt 3 using 2{

TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/

TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/

di_595 =(pwm_r>num_pwm)?1:0;sck_595 = 1;sck_595 = 0;led_di =(pwm_g>num_pwm)?1:0;sck_595 = 1;sck_595 = 0;led_di =(pwm_b>num_pwm)?1:0;sck_595 = 1;sck_595 = 0;

rck_595 = 1;rck_595 = 0;

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

}

Page 9: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

như tiều đề của [TUT] là PWM 32 cổng tức là 4Port luôn đó bạn. Nhưng mấy hôm nay đi rông ngoài đường hoài nên chưa viết tiếp phần4 cho các bạn được. Giới thiệu sơ qua về phần 4:- Tính số mức sáng tối đa có thể làm được cho 32 cổng PWM với 89S52- Code led kiểu sao băng 32 cổng.- Code led kiểu sóng biển xô bờ - Code led kết hợp vừa sao băng vừa sáng tắt led bình thường (Kiểu này thường dùng trong mấy bảng LED quảng cáo: LED sao băng cho viền bảng LED, chớp sáng cho các chữ cái).

Phần 4 [TUT] Led sao băng 32 cổng 8051

Phần 4:Như mình đã nói phần này gồm các phần như sau:a. Tính số mức sáng tối đa có thể làm được cho 32 cổng PWM với 89S52b. Code led kiểu sao băng 32 cổng.c. Code led kiểu sóng biển xô bờ d. Code led kết hợp vừa sao băng vừa sáng tắt led bình thường (Kiểu này thường dùng trong mấy bảng LED quảng cáo: LED sao băng cho viền bảng LED, chớp sáng cho các chữ cái).

Phần 4a:- Phần này hơi khó giải thích vì vậy mình sẽ đưa code ra trước rồi chỉ cách tính số mức tối đa có thể dùng để PWM 32 cổng cho 89S52.* Các bạn nên đọc từ đầu bài viết để biết vì sao mình viết đoạn code PWM 32 cổng dưới đây nha.Code PWM 32 cổng 100 mức sáng khác nhau trên timer1:Code:/*Thach anh su dung f=24Mhz*/#include "regx52.h"

typedef unsigned char uchar;typedef unsigned int uint;

sbit c1=P0^0;sbit c2=P0^1;sbit c3=P0^2;sbit c4=P0^3;sbit c5=P0^4;sbit c6=P0^5;sbit c7=P0^6;sbit c8=P0^7;sbit c9=P2^7;sbit c10=P2^6;sbit c11=P2^5;sbit c12=P2^4;sbit c13=P2^3;sbit c14=P2^2;sbit c15=P2^1;sbit c16=P2^0;sbit c17=P3^7;sbit c18=P3^6;sbit c19=P3^5;sbit c20=P3^4;sbit c21=P3^3;sbit c22=P3^2;sbit c23=P3^1;sbit c24=P3^0;

Page 10: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

sbit c25=P1^7;sbit c26=P1^6;sbit c27=P1^5;sbit c28=P1^4;sbit c29=P1^3;sbit c30=P1^2;sbit c31=P1^1;sbit c32=P1^0;

uchar num_pwm;uchar pwm_c[32];uint delay_in_t1;void isr_timer1() interrupt 3 using 2{

TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/

TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/

c1=(pwm_c[0]>num_pwm)?1:0;c2=(pwm_c[1]>num_pwm)?1:0;c3=(pwm_c[2]>num_pwm)?1:0;c4=(pwm_c[3]>num_pwm)?1:0;c5=(pwm_c[4]>num_pwm)?1:0; c6=(pwm_c[5]>num_pwm)?1:0;c7=(pwm_c[6]>num_pwm)?1:0;c8=(pwm_c[7]>num_pwm)?1:0;c9=(pwm_c[8]>num_pwm)?1:0;c10=(pwm_c[9]>num_pwm)?1:0;c11=(pwm_c[10]>num_pwm)?1:0;c12=(pwm_c[11]>num_pwm)?1:0;c13=(pwm_c[12]>num_pwm)?1:0;c14=(pwm_c[13]>num_pwm)?1:0;c15=(pwm_c[14]>num_pwm)?1:0;c16=(pwm_c[15]>num_pwm)?1:0;c17=(pwm_c[16]>num_pwm)?1:0;c18=(pwm_c[17]>num_pwm)?1:0;c19=(pwm_c[18]>num_pwm)?1:0;c20=(pwm_c[19]>num_pwm)?1:0;c21=(pwm_c[20]>num_pwm)?1:0;c22=(pwm_c[21]>num_pwm)?1:0;c23=(pwm_c[22]>num_pwm)?1:0;c24=(pwm_c[23]>num_pwm)?1:0;c25=(pwm_c[24]>num_pwm)?1:0;c26=(pwm_c[25]>num_pwm)?1:0;c27=(pwm_c[26]>num_pwm)?1:0;c28=(pwm_c[27]>num_pwm)?1:0;c29=(pwm_c[28]>num_pwm)?1:0;c30=(pwm_c[29]>num_pwm)?1:0;c31=(pwm_c[30]>num_pwm)?1:0;c32=(pwm_c[31]>num_pwm)?1:0;

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

}void delay_ms(uint time){

delay_in_t1 = 0;while(delay_in_t1 <= time*6);

}

void main(){TMOD=0x10; /*timer 1 16bit*/

Page 11: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

TR1=1;TH1=0xFE;TL1=0xB3;IE=0x88; /*Ket thuc khoi dong timer1*/

P0 = 0;P1 = 0;P2 = 0;P3 = 0;delay_ms(3000);while(1){}

}

Tiếp tục chúng ta chạy debug đoạn code trên trong ASM của KeilC để xem tổng thời gian xử lý trên ngắt timer1 tốn bao nhiêu chu kỳ máy nha.Code ASM:Code:43: void isr_timer1() interrupt 3 using 2{ C:0x001E C0E0 PUSH ACC(0xE0)C:0x0020 C0D0 PUSH PSW(0xD0) 44: TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/ C:0x0022 758DFE MOV TH1(0x8D),#0xFE 45: TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/ 46: C:0x0025 758BB3 MOV TL1(0x8B),#0xB3 47: c1=(pwm_c[0]>num_pwm)?1:0; C:0x0028 E509 MOV A,pwm_c(0x09)C:0x002A D3 SETB CC:0x002B 9508 SUBB A,num_pwm(0x08)C:0x002D 4003 JC C:0032C:0x002F D3 SETB CC:0x0030 8001 SJMP C:0033C:0x0032 C3 CLR CC:0x0033 9280 MOV c1(0x80.0),C 48: c2=(pwm_c[1]>num_pwm)?1:0; C:0x0035 E50A MOV A,0x0AC:0x0037 D3 SETB CC:0x0038 9508 SUBB A,num_pwm(0x08)C:0x003A 4003 JC C:003FC:0x003C D3 SETB CC:0x003D 8001 SJMP C:0040C:0x003F C3 CLR CC:0x0040 9281 MOV c2(0x80.1),C 49: c3=(pwm_c[2]>num_pwm)?1:0; C:0x0042 E50B MOV A,0x0BC:0x0044 D3 SETB CC:0x0045 9508 SUBB A,num_pwm(0x08)C:0x0047 4003 JC C:004CC:0x0049 D3 SETB CC:0x004A 8001 SJMP C:004DC:0x004C C3 CLR CC:0x004D 9282 MOV c3(0x80.2),C 50: c4=(pwm_c[3]>num_pwm)?1:0; C:0x004F E50C MOV A,0x0CC:0x0051 D3 SETB CC:0x0052 9508 SUBB A,num_pwm(0x08)C:0x0054 4003 JC C:0059C:0x0056 D3 SETB CC:0x0057 8001 SJMP C:005AC:0x0059 C3 CLR C

Page 12: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

C:0x005A 9283 MOV c4(0x80.3),C 51: c5=(pwm_c[4]>num_pwm)?1:0; C:0x005C E50D MOV A,0x0DC:0x005E D3 SETB CC:0x005F 9508 SUBB A,num_pwm(0x08)C:0x0061 4003 JC C:0066C:0x0063 D3 SETB CC:0x0064 8001 SJMP C:0067C:0x0066 C3 CLR CC:0x0067 9284 MOV c5(0x80.4),C 52: c6=(pwm_c[5]>num_pwm)?1:0; C:0x0069 E50E MOV A,0x0EC:0x006B D3 SETB CC:0x006C 9508 SUBB A,num_pwm(0x08)C:0x006E 4003 JC C:0073C:0x0070 D3 SETB CC:0x0071 8001 SJMP C:0074C:0x0073 C3 CLR CC:0x0074 9285 MOV c6(0x80.5),C 53: c7=(pwm_c[6]>num_pwm)?1:0; C:0x0076 E50F MOV A,0x0FC:0x0078 D3 SETB CC:0x0079 9508 SUBB A,num_pwm(0x08)C:0x007B 4003 JC C:0080C:0x007D D3 SETB CC:0x007E 8001 SJMP C:0081C:0x0080 C3 CLR CC:0x0081 9286 MOV c7(0x80.6),C 54: c8=(pwm_c[7]>num_pwm)?1:0; C:0x0083 E510 MOV A,0x10C:0x0085 D3 SETB CC:0x0086 9508 SUBB A,num_pwm(0x08)C:0x0088 4003 JC C:008DC:0x008A D3 SETB CC:0x008B 8001 SJMP C:008EC:0x008D C3 CLR CC:0x008E 9287 MOV c8(0x80.7),C 55: c9=(pwm_c[8]>num_pwm)?1:0; C:0x0090 E511 MOV A,0x11C:0x0092 D3 SETB CC:0x0093 9508 SUBB A,num_pwm(0x08)C:0x0095 4003 JC C:009AC:0x0097 D3 SETB CC:0x0098 8001 SJMP C:009BC:0x009A C3 CLR CC:0x009B 92A7 MOV c9(0xA0.7),C 56: c10=(pwm_c[9]>num_pwm)?1:0; C:0x009D E512 MOV A,0x12C:0x009F D3 SETB CC:0x00A0 9508 SUBB A,num_pwm(0x08)C:0x00A2 4003 JC C:00A7C:0x00A4 D3 SETB CC:0x00A5 8001 SJMP C:00A8C:0x00A7 C3 CLR CC:0x00A8 92A6 MOV c10(0xA0.6),C 57: c11=(pwm_c[10]>num_pwm)?1:0; C:0x00AA E513 MOV A,0x13C:0x00AC D3 SETB CC:0x00AD 9508 SUBB A,num_pwm(0x08)C:0x00AF 4003 JC C:00B4C:0x00B1 D3 SETB CC:0x00B2 8001 SJMP C:00B5C:0x00B4 C3 CLR CC:0x00B5 92A5 MOV c11(0xA0.5),C

Page 13: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

58: c12=(pwm_c[11]>num_pwm)?1:0; C:0x00B7 E514 MOV A,0x14C:0x00B9 D3 SETB CC:0x00BA 9508 SUBB A,num_pwm(0x08)C:0x00BC 4003 JC C:00C1C:0x00BE D3 SETB CC:0x00BF 8001 SJMP C:00C2C:0x00C1 C3 CLR CC:0x00C2 92A4 MOV c12(0xA0.4),C 59: c13=(pwm_c[12]>num_pwm)?1:0; C:0x00C4 E515 MOV A,0x15C:0x00C6 D3 SETB CC:0x00C7 9508 SUBB A,num_pwm(0x08)C:0x00C9 4003 JC C:00CEC:0x00CB D3 SETB CC:0x00CC 8001 SJMP C:00CFC:0x00CE C3 CLR CC:0x00CF 92A3 MOV c13(0xA0.3),C 60: c14=(pwm_c[13]>num_pwm)?1:0; C:0x00D1 E516 MOV A,0x16C:0x00D3 D3 SETB CC:0x00D4 9508 SUBB A,num_pwm(0x08)C:0x00D6 4003 JC C:00DBC:0x00D8 D3 SETB CC:0x00D9 8001 SJMP C:00DCC:0x00DB C3 CLR CC:0x00DC 92A2 MOV c14(0xA0.2),C 61: c15=(pwm_c[14]>num_pwm)?1:0; C:0x00DE E517 MOV A,0x17C:0x00E0 D3 SETB CC:0x00E1 9508 SUBB A,num_pwm(0x08)C:0x00E3 4003 JC C:00E8C:0x00E5 D3 SETB CC:0x00E6 8001 SJMP C:00E9C:0x00E8 C3 CLR CC:0x00E9 92A1 MOV c15(0xA0.1),C 62: c16=(pwm_c[15]>num_pwm)?1:0; C:0x00EB E518 MOV A,0x18C:0x00ED D3 SETB CC:0x00EE 9508 SUBB A,num_pwm(0x08)C:0x00F0 4003 JC C:00F5C:0x00F2 D3 SETB CC:0x00F3 8001 SJMP C:00F6C:0x00F5 C3 CLR CC:0x00F6 92A0 MOV c16(0xA0.0),C 63: c17=(pwm_c[16]>num_pwm)?1:0; C:0x00F8 E519 MOV A,0x19C:0x00FA D3 SETB CC:0x00FB 9508 SUBB A,num_pwm(0x08)C:0x00FD 4003 JC C:0102C:0x00FF D3 SETB CC:0x0100 8001 SJMP C:0103C:0x0102 C3 CLR CC:0x0103 92B7 MOV c17(0xB0.7),C 64: c18=(pwm_c[17]>num_pwm)?1:0; C:0x0105 E51A MOV A,0x1AC:0x0107 D3 SETB CC:0x0108 9508 SUBB A,num_pwm(0x08)C:0x010A 4003 JC C:010FC:0x010C D3 SETB CC:0x010D 8001 SJMP C:0110C:0x010F C3 CLR CC:0x0110 92B6 MOV c18(0xB0.6),C 65: c19=(pwm_c[18]>num_pwm)?1:0;

Page 14: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

C:0x0112 E51B MOV A,0x1BC:0x0114 D3 SETB CC:0x0115 9508 SUBB A,num_pwm(0x08)C:0x0117 4003 JC C:011CC:0x0119 D3 SETB CC:0x011A 8001 SJMP C:011DC:0x011C C3 CLR CC:0x011D 92B5 MOV c19(0xB0.5),C 66: c20=(pwm_c[19]>num_pwm)?1:0; C:0x011F E51C MOV A,0x1CC:0x0121 D3 SETB CC:0x0122 9508 SUBB A,num_pwm(0x08)C:0x0124 4003 JC C:0129C:0x0126 D3 SETB CC:0x0127 8001 SJMP C:012AC:0x0129 C3 CLR CC:0x012A 92B4 MOV c20(0xB0.4),C 67: c21=(pwm_c[20]>num_pwm)?1:0; C:0x012C E51D MOV A,0x1DC:0x012E D3 SETB CC:0x012F 9508 SUBB A,num_pwm(0x08)C:0x0131 4003 JC C:0136C:0x0133 D3 SETB CC:0x0134 8001 SJMP C:0137C:0x0136 C3 CLR CC:0x0137 92B3 MOV c21(0xB0.3),C 68: c22=(pwm_c[21]>num_pwm)?1:0; C:0x0139 E51E MOV A,0x1EC:0x013B D3 SETB CC:0x013C 9508 SUBB A,num_pwm(0x08)C:0x013E 4003 JC C:0143C:0x0140 D3 SETB CC:0x0141 8001 SJMP C:0144C:0x0143 C3 CLR CC:0x0144 92B2 MOV c22(0xB0.2),C 69: c23=(pwm_c[22]>num_pwm)?1:0; C:0x0146 E51F MOV A,0x1FC:0x0148 D3 SETB CC:0x0149 9508 SUBB A,num_pwm(0x08)C:0x014B 4003 JC C:0150C:0x014D D3 SETB CC:0x014E 8001 SJMP C:0151C:0x0150 C3 CLR CC:0x0151 92B1 MOV c23(0xB0.1),C 70: c24=(pwm_c[23]>num_pwm)?1:0; C:0x0153 E520 MOV A,0x20C:0x0155 D3 SETB CC:0x0156 9508 SUBB A,num_pwm(0x08)C:0x0158 4003 JC C:015DC:0x015A D3 SETB CC:0x015B 8001 SJMP C:015EC:0x015D C3 CLR CC:0x015E 92B0 MOV c24(0xB0.0),C 71: c25=(pwm_c[24]>num_pwm)?1:0; C:0x0160 E521 MOV A,0x21C:0x0162 D3 SETB CC:0x0163 9508 SUBB A,num_pwm(0x08)C:0x0165 4003 JC C:016AC:0x0167 D3 SETB CC:0x0168 8001 SJMP C:016BC:0x016A C3 CLR CC:0x016B 9297 MOV c25(0x90.7),C 72: c26=(pwm_c[25]>num_pwm)?1:0; C:0x016D E522 MOV A,0x22

Page 15: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

C:0x016F D3 SETB CC:0x0170 9508 SUBB A,num_pwm(0x08)C:0x0172 4003 JC C:0177C:0x0174 D3 SETB CC:0x0175 8001 SJMP C:0178C:0x0177 C3 CLR CC:0x0178 9296 MOV c26(0x90.6),C 73: c27=(pwm_c[26]>num_pwm)?1:0; C:0x017A E523 MOV A,0x23C:0x017C D3 SETB CC:0x017D 9508 SUBB A,num_pwm(0x08)C:0x017F 4003 JC C:0184C:0x0181 D3 SETB CC:0x0182 8001 SJMP C:0185C:0x0184 C3 CLR CC:0x0185 9295 MOV c27(0x90.5),C 74: c28=(pwm_c[27]>num_pwm)?1:0; C:0x0187 E524 MOV A,0x24C:0x0189 D3 SETB CC:0x018A 9508 SUBB A,num_pwm(0x08)C:0x018C 4003 JC C:0191C:0x018E D3 SETB CC:0x018F 8001 SJMP C:0192C:0x0191 C3 CLR CC:0x0192 9294 MOV c28(0x90.4),C 75: c29=(pwm_c[28]>num_pwm)?1:0; C:0x0194 E525 MOV A,0x25C:0x0196 D3 SETB CC:0x0197 9508 SUBB A,num_pwm(0x08)C:0x0199 4003 JC C:019EC:0x019B D3 SETB CC:0x019C 8001 SJMP C:019FC:0x019E C3 CLR CC:0x019F 9293 MOV c29(0x90.3),C 76: c30=(pwm_c[29]>num_pwm)?1:0; C:0x01A1 E526 MOV A,0x26C:0x01A3 D3 SETB CC:0x01A4 9508 SUBB A,num_pwm(0x08)C:0x01A6 4003 JC C:01ABC:0x01A8 D3 SETB CC:0x01A9 8001 SJMP C:01ACC:0x01AB C3 CLR CC:0x01AC 9292 MOV c30(0x90.2),C 77: c31=(pwm_c[30]>num_pwm)?1:0; C:0x01AE E527 MOV A,0x27C:0x01B0 D3 SETB CC:0x01B1 9508 SUBB A,num_pwm(0x08)C:0x01B3 4003 JC C:01B8C:0x01B5 D3 SETB CC:0x01B6 8001 SJMP C:01B9C:0x01B8 C3 CLR CC:0x01B9 9291 MOV c31(0x90.1),C 78: c32=(pwm_c[31]>num_pwm)?1:0; 79: C:0x01BB E528 MOV A,0x28C:0x01BD D3 SETB CC:0x01BE 9508 SUBB A,num_pwm(0x08)C:0x01C0 4003 JC C:01C5C:0x01C2 D3 SETB CC:0x01C3 8001 SJMP C:01C6C:0x01C5 C3 CLR CC:0x01C6 9290 MOV c32(0x90.0),C 80: if(++num_pwm==100){ C:0x01C8 0508 INC num_pwm(0x08)

Page 16: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

C:0x01CA E508 MOV A,num_pwm(0x08)C:0x01CC B46403 CJNE A,#0x64,C:01D2 81: num_pwm=0; C:0x01CF 750800 MOV num_pwm(0x08),#0x00 82: } 83: ++delay_in_t1; C:0x01D2 052A INC 0x2AC:0x01D4 E52A MOV A,0x2AC:0x01D6 7002 JNZ C:01DAC:0x01D8 0529 INC delay_in_t1(0x29) 84: }

Mình tính chu kỳ máy từng lệnh trong timer1 thế nào nha:Code C:Code:void isr_timer1() interrupt 3 using 2{

TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/

TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/

Code ASM:Code: 43: void isr_timer1() interrupt 3 using 2{ C:0x001E C0E0 PUSH ACC(0xE0) ;2ckmC:0x0020 C0D0 PUSH PSW(0xD0) ;2ckm 44: TH1=0xFE; /* -24000000/12/60/100 ~= -333 ->0xfeb3 (100 nghia la 100 muc sang)*/ C:0x0022 758DFE MOV TH1(0x8D),#0xFE ;2ckm 45: TL1=0xB3; /* chu ky ngat timer1 T=(333/2)us --> T*6 = 999 us ~= 1ms*/ 46: C:0x0025 758BB3 MOV TL1(0x8B),#0xB3 ;2ckm

T1= 2+2+2+2 = 8ckm

Chu kỳ máy PWM 1 cổng Code C:Code:c1=(pwm_c[0]>num_pwm)?1:0;

Code ASM:Code: 47: c1=(pwm_c[0]>num_pwm)?1:0; C:0x0028 E509 MOV A,pwm_c(0x09) ;1ckmC:0x002A D3 SETB C ;1ckmC:0x002B 9508 SUBB A,num_pwm(0x08) ;1ckmC:0x002D 4003 JC C:0032 ;2ckmC:0x002F D3 SETB C ;1ckmC:0x0030 8001 SJMP C:0033 ;2ckmC:0x0032 C3 CLR C ;1ckmC:0x0033 9280 MOV c1(0x80.0),C ;2ckm

T= 1+1+1+2+1+2+1+2 = 11ckm --> tổng chu kỳ máy của 32 cổng T2 = T*32 = 11*32 = 352ckm

Chu kỳ máyCode C:Code:

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

Code ASM:

Page 17: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

Code: 80: if(++num_pwm==100){ C:0x01C8 0508 INC num_pwm(0x08) ;1ckmC:0x01CA E508 MOV A,num_pwm(0x08) ;1ckmC:0x01CC B46403 CJNE A,#0x64,C:01D2 ;2ckm 81: num_pwm=0; C:0x01CF 750800 MOV num_pwm(0x08),#0x00 ;2ckm 82: } 83: ++delay_in_t1; C:0x01D2 052A INC 0x2A ;1ckmC:0x01D4 E52A MOV A,0x2A ;1ckmC:0x01D6 7002 JNZ C:01DA ;2ckmC:0x01D8 0529 INC delay_in_t1(0x29) ;1ckmC:0x01DA D0D0 POP PSW(0xD0) ;2ckmC:0x01DC D0E0 POP ACC(0xE0) ;2ckmC:0x01DE 32 RETI ;2ckm

T3 = 1+1+2+2+1+1+2+1+2+2+2 = 17ckmVậy tổng số chu kỳ máy tiêu tốn khi vào ngắt timer1 là: T(timer1) = T1 + T2 +T3 = 8 + 352 + 17 = 377ckmNhưng ta đã thiết lập ngắt timer1 là cứ 333 chu kỳ máy thì ngắt 1 lần. Do 333<377 --> không thể đảm bảo 100 mức sáng khác nhau cho LED. Ngoài ra để đảm bảo số mức sáng cho LED thì ta phải đảm bảo rằng tổng chu kỳ máy thực hiện trên ngắt timer1 và tổng chu kỳ máy các lệnh thực hiện trong hàm main() kể cả hàm con phải nhỏ hơn hoặc bằng tổng số chu kỳ máy để xảy ra ngắt timer1.Ví dụ: Số chu kỳ máy thực hiện PWM 32 cổng trong ngắt timer1 là 377ckm, giả sử số chu kỳ máy tốn cho các lệnh thực hiện chuyển đổi trong hàm main() là 100ckm thì số chu kỳ máy để xảy ra ngắt timer1 phải đảm bảo T >= (377+100) hay T >= 477ckm.- Để đảm bảo chắc chắn đạt các yêu cầu như trên mình chọn số mức sáng cho LED lần này là 50 mức sáng khác nhau. --> số chu kỳ máy để xảy ra ngắt timer là: T= 24000000/12/60/50 ~= 666ckm. Vậy ta có code mới để PWM cho 32 LED như sauCode C:Code:/*Thach anh su dung f=24Mhz*/#include "regx52.h"

typedef unsigned char uchar;typedef unsigned int uint;

sbit c1=P0^0;sbit c2=P0^1;sbit c3=P0^2;sbit c4=P0^3;sbit c5=P0^4;sbit c6=P0^5;sbit c7=P0^6;sbit c8=P0^7;sbit c9=P2^7;sbit c10=P2^6;sbit c11=P2^5;sbit c12=P2^4;sbit c13=P2^3;sbit c14=P2^2;sbit c15=P2^1;sbit c16=P2^0;sbit c17=P3^7;sbit c18=P3^6;sbit c19=P3^5;sbit c20=P3^4;sbit c21=P3^3;sbit c22=P3^2;

Page 18: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

sbit c23=P3^1;sbit c24=P3^0;sbit c25=P1^7;sbit c26=P1^6;sbit c27=P1^5;sbit c28=P1^4;sbit c29=P1^3;sbit c30=P1^2;sbit c31=P1^1;sbit c32=P1^0;

uchar num_pwm;uchar pwm_c[32];uint delay_in_t1;void isr_timer1() interrupt 3 using 2{

TH1=0xFD; /* -24000000/12/60/50 ~= -666 ->0xFD66(50 nghia la 50 muc sang)*/

TL1=0x66; /* chu ky ngat timer1 T=(666/2)us --> T*3 = 999 us ~= 1ms*/

c1=(pwm_c[0]>num_pwm)?1:0;c2=(pwm_c[1]>num_pwm)?1:0;c3=(pwm_c[2]>num_pwm)?1:0;c4=(pwm_c[3]>num_pwm)?1:0;c5=(pwm_c[4]>num_pwm)?1:0; c6=(pwm_c[5]>num_pwm)?1:0;c7=(pwm_c[6]>num_pwm)?1:0;c8=(pwm_c[7]>num_pwm)?1:0;c9=(pwm_c[8]>num_pwm)?1:0;c10=(pwm_c[9]>num_pwm)?1:0;c11=(pwm_c[10]>num_pwm)?1:0;c12=(pwm_c[11]>num_pwm)?1:0;c13=(pwm_c[12]>num_pwm)?1:0;c14=(pwm_c[13]>num_pwm)?1:0;c15=(pwm_c[14]>num_pwm)?1:0;c16=(pwm_c[15]>num_pwm)?1:0;c17=(pwm_c[16]>num_pwm)?1:0;c18=(pwm_c[17]>num_pwm)?1:0;c19=(pwm_c[18]>num_pwm)?1:0;c20=(pwm_c[19]>num_pwm)?1:0;c21=(pwm_c[20]>num_pwm)?1:0;c22=(pwm_c[21]>num_pwm)?1:0;c23=(pwm_c[22]>num_pwm)?1:0;c24=(pwm_c[23]>num_pwm)?1:0;c25=(pwm_c[24]>num_pwm)?1:0;c26=(pwm_c[25]>num_pwm)?1:0;c27=(pwm_c[26]>num_pwm)?1:0;c28=(pwm_c[27]>num_pwm)?1:0;c29=(pwm_c[28]>num_pwm)?1:0;c30=(pwm_c[29]>num_pwm)?1:0;c31=(pwm_c[30]>num_pwm)?1:0;c32=(pwm_c[31]>num_pwm)?1:0;

if(++num_pwm==100){num_pwm=0;

}++delay_in_t1;

}void delay_ms(uint time){

delay_in_t1 = 0;while(delay_in_t1 <= time*3);

}

Page 19: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

void main(){TMOD=0x10; /*timer 1 16bit*/TR1=1;TH1=0xFD;TL1=0x66;IE=0x88; /*Ket thuc khoi dong timer1*/

P0 = 0;P1 = 0;P2 = 0;P3 = 0;delay_ms(3000);while(1){}

}

Vậy là xong phần 4a rồi, các bạn có thắc mắc gì thì hỏi nha.Hôm khác mình sẽ tiếp tục các phần còn lại. Giờ thì chúc các bạn ngủ ngon nha!

mình có đoạn code sao băng 8 kênh viết bằng Keil C các bạn xem có gì trao đổi nhé#include<regx52.h>

sbit w1=P1^0;sbit w2=P1^1;sbit w3=P1^2;sbit w4=P1^3;sbit w5=P1^4;sbit w6=P1^5;sbit w7=P1^6;sbit w8=P1^7;// khai báo mảng cố định . mạng này là tài nguyên để tạo sao băngunsigned char code a[8][24]={{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}

};

void delayus(){ // ham tao thoi gian tre co uSunsigned char a,n;for(n=0;n<10;n++){a=0;}}void saobang8() // ham tao sao bang{ int n,k,h;

Page 20: Lý Thuyết Về Code LED Sao Băng Bằng ASM Và KeilC Cho 8051

for(k=0;k<17;k++) // dich chuyen 1 lan thi sao bang dich 1 lan{for(n=1;n<15;n++) // lap lai 15 lan de hien thi{for(h=0;h<8;h++) { P1=0;w1=a[h][k];w2=a[h][k+1];w3=a[h][k+2];w4=a[h][k+3];w5=a[h][k+4];w6=a[h][k+5];w7=a[h][k+6];w8=a[h][k+7]; delayus();}}}}main(){for( ; ; ){saobang8(); // gọi chương trình tạo sao băng ra dùng }}