Giáo trình linh kiện điện tử và vi điều khiển 8051 tại CDA Training.
Trang 1Mục Lục
Mục Lục 1
I Thiết kế phần cứng với 8051: 2
1 Làm quen với vi điều khiển 8051: 2
2 Các mạch cơ bản: 3
3 Nạp chương trình: 5
4 Mạch Vi điều khiển cơ bản: 9
5 Kết nối cơ bản với Led đơn: 9
6 Kết nối cơ bản với phím bấm: 10
7 Bộ nhớ RAM của 8051: 10
II Phần mềm Keil-C: 13
1 Khởi động: 13
2 Tạo Project: 13
3 Tạo chương trình: 15
4 Biên dịch chương trình: 17
III Tập lệnh cơ bản với C và thuật toán: 19
1 Các khối thuật toán cơ bản: 19
2 Các kiểu dữ liệu: 19
3 Lệnh phép toán: 21
4 Lệnh if: 23
5 Lệnh if… else…: 23
6 Lệnh switch… case…: 24
7 Lệnh for: 25
8 Lệnh while: 26
9 Lệnh do…while…: 27
10 Chương trình con và chương trình ngắt: 27
11 Cấu trúc một chương trình C: 30
IV Lập trình cơ bản với Led đơn: 33
1 Lập trình bật Led: 33
2 Lập trình Led sáng xen kẽ: 34
3 Lập trình Led sáng chớp tắt: 35
4 Lập trình Led sáng chớp tắt xen kẽ: 35
5 Lập trình Led sáng lần lượt: 36
6 Lập trình Led sáng dần: 37
7 Lập trình Led tắt dần: 38
Lập trình Led sáng dồn: 39
Trang 2I Thiết kế phần cứng với 8051:
1 Làm quen với vi điều khiển 8051:
a Chức năng:
Đối với vi điều khiển AT89S52:
- Có 8Kbyte bộ nhớ FLASH ROM bên trong để lưu chương trình Nhờ vậy Vi điều khiển có khả năng nạp xoá chương trình bằng điện đến 10000 lần
- 256 Byte RAM nội
- 4 Port xuất/nhập 8 bit
- Có 3 bộ định thời 16-bit (89S51 có 2 bộ định thời)
- Có khả năng giao tiếp truyền dữ liệu nối tiếp
- Chân 39-32: PORT 0 Các chân này được dùng để nhận tín hiệu từ bên ngoài vào
để xử lí, hoặc dùng để xuất tín hiệu ra bên ngoài, chẳng hạn xuất tín hiệu để điều khiển led đơn sáng tắt Với Port 0, khi sử dụng cần treo thêm trở treo để có được mức 1
- Chân 1-8: PORT 1 Tương tự Port 0 Ngoài ra: chân P1.5-P1.7 còn là cổng nạp nối tiếp của vi điều khiển
- Chân 21-28: PORT 2 Tương tự Port 0
Trang 3- Chân 10-17: PORT 3 Tương tự Port 0 Ngoài ra: Mỗi chân còn có các chức năng sau:
P3.0 RxD Ngõ vào nhận dữ liệu nối tiếp
P3.1 TxD Ngõ xuất dữ liệu nối tiếp
P3.2 INT0 Ngõ vào ngắt cứng thứ 0
P3.3 INT1 Ngõ vào ngắt cứng thứ 1
P3.4 T0 Ngõ vào của Timer/Counter thứ 0
P3.5 T1 Ngõ vào của Timer/Counter thứ 1
P3.6 WR Ngõ điều khiển ghi dữ liệu lên bộ nhớ ngoài
P3.7 RD Ngõ điều khiển đọc dữ liệu từ bộ nhớ bên ngoài
P1.0 T2 Ngõ vào của Timer/Counter thứ 2
P1.1 T2X Ngõ Nạp lại/thu nhận của Timer/Counter thứ 2
Bảng 1: Chức năng các chân ở Port 3
- Chân 9: RESET Là ngõ vào Reset dùng để thiết lập trạng thái ban đầu cho vi điều khiển Hệ thống sẽ được thiết lập lại các giá trị ban đầu nếu ngõ này ở mức
1 tối thiểu 2 chu kì máy
- Chân 18, 19: X1, X2 Là 2 chân dao động được sử dụng để nhận nguồn xung clock từ bên ngoài để hoạt động, thường được ghép nối với thạch anh và các tụ
để tạo nguồn xung clock ổn định
- Chân 29, 30: ALE, PSEN Là 2 chân liên quan đến bộ nhớ ngoài
- Chân 31: EA Chân EA dùng để xác định chương trình thực hiện được lấy từ ROM nội hay ROM ngoại
o Khi EA nối với logic 1(+5V) thì Vi điều khiển thực hiện chương trình lấy
Trang 4Y 1
12MHz C2
33p
C3 33p
X2 X1
Hình 1.2: Mạch dao động sử dụng thạch anh
c Mạch reset:
- Việc kết nối chân RESET đảm bảo hệ thống bắt đầu làm việc khi Vi điều khiển được cấp điện, hoặc đang hoạt động mà hệ thống bị lỗi cần tác động cho Vi điều khiển hoạt động trở lại, hoặc do người sử dụng muốn quay về trạng thái hoạt động ban đầu
- Vì vậy chân RESET được kết nối như sau:
C5 10UF
R5 10K
SW1 RESET
5V
RESET
Hình 1.3: Mạch Reset
d Các điều kiện cơ bản để Vi điều khiển hoạt động:
Để vi điều khiển hoạt động được cần có các điều kiện cơ bản sau:
- Cấp nguồn 5V ổn định cho vi điều khiển
- Lắp mạch dao động
- Lắp mạch Reset
- Chân EA (31) được nối với Vcc
Trang 53 Nạp chương trình:
a Mạch nạp Willar:
Hình 1.4: Mạch nạp Willar thực tế
Trang 6- Nhược điểm:
o Do chỉ có thể nạp song song nên muốn nạp Vi điều khiển cần phải nhổ Vđk ra khỏi mạch trung tâm, cắm vào mạch nạp để nạp chương trình, rồi lại cắm vào mạch trung tâm Như vậy sẽ rất mất thời gian và có thể gây
gãy chân Vđk
o Không nạp được các Vđk có kiểu chân SMD
o Giá thành cao
b Mạch nạp Burn-E:
Hình 1.6: Mạch nạp Burn-E thực tế và ý tưởng đặt tên
Hình 1.7: Giao diện phần mềm nạp Burn-E
Trang 7- Ưu điểm:
o Mạch nạp theo chế độ nối tiếp nên mạch nhỏ gọn
o Giá thành “rẻ” (Bằng mạch nạp Willar, tuy nhiên có thể nạp được cho Vđk AVR, PIC nên thuận tiện sau này mà không cần mạch nạp khác)
o Có thể nạp trực tiếp Vđk trên mạch mà không cần tháo Vđk ra Do đó có thể nạp được Vđk dạng SMD dễ dàng
Trang 8Hình 1.9: Mạch nạp qua cổng Com 9 chân
Hình 1.10: Giao diện phần mềm nạp
Trang 94 Mạch Vi điều khiển cơ bản:
Q1 LM7805
VI 1
C2 100uF/16V C3
104
C4 104
+
D2 LED
VCC 40 EA 31 X1 19 X2 18
RST 9
P0.0/AD0 39 P0.1/AD1 38 P0.2/AD2 37 P0.3/AD3 36 P0.4/AD4 35 P0.5/AD5 34 P0.6/AD6 33 P0.7/AD7 32
P1.0(T2) 1 P1.1(T2 EX) 2
P1.2 3 P1.3 4 P1.4 5 P1.5(MOSI) 6
P1.6(MISO) 7
P1.7(SCK) 8
P2.0/A8 21P2.1/A9 22P2.2/A10 23P2.3/A11 24P2.4/A12 25P2.5/A13 26P2.6/A14 27P2.7/A15 28P3.0/RXD 10P3.1/TXD 11P3.2/INT0 12P3.3/INT1 13P3.4/T0 14P3.5/T1 15P3.6/WR 16P3.7/RD 17
P0.2
P0.7 P0.4
RXD TXD
P3.6
P3.3 P3.5
P2.0
P2.6
P2.3 P2.5
P1.4
P1.0 P1.2 P1.1 P1.3
R2 10k
C7 10uF
5V
SW1 RESET RESET
5V 5V 5V 5V 5V 5V 5V 5V
J3
NAP BURN-E
1 3 5
J4
NAP PHILLIP
1 3
RESET
SCK MOSI MISO
TXD RXD
J6
P1
1 3 5
P2.2 P2.0
P2.6
P2.3 P2.5
P1.3
P1.0 P1.2 P1.1
R11
4k7
1 3 4 6 8
5V
RXD TXD P3.3
P3.6 P3.5
SW2 PHIM BAM
P3.2
SW3 PHIM BAM P3.3
SW4 PHIM BAM P3.4
SW5 PHIM BAM P3.5
SW6 PHIM BAM P3.6
SW7 PHIM BAM P3.7
Hình 1.11: Mạch vi điều khiển cơ bản
Trang 10b Kết nối Led sáng mức 1:
D18 LED
R21 330
R22 4k7
- RAM nội trong Vi điều khiển được tổ chức như sau:
o Các vị trí trên RAM được định địa chỉ theo từng Byte bằng các số thập lục phân (số Hex)
o Các bank thanh ghi có địa chỉ 00H đến 1FH
o 210 vị trí được định địa chỉ bit
o Các vị trí RAM bình thường
o Các thanh ghi có chức năng đặc biệt có địa chỉ từ 80H đến FFH
- Các byte RAM 8 bit của vi điều khiển được gọi là "ô nhớ", nếu các ô nhớ có chức năng đặc biệt thường được gọi là "thanh ghi", nếu là bit thì được gọi là "bit nhớ"
Trang 112FH 7F 7E 7D 7C 7B 7A 79 78
Vùng RAM có thể định địa chỉ Bit
Trang 12b Vùng Ram đặc biệt:
Địa
chỉ
Byte
Có thể
định địa
chỉ Bit
Không thể định địa chỉ Bit
F8H
F0H B
E8H
E0H ACC
D8H
D0H PSW
C8H (T2CON) (RCAP2L) (RCAP2H) (TL2) (TH2)
C0H
B8H IP SADEN
B0H P3
A8H IE SADDR
A0H P2
98H SCON SBUF BRL BDRCON
90H P1
Trang 13II Phần mềm Keil-C:
1 Khởi động:
Hình 2.1: Biểu tượng chương trình
2 Tạo Project:
Ta thao tác như sau
Hình 2.2: Tạo New Project
Trang 14Hình 2.3: Lưu Project
Hình 2.4: Chọn hãng sản xuất vi điều khiển
Trang 15Hình 2.5: Chọn loại vi điều khiển
Hình 2.6: Chọn No
3 Tạo chương trình:
Trang 16Lưu File với đuôi *.asm để viết bằng ngôn ngữ Asembly hoặc *.C nếu viết bằng ngôn ngữ C
Hình 2.8: Lưu chương trình vừa tạo (C hoặc Asm)
Add File vừa tạo vào Project:
Hình 2.9: Add chương trình vừa tạo vào project
Trang 17Hình 2.10: Chọn file
Hình 2.11: File sau khi add và Project
4 Biên dịch chương trình:
Trang 18Hình 2.13: Chọn Create HEX file
Hình 2.14: Rebuild sau khi viết chương trình xong để tạo file Hex
Trang 19III Tập lệnh cơ bản với C và thuật toán:
1 Các khối thuật toán cơ bản:
- Sử dụng phần mềm Microsoft Visio để vẽ sơ đồ thuật toán Phần mềm hỗ trợ vẽ thuật toán dễ sử dụng và dễ dàng xuất sang file Autocad và copy sang Word
- Để vẽ thuật toán trên MS Visio 2003, ta chọn Category là Flowchart, Tempale là Basic Flowchart (Metric)
- Các khối thuật toán cơ bản:
o Khối chuyển tiếp:
2 Các kiểu dữ liệu:
a Kiểu dữ liệu trong C:
Kiểu Số Byte Khoảng giá trị
Trang 20- Cũng có thể gán luôn giá trị ban đầu cho biến:
Kiểu_dữ_liệu Tên_biến = Giá_trị;
- Ví dụ:
unsigned char a;
- Có thể khai báo nhiều biến cùng lúc:
Kiểu_dữ_liệu Tên_biến_1, Tên_biến_2, Tên_Biến_3, ;
- Ví dụ:
unsigned int x,y,z;
b Kiểu dữ liệu trong Keil-C:
- sbit, sfr, sfr16: dùng để định nghĩa các cho các thanh ghi chức năng hoặc các cổng trên vi điều khiển dùng để truy nhập các đoạn dữ liệu 1 bit, 8 bit, 16 bit
- Mảng có thể là mảng một chiều hoặc mảng nhiều chiều
Trang 21Với khai báo trên ta sẽ có: mảng a là mảng một chiều 5 phần tử Mảng b
d Con trỏ:
- Khi ta khai báo một biến, biến đó sẽ được cấp phát một khoảng nhớ bao gồm một số byte nhất định dùng để lưu trữ giá trị Địa chỉ đầu tiên của khoảng nhớ đó chính là địa chỉ của biến được khai báo
- Con trỏ là một biến dùng để chứa địa chỉ mà không chứa giá trị, hay giá trị của con trỏ chính là địa chỉ khoảng nhớ mà nó trỏ tới
unsigned char a,*pa;
&a : //Lấy địa chỉ của biến a
pa = &a : //pa lấy địa chỉ của biến a
*pa : //Lấy giá trị của địa chỉ được lưu trong biến pa
3 Lệnh phép toán:
a Phép gán:
- Phép gán kí hiệu: “=”
- Cú pháp:
Trang 22/ Phép chia lấy phần nguyên X=a/b (a=9, b=2 → X=4)
% Phép chia lấy phần dư X=a%b (a=9, b=2 → X=1)
c Phép toán Logic:
&& And logic X=a&&b;X=1 chỉ khi a và b đúng
|| Or logic X=a||b;X=0 chỉ khi a và b sai
! Not logic X=!a;X đúng khi a sai và ngược lại
- Các phép toán logic thường được sử dụng trong các mệnh đề điều kiện Ví dụ
như mệnh đề điều kiện hàm if hay hàm while
d Phép toán so sánh:
> So sánh lớn hơn a>b 4>5 có giá trị 0
>= So sánh lớn hơn hoặc bằng a>=b 6>=2 có giá trị 1
< So sánh nhỏ hơn a<b 6<=7 có giá trị 1
<= So sánh nhỏ hơn hoặc bằng a<=b8<=5 có giá trị 0
== So sánh bằng nhau a==b6==6 có giá trị 1
!= So sánh khác nhau a!=b9!=9 có giá trị 0
e Phép toán xử lý Bit:
& Phép và (AND) Bit_1 & Bit_2
^ Phép hoặc loại trừ (XOR) Bit_1 ^ Bit_2
<< Dịch trái a<<3; a dịch trái 3 lần
>> Dịch phải a>>4; a dịch phải 4 lần
Trang 23f Phép toán kết hợp:
Phép toán Ví dụ += a+=5 <=> a=a+5 -= a-=5 <=> a=a-5
*= a*=5 <=> a=a*5 /= a/=5 <=> a=a/5
Trang 24b Thuật toán:
Điều kiện
Đoạn chương trình 1
Tiếp theo
Đ
S
Đoạn chương trình 2
- Giải thích: tuỳ vào biến có gia_tri_1 thì thực hiện các câu lệnh tương ứng
rồi sau đó thoát khỏi cấu trúc nhờ câu lệnh break
Biến có gia_tri_2 thì thực hiện câu lệnh tương ứng rồi thoát
………
Biến có gia_tri_n thì thực hiện các câu lệnh tương ứng rồi thoát
Trang 25Bien=GT2? Đ S
Đoạn chương trình 2
Bien=GT3? Đ
S
Đoạn chương trình 3
- Giải thích: trong khi biểu thức n<k còn đúng thì còn xử lý các câu lệnh Sau
mỗi lượt thực hiện các lệnh thì giá trị n lại tăng lên 1 nhờ lệnh n++ n có giá trị khởi đầu là m Do đó: nếu m>k thì biểu thức n<k sẽ sai và các câu lệnh sẽ không được thực hiện
- Biểu thức n<k không nhất thiết phải là “<” mà còn có thể thay bằng các biểu thức so sánh khác tùy vào người lập trình
Trang 26- Giải thích: thực hiện lặp các câu lệnh khi điều kiện đúng nếu điều kiện sai thì thoát khỏi vòng lặp
b Thuật toán:
Điều kiện?
Đoạn chương trình
Tiếp theo Đ
S
Trang 28- Hàm không trả lại giá trị:
o Cấu trúc:
{ //các xử lý ở đây }
o Ví dụ:
{ Data_LED = bang_ma[so];
Nếu kiểu trả về là void thì không cần return, còn trả về là giá trị thì phải return
o Ví dụ:
void init_main (void)
{ //các câu lệnh xử lý }
- Hàm có truyền biến vào:
o Cấu trúc:
Kiểu_giá_trị_trả_về Tên_hàm(các thông số truyền vào hàm)
{
//các xử lý ở đây }
Nếu kiểu trả về là void thì không cần return, còn trả về là giá trị thì phải return
o Ví dụ:
Tương tự ví dụ mục a và b’
Trang 29Trong đó a là số hiệu của ngắt:
c Thuật toán:
Tên chương trình
Đoạn chương trình
Các thiết lập ban đầu
Kết thúc CT
Trang 3011 Cấu trúc một chương trình C:
a Cấu trúc:
- Khai báo chỉ thị tiền xử lý
- Khai báo các biến toàn cục
- Khai báo nguyên mẫu các hàm
void delay(unsigned int n);
bit kiemtra(unsigned int a);
void delay(unsigned int n)
Khai báo biến cục bộ;
Mã chương trình kiểm tra biến a;
}
Khai báo biến toàn cục
Khai báo nguyên mẫu hàm
Xây dựng các hàm và chương trình chính Khai báo chỉ thị tiền xử lý
Trang 31c Nguyên mẫu hàm:
- Khi viết bằng ngôn ngữ C cần chú ý: hàm được gọi phải xây dựng trước vị trí được gọi Do đó để chương trình không bị rối ta cần dùng các khai báo nguyên mẫu hàm để xem như các hàm đều được khai báo ở đầu chương trình Cấu trúc giống như khi khai báo hàm nhưng kết thúc bằng dấu “;” Còn nội dung hàm có
thể xây dựng bất kỳ vị trí nào trong chương trình
d Chỉ thị tiền xử lý:
- Các chỉ thị tiền sử lý không phải là các lệnh của ngôn ngữ C mà là các lệnh giúp cho việc soạn thảo chương trình nguồn C trước khi biên dịch Khi dịch một chương trình C thì không phải chính bản chương trình nguồn mà ta soạn thảo được dịch Trước khi dịch, các lệnh tiền xử lý sẽ chỉnh lý bản gốc, sau đó bản chỉnh lý này sẽ được dịch Có ba cách chỉnh lý được dùng là:
o Phép thay thế #define
o Phép chèn tệp #include
o Phép lựa chọn biên dịch #ifdef
- Các chỉ thị tiền xử lý giúp ta viết chương trình ngắn gọn hơn và tổ chức biên dịch, gỡ rối chương trình linh hoạt, hiệu quả hơn
- Phép thay thế #define
o Chỉ thị #define cho phép tạo các macro thay thế đơn giản
o Cú pháp:
#define Tên_thay_thế Dãy_kí_tự
o Một Tên_thay_thế có thể được định nghĩa lại nhiều lần, nhưng trước khi định nghĩa lại phải giải phóng định nghĩa bằng chỉ thị:
#undef Tên_thay_thế
o Dãy ký tự có thể là 1 đoạn lệnh Khi gọi macro thì trình biên dịch chèn đoạn mã được khai báo vào vị trí gọi macro Do đó macro không có khả năng thay thế chương trình con vì không giảm được dung lượng chương trình mà chỉ giúp chương trình gọn hơn khi lập trình
o Ví dụ:
Trang 32- Chú thích trong chương trình sẽ không ảnh hưởng đến chương trình mà ta soạn thảo vì trình dịch sẽ bỏ qua tất cả lời chú thích khi biên dịch chương trình sang
mã máy
- Lời giải thích được đặt sau dấu “//” nếu chú thích chỉ viết trên một dòng hoặc
trong cặp dấu “/*” và “*/”
Trang 33IV Lập trình cơ bản với Led đơn:
Chuẩn bị:
- Các bài với Led đơn sau đây sử dụng mạch Led sáng ở mức 0 với kết nối như sau
D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED D9 LED D10 LED
P0.1 P0.0 P0.2 P0.3 P0.4 P0.5 P0.6 P0.7
R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 R9 330 R10 330
- #include các thư viện:
o #include “REG51F.H”: Để khai báo các địa chỉ ngõ ra, ngõ vào tương ứng của vi điều khiển 8051
o #include “delay.c”: Để thiết lập 2 hàm delay: delay_us() và delay_ms();
Sự cần thiết có hàm delay: do tốc độ xử lý vi điều khiển rất nhanh, mỗi lệnh ở ngôn ngữ asm xử lý khoảng 1-2µs Như vậy: ở chương trình thứ 3, nếu không sử dụng hàm delay, việc chớp tắt cực kỳ nhanh khiến mắt người thấy gần như liên tục Nên cần delay khoảng 100ms trở lên để có thể nhận biết được
Trang 34b Chương trình:
#include "reg51f.h"
void Bat_Led(void);//Nguyên mẫu hàm của hàm Bật Led
void main(void){
Bat_Led(); //Gọi hàm Bật Led
}
void Sang_Xen_Ke(void){//Hàm sáng xen kẽ
}