Professional Documents
Culture Documents
đơn
LỜI MỞ ĐẦU
Trong lập trình vi xử lý ngôn ngữ thường dùng là ngôn ngữ lập trình ASM và ngôn ngữ C .
Ngôn ngữ lập trình ASM hay lập trình hợp ngữ là ngôn ngữ lập trình trực tiếp cho vi điều khiển
( lập trình trực tiếp ) còn ngôn ngữ C hay còn gọi là lập trình hướng đối tượng nó gần với ngôn
ngữ con người hơn . Điều này có nghĩa là với ASM người lập trình ra lệnh trực tiếp thông qua
ngôn ngữ câu lệnh có tính ràng buộc còn ngôn ngữ C sử dụng các cấu trúc điều kiện và vòng
lặp theo ý muốn .Nói về ngôn ngữ C thì ưu điểm của ngôn ngữ C là nó dễ hiểu nhưng cấu trúc
lại dài và phức tạp so với ngôn ngữ ASM . Phần tiểu luận của em gồm 2 vấn đề và chia làm 2
phần chính
Trong đó bit có thể dung như các biến trong C nhưng các biến còn lại thì liên quan đến các
thanh ghi hoặc địa chỉ cổng cua 8051( có nghĩa là khi khai bao biến kiểu bit thì không cần định
địa chỉ trong RAM các biến khác phải địn rõ địa chỉ trong RAM vì nó là các dạng biến đặc biệt
gọi là special function registers (SFR)
VD: bit kiemtra;
sfr P1_0=0x90
Các SFR được khai báo trong thư viện
at89x51.h và at89x52.h
và chức năng chính của nó là lặp lại lệnh chừng nào điều kiện còn mang giá trị đúng, như
trong vòng lặp while. Nhưng thêm vào đó, for cung cấp chỗ dành cho lệnh khởi tạo và lệnh
tăng. Vì vậy vòng lặp này được thiết kế đặc biệt lặp lại một hành động với một số lần xác định.
Cách thức hoạt động của nó như sau:
(*) Khởi tạo được thực hiện. Nói chung nó đặt một giá khí ban đầu cho biến điều khiển. Lệnh
này được thực hiện chỉ một lần.
(**) Điều kiện được kiểm tra, nếu nó là đúng vòng lặp tiếp tục còn nếu không vòng lặp kết
thúc và lệnh được bỏ qua.
(***) Lệnh được thực hiện. Nó có thể là một lệnh đơn hoặc là một khối lệnh được bao trong
một cặp ngoặc nhọn.
(****) Cuối cùng, thực hiện để tăng biến điều khiển và vòng lặp quay trở lại bước kiềm tra
điều kiện.
Phần khởi tạo và lệnh tăng không bắt buộc phải có. Chúng có thể được bỏ qua nhưng vẫn phải
có dấu chấm phẩy ngăn cách giữa các phần. Vì vậy, chúng ta có thể viết for (;n<10;) hoặc for
(;n<10;n++).
Bằng cách sử dụng dấu phẩy, chúng ta có thể dùng nhiều lệnh trong bất kì trường nào trong
vòng for, như là trong phần khởi tạo. Ví dụ chúng ta có thể khởi tạo một lúc nhiều biến trong
vòng lặp:
for ( n=0, i=100 ; n!=i ; n++, i-- )
{
// các câu lệnh;
}
VD: Tạo hàm delayms dung vòng lăp for
void delay (unsigned int ms) // ham tao thoi gian tre ms
{
unsigned int i ; // hoặc ta có thể khai báo int i j;
unsigned char j ;
for (i=0;i<ms;i++)
{
for (j=0;j<125;j++)
{} // khong lam gi ca
}
}
+ Các lệnh rẽ nhánh và lệnh nhảy
Lệnh break.
Sử dụng break chúng ta có thể thoát khỏi vòng lặp ngay cả khi điều kiện để nó kết thúc chưa
được thoả mãn. Lệnh này có thể được dùng để kết thúc một vòng lặp không xác định hay buộc
nó phải kết thúc giữa chừng thay vì kết thúc một cách bình thường. Ví dụ, chúng ta sẽ dừng
việc đếm ngược trước khi nó kết thúc.
// break loop example
#include
int main ()
{
int n;
for (n=10; n>0; n--) {
cout << n << ", ";
if (n==3)
{
cout << "dung dem”;
break; //dem den 3 thi dung;
}}
return 0;
}
admin
Xem hồ sơ
Hàm exit.
Mục đích của exit là kết thúc chương trình và trả về một mã xác định. Dạng thức của nó như
sau
void exit (int exit code);
exit code được dùng bởi một số hệ điều hành hoặc có thể được dùng bởi các chương trình gọi.
Theo quy ước, mã trả về 0 có nghĩa là chương trình kết thúc bình thường còn các giá trị khác 0
có nghĩa là có lỗi. các lệnh trên chủ yếu chỉ dùng lệnh break để thoát khỏi vòng lặp . Các lệnh
khác thường rất ít dược sử dụng
Cú pháp của lệnh switch hơi đặc biệt một chút. Mục đích của nó là kiểm tra một vài giá trị hằng
cho một biểu thức, tương tự với những gì chúng ta làm ở đầu bài này khi liên kết một vài lệnh if
và else if với nhau. Dạng thức của nó như sau:
switch (expression)
{
case constant1:
block of instructions 1
break;
case constant2:
block of instructions 2
break;
.
.
.
default:
default block of instructions
}
Nó hoạt động theo cách sau: switch tính biểu thức và kiểm tra xem nó có bằng constant1 hay
không, nếu đúng thì nó thực hiện block of instructions 1 cho đến khi tìm thấy từ khoá break,
sau đó nhảy đến phần cuối của cấu trúc lựa chọn switch. Còn nếu không, switch sẽ kiểm tra
xem biểu thức có bằng constant2 hay không. Nếu đúng nó sẽ thực hiện block of instructions 2
cho đến khi tìm thấy từ khoá break. Cuối cùng, nếu giá trị biểu thức không bằng bất kỳ hằng
nào được chỉ định ở trên (bạn có thể chỉ định bao nhiêu câu lệnh case tuỳ thích), chương trình
sẽ thực hiện các lệnh trong phần default: Nếu nó tồn tại vì phần này không bắt buộc phải có.
e. Cấu trúc cơ bản của của một chương trình C cho 8051 :
Viết theo cách thứ hai thì trình biên dịch sẽ tìm luôn trong thư mục /INC luôn.
Để có thể sử dụng đúng các file .h cho các vi điều khiển mở thư mục /inc trong thư mục này có
các thư mục con như tên của hãng sản xuất. Ví dụ như của Atmel thì bạn tìm trong thư mục
/Atmel thì sẽ thấy được file reg51.h
Phần thứ 2 : Định nghĩa các macro (thiết lập vĩ mô). Cách khai báo sử dụng từ khóa #define. Ví
dụ:để khai báo mặc led 1 được nối với chân 0 của port 1 ta viết như sau
#define led1 P1_0
+ Các hàm ngắt như ngắt (timer0, timer1, ngắt nối tiếp, ngắt ngoài )nêu ở phần khai báo biến .
Copy lại như sau :
Cấu trúc:
void Tên hàm(void) interrupt nguồn ngắt using băng thanh ghi
{
}
Hàm ngắt không được phép trả lại giá tri hay truyền tham biến vào hàm
Tên hàm : tùy chọn
Interrupt : từ khóa chỉ hàm ngắt
Nguồn ngắt : từ 0 đến 5 theo bảng vecter ngắt
TM1=0, TM0 =0 chế độ 0 : Chế độ định thời 13 bit , số đếm 0000H – 1FFFH
TM1=0, TM0 =1 chế độ 1 : Chế độ định thời 16 bit , số đếm 0000H - FFFFH
TM1=1, TM0 =0 chế độ 2 : Chế độ định thời 8 bit tự động nạp số đếm 00H - FFH
TM1=1, TM0 =1 chế độ 3 : Chế độ định thời chia sẻ số đếm 00H – FFH
VD : Gây trễ 1 ms = 1000us ta dùng chế độ định thời 16 bit sử dụng timer 0
Tdelay=1000 sử dụng calculator của hệ điều hành Windows XP trong
Start\Program\Accessories\Calculator ta được
TH0=FC
TL0=18
Vậy chương trình sẽ như sau :
void delay(unsigned ms)
{
while (ms--)
{
TMOD=0x01; //dùng timer 0 chế độ 1 ( 16bit )
TH0=0xfc;
TL0=0x18; //hai câu lệnh nạp giá tri đếm
TR0=1; // cho phép timer 0 hoạt động
while (TF0); //chờ TF0=1(cờ tràn =1 )
TF0=0; //xóa cờ tràn
TR0=0; // ngừng Timer
}
}
+ Chương trình chính:
void main(void)
{
//cấu trúc lệnh điều khiển
}
đối tượng của chương trình là vi điều khiển nên hàm main không có giá trị trả về và không có
tham số đưa vào.
Cài đặt:
+ Copy file l51.dll trong thư mục vào trong phần đã được cài đặt trong folder C:\Keil\C51\BIN
ghi đè lên phần l51.dll file có sẵn . Sau đó chạy licgen-v32 và chọn như hình vẽ copy dãy ký tự
trong khung LIC0
Mở chương trình Keil C chạy HELLO.C ta thấy chương trình báo lỗi
Vào trong File chọn mục Lisence Management nhập dãy ký tự trong LIC0 vào add
Đóng cửa sổ Lisence Management lại chạy lại chượng trình HELLO.C mà không thấy báo lỗi nữa
là được.
Tạo chương trình trên notepad ở đây em ví dụ chương trình chạy một led sáng tắt :
Tiêp đó vào File chọn tiếp Save đánh tên Fle name là “ 1ledsangtat.c” Save lại :
Hoàn thành:
Copy từ Notepad vào vùng soạn thảo. Vào Project chọn như hình vẽ
Tạo file Hex để mô phỏng: Nhân tổ hợp phím Ctrl + F5. Chương trình sẽ báo địa chỉ
admin
Xem hồ sơ
Ví dụ 4 :
Chương trình điều khiển 8led sáng đuổi lần lượt led 0 sáng các led còn lại tắt , led 1 sáng các
led còn lại tắt,….led 7 sáng các led còn lại tắt :
//*******************************************
#include <regx51.h>
#define led P1
void delay (unsigned int ms) // ham tao tre ms
{
unsigned int i ;
unsigned char j ; //khai bien 1 byte
for (i=0;i<ms;i++)
{
for (j=0;j<125;j++)
// 1 vong lap for mat 8 us
// Nhu vay ta co: ms*(125*8)=1000*1000 ~= 1ms
// *********************************************
{} // khong lam gi ca
}
}
main ()
{
while (1)
{
P1=0X01;delay(1000);
P1=0X02;delay(1000);
P1=0X04;delay(1000);
P1=0X08;delay(1000);
P1=0X10;delay(1000);
P1=0X20;delay(1000);
P1=0X40;delay(1000);
P1=0X80;delay(1000);
}
}
Ví dụ 5 :
Chạy tổng hợp : ( 8 led chạy các kiểu):
// Chuong trinh 8 led ket noi port1 chay cac kieu
#include <regx51.h> // khai bao chuong trinh thu vien 8051
#define led P1 // Led ket noi port 1
void delay (unsigned int ms) // Ham tao thoi gian tre ms
{
unsigned int i ;
unsigned char j ; //Khai bao bien 1 byte
for (i=0;i<ms;i++)
{
for (j=0;j<125;j++)
// 1vong lap for mat 8us
//Nhu vay ta co: ms*(125*8)=1000*1000 ~= 1ms
// *********************************************
{} // Khong lam gi ca
}
}
void sangdon(void)
{
P1=0x00;//0x00=00000000
delay(1000);// ham tre 1000ms=1s
P1=0xff;//0xff=11111111
delay(1000);
}
void sangdan(void)
{
void sangduoi(void)
{
P1=0X01;delay(1000);
P1=0X02;delay(1000);
P1=0X04;delay(1000);
P1=0X08;delay(1000);
P1=0X10;delay(1000);
P1=0X20;delay(1000);
P1=0X40;delay(1000);
P1=0X80;delay(1000);
}
main ()
{
while (1)
{
sangdon();delay(1000);
sangdan();delay(1000);
sangduoi();delay(1000);
}
}
TỔNG KẾT
Nói tóm lại việc lập trình trên mỗi loại ngôn ngữ đều có ưu nhược điểm riêng điều quan trọng là
nắm vững mục đích của việc lập trình . Việc học lập trình trước tiên là làm trên ngôn ngữ ASM
phát triển trên ngôn ngữ này để hiểu rõ sau đó lập trình trên C . Chương trình chạy dãy led trên
ngôn ngữ C là ví dụ đơn giản và là kiến thức cơ bản đầu tiên khi bước vào tìm hiểu C ứng dụng
của lập trình hướng đối tượng vào lập trình VXL . Từ chương trình mô phỏng có thể thấy ngôn
ngữ trong lập trình hoàn toàn có thể hiểu được từ nghĩa của các từ ngữ và câu lệnh . Đó là lý do
mà ngôn ngữ C ngày càng được ứng dụng rộng rãi không chỉ trong lập trình VXL mà trong nhiều
lĩnh vực khác .