Professional Documents
Culture Documents
Chương trình viết bằng C đọc dễ hiểu hơn chương trình viết bằng hợp ngữ.Tuy nhiên khi biên dịch
sang mã máy(code) chương trình C dài 42 byte trong khi chương trình hợp ngữ dài 22 byte chỉ bằng
½ chương trình C!Ngoài ra chương trình C phải có một số khai báo có liên quan ở hai dòng đầu tiên.
9.3: Biên dịch C 8051:
Trình biên dịch (compiler)C 8051 sang mã máy phức tạp hơn nhiều so với trình biên dịch hợp ngữ
(assembler) vì hợp ngữ rất sát mã máy.
Có nhiều trình biên dịch C 8051,như trên đã giới thiệu ta sử dụng trình biên dịch Keil µvision rất
thuận tiện vì có bao gồm trình biên dịch chéo C51(cross compiler) chuyển sang hợp ngữ 8051.Ta có thể
quan sát chương trình hợp ngữ tương ứng trong cửa sổ Disassembly phía trên cửa sổ chứa chương trình
C khi chạy Debug chương trình C.
9.6: Dãy(Arrays):
Thông thường một nhóm các biến dùng để lưu trữ data cùng một kiểu nên được gom chung thành một
dãy sẽ dễ truy xuất hơn.Chẳng hạn để xuất ra một thông điệp hay bảng tra mã 7 đoạn Anode chung như
trong ví dụ 4.7.Trong C 8051,ta sử dụng khai báo dãy array sẽ thuận tiện hơn khi truy xuất.
Ta xem hai ví dụ 9.5 và 9.6.
Ví dụ 9.5: Viết một đoạn chương trình xuất thông điệp “This is a message” ra port1.
Giải:
Chương trình hợp ngữ
;Thông điệp có tổng cộng 17 ký tự kể cả khoảng trống
TAB_CHR: DB “This is a message”
9.9: Hàm(Function):
Trong lập trình hợp ngữ,ta có các lệnh gọi chương trình con(subroutine).Trong C51 cũng có các lệnh
gọi chương trình con tương tự như vậy nhưng ta gọi là hàm(Function).
Cú pháp khai báo hàm đầy đủ trong C51 như sau:
return_type function_name ( arguments) [memory] [reentrant] [interrupt] [using]
return_type là kiểu data của giá trị trả về(output)
function_name là tên hàm,ta sẽ gọi tên hàm khi muốnthực hiện hàm
arguments là danh sách số lượng và kiểu data của các biến vào(inputs)
memory xác định mô thức bộ nhớ(small,compact,large) của các biến vào(arguments)
reentrant xác định hàm có đệ quy(recursive) hay không
interrupt xác định hàm có phải thật sự là trình phục vụ ngắt(ISR)
using xác định bank thanh ghi sử dụng cho hàm
Các lưu ý quan trọng:
Mỗi hàm chỉ trả về một giá trị (một output)
Kết thúc hàm bằng phát biểu return (output) để trình biên dịch trả về giá trị output.Nếu không
có giá trị trả về không cần phát biểu này.
Khi gọi thực hiện hàm chỉ cần viết tên hàm(function_name) và gán các giá trị cho các input
Bảng vd9.6.4:
Td(µs) T2(µs) TDE(µs) Texe=TDE-T2(µs) E=TDE-Td(µs)
50 423 472 49 -1
100 423 520 97 -3
200 423 616 193 -7
500 536 1029 493 -7
1000 540 1535 997 -3
2000 540 2533 1993 -7
5000 544 5538 4994 -6
10000 534 10534 10000 0
50000 538 50547 50009 +9
Với khai báo MAX là biến unsigned int hàm DELAY(MAX) có thể tạo thời gian trễ tối đa với
MAX=65535 là khoảng 0.786 s
Dựa vào các kết quả trên, ta phát triển lên hàm tạo thời gian trễ hàng giây.Ví dụ như viết một hàm tạo
thời gian trễ 1s.
#include <reg51.h>
unsigned int MAXi,MAXj;
unsigned long Td ; // khai báo Td long để tăng MAXi tối đa =65535
void DELAY_S ( unsigned int t1,t2)
{ unsigned int i ,j ;
for (j=1;j<=t2;j++)
{
for (i=1; i <= t1 ; i++);
}
}
void main()
{
Td = 50000; // vòng for i tạo trễ 50ms
MAXi=(Td-13)/11 ;
MAXj=20 ; // vòng for j tạo trễ =20x50ms=1s
DELAY_S(MAXi,MAXj) ;
}
Hàm DELAY_S có 2 vòng for,khi chạy thực tế trên C51 thời gian thực thi 1 vòng lặp for cho i là
11µs như biểu thức (9.2).Do đó ta tính MAXi theo (9.2).
Tính MAXj cho vòng for j như sau:
Gọi Tj là thời gian trễ cần tạo,Ti là thời gian thực thi xong vòng for i với MAXi theo (9.2).
Tj=MAXj*Ti
Suy ra: MAXj=Tj/Ti (9.4)
Tóm lại, từ ví dụ trên ta có thể viết đoạn chương trình hoặc hàm tạo trễ từ 24µs đến hàng trăm s dựa
vào 3 biểu thức (9.1),(9.2),(9.3) và 3 mẫu chương trình trên!