Bài 1 : Hướng dẫn cài đặt Keil C và Flash Magic. 4
1.1 Cài đặt Keil C. 4
1.2 Cài đặt Flash Magic . 9
1.3 Cấu hình cho Flash Magic . 14
Bài 2 : Truy xuất Port I/O. 20
2.1 Tạo project trên Keil C . 20
2.2 Viết chương trình đơn giản. 30
2.2.1 Kết nối phần cứng. 30
2.2.2 Viết chương trình. 31
2.2.3 Nạp chương trình . 32
Bài 3 : Điều khiển đơn giản Led 7 đoạn. 34
3.1 Kết nối phần cứng:. 34
3.2 Viết chương trình. 35
3.2.1 Hàm init_main(). 35
3.2.2 Hàm main() . 35
3.3 Một số lỗi quan trọng. 37
Bài 4 : Ngắt Timer. 38
4.1 Khai báo ngắt timer. 38
4.2 Viết chương trình. 39
4.2.1 Hàm init_timer1() . 39
4.2.2 Hàm start_timer1(). 39
4.2.3 Hàm timer1_isr(). 39
4.2.4 Hàm delay_ms(unsigned int duration). 40
4.2.5 Hàm stop_timer1(). 40
Bài 5 : Dùng ngắt timer viết ứng dụng LED RIVER . 41
5.1 Kết nối phần cứng. 41
5.2 Viết chương trình. 41
Bài 6 : Chống rung cho phím. 43
6.1 Nguyên lý chống rung. 43
6.2 Kết nối phần cứng. 44
6.3 Viết chương trình. 45
6.3.1 Hàm initKey() . 45
6.3.2 Hàm getKey(). 45
Bài 7 : Quét led điều khiển Led 7 đoạn . 47
7.1 Nguyên lý quét led 7 đoạn . 47
7.2 Kết nối phần cứng. 48
7.3 Viết chương trình. 48
7.3.1 Hàm init_led7(). 48
7.3.2 Hàm clear_led7() . 49
7.3.3 Hàm set_position(unsigned int pos). 49
7.3.4 Hàm get_position() . 49
7.3.5 Hàm put_Number(unsigned int num) . 50
7.3.6 Hàm put_string(char strNum[]) . 50
7.3.7 Hàm scan_led7. 50
Bài 8 : Điều khiển Ma trận led . 52
8.1 Nguyên lý điều khiển ma trận led. 52
8.2 Kết nối phần cứng. 52
8.3 Viết chương trình. 52
8.3.1 Hàm init_led_matrix() . 53
8.3.2 Hàm scan_led_matrix(). 53
8.3.3 Hàm update_display_led_matrix(). 53
Bài 9 : Chạy chữ trên Ma trận led . 55
9.1 Nguyên lý chạy chữ trên ma trận led . 55
9.2 Kết nối phần cứng. 56
9.3 Viết chương trình. 56
9.3.1 Hàm set_message(char strMsg[]) . 56
9.3.2 Hàm main() . 57
Bài 10 : Ngắt ngoài. 58
10.1 Nguyên lý điều khiển ngắt ngoài . 58
10.2 Kết nối phần cứng. 58
10.3 Viết chương trình. 58
10.3.1 Hàm init_ext_int0(). 58
10.3.2 Hàm init_ext_int1(). 58
10.3.3 Hàm ext0_isr() . 59
10.3.4 Hàm ext1_isr() . 59
Bài 11 : Điều khiển encoder . 60
11.1 Nguyên lý điều khiển encoder . 60
11.2 Kết nối phần cứng. 61
11.3 Viết chương trình. 61
Bài 12 : Giao tiếp UART. 63
12.1 Nguyên lý giao tiếp UART. 63
12.2 Giao tiếp UART với máy tính. 64
12.3 Viết chương trình. 65
12.3.1 Thanh ghi điều khiển truyền nhận nối tiếp . 65
12.3.2 Dùng Timer1 tạo Baud rate. 67
12.3.3 Chương trình truyền nhận UART trên 8051. 67
Bài 13 : Giao tiếp PS2 với bàn phím . 70
13.1 Nguyên lý giao tiếp PS2 . 70
13.2 Kết nối phần cứng. 71
13.3 Viết chương trình. 72
Bài 14 : PWM điều khiển motor. 73
14.1 Khái niệm PWM . 73
14.2 Lập trình PWM trên 89V51 . 74
Bài 15 : Giao tiếp LCD character . 75
15.1 Chức năng các chân của LCD. 75
15.2 Kết nối màn hình LCD. 76
15.3 Bộ nhớ CGROM . 76
15.4 Các lệnh cơ bản của LCD . 77
15.5 Kết nối LCD với vi điều khiển. 78
84 trang |
Chia sẻ: trungkhoi17 | Lượt xem: 416 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Giáo trình Hướng dẫn sử dụng Kit 89, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
1 Khai báo ngắt timer
Trình tự là cho phép ngắt toàn cục, cho phép ngắt timer và thiết lập chế độ hoạt
động cho timer:
IE = 0x80; //enable global interrupt
IE &= ~(0x02);// enable timer 0
IE |= 0x02;
TMOD &= ~(0x01);// setup mode for timer 0
TMOD |= 0x01;
TH0 = (-10000/256); //10 ms
TL0 = (-10000%256);
TR0 = 1;//start timer0
Hàm phục vụ ngắt sẽ được khai báo như sau:
void timer0_isr() interrupt 1
{
TR0 = 0;//stop timer 0
// reinitialize
TH0 = (-10000/256);
TL0 = (-10000%256);
//Add your code here
TR0 = 1;//start timer 0
}
BKIT HARDWARE CLUB – www.bkit4u.com 38
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
4.2 Viết chương trình
Vì mục đích là tạo ra module Timer có khả năng dùng lại, nên chương trình sẽ
gồm group TIMER có 2 file timer.h và timer.c. File timer.h đặc tả các hàm của module
này còn file timer.c sẽ hiện thực các hàm đó. Các hàm trong timer.h bao gồm:
void init_timer0(); //init timer 0, interrupt after 10ms
void init_timer1(); //init timer 1, interrupt after 1ms
void start_timer0();
void start_timer1();
void stop_timer0();
void stop_timer1();
void delay_ms(unsigned int duration);//using timer1 to delay in ms
4.2.1 Hàm init_timer1()
Hàm này làm nhiệm vụ khởi tạo ngắt timer1 sau mỗi 1ms, khi khởi tạo ngắt
timer1 xong, ta phải hiện thực hàm phục vụ ngắt quãng cho nó, nếu không chương trình
sẽ chạy sai.
void init_timer1()
{
IE &= ~(0x08);// enable timer 1
IE |= 0x08;
TMOD &= ~(0x10);// setup mode for timer 1
TMOD |= 0x10;
TH1 = (-1000/256); //1 ms
TL1 = (-1000%256);
TR1 = 1; //start timer1
}
4.2.2 Hàm start_timer1()
void start_timer1()
{
TR1 = 1;
}
4.2.3 Hàm timer1_isr()
Đây là hàm phục vụ ngắt quãng của timer1, được khai báo và định nghĩa như sau:
BKIT HARDWARE CLUB – www.bkit4u.com 39
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
void timer1_isr() interrupt 3
{
TR1 = 0;//stop timer 1
// reinitialize
TH1 = (-1000/256);
TL1 = (-1000%256);
//Add your code here
if(counter1!= 0)
{
counter1--;
}
//End your code
TR1 = 1;//start timer 1
}
4.2.4 Hàm delay_ms(unsigned int duration)
Hàm này chỉ cần cài đặt giá trị cho biến counter1, giá trị này sẽ tự động giảm nhờ
đoạn code trong hàm phục vụ ngắt quãng của timer1. Vòng lặp while để chờ cho đến khi
counter1 bằng 0.
void delay_ms(unsigned int duration)
{
counter1 = duration;
while(counter1 !=0)
{
}
}
4.2.5 Hàm stop_timer1()
void stop_timer1()
{
TR1 = 0;
}
Phần hiện thực các bạn xem trong project Bai 4 để biết thêm chi tiết.
BKIT HARDWARE CLUB – www.bkit4u.com 40
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 4 : Ngắt Timer
Mục đích:
Tìm hiểu ngắt timer của 89V51
Xây dựng module dành cho timer của 89V51 có thể dùng lại được.
Yêu cầu:
Viết chương trình hiển thị từ 0, sau 1 giây tăng lên 1, khi tăng đến 9 thì chuyển
sang hiển thị ở led kế tiếp, hiển thị bắt đầu lại từ 0.
4.1 Khai báo ngắt timer
Trình tự là cho phép ngắt toàn cục, cho phép ngắt timer và thiết lập chế độ hoạt
động cho timer:
IE = 0x80; //enable global interrupt
IE &= ~(0x02);// enable timer 0
IE |= 0x02;
TMOD &= ~(0x01);// setup mode for timer 0
TMOD |= 0x01;
TH0 = (-10000/256); //10 ms
TL0 = (-10000%256);
TR0 = 1;//start timer0
Hàm phục vụ ngắt sẽ được khai báo như sau:
void timer0_isr() interrupt 1
{
TR0 = 0;//stop timer 0
// reinitialize
TH0 = (-10000/256);
TL0 = (-10000%256);
//Add your code here
TR0 = 1;//start timer 0
}
BKIT HARDWARE CLUB – www.bkit4u.com 38
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
4.2 Viết chương trình
Vì mục đích là tạo ra module Timer có khả năng dùng lại, nên chương trình sẽ
gồm group TIMER có 2 file timer.h và timer.c. File timer.h đặc tả các hàm của module
này còn file timer.c sẽ hiện thực các hàm đó. Các hàm trong timer.h bao gồm:
void init_timer0(); //init timer 0, interrupt after 10ms
void init_timer1(); //init timer 1, interrupt after 1ms
void start_timer0();
void start_timer1();
void stop_timer0();
void stop_timer1();
void delay_ms(unsigned int duration);//using timer1 to delay in ms
4.2.1 Hàm init_timer1()
Hàm này làm nhiệm vụ khởi tạo ngắt timer1 sau mỗi 1ms, khi khởi tạo ngắt
timer1 xong, ta phải hiện thực hàm phục vụ ngắt quãng cho nó, nếu không chương trình
sẽ chạy sai.
void init_timer1()
{
IE &= ~(0x08);// enable timer 1
IE |= 0x08;
TMOD &= ~(0x10);// setup mode for timer 1
TMOD |= 0x10;
TH1 = (-1000/256); //1 ms
TL1 = (-1000%256);
TR1 = 1; //start timer1
}
4.2.2 Hàm start_timer1()
void start_timer1()
{
TR1 = 1;
}
4.2.3 Hàm timer1_isr()
Đây là hàm phục vụ ngắt quãng của timer1, được khai báo và định nghĩa như sau:
BKIT HARDWARE CLUB – www.bkit4u.com 39
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
void timer1_isr() interrupt 3
{
TR1 = 0;//stop timer 1
// reinitialize
TH1 = (-1000/256);
TL1 = (-1000%256);
//Add your code here
if(counter1!= 0)
{
counter1--;
}
//End your code
TR1 = 1;//start timer 1
}
4.2.4 Hàm delay_ms(unsigned int duration)
Hàm này chỉ cần cài đặt giá trị cho biến counter1, giá trị này sẽ tự động giảm nhờ
đoạn code trong hàm phục vụ ngắt quãng của timer1. Vòng lặp while để chờ cho đến khi
counter1 bằng 0.
void delay_ms(unsigned int duration)
{
counter1 = duration;
while(counter1 !=0)
{
}
}
4.2.5 Hàm stop_timer1()
void stop_timer1()
{
TR1 = 0;
}
Phần hiện thực các bạn xem trong project Bai 4 để biết thêm chi tiết.
BKIT HARDWARE CLUB – www.bkit4u.com 40
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 5 : Dùng ngắt timer viết ứng dụng LED RIVER
Mục đích:
Nắm vững ngắt timer.
Sử dụng ngắt timer để viết ứng dụng LED RIVER.
Yêu cầu:
Viết chương trình led river đơn giản, 1 led chạy từ P0.0 sang P1.1, đến P0.7
chuyển sang P3.7, P3.6. Khi tới P3.0 thì trở về P0.0. Thời gian chuyển qua trạng thái mới
là 1s
5.1 Kết nối phần cứng
Gạt switch 1 lên ON để kích hoạt Port 1 (các led đơn).
Gạt switch 2 lên ON để kích hoạt Port 3 (các led đơn và nút nhấn).
5.2 Viết chương trình
Đối với led chạy như yêu cầu, ta thấy có 16 trạng thái của P1 và P3 như sau
P0.0 sáng : P1 = 0x01, P3 = 0x00
P0.1 sáng : P1 = 0x02, P3 = 0x00
P0.7 sáng : P1 = 0x80, P3 = 0x00
P3.7 sáng : P1 = 0x00, P3 = 0x80
P3.6 sáng : P1 = 0x00, P3 = 0x40
P3.0 sáng : P1 = 0x00, P3 = 0x01
Như vậy, ta sẽ khai báo 2 mảng, mỗi mảng 16 phần tử cho P1 và P3, rồi cho 1
biến index tự động tăng lên sau 1s, khi index bằng 16 thì gán lại index bằng 0, để quá
trình được lặp lại.
Đối với led river có nhiều trạng thái hơn, bạn chỉ cần khai báo ra tất cả các trạng
thái vào 1 mảng, rồi lần lượt định kì xuất nó ra.
Việc delay giữa các trạng thái, ta sẽ sử dụng lại hàm delay_ms(unsigned int
duration) đã làm ở bài thí nghiệm trước.
Đối với yêu cầu của bài led river này, chúng tôi chỉ sử dụng 1 mảng 16 phần tử
dùng cho cả 2 Port. Index của P1 sẽ tăng dần từ 0 đến 15, Index của P3 sẽ giảm dần từ 15
đến 0.
//led_river : mảng 16 phần tử
//INDEX_MAX = 16
//duration = 1000ms
while(1)
{
P3 = led_river[INDEX_MAX - index-1];
P1 = led_river[index++];
if(index == INDEX_MAX)
index = 0;
BKIT HARDWARE CLUB – www.bkit4u.com 41
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
delay_ms(duration);
}
Chi tiết code của bài thí nghiệm này, bạn xem thêm trong thư mục Bài 5 trong CD
đi kèm.
BKIT HARDWARE CLUB – www.bkit4u.com 42
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 6 : Chống rung cho phím
Mục đích:
Nắm vững kĩ thuật chống rung cho phím.
Yêu cầu:
Viết chương trình xuất số đếm ra led 7 đoạn với giá trị khởi tạo là 0. Khi nhấn nút
1 (được nối với P3.0) thì giá trị này tăng lên 1, tăng đến 9 thì quay trở lại 0.
6.1 Nguyên lý chống rung
Hình trên minh hoạ mức điện áp của 1 phím nhấn tích cực mức 0, ở trạng thái
bình thường, điện áp vi điều khiển nhận vào là 5V còn khi nhấn là 0V. Tuy nhiên, do độ
rung cơ học của phím, tại thời điểm vừa nhấn xuống, điện áp sẽ không ổn định trong 1
khoảng thời gian, trước khi ổn định ở mức 0V. Hiệu tượng này gọi là rung phím.
Mặc dù khoảng thời gian điện áp ở mức 0 trong giai đoạn rung phím là nhỏ nhưng
cũng đủ để vi điều khiển nhận được. Vì vậy khi ta xét nếu điện áp là 0 thì gọi hàm func()
thì hàm này sẽ được gọi rất nhiều lần, là điều mà ta không mong muốn. Để khác phục
hiện tượng rung phím, có 2 hướng giải quyết : dùng phần cứng và phần mềm.
Về giải pháp phần cứng : thay vì mắc đơn giản như kit thí nghiệm này (xem lại sơ
đồ ở Bài 2), ta có thể dùng thêm tụ điện để hạn chế việc thay đổi điện áp đột ngột, sơ đồ
nguyên lý như sau:
BKIT HARDWARE CLUB – www.bkit4u.com 43
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Ở sơ đồ trên, khi không nhấn là mức 1, khi nhấn là mức 0. Phím nhấn trên tích
cực mức 0. Mạch ở trên còn gọi là mạch RC.
Nếu nút nhấn có 2 cực, ta có thể chọn giải pháp dùng mạch RS flip flop, đây là
mạch phần cứng chống rung tốt nhất, sơ đồ nguyên lý như sau:
Về giải pháp phần mềm : Ta sẽ định kì đọc tín hiệu từ nút nhấn, cho đến khi nào
chúng trùng nhau n lần thì mới xử lý. Hình dưới đây minh hoạ trong trường hợp 2 lần là 0
thì mới xác nhận là phím được nhấn và mới xử lý tác vụ mà ta mong muốn.
Khoảng thời gian giữa 2 lần đọc là khoảng 10ms, ta sẽ hiện thực hàm đọc này và
gọi nó trong timer. Giải thuật đơn giản để xử lý chống rung có thể hiện thực như sau:
previous_key = current_key;
current_key = Port_key;
If(previous_key == current_key)
effective_key = current_key;
Trong đó :
previous_key : biến lưu giá trị phím trước đó.
current_key : biến lưu giá trị phím hiện tại.
Port_key : Port của vi điều khiển kết nối với phím.
effective_key : giá trị phím hợp lệ (giá trị trong giai đoạn ổn định)
Để tăng tính chính xác, ta có thể dùng nhiều biến previous_key để lưu lại các giá
trị và so sánh nhiều lần. Đoạn code trên chỉ so sánh trùng nhau 2 lần.
6.2 Kết nối phần cứng
Sơ đồ nguyên lý của phím trong kit này như sau :
BKIT HARDWARE CLUB – www.bkit4u.com 44
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Phím nhấn này tính cực mức 0, được kết nối khá đơn giản, nên ta sẽ dùng phần
mềm để chống rung. Ta sẽ dùng 3 biến để so sánh 2 lần trùng nhau, 2 lần liên tiếp cách
nhau 10ms.
Trong trường hợp nhấn đè 1 phím, ta sẽ dùng biến TimeOutForKeyPress để xác
định thời gian tích cực tiếp theo. Biến này sẽ quan trọng trong trường hợp ta viết 1 ứng
dụng chẳng hạn như soạn thảo văn bản. Nếu không có biến này để quản lý, nếu ta đè thì
trong 1s có tới 100 lần tích cực. Trong ví dụ của Bài 6, thời gian TimeOutForKeyPress =
100 tương ứng với 1s (100*10 = 1000ms = 1s).
6.3 Viết chương trình
Module này có 2 hàm như sau :
void initKey() : Khởi động các thông số ban đầu
void getKey() : Hàm này được gọi trong timer0, dùng để quét phím.
void SubKeyProcess() : Hàm này hiện thực tác vụ bạn cần thực hiện khi
nhấn phím.
Ở kit thí nghiệm này, các nút nhấn được nối với port 3, nên ta có định nghĩa sau ở
đầu file key.c :
#define KEY_PORT P3
6.3.1 Hàm initKey()
void initKey()
{
KeyReg0 = 0x00;
KeyReg1 = 0x00;
KeyReg2 = 0x00;
KeyReg3 = 0x00;
}
Trong đó KeyReg0, KeyReg1, KeyReg2 dùng để lưu 3 lần liên tiếp. Khi 3 biến
này bằng nhau, biến KeyReg3 mới được cập nhật. Biến KeyReg3 là giá trị hợp lệ của
phím nhấn.
6.3.2 Hàm getKey()
Hàm này được chia làm 2 phần, phần đầu là để chống rung phím dùng 2 lần so
sánh trùng nhau. Phần thứ 2 xử lý khi 1 phím được đè, phải sau 1 khoảng thời gian
TimeOutForKeyPress mới được tính cực.
BKIT HARDWARE CLUB – www.bkit4u.com 45
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
void getKey()
{
KeyReg2 = KeyReg1;
KeyReg1 = KeyReg0;
KeyReg0 = KEY_PORT;// Cho phep nut nhan nao duoc tich cuc.
if ((KeyReg1 == KeyReg0) && (KeyReg1 == KeyReg2))
{
TimeOutForKeyPress --;
if (TimeOutForKeyPress == 0)
{
KeyReg3 = 0x00;
}
if (KeyReg2 != KeyReg3)
{
KeyReg3 = KeyReg2;
if (FlagFirstTimeKeyPress == 1)// Day la lan dau phim
duoc nhan.
{
TimeOutForKeyPress = 100;
SubKeyProcess();
FlagFirstTimeKeyPress = 0;
}
else
{
if (KeyReg2 == 0x00)
FlagFirstTimeKeyPress = 1;
else
{
TimeOutForKeyPress = 100;
SubKeyProcess();
}
}
}
}
}
BKIT HARDWARE CLUB – www.bkit4u.com 46
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 7 : Quét led điều khiển Led 7 đoạn
Mục đích:
Nắm vững kĩ thuật quét Led.
Ứng dụng quét Led vào việc điều khiển 8 led 7 đoạn.
Yêu cầu:
Viết module điều khiển Led 7 đoạn có thể dùng lại cho các ứng dụng khác.
Đưa ra hàm xuất giá trị số nguyên ra led 7 đoạn tại bất kì vị trí nào.
7.1 Nguyên lý quét led 7 đoạn
Để hiện thị 1 led 7 đoạn, ta cần 8 chân để gửi dữ liệu cho nó. Như vậy, với 8 led 7
đoạn, theo kết nối bình thường,ta cần tổng cộng 56 đường tín hiệu để thắp sáng 8 led
cùng lúc.
Để khắc phục việc tốn tài nguyên này, người ta dùng kĩ thuật quét led. Tại 1 thời
điểm, chỉ có 1 led sáng. Tại thời điểm t1 chỉ có led 1 sáng, tại thời điểm t2 = t1 + t0 chỉ có
led 2 sáng, khi t0 rất nhỏ, mắt người không thể nhận biết được độ nhấp nháy giữa 2 lần
luân chuyển, và sẽ có cảm giác là 2 đèn sáng cùng lúc.
Để quét led, sơ đồ nguyên lý sẽ được mắc như trên. Port 2 gọi là port dữ liệu, dữ
liệu này sẽ được nối với tất cả các led. Port 1 dùng để chọn led, cực E của transitor được
nối với chân mass của led 7 đoạn.
Port 1 bằng 1 tại bit nào thì transitor tương ứng sẽ dẫn. Giả sử Port 1 = 0x80,
transitor T4 dẫn, dòng data sẽ đi qua led 7 đoạn nối với T4 xuống đất, và led này sẽ sáng,
các led còn lại thì không.
BKIT HARDWARE CLUB – www.bkit4u.com 47
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Khi số lượng led càng nhiều, ta phải tính toán để tìm ra số t0 hợp lý.Thông
thường, khoảng thời gian tối đa giữa led đầu tiên và led cuối cùng trong khi quét led phải
nhỏ hơn 1/50 giây (50Hz).
Để quét 8 led 7 đoạn trong bài thí nghiệm này, ta sẽ dùng 1 buffer có 8 phần tử,
rồi định kì xuất từng phần tử ra led 7 đoạn tương ứng. Việc thay đổi dữ liệu trong buffer
này sẽ do các hàm được cung cấp cho người dùng sử dụng cập nhật.
Ta sẽ dùng ngắt timer để định kì gọi hàm scan_led7(), hàm này có chức năng xuất
1 giá trị trong buffer ra led tưng ứng, sau mỗi lần gọi, index sẽ tăng lên 1, đến khi bằng 8
sẽ quay trở về 0.
7.2 Kết nối phần cứng
Gạt switch 4 lên ON để kích hoạt led 7 đoạn.
7.3 Viết chương trình
Để module này có thể dùng lại cho các ứng dụng khác, ta sẽ hiện thực các hàm
dưới đây :
void init_led7() : Khởi tạo các thông số ban đầu
void clear_led7() : Xoá dữ liệu đang hiển thị trên led 7 đoạn
void set_position(unsigned int pos) : Thiết lập vị trí xuất dữ liệu, vị trí 0 là led
ngoài cùng bên trái.
unsigned int get_position() : Truy xuất vị trí đang xuất dữ liệu.
void put_number(unsigned int num) : Xuất giá trị num (là số unsigned int) ra led
7 đoạn từ vị trí hiện tại.
void put_string(char strNum[]) : Xuất giá trị strNum (là giá trị char) ra led 7
đoạn từ vị trí hiện tại.
void scan_led7() : Xuất dữ liệu từ buffer ra led 7 đoạn.
Các hàm interface này được khai báo trong file led7.h. File led7.c sẽ hiện thực các
hàm này.
7.3.1 Hàm init_led7()
void init_led7()
{
P0 = 0x00; //data port
P2 = 0x00; //selected port
position = 0; //output index
led7_index = 0; //scan index
is_valid_data = 1; //flag to check if data is valid
}
P0 : Port để xuất dữ liệu cho led 7 đoạn, khởi tạo 0x00 tức là không có led nào
trong led 7 đoạn sáng.
P2 : Port để chọn led 7 đoạn nào trong 8 led sẽ nhận data từ Port 0, tức cực mức 1,
P2 = 0x01 (0000 0001)tức là led 7 đoạn ngoài cùng bên trái sẽ sáng, P2 = 0x20 (0000
0010) tức là led thứ 2 tính từ trái sẽ sáng.
BKIT HARDWARE CLUB – www.bkit4u.com 48
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
position : vị trí bắt đầu hiển thị giá trị, chẳng hạn người dùng mún hiển thị số 123
từ vị trí thứ 2 tính từ trái thì phải thiết lập position là 1 (position = 0 là led ngoài cùng bên
trái). Biến position này người dùng phải dùng hàm set_positon thì mới thay đổi được (chi
tiết xem bên dưới).
led7_index : vị trí sẽ xuất data, biến này được dùng trong hàm scan_led, người
dùng không can thiệp vào biến này được.
is_valid_data : biến dùng trong hàm scan_led, biến này để tạm dừng việc quét led
trong khi đang thay đổi buffer hiển thị, người dùng cũng không can thiệp được vào biến
này.
7.3.2 Hàm clear_led7()
void clear_led7()
{
led7_buffer[0] = 0x00;
led7_buffer[1] = 0x00;
led7_buffer[2] = 0x00;
led7_buffer[3] = 0x00;
led7_buffer[4] = 0x00;
led7_buffer[5] = 0x00;
led7_buffer[6] = 0x00;
led7_buffer[7] = 0x00;
}
Hàm này chỉ đơn giản là xoá buffer 8 phần tử, lúc đó toàn bộ các led sẽ tắt. Buffer
này dùng để chứa dữ liệu của 8 led 7 đoạn, dữ liệu của từng led sẽ được định kì đưa ra
led tương ứng.
7.3.3 Hàm set_position(unsigned int pos)
void set_position(unsigned int pos) //set position to begin output
{
position = pos;
}
Hàm này sẽ lấy thông số từ người dùng để cập nhật cho biến position.
7.3.4 Hàm get_position()
unsigned int get_position() //get current position
{
return position;
}
Hàm này trả về vị trí đang xuất dữ liệu.
BKIT HARDWARE CLUB – www.bkit4u.com 49
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
7.3.5 Hàm put_Number(unsigned int num)
void put_number(unsigned int num)
{
int i;
is_valid_data = 0; //disable scan led
for(i=position; i<8; i++)
{
if(i>=0)
{
led7_buffer[i] = led7_data[num % 10];
}
num = num / 10;
if(num == 0)
break;
}
position = i;
is_valid_data = 1; //enable scan led
}
Hàm này dùng để cắt từng chữ số của số num để bỏ vào buffer tương ứng. Vòng
lập for dùng để hiện thực tác vụ này, chữ số hàng đơn vị của num sẽ được bỏ vào buffer
vị trí position.
7.3.6 Hàm put_string(char strNum[])
Hàm này cũng gần giống với hàm put_Number, chỉ khác là đối số là kiểu char[].
Việc thao tác trên dữ liệu kiểu char[] cần phải include thêm thư viện string.h (ở đầu file
led7.c). Việc hiện thực hàm này phức tạp hơn, các bạn có thể tham khảo thêm trong code
mẫu ở thư mục Bài 7 được đính kèm trong CD. Mục đích của hàm này cũng là lấy từng
phần tử trong mảng strNum bỏ vào buffer cho đúng vị trí.
7.3.7 Hàm scan_led7
void scan_led7()
{
if(is_valid_data)
{
P2 = 0x00; //remove noise
P0 = led7_buffer[led7_index]; //data for the next led
P2 = 1 << led7_index; //enable data
led7_index++; //update new index
if(led7_index == 8)
BKIT HARDWARE CLUB – www.bkit4u.com 50
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
led7_index = 0;
}
}
Đây là hàm dùng để quét led, và sẽ được ngắt timer gọi. Mục đích của hàm này là
xuất dữ liệu ra led ở vị trí tiếp theo.
Port 2 dùng để chọn led, và để tránh hiện tượng bóng mờ khi quét led, bạn phải
gán nó về 0x00 trước.
led7_index là biến chỉ vị trí của led hiện tại chuẩn bị nhận dữ liệu.
Hàm scan_led7() được gọi trong ngắt timer0.
Với các hàm đã thiết kế ở trên, để xuất số 1234 tại vị trí thứ 2 tính từ trái sang ta
viết trong hàm main() như sau:
void main()
{
init_main();
init_timer0();
init_led7();
set_position(1);
put_Number(1234);
while(1){};
}
Hàm main() trong ví dụ của Bài 7 xuất các số 123 và 4321 tại các vị trí liên tiếp
nhau, thời gian giữa 2 lần xuất là 1s (1000ms), ta sẽ có cảm giác là dòng số này chạy qua
các led 7 đoạn.
BKIT HARDWARE CLUB – www.bkit4u.com 51
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 8 : Điều khiển Ma trận led
Mục đích:
Ứng dụng quét Led để điều khiển Ma trận led 2 màu.
Yêu cầu:
Viết chương trình định kì 1s xuất các chữ cái in hoa từ A-Z ra ma trận led.
8.1 Nguyên lý điều khiển ma trận led
Ma trận led 2 màu được cấu tạo gồm những điểm sáng, mỗi điểm sáng có 2 bóng
đèn đỏ và xanh lá bên trong. Khi cả 2 đèn này cùng sáng cho ta cảm giác màu vàng.
Nguyên lý điều khiển ma trận led cũng tương tự như led 7 đoạn, ta dùng Port1 để
chọn cột, Port0 và Port2 dùng để gửi dữ liệu đỏ và xanh cho hàng đó. Các kĩ thuật điều
khiển ở ma trận led hoàn toàn tương tự như led 7 đoạn.
8.2 Kết nối phần cứng
Gạt switch 3 lên ON để kích hoạt ma trận led.
8.3 Viết chương trình
Chương trình được tổ chức gồm 3 module : MAIN để chứa file main.c, TIMER
để gọi hàm quét ma trận led và LED MATRIX để chứa các hàm liên quan đến ma trận
led.
Các hàm về ma trận led như sau :
void init_led_matrix(); //Khởi tạo ma trận led
void scan_led_matrix(); //Quét ma trận led, hàm này được gọi trong
timer.
void update_display_led_matrix(); //Cập nhật buffer hiển thị.
BKIT HARDWARE CLUB – www.bkit4u.com 52
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
8.3.1 Hàm init_led_matrix()
void init_led_matrix()
{
P0 = 0x00; //red data
P2 = 0x00; //green data
index_led_matrix = 0; //index use to scan led
alphabet_index = 208;// in the initial, led matrix doesn't display
anything
}
Trong đó :
P0 : Port để xuất dữ liệu đỏ cho ma trận led.
P2 : Port để xuất dữ liệu xanh cho ma trận led.
index_led_matrix : biến dùng để quét dữ liệu hiển thị trên ma trận led, ta dùng
biến này để lấy dữ liệu trong 2 buffer (mỗi buffer 8 phần tử) để hiển thị và chọn cột.
alphabet_index : biến dùng để lấy dữ liệu cần hiển thị, bỏ vào 2 buffer đỏ và
xanh. Mảng dữ liệu này thường khá lớn và được khai báo trong file table_led_matrix.h.
8.3.2 Hàm scan_led_matrix()
Hàm này được gọi trong timer, có nhiệm vụ xuất buffer hiển thị ra ma trận led,
định kì xuất từng phần tử của buffer ra cột tương ứng.
void scan_led_matrix()
{
P1 = 0; //remove noise
P0 = red_buff[index_led_matrix];
P2 = green_buff[index_led_matrix];
P1 = 1 << index_led_matrix;
index_led_matrix = (index_led_matrix + 1) % 8; //next column
}
8.3.3 Hàm update_display_led_matrix()
Hàm này dùng để thay đổi nội dung hiển thị, các ứng dụng của người dùng chủ
yếu là thay đổi code ở hàm này.
void update_display_led_matrix()
{
char i;
for(i = 0; i < 8; i++)
{
red_buff[i]=alphabet_upcase_led_matrix[i+alphabet_index ];
green_buff[i]=alphabet_upcase_led_matrix[i+alphabet_index];
}
}
Hàm main chỉ việc thay đổi alphabet_index (dữ liệu của chữ cái kế tiếp) rồi gọi
hàm update_display_led_matrix(), định kì 1s sau đó thay đổi chữ kế tiếp:
BKIT HARDWARE CLUB – www.bkit4u.com 53
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
while(1)
{
alphabet_index = (alphabet_index + 8) % 216;
update_display_led_matrix();
delay_ms(1000);
}
BKIT HARDWARE CLUB – www.bkit4u.com 54
Simpo PDF Merge and Split Unregistered Version -
Hướng dẫn sử dụng Kit 89
Bài 9 : Chạy chữ trên Ma trận led
Mục đích:
Nắm vững nguyên lý điều khiển ma trận led. Xây dựng ứng dụng trên ma trận led.
Yêu cầu:
Viết chương trình chữ chạy trên ma trận led, cung cấp interface giúp người dùng
có thể thay đổi dễ dàng.
9.1 Nguyên lý chạy chữ trên ma trận led
Để chạy 1 dòng chữ qua ma trận led, bạn sẽ có 1 buffer lưu toàn bộ dòng chữ đó.
Buffer này thường là 1 mảng các byte. Chương trình sẽ định kì cắt 1 phần trong buffer
này đổ dữ liệu vào buffer nhỏ hơn dùng để quét led. Chương trình quét led sẽ hiển thị ra
led ma trận.
Tại thời điểm T1, dữ liệu đổ vào buffer quét led là chữ “H”. Tại thời điểm T2, 1
phần chữ H và E được đổ vào buffer này, và tại thời điểm T3 là chữ “E”. Nếu khoảng
cách giữa các thời điểm nhỏ lại, bạn sẽ thấy hiệu ứng dòng chữu chạy qua ma trận led.
Để sinh ra được buffer chứa toàn bộ dòng chữ, bạn phải xử lý dữ liệu đã lưu sẵn
(tạm gọi là font chữ), ghép nối chúng sao cho đẹp mắt. Chẳng hạn muốn hiện chữ
“HELLO WORLD”,bạn phải làm như sau:
¾ Lấy font của chữ “H”, bỏ những cột trống ở đầu và cuối, phần còn lại bỏ vào
buffer.
¾ Lấy font của chữ “E”, bỏ những cột trống ở đầu và cuối,thêm 1 byte 0x00 vào
buffer (tạo 1 nét rời giữa H và E) rồi bỏ dữ liệu của E vào.
¾ Tương tự, hết chữ “O”, bạn thêm khoảng 3 byte 0x00.
Tuỳ vào tài nguyên của hệ thống, bạn định nghĩa ra độ dài tối đa của buffer này.
Trong quá trình sinh ra buffer, chương trình sẽ cập nhật độ dài hiện tại và sẽ dừng việc
ghép chữ nếu độ dài là quá mức cho phép.
BKIT HARDWARE CLUB –
Các file đính kèm theo tài liệu này:
- giao_trinh_huong_dan_su_dung_kit_89.pdf