You are on page 1of 19

Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.

ORG

CHƯƠNG 1: GIỚI THIỆU VI ĐIỀU KHIỂN


AVR
VÀ CÁC THÀNH PHẦN HỖ TRỢ

I. Giới thiệu
Ở chương này chúng ta sẽ tìm hiểu 1 cách khái quát về cấu trúc của vi
điều khiển AVR.
Vi điều khiển AVR là bộ xử lý RISC (viết tắt của Reduced Instructions
Set Computer - Máy tính với tập lệnh đơn giản hóa) là một phương pháp thiết
kế các bộ vi xử lý (VXL) theo hướng đơn giản hóa tập lệnh, trong đó thời gian
thực thi tất cả các lênh đều như nhau.
AVR có cấu trúc Harvard, cụm từ kiến trúc Harvard được dùng để chỉ
những kiến trúc máy tính mà trong đó phân biệt rõ ràng bộ nhớ dữ liệu và bộ
nhớ chương trình, chúng có những đường truyền (bus) riêng để truy cập vào bộ
nhớ dữ liệu và bộ nhớ chương trình.

Họ vi điều khiển AVR có những đặc điểm sau:


+Sử dụng xung đồng hồ (clock) có tần số lên đến 16MHz tạo ra bởi
mạch RC hoặc thạch anh bên ngoài chip, hoặc dùng xung clock nội lên đến
8MHz sai số 3%.
+Bộ nhớ chương trình Flash ROM có thể lập trình nhiều lần và dung
lượng khá lớn.
+Bộ nhớ truy xuất ngẫu nhiên tĩnh (Static RAM) khá lớn.
+Có bộ nhớ lưu trữ lập trình được EEPROM.
+Nhiều ngõ vào-ra (I/O) với 2 hướng dữ liệu.
+8 bit, 16 bit timer/counter tích hợp PWM (điều biến bề rộng xung,
thường dùng trong điều khiển động cơ)
+Các bộ chuyển đổi tương tự sang số - ADC độ phân giải 10 bit và có
nhiều kênh.
+Giao diện USART (tương thích chuẩn nối tiếp RS 232).
+Giao diện nối tiếp TWO-WIRE-SERIAL (tương thích chuẩn I2C)
+Giao diện nối tiếp SPI(SERIAL PERIPHERAL INTERFACE).
Một số chip AVR thông dụng:
Dòng 90S: AT90S1200, AT90S2313, AT90S2323, AT90S2343…
Dòng tiny: ATtiny10, ATtiny11, ATtiny12, ATtiny2313…

Trần Thừa – 2010 3


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Dòng MEGA: ATmega8/8515/8535, Atmega16, Atmega32, Atmega64,


Atmega128…
Trong đó dòng Mega đang thịnh hành và có các tính năng đầy đủ nhất và cũng
là đối tượng chính của tài liệu này. Chúng tôi sử dụng datasheet của ATmega8
và ATmega16 làm tài liệu tra cứu thông tin chính.

II. Cấu trúc AVR


1. Bộ nhớ chương trình.
Là bộ nhớ flash lập trình được, trong các chip AVR thế hệ trước như dòng
AT90S, bộ nhớ chương trình chỉ gồm 1 phần là Application Flash Section
nhưng trong các chip AVR mới chúng ta có thêm phần Boot Flash Section.
+ Application Flash Section bao gồm 2 phần: phần chứa các mã lệnh và
phần chứa các vector ngắt (interrupt vectors). Các vector ngắt nằm ở phần
đầu của application section (từ địa chỉ 0x0000) và dài đến bao nhiêu tùy
thuộc vào loại chip. Phần chứa lệnh nằm liền sau đó, chương trình viết cho
chip sau khi biên dịch thành mã máy phải được nạp vào phần này thông qua
1 mạch chuyên dụng gọi là mạch nạp (programmer). Vi điều khiển sẽ đọc
các lệnh này ra và thực hiện chương trình đã viết.
+ Boot Flash Section: là phần bộ nhớ đặc biệt, phần mềm trong boot flash
vẫn tiếp tục chạy khi application flash đang được cập nhật. Việc chạy phần
mềm ở vùng này được thiết lập qua BOOTRST fuse sẽ đề cập ở phần sau.

Hình 1. Bộ nhớ flash của Atmega16

Trần Thừa – 2010 4


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Hình 2. Tổ chức bộ nhớ của AVR


2. Bộ nhớ dữ liệu (data memory):
Đây là phần chứa các thanh ghi quan trọng nhất của chip, việc lập trình cho
chip phần lớn là truy cập bộ nhớ này. Bộ nhớ dữ liệu trên các chip AVR có độ
lớn khác nhau tùy theo mỗi chip, tuy nhiên về cơ bản phần bộ nhớ này được
chia thành 5 phần:
Phần 1: là phần đầu tiên trong bộ nhớ dữ liệu, phần này bao gồm 32 thanh
ghi có tên gọi là register file (RF), hay General Purpose Register – GPR – các
thanh ghi đa dụng. Tất cả các thanh ghi này đều là các thanh ghi 8 bits như
trong hình 2.

Hình 2. Thanh ghi 8 bits.


Tất cả các chip trong họ AVR đều bao gồm 32 thanh ghi Register File có địa
chỉ tuyệt đối từ 0x0000 đến 0x001F. Mỗi thanh ghi có thể chứa giá trị dương từ
0 đến 255 hoặc các giá trị có dấu từ -128 đến 127 hoặc mã ASCII của một ký
tự nào đó…Các thanh ghi này được đặt tên theo thứ tự là R0 đến R31. Chúng
được chia thành 2 phần, phần 1 bao gồm các thanh ghi từ R0 đến R15 và phần
2 là các thanh ghi R16 đến R31. Các thanh ghi này có các đặc điểm sau:
+Được truy cập trực tiếp trong các lệnh.
+Các toán tử, phép toán thực hiện trên các thanh ghi này chỉ cần 1 chu kỳ xung
clock.
+Register File được kết nối trực tiếp với bộ xử lí trung tâm – CPU của chip.

Trần Thừa – 2010 5


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Tất cả các instruction sử dụng Register File làm toán hạng đều có thể truy nhập
tất cả các RF một cách trực tiếp trong 1 chu kỳ xung clock, ngoại trừ SBCI,
SUBI, CPI, ANDI và LDI, các instruction này chỉ có thể truy nhập các thanh
ghi từ R16 đến R31.
Thanh ghi R0 là thanh ghi duy nhất được sử dụng trong instruction LPM
(Load Program Memory). Các thanh ghi R26, R27, R28, R29, R30 và R31
ngoài chức năng thông thường còn được sử dụng như các con trỏ (Pointer
register) trong một số instruction truy xuất gián tiếp
+Chúng là nguồn chứa các số hạng trong các phép toán và cũng là đích chứa
kết quả trả lại của phép toán.
Tóm lại 32 RF của AVR được xem là 1 phần của CPU, vì thế chúng được CPU
sử dụng trực tiếp và nhanh chóng, để gọi các thanh ghi này, chúng ta không cần
gọi địa chỉ mà chỉ cần gọi trực tiếp tên của chúng. RF thường được sử dụng
như các toán hạng (operand) của các phép toán trong lúc lập trình.
Phần 2: là phần nằm ngay sau register file, phần này bao gồm 64 thanh
ghi được gọi là 64 thanh ghi nhập/xuất (64 I/O register) hay còn gọi là vùng
nhớ I/O (I/O Memory). Vùng nhớ I/O là cửa ngõ giao tiếp giữa CPU và thiết bị
ngoại vi. Tất cả các thanh ghi điều khiển, trạng thái…của thiết bị ngoại vi đều
nằm ở đây. Việc điều khiển các PORT của AVR liên quan đến 3 thanh ghi
DDRx, PORTx và PINx (x là tên PORT), tất cả 3 thanh ghi này đều nằm trong
vùng nhớ I/O. Xa hơn, nếu muốn truy xuất các thiết bị ngoại vi khác như
Timer, chuyển đổi Analog/Digital, giao tiếp USART…đều thực hiện thông qua
việc điều khiển các thanh ghi trong vùng nhớ này.
Vì các thanh ghi trong vùng I/O không được hiểu theo tên gọi như các
Register file, khi lập trình cho các thanh ghi này, người lập trình cần nhớ địa
chỉ của từng thanh ghi, đây là việc tương đối khó khăn. Tuy nhiên, trong hầu
hết các phần mềm lập trình cho AVR, địa chỉ của tất cả các thanh ghi trong
vùng I/O đều được định nghĩa trước trong 1 file định nghĩa, bạn chỉ cần đính
kèm file này vào chương trình của bạn là có thể truy xuất các thanh ghi với tên
gọi của chúng. Giả sử dùng phần mềm MikroC for AVR thanh ghi PORTB
được định nghĩa sẵn, bạn chỉ cần gọi tên thanh ghi này để truy xuất.
Phần 3: RAM tĩnh, nội (internal SRAM), là vùng không gian cho chứa
các biến (tạm thời hoặc toàn cục) trong lúc thực thi chương trình, vùng này
tương tự các thanh RAM trong máy tính nhưng có dung lượng khá nhỏ (khoảng
vài KB, tùy thuộc vào loại chip).

Phần 4: RAM ngoại (external SRAM), các chip AVR cho phép người
sử dụng gắn thêm các bộ nhớ ngoài để chứa biến, vùng này thực chất chỉ tồn tại
khi nào người sử dụng gắn thêm bộ nhớ ngoài vào chip.
Phần 5: EEPROM (Electrically Ereasable Programmable ROM) là một phần
quan trọng của các chip AVR mới, vì là ROM nên bộ nhớ này không bị xóa
ngay cả khi không cung cấp nguồn nuôi cho chip, rất thích hợp cho các ứng

Trần Thừa – 2010 6


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

dụng lưu trữ dữ liệu. Như trong hình 2, phần bộ nhớ EEPROM được tách riêng
và có địa chỉ tính từ 0x0000.

Hình 3. Kiến trúc vi điều khiển AVR


Hoạt động của AVR
Hình 3 biểu diễn cấu trong bên trong của 1 AVR. Ta thấy rằng 32 thanh
ghi trong Register File được kết nối trực tiếp với Arithmetic Logic Unit - Đơn
vị số học-logic (ALU cũng được xem là bộ xử lý trung tâm của AVR) bằng 2
đường dữ liệu, vì thế ALU có thể truy xuất trực tiếp cùng lúc 2 thanh ghi RF
chỉ trong 1 chu kỳ máy.
Các lệnh được chứa trong bộ nhớ chương trình Flash memory dưới
dạng các thanh ghi 16 bit. Bộ nhớ chương trình được truy cập trong mỗi chu kỳ
xung clock và 1 lệnh chứa trong program memory sẽ được nạp vào trong thanh
ghi lệnh, thanh ghi lệnh tác động và lựa chọn register file cũng như RAM cho
ALU thực thi.
Trong lúc thực thi chương trình, địa chỉ của lệnh kế tiếp được lưu trong
bộ đếm chương trình– PC (Program Counter).
AVR có ưu điểm là hầu hết các lệnh đều được thực thi trong 1 chu kỳ máy,
vì vậy có thể nguồn clock lớn nhất cho AVR có thể nhỏ hơn 1 số vi điều khiển
khác như PIC nhưng thời gian thực thi vẫn nhanh hơn.

Trần Thừa – 2010 7


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

3. Stack – ngăn xếp .


Ngăn xếp là vùng nhớ đặc biệt trong bộ nhớ, có cách truy xuất khác hẳn với
việc truy xuất ngẫu nhiên. Việc truy xuất ngăn xếp tuân theo quy tắc LIFO(Last
In – First Out) – nghĩa là dữ liệu vào sau cùng sẽ được lấy ra trước.

Hình 4. Stack.
Stack được truy xuất thông qua thanh ghi Stack Pointer(con trỏ ngăn
xếp). Thanh ghi này được dùng để chỉ đến vùng trong bộ nhớ SRAM ở đỉnh
của ngăn xếp.
Do cách truy xuất đặc biệt của stack, nên stack được dùng để lưu trữ địa
chỉ trở về của bộ đếm chương trình trong khi thực hiện các ngắt.
+Khi có ngắt xảy ra, vi điều khiển tự động lưu địa chỉ lệnh kế tiếp vào
stack và PC lúc này sẽ hướng đến vector ngắt tương ứng
+Khi AVR thoát khỏi 1 ngắt, địa chỉ của lệnh kế tiếp của chương trình
chính sẽ trả lại cho PC để tiếp tục thực hiện chương trình.

4. Thanh ghi trạng thái - SREG (STATUS REGISTER)


Nằm trong vùng nhớ I/O, thanh ghi SREG có địa chỉ I/O là 0x003F và địa
chỉ bộ nhớ là 0x005F (thường đây là vị trí cuối cùng của vùng nhớ I/O) là một
trong số các thanh ghi quan trọng nhất của AVR. Thanh ghi SREG chứa 8 bit
cờ (flag) chỉ trạng thái của bộ xử lí, tất cả các bit này đều bị xóa sau khi reset,
các bit này cũng có thể được đọc và ghi bởi chương trình. Chức năng của từng
bit được mô tả như sau:

Trần Thừa – 2010 8


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Bit 0 – C (Carry Flag: Cờ nhớ): là bit nhớ trong các phép đại số hoặc logic, ví
dụ thanh ghi R1 chứa giá trị 200, R2 chứa 70, chúng ta thực hiện phép cộng có
nhớ: R1, R2, sau phép cộng, kết quả sẽ được lưu lại trong thanh ghi R1, trong
khi kết quả thực là 270 mà thanh ghi R1 lại chỉ có khả năng chứa tối đa giá trị
255 (vì có 8 bit) nên trong trường hợp này, giá trị lưu lại trong R1 thực chất chỉ
là 14, đồng thời cờ C được set lên 1 (vì 270=100001110, trong đó 8 bit sau
00001110 =14 sẽ được lưu lại trong R1).
Bit 1 – Z (Zero Flag: Cờ 0): cờ này được set lên 1 nếu kết quả phép toán đại số
hay phép Logic bằng 0.
Bit 2 – N (Negative Flag: Cờ âm): cờ này được set lên 1 nếu kết quả phép toán
đại số hay phép Logic là số âm.
Bit 3 – V (Two’s complement Overflow Flag: Cờ tràn của bù 2): hoạt động của
cờ này liên quan đến kiến thức số nhị phân (phần bù), chúng ta sẽ đề cập đến
khi nào thấy cần thiết.
Bit 4 – S (Sign Bit: Bit dấu): Bit S là kết quả phép XOR giữa 1 cờ N và V,
S=N xor V.
Bit 5 – H (Half Carry Flag: Cờ nhớ nữa): cờ H là cờ nhớ trong 1 vài phép toán
đại số và phép Logic, cờ này hiệu quả đối với các phép toán với số BCD.
Bit 6 – T (Bit Copy Storage): được sử dụng trong 2 lệnh BLD (Bit LoaD) và
BST (Bit STorage).
Bit 7 – I (Global Interrupt Enable) : Cho phép ngắt toàn cục): Bit này phải được
set lên 1 nếu trong chương trình có sử dụng ngắt. Sau khi set bit này, bạn muốn
kích hoạt loại ngắt nào cần set các bit ngắt riêng của ngắt đó.
Phần này chỉ giải thích ngắn gọn chức năng của các bit trong thanh ghi
SREG, đối với ngôn ngữ ASEMBLY thì việc theo dõi cờ trạng thái giúp ta
kiểm soát các phép toán số học, tuy nhiên trong ngôn ngữ C ta chỉ dùng 1 số bit
cần thiết như bit 7 sử dụng trong các ứng dụng của ngắt. Trong trình biên dịch
MikroC, ta có thể truy xuất thanh ghi này như bằng tên gọi của nó.
Trên đây là các thành phần cơ bản trong cấu trúc AVR. Để hiểu sâu hơn
về các chức năng của AVR, các bạn cần tìm hiểu thêm về các thanh ghi
chức năng đặc biệt để phục vụ việc lập trình cho AVR sau này.

II. Làm việc với vi điều khiển AVR


1. Mô tả các chân.
a/. Chân nguồn
VCC: cấp nguồn cho vi điều khiển hoạt động với điện thế làm việc tối đa
là 6 Volt.
GND: nối vào điểm có điện thế quy ước là 0 Volt.
Thông thường, ta có thể mắc mạch ổn áp như sau để AVR hoạt động ổn
định ở điện áp 5 Volt.

Trần Thừa – 2010 9


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

U1

1 3

GND
+5 Volt In Out +5 Volt

C1 LM7805 C2

2
470uF 100uF

Ground Ground

Lưu ý: tùy vào dạng đóng gói và loại vi điều khiển mà có thể có nhiều hơn 1
cặp chân nguồn-mass. Cần cung cấp đầy đủ để AVR vi điều khiển hoạt động
ổn định.
b/. Các chân phục vụ chức năng ADC.
AVCC: là chân cấp nguồn cho bộ chuyển đổi ADC, chân này được nối lên
nội bộ lên VCC ngay cả khi bộ chuyển đổi ADC không hoạt động. iá trị
điện áp cấp cho AVCC không được khác nguồn nuôi chip (VCC) quá +/-
0.3V. Nhiễu là vấn đề rất quan trọng khi sử dụng các bộ ADC, để giảm
thiểu sai số chuyển đổi do nhiễu, nguồn cấp cho ADC cần phải được “lọc”
(filter) kỹ càng. Một cách đơn giản để tạo nguồn AVCC là dùng một mạch
LC kết nối từ nguồn VCC của chip như minh họa trong hình 3, đây là cách
được gợi ý bởi nhà sản xuất AVR.

Trần Thừa – 2010 10


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Aref: chân cung cấp điện thế tham chiếu cho bộ ADC, nếu cấu hình cho
AVR dùng điện áp tham chiếu nội thì chân này phải nối mass thông qua 1
tụ điện để chống nhiễu.
c/. Các chân cấp xung đồng hồ.
Như đã nói, AVR có 2 nguồn cấp dao động chính là dao động nội có
xung nhịp tối đa 8MHz và dao động ngoại lên đến 16MHz.
Khi dùng mạch dao động ngoại, ta có 2 cách:
+Dùng mạch RC: Khi đó chân XTAL2 bỏ trống, cách này cũng dùng
khi ta có 1 nguồn dao động bất kỳ được cấp vào chân XTAL1

+Dùng dao động thạch anh: Trong đó, giá trị tụ C1=C2 từ 12pF đến
22pF. Mạch dao động thạch anh rất thông dụng do có độ chính xác cao.

d/. Các PORT giao tiếp vào ra số (I/O).


Tùy vào số lượng chân mà có các số lượng PORT giao tiếp khác nhau.
Số lượng chân mỗi PORT cũng không giống nhau, nếu có đầy đủ thì mỗi
PORT có 8 chân từ 0-7.

Trần Thừa – 2010 11


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Các chân của mỗi PORT đều có 2 hướng dữ liệu, hướng dữ liệu được
cấu hình bởi thanh ghi DDRx (x là tên PORT). Nếu bit nào được set lên 1
thì chân tương ứng sẽ là ngõ ra và ngược lại nếu bit nào bị xóa thì chân
tương ứng sẽ là ngõ vào.
Vd: DDRA=0b00001111 (“0b” trong ngôn ngữ C cho biết đang dùng
số ở hệ nhị phân)
Có nghĩa là PORT A có 4 bit thấp là ngõ ra và 4 bit cao là ngõ vào.
+Khi các chân được cấu hình là ngõ ra, chúng được ánh xạ trực tiếp tới
thanh ghi PORTx, khi đó trạng thái của mỗi chân sẽ tương ứng với từng bit
dữ liệu mà thanh ghi đang chứa. Hay nói cách khác, đây là thanh ghi xuất
dữ liệu.
Vd : PORTD=0b11110000
Có nghĩa là PORTD có các chân từ D0 đến D3 ở mức điện thế thấp và
các chân D4 đến D7 có mức điện thế cao.
+Khi các chân được cấu hình là ngõ vào, chúng được ánh xạ trực
tiếp đến thanh ghi PINx, khi đó tùy mức logic ở mỗi chân mà bit tương ứng
của thanh ghi PINx có giá trị 0 hay 1. Hay nói cách khác, đây là thanh ghi
nhận dữ liệu.
Vd : Khi các chân từ D0 đến D3 nối lên mức điện thế cao, các chân còn
lại nối với mức điện thế thấp thì thanh ghi PIND sẽ có giá trị 0b00001111.
Các chân vào-ra số đều được bảo vệ bởi diode và có khả năng cấp dòng lên đến
20mA nên có thể dễ dàng điều khiển các led mà không cần mắc thêm tầng công
suất.

Hình 4. Sơ đồ chân I/O của AVR

Trần Thừa – 2010 12


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Ngoài chức năng là ngõ vào-ra số, các chân của AVR còn có thể mang thêm 1
hoặc vài chức năng như ngắt ngoài, ADC…Ta có thể nhận ra chức năng khác
bằng tên trên sơ đồ chân của vi điều khiển.
Ví dụ : trong hình 5 chân số 23 có 2 chức năng là chân I/O thứ nhất của
PORTC (PC0) và là kênh ADC thứ nhất (ADC0).

Hình 5. Sơ đồ chân Atmega8


e/. Chân khởi động lại (reset) vi điều khiển.
Các vi điều khiển AVR có chân RESET tác động mức thấp. Tùy mỗi
loại mà chân này có thể là chân chức năng riêng hoặc cùng chân với 1 chân I/O
nào đó. Vi điều khiển AVR có chức năng tự reset khi mở nguồn nên không cần
mạch hỗ trợ tự reset.
Mạch đơn giản để reset vi điều khiển như sau: điện trở kéo lên khoảng
10 kOhm.
VCC

R1
10k

RESET PIN

SW1
RESET BUTTON

Trần Thừa – 2010 13


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

III. Các công cụ hỗ trợ.


1. Trình biên dịch
Là phần mềm chạy trên máy tính cho phép dịch mã lệnh của người viết
chương trình sang mã máy để nạp vào vi điều khiển.
Tùy ngôn ngữ lập trình mà có các trình biên dịch khác nhau.
+AvrStudio: là trình biên dịch ASM chính thức cung cấp bởi
Atmel, đây là trình biên dịch hoàn toàn miễn phí và tất nhiên là tốt nhất
cho lập trình AVR bằng ASM. Ngoài ra đi kèm với nó còn có 1 số gói
công cụ hưu ích ví dụ như chương trình nạp AVR tương thích với các
mạch nạp của hãng.
+Codevision AVR : là phần mềm thương mại (phải mua key của
nhà sản xuất). Đây là trình biên dịch ngôn ngữ C cho AVR rất mạnh với
rất nhiều thư viện và chức năng cấu hình AVR thông qua giao diện
người dùng, ngoài ra nó cũng được tích hợp cả trình nạp chip cho 1 số
mạch nạp thông dụng. Chương trình này thích hợp với những lập trình
viên chuyên nghiệp.
+Mikrox for AVR : cũng là 1 phần mềm thương mại. Đây là trình
dịch đa ngôn ngữ (x tương ứng với phiên bản cho ngôn ngữ tên x ví dụ
MikroC ), hỗ trợ khá nhiều thư viện, giao diện bắt mắt và thân thiện, tuy
nhiên các cấu hình AVR phải tự thực hiện bằng code nên thích hợp với
các bạn đang nghiên cứu hoạt động của AVR. Trong tài liệu này, tôi sử
dụng MikroC làm trình biên dịch.
2. Mạch nạp (programmer).
Là board mạch có nhiệm vụ tải chương trình đã biên dịch trên máy tính
xuống vi điều khiển.
Vi điều khiển AVR có nhiều chuẩn nạp và do đó cũng có nhiều loại
mạch nạp khác nhau với các loại giao tiếp với máy tính khác nhau.
Chuẩn nạp ISP(In System Programmer) : đây là ưu điểm của AVR, nó
cho phép nạp chương trình qua chip ngay khi chip đang nằm trên mạch ứng
dụng. Các chân cần thiết bao gồm: MISO-MOSI-SCK-RESET-VCC-GND.
Trong đó VCC có thể dùng nguồn của mạch nạp hoặc dùng nguồn của
board ứng dụng.
Chuẩn nạp song song điện thế cao(High Voltage Parallel Programmer):
khá phức tạp, cần 1 cắm chip vào 1 board chuyển đổi(adapter) chuyên dụng
rồi kết nối với mạch nạp có hỗ trợ chức năng nạp này như STK500 của
ATMEL. Ưu điểm là có thể lập trình lại các thiết lập sai (fuse bit).
Các mạch nạp cơ bản :
STK200/300 : là mạch nạp đơn giản nhất, chỉ dùng vài linh kiện thông
thường, không dùng chip giao tiếp, nạp cực nhanh. Tuy nhiên do dùng chuẩn
giao tiếp với máy tính là LPT mà hiện nay hầu như không máy tính nào còn
nên sẽ gây khó khăn cho chúng ta. Hình 6 là sơ đồ mạch nạp này

Trần Thừa – 2010 14


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Hình 6. Sơ đồ mạch nạp STK200/300 thu gọn.

AVR910USB : là phiên bản cải tiến của mạch nạp AVR910 của
ATMEL, nó cho phép giao tiếp qua cổng USB của máy tính. Vì vậy trên mạch
cần có 1 chip giao tiếp, đó là chip Atmega8. Tuy nhiên, ta lại gặp vấn đề « con
gà và quả trứng » : muốn thi công mạch này thì phải có 1 mạch nạp khác nạp
firmware cho chip giao tiếp Atmega8. Ta có thể thi công trước 1 mạch
STK200/300 rồi nạp cho chip Atmega8. Sơ đồ mạch và file chương trình-
firmware (*.hex) các bạn có thể tham khảo trên website www.eeelabs.org
USB AVR-Lab : là mạch nạp do website www.ullihome.de phát
triển, đây cũng là mạch nạp giao tiếp qua USB và chip giao tiếp vẫn là
Atmega8. Điểm đặc biệt là mạch này giả lập các loại mạch nạp khác như
STK500, MkII... Firmware nạp cho chip được ghi vào phần boot flash, khi cần
thay đổi, ta chỉ cần dùng phần mềm trên máy tính để thay đổi loại mạch nạp mà
mạch này giả lập, không cần phải nạp lại firmware mới. Sơ đồ mạch, layout
mạch in, driver, firmware và chương trình các bạn có thể tham khảo trên
website www.eeelabs.org
3. Chương trình nạp.
Là phần mềm chạy trên máy tính để lấy file hex nạp vào vi điều khiển,
ngoài ra nó còn có thể kiêm luôn chức năng lập trình fuse bit (sẽ đề cập ở
phần sau).

Trần Thừa – 2010 15


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Như đã nói ở trên, chương trình nạp thông dụng được tích hợp sẵn trong
1 số trình biên dịch như AVR Studio hay Codevision.
Tôi sẽ giới thiệu cách nạp chương trình bằng AVR Studio 4 như sau :

+Khởi động chương trình, ở gaio diện chính chọn nút (display
the ‘Connect’ dialog).
+Cửa sổ mới hiện ra:

Chọn loại mạch nạp đang dùng ở mục Platform, sau đó ở phần Port chọn
Auto nếu mạch nạp sử dụng cổng COM hoặc COM ảo(USB giả lập COM – ví
dụ như AVR910USB). Nếu mạch nạp chuẩn USB thì chọn USB. Chọn xong
bấm Connect…
+Nếu máy nhận ra mạch nạp thì có cửa sổ sau hiện ra:

Ở thẻ main, ta chọn loại chip sử dụng trong list mà mạch nạp đang dùng
hỗ trợ ở mục Device anh Signature Bytes, sau đó bấm Read Signature để kiểm

Trần Thừa – 2010 16


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

tra. Sẽ có thông báo cho biết có đúng loại chip bạn chọn đang được kết nối hay
không.
+Chọn tiếp chuẩn nạp: ở mục Programming Mode anh Target Settings.
Nếu chuẩn nạp là ISP thì chọn setting chọn tần số ISP Freq sao cho tần số này
nhỏ hơn ¼ xung nhịp của chip đích(chip cần nạp) đang dùng. Sau đó bấm
write, bấm read để kiểm tra lại. Bấm close để thoát.
+Thẻ Program: Check vào các mục Erase device before flash
programming và mục Verify device after programming. Mục đích là đảm bảo
quá trình nạp diễn ra suôn sẻ.

Mục Flash chọn Input HEX file, sau đó chỉ đường dẫn đến file chương
trình cần nạp. Sau đó bấm Program. Nếu muốn đọc dữ liệu trong chip và ghi
thành file hex trên máy thì bấm Read và chọn nơi lưu file hex.
Các chức năng còn lại sẽ đề cập ở các chương sau.
4. Trình mô phỏng ISIS Proteus.
Đây là trình mô phỏng mạch điện tử rất thông dụng nhờ tính trực quan,
giao diện thân thiện, thư viện linh kiện khá lớn, và hỗ trợ hầu hết các loại vi
điều khiển thông dụng như AVR, PIC,8051.
Khi mô phỏng vi điều khiển AVR với ISIS Proteus các công đoạn như
fuse bit(cấu hình cứng), được thực hiện bằng cách cấu hình linh kiện.
Sau đây là vài bước thực hiện việc mô phỏng mạch vi điều khiển AVR
với ISIS Proteus.

Trần Thừa – 2010 17


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Hình 7. Giao diện ISIS Proteus 7.6 sp0

Bước 1: Chọn linh kiện. Bấm vào nút để chọn chế độ lấy linh kiện.
Sau đó, bấm vào nút để lấy linh kiện trong thư viện, cửa sổ mới hiện ra, gõ
tên linh kiện cần lấy (hoặc cần tìm) vào ô keyword. Bấm vào linh kiện hiện ra ở
kết quả, sau đó bấm ok. Lấy các linh kiện cần thiết với các bước như trên.

Bước 2: Lấy nguồn và mass. Bấm vào nút để lấy các thành phần đầu
cuối(terminal) như POWER(nguồn) hoặc Ground(mass).
Bước 3: Vẽ đường liên kết. Bấm vào nút , sau đó bấm vào chân linh
kiện bất kỳ rồi kéo đường dây đến chân linh kiện khác. Trong quá trình kéo,
bấm chuột vào không gian để định hướng đường dây.
Trường hợp có quá nhiều đường dây có đặt tính gần giống nhau, ta dùng
công cụ tuyến (BUS) để vẽ , bấm vào để vẽ tuyến, sau đó vẽ các đường liên
kết ngắn nhất đến tuyến. Tiếp theo là đặt tên các đường tín hiệu, các đường dây
trong 1 tuyến chỉ nối với nhau khi chúng có cùng tên nhãn(label). Ta bấm
sau đó bấm vào đường dây để đặt tên.
Bước 4: Sau khi đã vẽ xong mạch, bấm bào linh kiện để điều chỉnh các
trị số thích hợp như giá trịn điện trở, tụ điện. Đối với vi điều khiển AVR thì các
thông số khá nhiều và có thể khác nhau ở mỗi loại:
Các thông số cần quan tâm:
+Program File: đường dẫn đến file hex đã biên dịch, chính là file dùng
để nạp xuống chip trong thực tế.
+Clock Frequency: tần số thạch anh mà vi điều khiển đang dùng trong
mạch thực tế ( cấu hình trong trình biên dịch).
+Các thông số còn lại chính là các fuse bit, sẽ được giới thiệu ở phần
sau.

Trần Thừa – 2010 18


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Hình 8. Cửa sổ cấu hình của Atmega8.

Hình 9. Mạch vẽ xong

Trần Thừa – 2010 19


Lập trình vi điều khiển AVR với ngôn ngữ C WWW.EEELABS.ORG

Bước 5: Sau khi hoàn tất vẽ mạch, ta tiến hành dùng các nút

Play(chạy)-Step(nhảy bước)-Pause(tạm dừng)-Stop(dừng) để điều khiển việc


mô phỏng.
Lưu ý: các sơ đồ mô phỏng trên Proteus chỉ có thể tham khảo như là sơ
đồ nguyên lý, vì nếu bỏ qua 1 số thành phần thì mạch mô phỏng vẫn chạy được
nhưng thực tế lại sai nghiêm trọng. Để thiết kế mạch chi tiết, cần tính toán kỹ
thông số linh kiện.
Ngoài ra, Proteus còn cung cấp rất nhiều công cụ phục vụ việc
mô phỏng như 1 phòng thí nghiệm thực thụ. Các bạn có thể tham khảo thêm
các tính năng của Proteus trên website www.eeelabs.org

5. Mạch phát triển vi điều khiển AVR.


Các chương trình mô phỏng chỉ hỗ trợ ta trong việc kiểm tra thiết kế
giảm thiểu sai sót trong thiết kế phần cứng và lập trình phần mềm. Thực tế đôi
khi lại cho kết quả khác nhiều so với mô phỏng, vì vậy cần một công cụ khác,
sử dụng song song với trình mô phỏng đó là mạch phát triển.
Mạch phát triển bao gồm các khối mạch chính sau:
+Khối nguồn: tạo ra nguồn nuôi ổn định cho vi điều khiển và các thiết bị
khác có thể có. Nguồn cho vi điều khiển hoạt động thường ở mức điện thế 5
volt DC.
+Khối MCU: khối này là socket để cắm vi điều khiển, tùy loại board mà
có thể có 1 hoặc 1 vài socket để hỗ trợ nhiều loại vi điều khiển.
+Khối dao động thạch anh: cung cấp dao động thạch anh cho vi điều
khiển (khối này có thể tinh giảm nếu sử dụng dao động dao động nội).
+Khối giao tiếp ngoại vi: bao gồm các PORT I/O, mỗi PORT được sắp
xếp vào 1 khối nối để kết nối vào các module rời khác. Các khối nối thường
bao gồm luôn nguồn và mass để cấp nguồn và điện thế chuẩn cho module rời.
Trên đây là các khối cơ bản của 1 mạch phát triển vi điều khiển, sau đây
xin giới thiệu mạch phát triển đơn giản sử dụng Atmega16.

Trần Thừa – 2010 20


J7
ISP
VCC VCC VCC VCC

1
2
3
4
5
6
VCC IC1 L1
10uH

Trần Thừa – 2010


PORTB ATMega32 PORTA

10
1 1 40 1
2 2 PB0/(XCK/T0) PA0/(ADC0) 39 2

VC C
PB1/(T1) PA1/(ADC1) J6
3 3 38 3
PB2/(INT2/AIN0) PA2/(ADC2) EXTERNAL Vref
4 4 37 4
PB3/(OC0/AIN1) PA3/(ADC3)
5 5 36 5
PB4/(SS) PA4/(ADC4)
6 6 35 6
PB5/(MOSI) PA5/(ADC5)
VCC 7 7 34 7
1
2

PB6/(MISO) PA6/(ADC6)
8 8 33 8
PB7/(SCK) PA7/(ADC7)
9 9
10 9 10 J5
C1 RESET
R1 22p 32
AREF
10K J1 12 J4 1
Lập trình vi điều khiển AVR với ngôn ngữ C

XTAL2
2
RESET 30 3
Y1 AVCC
SW1 VCC 16Mhz C4
C5 C2 104 VCC C3 Vref SELECTOR
10uF PORTD 22p 13 PORTC 104
XTAL1
10 14 29 1
PD0/(RXD) PC7/(TOSC2)
9 15 28 2
PD1/(TXD) PC6/(TOSC1)
8 16 27 3
PD2/(INT0) PC5/(TDI)
7 17 26 4
6 18 PD3/(INT1) PC4/(TDO) 25 5
PD4/(OC1B) PC3/(TMS)
5 19 24 6
PD5/(OC1A) PC2/(TCK)
4 20 23 7
PD6/(ICP) PC1/(SDA)
3 21 22 8
GN D
GN D

PD7/(OC2) PC0/(SCL)
2 9
1 10
11
31

J2 J3
WWW.EEELABS.ORG

21

You might also like