59
Copyright © 2010 Cùng hc AVR Thanhtam Ho - www.hocavr.com Created by QuocHuy Hoang [email protected] Page 1 Lp trình vi AVR Studio Ni dung Các bài cn tham kho trước 1. Lp trình Asembly bng AVR Studio. 2. Lp trình C bng AVR Studio. Download AVRStudio Làm quen AVR. Trong bài này tôi hướng dn cách sdng bcông cAVRStudio đề to các Project lp trình bng ngôn ngAssembly và C. Tôi sdùng ví dchương trình quét LED bài 1để minh ha cho c2 cách to mt Project Assembly và C. I. Lp trình Assembly bng AVRStudio. Vic cài đặt AVRStudio tương đối đơn gin. Bn hãy download bn mi nht ca phn mm này twebsite Atmel hoc bn 4.623 ti đây (hoc mt mirror khác ) và cài đặt vào máy. Theo mc định, chương trình sđược cài vào đĩa C ti: C:\Program Files\Atmel\AVR Tools. Bt đầu vi AvrStudio4: bn chy AvrStudio t“Start/ All Programs/ Atmel AVR Tools/ AvrStudio 4”. ln đầu chy AvrStudio, 1 dialog “Welcome to AvrStudio 4” xut hin, hãy bcheck ô “show dialog at Startup” và nhn cancel. Hình 1. Welcome to AVR studio 4 Diaolg. Bn thy giao din AVR Studio 4 như sau:

AVR-Ho tro phan mem

Embed Size (px)

DESCRIPTION

Uploaded from Google Docs

Citation preview

Page 1: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 1

Lập trình với AVR Studio

Nội dung Các bài cần tham khảo trước

1. Lập trình Asembly bằng AVR Studio. 2. Lập trình C bằng AVR Studio.

Download AVRStudio

• Làm quen AVR.

Trong bài này tôi hướng dẫn cách sử dụng bộ công cụ AVRStudio đề tạo các Project lập trình bằng ngôn ngữ Assembly và C. Tôi sẽ dùng ví dụ chương trình quét LED ở bài 1để minh họa cho cả 2 cách tạo một Project Assembly và C.

I. L ập trình Assembly bằng AVRStudio.

Việc cài đặt AVRStudio tương đối đơn giản. Bạn hãy download bản mới nhất của phần mềm này từ website Atmel hoặc bản 4.623 tại đây (hoặc một mirror khác) và cài đặt vào máy. Theo mặc định, chương trình sẽ được cài vào ổ đĩa C tại: C:\Program Files\Atmel\AVR Tools.

Bắt đầu với AvrStudio4: bạn chạy AvrStudio từ “Start/ All Programs/ Atmel AVR Tools/ AvrStudio 4”. Ở lần đầu chạy AvrStudio, 1 dialog “Welcome to AvrStudio 4” xuất hiện, hãy bỏ check ở ô “show dialog at Startup” và nhấn cancel.

Hình 1. Welcome to AVR studio 4 Diaolg.

Bạn thấy giao diện AVR Studio 4 như sau:

Page 2: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 2

Hình 2. Giao diện AVR Studio.

Giao diện AVR Studio rất dễ sử dụng, vì vậy chúng ta sẽ kết hợp tìm hiểu trong lúc viết ví dụ.

Tạo Project mới: từ menu Project, chọn “Project/New Project”.

Hình 3. Tạo Project mới.

Một dialog mới xuất hiện cho phép bạn setting Project của bạn, trong vùng “Project Type” chọn “Atmel AVR assembler”, tức lập trình bằng ngôn ngữ Assembly và trình dịch là Atmel AVR assembler (trình dịch tích hợp trong AVR Studio);

Page 3: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 3

“Location”, chọn nơi chứa Project (trong ví dụ này tôi chọn thư mục D/AVR1); “Project name”, tên Projetc của bạn, hãy đặt là avr1.

Hình 4.Setting Project.

Nhấn Next để tiếp tục chọn Platform và device, việc này phục vụ cho mục đích debug chương trình hay mô phỏng bằng avr simulator. Bạn hãy chọn “AVR Simulator” trong ô Platform và Atmega8 trong ô device (chúng ta sẽ viết chương trình cho chip Atmega8).

Hình 5. Chọn Platform và device.

Nhấn finish để kết thúc setting project, bạn thấy các cửa số của “Project” chứa các thông tin Project của bạn, bạn thấy trong mục “Source files” có 1 file “avr1.asm” là

Page 4: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 4

source code của bạn. Bạn có thể nhấn vào switch tab bên dưới cửa sổ Project để xem cửa số “I/O View”, cửa số này chứa thông tin chip dùng khi mô phỏng. Cửa số Build chứa thông tin kết quả biên dịch. “Editor” là vùng viết chương trình, trong trường hợp này đó là file “avr1.asm” của bạn.

Hình 6. Cửa sổ lập trình.

Việc còn lại là viết code vào cửa sổ Editor sau đó dịch chương trình bằng phím F7.

II. L ập trình C bằng AVRStudio.

Về bản chất AVRStudio không hỗ trợ lập trình ngôn ngữ C vì không có trình dịch C. Tuy nhiên nó cho phép tích hợp trình dịch C của bộ công cụ WinAVR. Vì thế, nếu muốn sử dụng AVRStudio để lập trình C cho AVR bạn phải cài đặt trình dịch và thư viện avr-gcc từ GNU hoặc đơn giản là cài đặt WinAVR cùng AVRStudio. Bạn tham khảo thêm bài hướng dẫn WinAVR để biết cách download cài đặt WinAVR. Các hướng dẫn bên dưới giả sử rằng bạn đã cài đặt thành công AVRStudio và WinAVR.

Việc tạo 1 Project lập trình bằng ngôn ngữ C trong AVR Studio không khác mấy so với việc tạo Project ASM. Điều duy nhất cần chú ý là bước chọn trình biên dịch. Xem lại hình 4 khi tạo Project ASM, chúng ta chọn Atmel AVR Assempler làm trình

Page 5: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 5

dịch chính, để tạo Project C chúng ta chọn AVR GCC làm trình biên dịch như trong hình 7. Cần lưu ý là trình dịch AVR GCC chỉ xuất hiện trong danh sách lựa chọn của AVR Studio khi bạn đã cài WinAVR vào máy trước đó.

Hình 7. Chọn AVR GCC làm trình biên dịch chính.

Xem hình 7, giả sử bạn đặt tên Project là avr1 trong ô Project name, bạn sẽ thấy AVR Studio đề nghị tự tạo ra 1 file chương trình chính tên là avr1 có phần mở rộng là ".c", khác với phần mở rộng ".asm" khi tạo Project Assembly. Các việc còn lại hoàn toàn tương tự trong trường hợp tạo Project ASM nên bạn có thể xem lại phần trên. Sau khi tạo Project lập trình C trong AVR Studio, bạn save Project rồi vào thư mục chứa Project mới tạo, bạn sẽ thấy 1 file Makefile được tự động tạo ra. Makefle được AVR Studio tạo tự động trong lúc tạo Project, bạn không cần dùng đến trình MFile. Ngôn ngữ C cho AVR Studio hoàn toàn là AVR GCC như trong WinAVR, vì thế bạn có thể copy, load 1 file source từ WinAVR vào mà không cần bất kỳ chỉnh sửa nào. Một trong những ưu điểm khác khi bạn lập trình C trong AVR Studio là bạn có thể tận dùng trình AVR Simulator để debug code C trực tiếp. Đồng thời, trình biên tập (Editor) của AVR Studio cũng giúp bạn viết code thuận tiện hơn Programmer notepad.

Page 6: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 6

Assembly cho AVR

Nội dung Các bài cần tham khảo trước

1. Instruction chỉ dùng cho Register Files. 2. Instruction cho các thanh ghi I/O. 3. Các con trỏ X, Y, Z và cách truy cập toàn bộ không

gian bộ nhớ. 4. Rẽ nhánh và vòng lặp.

• Làm quen AVR. • Cấu trúc AVR. • WinAVR.

Phần này tôi giới thiệu một số instruction mà chúng ta rất hay sử dụng khi lập trình cho AVR. Tôi sẽ chia các instruction này ra thành nhiều nhóm dựa theo phạm vi tác động và chức năng của chúng.

Trước hết chúng ta thống nhất một số cách sử dụng ký hiệu trong cách viết cú pháp của các instruction như sau:

• Rd: thanh ghi nguồn và cũng là đích thuộc Register File. • Rr: thanh ghi nguồn thuộc Register File.

Khái niệm nguồn (Source), đích (Destination) là chỉ các toán hạng và kết quả trong các phép toán đại số và Logic, ví dụ ADD R1, R2 là lệnh cộng 2 giá trị chứa trong 2 thanh ghi R1, R2, trong trường hợp này cả R1 và R2 đều được gọi là nguồn vì chứa giá trị trước khi thực hiện phép cộng. Sau khi phép cộng được thực hiện, kết quả được chứa lại trong R1 và vì thế R1 được gọi là đích trong trường hợp này. R1 vừa là nguồn, vừa là đích trong khi R2 chỉ là nguồn, nếu viết ví dụ này dưới dạng tổng quát sẽ là : ADD Rd, Rr.

• R: kết quả sau khi lệnh được thực thi. • K: hằng số. • k: hằng số chỉ địa chỉ tuyệt đối của thanh ghi. • b: (0 đến 7) số thứ tự bit trong các thanh ghi của Register File và vùng nhớ I/O. • s: (0 đến 7) số thứ tự bit trong thanh ghi trạng thái SREG. • X,Y,X: các thanh ghi địa chỉ tương đối (X=R27:R26, X=R29:R28,

X=R31:R30). • A: địa chỉ I/O. • q: độ dịch chuyển của địa chỉ tuyệt đối.

I. Instruction ch ỉ dùng cho Register Files.

- LDI (LoaD Immediate).

Page 7: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 7

• Cú pháp: LDI Rd,K • Chức năng: Load hằng số K vào thanh ghi Rd. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: LDI R16, 99 kết quả là thanh ghi R1 mang giá trị 99.

- MOV (MOVE).

• Cú pháp: MOV Rd, Rr • Chức năng: Copy giá trị trong thanh ghi Rr vào thanh ghi Rd. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ: MOV R15, R16 kết quả là R15 có cùng giá trị với R16 (R15=R16=99).

- CLR (CLEAR Register).

• Cú pháp: CLR Rd • Chức năng: Copy giá trị trong thanh ghi Rr vào thanh ghi Rd. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ: áp dụng cho tất cả các thanh ghi trong RF.

- SER (SET Register).

• Cú pháp: SER Rd • Chức năng: set tất cả các bit tronh thanh ghi Rd lên 1, sau lệnh này thanh ghi

Rd=0xFF. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: SER R16 kết quả là R16 = 0xFF.

- CBR (CLEAR Bit in Register).

• Cú pháp: CBR Rd, K • Chức năng: xóa các bit trong thanh ghi Rd với “mặt nạ” K, nếu Bit nào trong K

là 1 thì Bit tương ứng trong Rd sẽ bị xóa. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: CBR R16, 0xF0 kết quả là 4 bit cao nhất của R16 bị xóa vì

K=11110000 (B).

- SBR (SET Bit in Register).

• Cú pháp: SBR Rd, K • Chức năng: set các bit trong thanh ghi Rd với “mặt nạ” K, nếu Bit nào trong K

là 1 thì Bit tương ứng trong Rd sẽ được set lên 1. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: SBR R16, 0xF0 kết quả là 4 bit cao nhất của R16 được set lên 1 vì

K=11110000 (B).

- BLD (Bit LoaD from T Flag).

Page 8: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 8

• Cú pháp: BLD Rd,b • Chức năng: Load giá trị trong cờ T của thanh ghi SREG vào bit thứ b trong

thanh ghi Rd. Đây cũng chính là chức năng chính của cờ T. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

SET ; set bit T lên 1 BLD R16, 4 Kết quả là bit 4 của thanh ghi R16 được set lên 1 vì giá trị của bit T là 1.

- BST (Bit Storage from T Flag).

• Cú pháp: BST Rd,b • Chức năng: Copy bit thứ b trong thanh ghi Rd vào trong cờ T của thanh ghi

SREG. Đây cũng chính là chức năng chính của cờ T. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ: BST R16, 4 kết quả là cờ T chứa giá trị của bit 4 của thanh ghi R16.

- CPI (COMPARE with Immediate).

• Cú pháp: CPI Rd, K • Chức năng: so sánh thanh ghi Rd với hằng số K, lệnh này làm thay đổi nhiều bit

trong thanh ghi SREG trong đó sự thay đổi của cờ Zero là quan trọng nhất, nếu Rd = K cờ Z=1, ngược lại Z=0, sử dụng đặc điểm thay đổi của cờ Z kết hợp với lệnh BRNE hoặc BREQ chúng ta có thể tạo thành một lệnh rẽ nhánh.

• Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ:

LDI R16, 10 CPI R16, 10 Kết quả là cờ Z được set thành 1 vì lúc này R16 =10.

- ANDI (AND with Immediate).

• Cú pháp: ANDI Rd, K • Chức năng: thực hiện phép Logic AND giữa thanh ghi Rd với hằng số K và kết

quả đặt lại trong Rd. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: ANDI R17, 0x00 kết quả là R17 có 0x00.

- AND (Logical AND).

• Cú pháp: AND Rd, Rr • Chức năng: thực hiện phép Logic AND giữa 2 thanh ghi Rd và Rr , kết quả đặt

lại trong Rd. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R1, 0xFF ;(11111111)

Page 9: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 9

LDI R17, 0xAA; (10101010) AND R1, R17 Kết quả là R1=0xAA vì 11111111 & 10101010 =10101010.

- ORI (Logical OR with Immediate).

• Cú pháp: ORI Rd, K • Chức năng: thực hiện phép Logic OR giữa thanh ghi Rd với hằng số K và kết

quả đặt lại trong Rd. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ: ORI R17, 0xFF kết quả là R17 có 0xFF.

- OR (Logical OR).

• Cú pháp: OR Rd, Rr • Chức năng: thực hiện phép Logic OR giữa 2 thanh ghi Rd và Rr , kết quả đặt lại

trong Rd. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R1, 0xFF ;(11111111) LDI R17, 0xAA; (10101010) OR R1, R17 Kết quả là R1=0xFF vì 11111111 or 10101010 =11111111.

- LSL (Logical Shift Left).

• Cú pháp: LSL Rd • Chức năng: dịch tất thanh ghi Rd sang trái 1 vị trí, Bit 7 (bit lớn nhất) của Rd sẽ

được chứa trong cờ nhớ C, bit 0 của Rd bị xóa thành 0. Thực chất LSL tương đương với phép nhân thanh ghi Rd với 2. Bạn xem hình minh họa bên dưới.

• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R1, 0B11000011 ; (dạng nhị phân của 195) LSL R1

Kết quả là R1=10000110 và cờ C =1 vì thanh ghi R1 đã được dịch sang trái 1 vị trí, trước khi dịch bit 7 của R1 là 1 nên sau khi dịch bit này được chứa trong C, cho nên C=1.

- LSR (Logical Shift Right).

Page 10: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 10

• Cú pháp: LSR Rd • Chức năng: dịch tất thanh ghi Rd sang phải 1 vị trí, Bit 0 (bit nhỏ nhất) của Rd

sẽ được chứa trong cờ nhớ C, bit 7 của Rd bị xóa thành 0. Thực chất LSR tương đương với phép chia thanh ghi Rd cho 2. Bạn xem hình minh họa bên dưới.

• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R1, 0B11000110 ; (dạng nhị phân của 195) LSR R1

Kết quả là R1=01100001 và cờ C =1 vì thanh ghi R1 đã được dịch sang phải 1 vị trí, trước khi dịch bit 0 của R1 là 1 nên sau khi dịch bit này được chứa trong C, cho nên C=1.

- ADD (ADD without Carry).

• Cú pháp: ADD Rd, Rr • Chức năng: thực hiện phép cộng 2 thanh ghi Rd và Rr , kết quả đặt lại trong Rd.

Cờ nhớ C không được sử dụng. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R16, 30 LDI R17, 25 ADD R16, R17 Kết quả là R16=55.

- INC (INCrement).

• Cú pháp: INC Rd • Chức năng: tăng thanh ghi Rd 1 đơn vị và kết quả đặt lại trong Rd. Lệnh này

đặc biệt thích hợp cho các ứng dụng lặp, kết hợp với BREQ hay BRNE có thể tạo thành 1 vòng lặp FOR.

• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ: INC R17 kết quả là R17 được tăng thêm 1 đơn vị.

- SUB (SUBtract without Carry).

• Cú pháp: SUB Rd, Rr • Chức năng: thực hiện phép trừ 2 thanh ghi Rd - Rr , kết quả đặt lại trong Rd. Cờ

nhớ C không được sử dụng. • Giới hạn: áp dụng cho tất cả các thanh ghi trong RF.

Page 11: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 11

• Ví dụ: LDI R16, 30 LDI R17, 25 SUB R16, R17 Kết quả là R16=5.

- SUBI (SUBtract Immediate).

• Cú pháp: SUBI Rd, K • Chức năng: thực hiện phép trừ thanh ghi Rd với hằng số K, kết quả đặt lại

trong Rd. • Giới hạn: chỉ áp dụng cho các thanh ghi từ R16 đến R31. • Ví dụ:

LDI R16, 30 SUBI R16, 20 Kết quả là R16=10.

- DEC (DECrement).

• Cú pháp: DEC Rd • Chức năng: giảm thanh ghi Rd 1 đơn vị và kết quả đặt lại trong Rd. Lệnh này

đặc biệt thích hợp cho các ứng dụng lặp, kết hợp với BREQ hay BRNE có thể tạo thành 1 vòng lặp FOR.

• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ: DEC R17 kết quả là R17 được giảm đi 1 đơn vị.

- MUL (MULtiply unsigned).

• Cú pháp: MUL Rd, Rr • Chức năng: thực hiện phép nhân không dấu 2 thanh ghi 8 bit Rd, Rr, kết quả là

1 số 16 bit đặt trong 2 thanh ghi R1:R0. Chú ý nếu Rd và Rr là các thanh ghi R1 và R0 thì kết quả sau khi tính được sẽ được viết đè lên. Xem hình minh họa instruction MUL bên dưới.

• Giới hạn: áp dụng cho tất cả các thanh ghi trong RF. • Ví dụ:

LDI R16, 30 LDI R17, 25

Page 12: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 12

MUL R16, R17 Kết quả là R1=0x2, R0=0xEE, vì 30x25=750=0x02EE.

II. Instruction cho các thanh ghi I/O.

Bốn instruction sau đây được thiết kế riêng để truy cập vùng nhớ I/O, các instruction này sử dụng địa chỉ I/O của các thanh ghi trong vùng nhớ này. Vì là thiết kế riêng cho vùng nhớ I/O, bạn không thể sử dụng các thanh ghi này để truy cập RF hay SRAM. Trong các cú pháp của instruction này, khái niệm địa chỉ A là địa chỉ I/O, 0 ≤ A ≤ 63, nếu trong ví dụ A=0x00 thì đó là thanh ghi đầu tiên của vùng I/O, không phải là thanh ghi R0.

- OUT (OUTPUT Data).

• Cú pháp: OUT A, Rr • Chức năng: xuất giá trị từ thanh ghi Rr ra thanh ghi có địa chỉ A trong vùng

nhớ I/O. đây là cách phổ biến nhất để xuất giá trị ra vùng I/O. • Giới hạn: Rr là thanh ghi RF bất kỳ, A bị giới hạn từ 0 đến 63. • Ví dụ:

LDI R16, 0xFF OUT 0x11, R16 Kết quả là thanh ghi có địa chỉ 0x11 trong vùng I/O, tức thanh ghi DDRD, có giá trị bằng 0xFF.

- IN (INPUT Data).

• Cú pháp: IN Rr, A • Chức năng: Load giá trị từ thanh ghi có địa chỉ A trong vùng nhớ I/O vào thanh

ghi Rr. Đây là cách phổ biến nhất để nhận giá trị từ vùng I/O. • Giới hạn: Rr là thanh ghi RF bất kỳ, A bị giới hạn từ 0 đến 63. • Ví dụ:

IN R16, 0x10 Kết quả là thanh ghi R16 nhận được giá trị của thanh ghi có địa chỉ 0x11 trong vùng I/O, tức thanh ghi PIND, đây chính là ví dụ đọc giá trị các chân của PORTD vào R16.

- SBI (Set Bit in I/O Register).

• Cú pháp: SBI A, b • Chức năng: Set bit thứ b trong thanh ghi có địa chỉ A trong vùng nhớ I/O. Tuy

nhiên lệnh này không có tác dụng trên toàn bộ vùng I/O mà chỉ có tác đối với 32 thanh ghi đầu (địa chỉ từ 0 đến 31).

• Giới hạn: b là số thứ các bit trong thanh ghi, 0≤b≤7; A bị giới hạn từ 0 đến 31. • Ví dụ:

SBI 0x12, 2

Page 13: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 13

Kết quả là bit 2 của thanh ghi có địa chỉ 0x12 trong vùng I/O, tức thanh ghi PORTD, được set lên 1. Đây chính là ví dụ set chân PD2 của PORTD.

- CBI (Clear Bit in I/O Register).

• Cú pháp: CBI A, b • Chức năng: xóa bit thứ b trong thanh ghi có địa chỉ A trong vùng nhớ I/O. Tuy

nhiên lệnh này không có tác dụng trên toàn bộ vùng I/O mà chỉ có tác đối với 32 thanh ghi đầu (địa chỉ từ 0 đến 31).

• Giới hạn: b là số thứ các bit trong thanh ghi, 0≤b≤7; A bị giới hạn từ 0 đến 31. • Ví dụ:

CBI 0x12, 2 Kết quả là bit 2 của thanh ghi có địa chỉ 0x12 trong vùng I/O, tức thanh ghi PORTD, bị xóa thành 0. Đây chính là ví dụ xóa chân PB2 của PORTD.

III. Các con tr ỏ X, Y, Z và cách truy cập toàn bộ không gian bộ nhớ.

Trong Register File của AVR, các thanh ghi từ R26 đến R31ngoài chứa năng thanh ghi thông thường còn có chức năng là con trỏ (Pointer) trong việc truy cập bộ nhớ (cả bộ nhớ data và bộ nhớ Program). Nếu được sử dụng như các Pointer, các thanh ghi trên được biết đến với tên gọi X, Y, Z. Định nghĩa như sau: X=R27:R26, Y=R29:R28, Z=R31:R30. Chúng là 3 thanh ghi 16 bit được định nghĩa trước cho tất cả các AVR. Ngoài ra trong các file định nghĩa cho chip chúng ta có thêm 6 định nghĩa khác là XL, XH, YL, YH, ZL, ZH cũng chính là tên gọi của R26-> R31. Phần này chúng ta khảo sát một số instruction dùng truy cập toàn bộ khồi nhớ của AVR bằng cách sử dụng địa chỉ trực tiếp và bằng cách sử dụng Pointer.

- LDS (LoaD direct from data Space).

• Cú pháp: LDS Rd, k • Chức năng: load giá trị 1 byte từ thanh ghi có địa chỉ k trong SRAM vào thanh

ghi Rd, k là dạng địa chỉ tuyệt đối có giới hạn từ 0 đến 65535(2^16-1). • Giới hạn: Rd là thanh ghi bất kỳ trong RF nhưng giá trị lớn nhất của k là 65535,

vì thế với lệnh này ta không thể truy cập vượt quá khoảng không gian 64KB. Nếu muốn truy cập vùng không gian lớn hơn 64KB chúng ta cần một số hỗ trợ, tuy nhiên ở đây tôi giả sử bộ nhớ của chip (thường là bộ nhớ data) không vượt quá 64KB (thực tế chưa có chip AVR nào có SRAM hay EEPROM vượt quá 64KB).

• Ví dụ: LDS R2, 0x0060 Kết quả là thanh ghi R2 chứa giá trị của thanh ghi có địa chỉ 0x0060, đây là thanh ghi đầu tiên trong khoảng SRAM (sau RF và vùng I/O) của AVR.

- STS (STorage direc to data Space).

• Cú pháp: STS k, Rr

Page 14: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 14

• Chức năng: instruction này hoàn toàn giống LDS nhưng dùng để xuất dữ liệu từ thanh ghi Rr ra RAM, ngươi đọc có thể tham khảo phần giải thích cho LDS.

Sử dụng địa chỉ trực tiếp thì câu lệnh sẽ đơn giản nhưng rất khó nhớ phần địa chỉ, thông thường SRAM là vùng chúng ta hay sử dụng để chứa biến tạm thời, trong các ngôn ngữ cấp cao ta chỉ cần nhớ tên biến nhưng với ASM chúng ta phải nhớ địa chỉ của chúng. Một cách tốt để tránh việc này là dùng chỉ thị (DIRECTIVE, bạn xem lại bài 1) . EQU để gán tên biến cho 1 địa chỉ, ví dụ .EQU bientam = 0x0060 và sau đó sử dụng bientam thay cho 0x0060.

Một cách khác được dùng để truy cập bộ nhớ mà không dùng địa chỉ tuyệt đối là sử dụng sử dụng con trỏ. Có 2 instruction hỗ trợ con trỏ là LD(LoaD indirec from data Space), và ST (STorage indirec to data Space), LD đọc dữ liệu từ SRAM vào thanh ghi còn ST lưu dữ liệu từ thanh ghi vào SRAM. Cả 3 con trỏ X, Y và Z đều có thể được dùng nhưng có một số điểm lưu ý: cả 3 đều dùng được trong trường hợp truy xuất thông thường nhưng với cách truy cập có offset, con trỏ X không sử dụng được. Để truy xuất bộ nhớ chương trình bằng con trỏ thì Z là giải pháp duy nhất…Dưới đây là 1 số cách sử dụng LD, ST kết hợp với con trỏ, chúng ta xét thông qua các ví dụ.

Ví dụ 1:

CLR R27 ; xóa R27, tức xóa byte cao của pointer X LDI R26, 0x60 ; load giá trị 0x60 vào R26, tức byte thấp của pointer X ; sau 2 dòng trên, giá pointer X là 0x0060, sẵn sàng để trỏ đến vị trí đầu tiên trong SRAM. LD R1, X+ ; Load giá trị ở ố nhớ 0x0060 vào R1 (vì X trỏ đến 0x0060), sao đó tăng giá trị ;X lên 1, như thế sau lệnh này X=0x0061 LD R2, X+ ; Load giá trị ở ố nhớ 0x0061 vào R2, sao đó tăng giá trị ;X lên 1, như thế sau lệnh này X=0x0062 LD R3, X ; Load giá trị ở ô nhớ 0x0062 vào R3 và không thay đổi X LD R4, -X ; Giảm giá trị của X trước (X=0x0061), sau đó load giá trị ở ô nhớ 0x0061 vào R4

Từ ví dụ này chúng ta thấy có 3 cách cơ bản để load dữ liệu từ SRAM bằng con trỏ, cách Load trực tiếp trong trường hợp LD R3, X, cách load post-increment (hoặc post-decrement) như trong trường hợp LD R1, X+ và cách load pre-decrement (hoặc pre-increment) trong trường hợp LD R4, -X.

Chúng ta có thể viết lại ví dụ trên nhưng sử dụng con trỏ Y hoặc Z thay cho X. Ví dụ viết cho instruction ST cũng hoàn toàn tương tự.

Tuy nhiên cách truy cập theo cách pre hay post đều làm thay đổi giá trị của con trỏ, điều này có 1 bất lợi là nếu chúng ta muốn quay lại vị trí ô nhớ nào đó, chúng ta phải tiếp tục thay đổi con trỏ. Để tránh việc làm này, 1 cách truy cập khác được hỗ trợ là truy cập “Offset”. Xét ví dụ sau:

Page 15: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 15

LD R1, Y+1

Đây chính là cách truy cập Offset dùng con trỏ Y, cách viết trên là tương đương với cách viết

LD R1, Y+

Nhưng điểm khác biệt ở đây là cách viết Offset không làm thay đổi giá trị của con trỏ Y. Sử dụng Offset có ưu điểm như sử dụng mảng (array) trong các ngôn ngữ lập trình cấp cao. Cần chú ý là giá trị offset không vượt quá 63 và phương pháp này chỉ dùng cho 2 thanh ghi Y và Z.

IV. Rẽ nhánh và vòng lặp.

Không giống như các ngôn ngữ cấp cao, khi lập trình bằng ASM bạn không được hỗ trợ các cấu trúc điều khiển như If, For, While…người lập trình ASM phải tự xây dựng cho mình các cấu trúc này từ những instruction cơ bản. Nếu bạn có trong tay tài liệu tra cứu instruction cho AVR bạn sẽ thấy có rất nhiều instruction có dạng BRxx, với BR là viết tắt của từ Branch (rẽ nhánh). Đây là các instruction cơ bản giúp bạn xây dựng các cấu trúc điều khiển tương đương If, For, While…cho riêng mình.

Trước hết ta sẽ khảo sát instruction BRNE bằng cách xem lại ví dụ trong bài "Làm quen AVR", đây là đoạn chương trình con DELAY:

DELAY: LDI R20, 0xFF DELAY0: LDI R21, 0xFF DELAY1: DEC R21 BRNE DELAY1 DEC R20 BRNE DELAY0 RET

Bạn hãy chú ý 4 dòng lệnh nằm giữa đoạn chương trình trên (bắt đầu từ dòng 4), dòng đầu tiên thì bạn đã biết - load giá trị 255 vào thanh ghi R21, sau đó tôi đặt 1 label DELAY1- xem như là 1 cột mốc, dòng 3, instruction DEC bạn mới được học hôm nay - giảm giá trị thanh ghi R21 đi 1 đơn vị, và cuối cùng BRNE DELAY1, BRNE là viết tắt của BRanch if Not Equal – rẽ nhánh nếu không bằng, thực ra bản chất của lệnh này là rẽ nhánh nếu cờ Zero không bằng 1. Như thế câu lệnh BRNE DELAY1 của chúng ta được AVR thực hiện như sau: kiểm tra cờ Z, nếu Z=1 tiếp tục thực hiện dòng tiếp theo sau mà không quan tâm đến nhãn DELAY1, nhưng nếu Z=0 thì nhảy đến nhãn DELAY1. Bạn thấy rằng ban đầu R21 =255, sau khi giảm 1 bởi DEC, thanh ghi R21=254≠0, cờ Z =0, rẽ nhánh xảy ra, bộ đếm chương trình nhảy về nhãn DELAY1. Quá trình này lặp lại khoảng 255 lần trước khi R21 =0 dẫn đến Z=1.

Page 16: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 16

Bao bên ngoài vòng lặp của nhãn DELAY1 là vòng lặp của nhãn DELAY0, cách hiểu hoàn toàn tương tự nhưng trước khi lệnh DEC R20 được thực thi thì phải chờ cho vòng lặp DELAY1 kêt thúc. Bản thân DELAY0 cũng là 1 vòng lặp 255 lần. kết quả cuối cùng là ta thu được 1 vòng lặp khoảng 255x255 lần mà không làm gì cả, đó chính là ý nghĩa và cách hoạt động của đoạn chương trình con DELAY.

Bên cạnh BRNE chúng ta có 1 số instruction phục vụ rẽ nhánh khác như:

- BREQ (BRanch if EQual).

• Cú pháp: BREQ LABEL • Chức năng: Nhảy đến nhãn LABEL nếu cờ Z =1. Cờ Z chịu tác động của rất

nhiều instruction như CP, CPI, SUB, SUBI…vì thế BREQ thường được sử dụng sau các instruction này.

• Ví dụ: LDI R16, 0xFF LDI R17, 0xFF CP R16, R17 ; so sanh 2 thanh ghi R16, R17 BREQ RENHANH ….. RENHANH: ; thực hiện những việc khi rẽ nhánh. Kết quả là việc rẽ nhánh xảy ra vì khi so sánh bằng CP, R17=R16 nên cờ Z tự động được set bằng 1, lệnh BREQ được thực thi và nhảy đến nhãn RENHANH. Ví dụ này tương đương cấu trúc if (R16=R17) {thực hiện những việc khi rẽ nhánh}.

- BRLO (BRanch if LOwer).

• Cú pháp: BRLO LABEL • Chức năng: bản chất của câu lệnh là nhảy đến nhãn LABEL nếu cờ C =1. Tuy

nhiên, thông thường lệnh này sử dụng theo sau các instruction như CP, CPI, SUB, SUBI…khi đó việc rẽ nhánh sẽ xảy ra nếu thanh ghi Rd

• Ví dụ: EOR R16, R16 ;XOR R16 với chính nó, tương đương CLR R16 VONG LAP: INC R16 ;tăng R16 thêm 1 đơn vị CPI R16, $10 ;so sánh R16 với số hexadecimal $10 BRLO VONGLAP ;nhảy về VONGLAP nếu R16 <$10 NOP ;câu lệnh này sẽ được thực thi nếu điều kiện rẽ nhánh ở trên không thỏa, ; NOP là 1 instruction, chức năng là không làm gì cả. Kết quả là phần lệnh bên trong VONGLAP sẽ được thưc hiện khoảng 16 lần ($10=16) trước khi thực hiện lệnh NOP.

- BRSH (BRanch if Same or Higher).

Page 17: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 17

• Cú pháp: BRSH LABEL • Chức năng: bản chất của câu lệnh là nhảy đến nhãn LABEL nếu cờ C =0. Tuy

nhiên, thông thường lệnh này sử dụng theo sau các instruction như CP, CPI, SUB, SUBI…khi đó việc rẽ nhánh sẽ xảy ra nếu thanh ghi Rd ≥Rr.

• Ví dụ: SUBI R16, 4 ;trừ R16 đi 4 đơn vị BRSH RENHANH ; nhảy đến RENHANH nếu R16 ≥ 4 …. RENHANH: NOP …

Còn rất nhiều instruction rẽ nhánh bạn có thể sử dụng để tạo cấu trúc điều khiển, chú ý là các instruction này đều hoạt động dựa trên trạng thái của 1 cờ nào đó, do đó bạn cần lựa chọn 1 lệnh phù hợp để thực thi trước các instruction rẽ nhánh này, để làm được như vậy bạn cần xem kỹ tài liệu hướng dẫn INSTRUCITON cho AVR.

Page 18: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 18

Mô phỏng chương trình với Proteus

Nội dung Các bài cần tham khảo trước

1. Vẽ mạch điện trong Proteus. 2. Nạp chương trình và mô phỏng.

• Làm quen AVR.

Proteus VSM (Virtual Simulation Machine) của Labcenter Electronics là phần mềm mô phỏng mạch điện rất được ưa thích hiện nay. So với các phần mềm mô phỏng mạch điện tử khác, Proteus có nhiều ưu điểm nổi trội như: mô phỏng được rất nhiều linh kiện điện tử và các thiết bị hiển thị, kết quả mô phỏng rất trực quan như một mạch điện tử thật. Và một tính năng mà chúng ta, những người học vi điều khiển, quan tâm nhất là khả năng mô phỏng các chip vi điều khiển với chương trình do người dùng nạp. Proteus hỗ trợ rất nhiều các chip vi điều khiển như 8051, AVR, PIC, HC11, ARM7/LPC2000... Nếu bạn đang muốn học AVR mà không có điều kiện hoặc kinh nghiệm để làm các mạch phát triển hoặc bạn muốn kiểm tra chương trình trước khi nạp vào mạch phát triển thì Proteus là lựa chọn không thề bỏ qua.

Trong các bài hướng dẫn AVR trên website này, tôi chủ yếu dùng Proteus để mô phỏng minh họa các ví dụ lập trình. Vì thế trong phần này tôi sẽ hướng dẫn cơ bản cách sử dụng Proteus để vẽ và mô phỏng một mạch điển đơn giản với AVR. Tôi dùng mạch quét LED trong bài "Làm quen AVR" để minh họa.

Trước hết, bạn hãy download bản demo Proteus từ website Labcenter Electronics hoặc ở đây. Sau khi cài đặt phần mềm chúng ta sẽ thực hiện tuần tự các bước sau để tạo điện quét LED.

I. Vẽ mạch điện.

Chạy Proteus: sau đó nhấn vào buton “Components” rồi “Pick Devices” để chọn linh kiện.

Page 19: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 19

Hình 1. Giao diện Proteus.

Chọn linh ki ện: trong dialog Pick Divices, ô “Keywords” nhập mega8, bạn sẽ thấy 1 linh kiện có tên “ATMEGA8” bên cửa sổ “Results”, double click vào linh kiện đó để mang nó ra cửa sổ “Object selector”.

Page 20: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 20

Hình 2. Chọn linh kiện.

Để tìm điện trở, bạn đánh keyword “res”, chọn “Resistors” trong “category” và Double click vào link kiện “RES” trong ô “Results”.

Page 21: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 21

Hình 3. Chọn điện trở.

Thực hiện tương tự để chọn GREEN - LED bằng keyword “green led”.

Hình 4. Chọn Green LED.

Sau khi chọn 3 loại linh kiện cần thiết bạn hãy nhấn OK và quay về cửa số chính, khi đó bạn thấy trong cửa sổ “Object selector” như sau:

Page 22: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 22

Hình 5. Các link kiện cần cho mô phỏng.

Thao tác với mouse trong Proteus: khác với 1 số chương trình vẽ mạch điện khác, tháo tác mouse trong Proteus hơi lạ nên có thể gây bối rối cho bạn, hãy theo hướng dẫn sau đây:

• Chọn linh kiện để vẽ: left – click lên tên linh kiện trong cửa sổ “Object selector”.

• Đặt linh kiện: Left – click lên cửa sổ mạch điện Right click lên linh kiện trong cửa số mạch điện sẽ làm cho linh kiện đó được bao bởi màu “đỏ”, tức bạn đang chọn linh kiện đó.

• Bỏ chọn linh kiện: thực hiện bằng cách Right – click lên một vị trí trống trên cửa sổ mạch điện.

• Delete linh kiện: Right – click 2 lần lên 1 linh kiện là delete linh kiện đó khỏi cửa sổ mạch điện, hoặc Right click 1 lần lên 1 linh kiện đã được chọn trước đó (có màu đỏ) cũng sẽ xóa linh kiện này.

• Di chuyển linh kiện: chọn linh kiện trước (right – click) và drag để di chuyển linh kiện bằng mouse left.

• Xoay và lật linh kiện: chọn linh kiện cần xoay hay lật (right – click), dùng các nút công cụ để xoay hoặc lật linh kiện.

Hình 6. Các nút công cụ xoay và lật linh kiện.

• Hiện cửa sổ thuộc tính linh kiện: rất nhiều khi bạn cần thay đổi 1 số thuộc tính của linh kiện (ví dụ giá trị của điện trở), bạn thực hiện điều này trong cửa sổ thuộc tính của linh kiện. Để hiện cửa sổ thuộc tính của 1 linh kiện bạn hãy right – click trước (để chọn linh kiện – linh kiện sẽ đỏ lên) và sau đó left – click sau.

Page 23: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 23

Theo hướng dẫn trên, bạn hãy click vào ATMEGA8 và đặt linh kiện này lên mạch điện của bạn (đặt lên cửa sổ làm việc lớn) bằng cách left - click lên bất vị trí nào trên cửa sổ mạch điện. Thực hiện tương tự cho 8 LED và 1 điện trở như hình vẽ bên dưới.

Hình 7. Đặt linh kiện lên mạch điện.

Tiếp theo là đặt “Ground” cho LED, nhấn vào nút công cụ “Inter – sheet Terminal” như hình bên dưới.

Page 24: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 24

Hình 8. Nút công cụ Inter – sheet Terminal.

Bạn thấy trong cửa sổ “Object devices” có 1 số thiết bị, hãy chú ý dến “POWER” và “GROUND”, đây là nguồn và mass cho mạch điện của bạn. Hãy chọn GROUND và đặt lên mạch điện của bạn.

Bước tiếp theo, nối dây: không cần công cụ, để nối dây bạn chỉ cần rê mouse đến điểm cần nối của linh kiện, bạn sẽ thấy xuất hiện 1 dấu chéo “x”, lúc đó hãy click mouse và di chuyển (không cần giữ mouse) đến vị trí tiếp theo và click lần nữa.

Hình 9. Nối dây.

Theo cách này bạn hãy nối dây cho mạch điện của bạn, mạch điện hoàn chỉnh như sau.

Page 25: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 25

Hình 10. Sau khi nối dây.

Bây giờ hãy thay đổi giá trị của điện trở, giá trị mặc định là 10k, giá trị này quá lớn, dòng điện sẽ rất nhỏ, khi mô phỏng bạn sẽ không thấy các LED sáng lên. Bạn hãy thay đổi nó thành 100 (100 Ohm). Trước hết cho hiện cửa sổ thuộc tính của điện trở (right click rồi left click lên điện trở), thay đổi ô resistance của nó.

Page 26: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 26

Hình 11. Thay đổi giá trị của điện trở.

II. N ạp chương trình và mô phỏng.

Đổ chương trình vào chip Atmega8: hãy hiện cửa sổ thuộc tính của chip Atmega8, trong ô “Program file” hãy click và tìm đến file “avr1.hex” mà bạn đã tạo trong thư mục Project của bài AVR1 sau khi biên dịch. Chú ý thay đổi thông số “Clock frequency” là 1 Mhz.

Hình 12. Đổ chương trình cho chip.

Hãy lưu mạch điện của bạn và việc cuối cùng là chạy mô phỏng, sử dụng thanh công cụ Play để chạy mô phỏng mạch điện của bạn, kết quả như sau.

Page 27: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 27

Hình 13. Kết quả mô phỏng.

Page 28: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 28

Lập trình với WinAVR

Nội dung Các bài cần tham khảo trước

1. Giới thiệu WinAVR. 2. Khởi động cùng Programmer Notepad.

Download WinAVR

• Làm quen AVR. • Cấu trúc AVR.

WinAVR là công cụ chính tôi dùng trong các bài hướng dẫn sử dụng các modules trên chip AVR bằng ngôn ngữ C. Tuy nhiên, bài này tôi không nói về lập trình C mà chủ yếu hướng dẫn cách cài đặt và sử dụng WinAVR. Tôi sẽ dùng ví dụ quét LED của bài "Làm quen AVR" để minh họa, nhưng phần code sẽ được viết lại bằng ngôn ngữ C thay cho ASM.

I. Giới thi ệu WinAVR.

Tại sao C: như tôi đã trình bày ở các bài học trước, khi bạn đã hiểu về AVR, để thực hiện các ứng dụng, bạn có thể không nhất thiết phải luôn lập trình bằng ASM. Ngôn ngữ cấp cao như C sẽ giúp cho bạn xây dựng các ứng dụng nhanh chóng và dễ dàng hơn, tuy nhiên không vì thế mà bạn “quên” ASM, lập trình bằng C kết hợp ASM là giải pháp hay nhất. Một chú ý là chúng ta chỉ sử dụng C để đơn giản hóa lập trình tính toán, cấu trúc điều khiển…lập trình C cho AVR không có nghĩa là bạn không cần biết cấu trúc và cách thức hoạt động của chip!!!

Tại sao WinAVR: WinAVR (đọc là Whenever: theo tác giả của WinAVR) là một bộ phần mềm mã nguồn mở bao gồm các công cụ cho dòng vi điều khiển AVR . WinAVR chạy trên nền hệ điều hành Windows, nó bao gồm các công cụ sau:

• Trình biên dịch avr-gcc: GNU GCC là trình biên dịch C, C++ phát triển bởi cộng đồng mã nguồn mở GNU, avr-gcc phát triển riêng cho AVR.

• Chương trình nạp chip avrdude. • Chương trình debugger avr-gdb. • Programmer Notepad: trình biên tập code hỗ trợ nhiều ngôn ngữ như C, C++,

CSS, HTML, Java,… • MFile: tiện ích tạo các file Makefile dùng trong quá trình biên dịch code…

Cốt lõi của WinAVR là trình biên dịch GNU GCC và thư viện avr-libc, đây là bộ công cụ lập trình C miễn phí hoàn chỉnh duy nhất cho AVR. Có thể nói bộ công cụ này góp phần không nhỏ giúp cho chip AVR ngày càng trở nên phổ biến. WinAVR liên tục được cập nhật và hoàn thiện bởi rất nhiều người, nguồn tài liệu và chương trình mẫu viết bằng công cụ này là rất lớn…Đây là những lí do chính khiến tôi chọn WinAVR để giới thiệu với bạn.

Page 29: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 29

Download và cài đặt: có 2 cách để bạn cài đặt bộ công cụ C cho AVR, cách thứ nhất, bạn download từng phần gồm binutils, gnu-gcc, avr-libc, và avrdude…rồi cài đặt (cách này thường được sử dụng trên hệ điều hành Linux…tôi sẽ giới thiệu trong 1 tài liệu khác) và cách thứ 2 là dùng WinAVR (dành cho windows). Bạn có thể download trực tiếp phiên bản mới nhất tại website chính thức của WinAVR: http://winavr.sourceforge.net/index.html. Quá trình cài đặt tương đối dễ dàng vì bạn có thể chỉ cần làm theo các lựa chọn mặc định. Sau khi cài đặt WinAVR vào máy (tôi giả sử thư mục cài đặt của bạn là C:\WinAVR) bạn sẽ có đầy đủ bộ công cụ từ IDE (Integrated Development Environment) để biên tập code, trình biên dịch, linker, chương trình nạp chip, tiện ích tạo Makefile…

Programmer Notepad (pn): Programmer Notpad là phần mềm môi trường phát triển tích hợp (IDE) miễn phí cho việc lập trình các ngôn ngữ như C, C++, CSS, HTML, Java,…Tuy giao diện của pn khá đơn giản nhưng đây là công cụ rất hoàn hảo và được tích hợp sẵn trong WinAVR, avr-gcc lugin được tích hợp sẵn trong pn cho WinAVR nên chúng ta có thể biên dịch code, download chương trình vào chip trực tiếp với pn. (có thể tham khảo thêm về pn tại website http://www.pnotepad.org) (chú ý, bạn có thể viết code cho avr-gcc bằng AVRStudio, Eclipse IDE hay ngay cả với Windows Notepad...).

MFile : để biên dịch 1 chương trình bằng trình biên dịch gnu gcc, bạn cần 1 file tên là Makefile không có phần mở rộng, file này chứa thông tin cần thiết như thông tin về trình biên dịch, target (tên các file code cần dịch), loại chip, trình nạp chip…MFile là tiện ích giúp chúng ta tạo các Makefile nhanh chóng và chinh xác. MFile được tích hợp sẵn trong WinAVR.

II. Kh ởi động cùng Programmer Notepad (pn).

Sau khi cài đặt WinAVR, trên desktop của bạn có thể sẽ xuất hiện 2 icon của pn và MFile như trong hình 1.

Hình 1. Icons trên Desktop

Phần này chúng ta tìm hiểu cách viết một chương trình C trong pn thông qua 1 ví dụ đơn giản. Từ Desktop, hãy khởi động pn, lần đầu chạy pn bạn sẽ thấy giao diện của chương trình như trong hình 2.

Page 30: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 30

Hình 2. Giao diện pn

Trước hết chúng ta hãy cài đặt thêm một số tính năng vào pn bao gồm chức năng tạo ra file coff (dùng mô phỏng với AVR Studio Simulator) và chức năng vừa biên dịch vừa nạp chip. Từ menu chính của pn, chọn menu “Tool > Option”, bạn sẽ thấy hộp thoại Option xuất hiện, hãy chọn mục Tool trong hộp thoại Option rồi nhấn button “Add” như trong hình 3.

Page 31: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 31

Hình 3. Option cho pn.

Trong hộp thoại “New Tool Properties” hãy đặt các thông số như trong hình 4:

Hình 4. Add chức năng tạo file COFF cho pn.

Lặp lại các bước trên để add thêm chức năng vừa biên dịch vừa đổ chương trình vào pn (xem hình 5).

Page 32: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 32

Hình 5. Add chức năng Make và Program cho pn.

Nhấn “OK” để kết thúc cài đặt, click vào menu Tools bạn sẽ thấy có 2 lệnh mới được add vào, chúng ta sẽ sử dụng chúng sau này.

Hình 6. Tools menu.

Khi add các chức năng mới vào pn, bạn chú ý 2 mục là command và parameters, command thì luôn là “make” vì đây chính là lệnh “đa năng” khi làm việc với trình biên dịch gnu-gcc. Parameters là các thông số gởi kèm với lệnh make, như vậy khi bạn click vào 1 dòng lệnh mới tạo ra, pn sẽ yêu cầu trình dịch gcc thực hiện lệnh make với thông số mà bạn đã tạo.

Page 33: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 33

Chúng ta đã sẵn sàng để viết ví dụ đầu tiên bằng WinAVR. Từ pn, chọn menu “File>New>Project” , bạn chọn nơi lưu Project của bạn (ví dụ C:\WinAVR\My Project) và hãy đặt tên cho Project của bạn là AVR1-gcc vì chúng ta sẽ viết lại ví dụ cho bài AVR1 bằng C.

Hãy type đoạn code sau vào của sổ “new” (phần bên phải trong pn)

List 1. ví dụ quét LED bằng C.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

//file: main.c //Description: AVR1 by GCC, "Cung hoc AVR" Series #include <avr/io.h> #include <util/delay.h> unsigned char val=1; int main(void){ DDRB=0xFF; //set PORTB as output lines while(1){ PORTB=val; _delay_loop_2(65000); val*=2; if (!val) val=1; } return 0; }

Chọn “File>save” để lưu đoạn code trên thành 1 file có tên là main.c.

Trong vùng “Project” (phần bên trái), click phải vào Project “AVR1-gcc” rồi chọn “Add Files”, hãy add file “main.c” vào Project của bạn.

Hãy thử biên dịch Project của bạn bằng cách chọn menu “Tools>[WinAVR] Make All”, quan sát vùng thông báo biên dịch (nằm ở phía dưới) bạn sẽ thấy thông báo như sau:

Nghĩa là có lỗi trong quá trình biên dịch, quá trình biên dịch thất bại vì “No rule to make target ‘all’.” Lỗi này do Project của chúng ta không có file Makefile. Hãy tạo 1 file Makefile bằng tiện ích MFile.

Page 34: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 34

Từ Desktop, chạy chương trình MFile, giao diện của MFile rất đơn giản như trong hình 7 (chú ý: chúng ta có thể thêm bớt các cài đặt cho MFile bằng cách chỉnh sửa file mfile.tcl trong thư mục cài đặt của WinAVR).

Hình 7. Chương trình tiện ích MFile.

Hãy chọn menu “Makefile>Main file name”, một hộp thoại nhỏ xuất hiện, điền tên file chính trong Project của bạn (trong trường hợp của chúng ta ở đây là “main”), nhấn “OK”. Ti ếp tục chọn “Makefile > MCU type > ATmega > atmega8”. Đối với Project ví dụ này, chỉ cần set 2 tham số tên file và loại chip như trên là đủ, bạn chọn “File>save as” và lưu Makefile vào chung thư mục chứa Project (C:\WinAVR\My Project trong trường hợp của tôi). Bạn đã có thể tắt chương trình MFile.

Trở lại pn, chọn menu “Tools>[WinAVR] Make All” lần nữa để biên dịch, lần này bạn sẽ thấy thông báo cuối cùng là “>Process Exit code: 0”, biên dịch thành công. Vào thư mục chứa Project bạn sẽ thấy 1 file “main.hex” được tạo ra. Để thử nghiệm chức năng tạo file COFF mà bạn đã add vào pn, chọn “Tools > [WinAVR] Make COFF”, quay lại thư mục chứa Project bạn sẽ thấy 1 file mới “main.cof” được tạo.

Hãy tìm và copy file “AVR1.DSN” (file của phần mềm Proteus) trong bài học AVR1 vào thư mục Project của bạn, chạy AVR1.DSN với Proteus, đổi file program cho chip atmega8 thành main.hex (xem lại bài "Mô phỏng bằng Proteus" nếu bạn quên cách thực hiện). Chạy mô phỏng để kiểm tra kết quả, nếu kết quả tương tự như trong AVR1, bạn đã thành công. Lưu Project của bạn.

Page 35: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 35

Như vậy bạn đã hoàn tất việc cài đặt và tạo Project mới với WinAVR. Vi ệc còn lại mà bạn phải thực hiện chính là viết code, tức lập trình bằng ngôn ngữ C trong WinAVR, phần này bạn hãy tham khảo bài "C cho AVR".

Page 36: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 36

C cho AVR

Nội dung Các bài cần tham khảo trước

1. Một số khái niệm C cho AVR. 2. Cấu trúc điều khiển và hàm. 3. Ví dụ minh họa.

Làm quen AVR.

Cấu trúc AVR.

WinAVR.

Như tôi đã trình bày ở các bài học trước, khi bạn đã hiểu AVR, để thực hiện các ứng dụng, bạn có thể không nhất thiết phải luôn lập trình bằng Assembly(ASM). Ngôn ngữ cấp cao như C sẽ giúp cho bạn xây dựng các ứng dụng nhanh chóng và dễ dàng hơn, tuy nhiên không vì thế mà bạn “quên” ASM, lập trình bằng C kết hợp ASM là giải pháp hay nhất. Một chú ý là chúng ta chỉ sử dụng C để đơn giản hóa lập trình tính toán, cấu trúc điều khiển…lập trình C cho AVR không có nghĩa là bạn không cần biết cấu trúc và cách thức hoạt động của chip. Tôi không có ý định nói về ngôn ngữ C ở đây nhưng chỉ giới thiệu một cách cơ bản nhất về cách viết chương trình cho AVR bằng C, cụ thể là C trong avr-gcc. Để có thể hiểu và viết những chương trình phức tạp hơn, bạn cần tự trang bị kiến thức về C, tài liệu này sẽ không giúp bạn phần đó. Tuy nhiên, nếu bạn chưa từng lập trình bằng C thì bạn cũng yên tâm đọc tài liệu này, vì ít ra tôi sẽ giải thích những gì tôi viết.

I. M ột số khái niệm C cho AVR.

Một chương trình C cho AVR thường bao gồm các thành phần như: chú thích (comments), biểu thức (expressions), câu lệnh (statements), khối (blocks), toán tử, cấu trúc điều khiển (Flow controls), hàm (functions)…

Chú thích (comments): có 2 cách để tạo phần chú thích trong C là chú thích từng dòng bằng 2 dấu “//” như trong dòng đầu của đoạn ví dụ “//day la chu thich, khong duoc bien dich” hoặc chú thích block bằng cách kẹp block cần chú thích vào giữa /* ….*/ ví dụ:

/* Ban co the type bat ky chu thich nao trong block nay Ngay ca khi ban xuong dong Phan chu thich thuong co mau chu la green */

Tiền xử lí (preprocessor): là một tiện ích của ngôn ngữ C, các preprocessor được trình biên dịch xử lí trước tất cả các phần khác, các preprocessor có chức năng tương tự các Directive trong ASM cho AVR.Các preprocessor được bắt đầu bằng dấu “#”,

Page 37: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 37

trong số các preprocessors trong ngôn ngữ C có hai preprocessors được sử dụng phổ biến nhất là #include và #define. Preprocessor #include chỉ định 1 file được đính kèm trong quá trình biên dịch (tương đương .INCLUDE trong ASM) và #define để định nghĩa 1 chuổi thay thế hoặc 1 macro. Xem các ví dụ sau:

#include /*đính kèm nội dung file io.h trong lúc biên dịch (file io.h nằm trong thư mục con avr của thư mục include trong thư mục cài đặt của WinAVR).*/ #define max (a,b) ((a)>(b)? (a): (b)) /*định nghĩa một macro tìm số lớn nhất trong 2 số a và b, trong chương trình nếu bạn gọi x=max(2,3) thì kết quả thu được x=3.*/

Biểu thức (Expressions): là 1 phần của các câu lệnh, biểu thức có thể bao gồm biến, toán tử, gọi hàm…, biểu thức trả về 1 giá trị đơn. Biểu thức không phải là 1 câu lệnh hoàn chỉnh. Ví dụ: PORTB=val.

Câu lệnh (Statement): thường là 1 dòng lệnh hoàn chỉnh, có thể bao gồm các keywords, biểu thức và các câu lệnh khác và được kết thúc bằng dấu “;”. Ví dụ: unsigned char val=1; val*=2; …là các câu lệnh.

Khối (Blocks): là sự kết hợp của nhiều câu lệnh để thực hiện chung 1 nhiệm vụ nào đó, khối được bao bởi 2 dấu mở khối “{“ và đóng khối “}”: ví d ụ 1 khối:

while(1){ PORTB=val; _delay_loop_2(65000); val*=2; if (!val) val=1; }

Toán tử (Operators): là những ký hiệu báo cho trình biên dịch các nhiệm vụ cần thực hiện, các bảng bên dưới tóm tắt các toán tử C dùng cho lập trình AVR:

• Bảng 1 các toán tử đại số: dùng thực hiện các phép toán đại số quen thuộc, trong đó đáng chú ý là các toán tử “++” (tăng thêm 1) và “--“ (bớt đi 1), chú ý phân biệt y=x++ và y=++x, ví dụ ta có x=3 trong khi y=x++ nghĩa là gán x cho y rồi sau đó tăng x thêm 1, điều này không ảnh hưởng đến y (cuối cùng y=3, x=4) trong khi y=++x nghĩa là tăng x trước rồi mới gán cho y (cuối cùng y=x=4), tương tự cho các trường hợp của toán tử “--“ .

Page 38: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 38

• Bảng 2 Toán tử truy cập và kích thức: toán tử [] thường được sử dụng khi bạn dùng mảng trong lúc lập trình, phần tử thứ của mảng sẽ được truy xuất thông qua [i], chú ý mảng trong C bắt đầu từ 0.

• Bảng 3 Toán tử Logic và quan hệ: thực hiện các phép so sánh và logic, thường được dùng làm điều kiện trong các cấu trúc điều khiển, chú ý toán tử so sánh bằng “==”, toán tử này khác với toán tử gán “=”, trong khi y = x nghĩa là lấy giá trị của x gán cho y thì (y== x) nghĩa là “nếu y bằng x”.

Page 39: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 39

• Bảng 4 Toán tử thao tác Bit (Bitwise operator): là các toán tử thực hiện trên từng bit nhị phân của các con số, các toán tử dịch trái “” rất thường được sử dụng khi sử lí số.

• Bảng 5 các toán tử khác: là 1 số toán tử đặc biệt rất hay sử dụng nhưng chúng ta thường không để ý vì vai trò của chúng rất dễ nhận thấy. Đặc biệt chú ý toán tử “?:” là 1 toán tử rất đặc biệt của C so với các ngôn ngữ lập trình khác, “?:” là toán tử 3 ngôi duy nhất có thể dùng thay thế cho cấu trúc “if” đơn giản.

II. C ấu trúc điều khiển và hàm.

2.1 Cấu trúc điều khiển (Flow Controls).

Các cấu trúc điều khiển biến ý tưởng của bạn thành hiện thực. Một số cấu trúc điều khiển cơ bản trong C như sau:

“If ( điều kiện) statement;”: nếu điều kiện là đúng thì thực hiện statement theo sau, statement có thể được trình bày cùng dòng hoặc dòng sau điều khiển If. Điều kiện có thể là một biểu thức bất kỳ, có thể là sự kết hợp của nhiều điều kiện bằng các toán tử quan hệ AND (&&), OR (||)…Điều kiện được cho là đúng khi nó khác 0, ví dụ if (1) thì điều kiện hiển nhiên là đúng. Xét một vài ví dụ dùng cấu trúc if như sau:

If (!val) val=1; nghĩa là nếu val bằng 0 thì chương trình sẽ gán cho val giá trị là 1, “!” là toán tử NOT, NOT của một số khác 0 thì bằng 0, ngược lại, NOT của 0 thì thu được kết quả là 1. Trong ví dụ này, nếu val bằng 0 thì !val sẽ bằng 1, như thế điều kiện sẽ trở thành đúng và câu lệnh “val=1” được thực thi.

Page 40: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 40

If (x==1 && y==2) result=’A’; nghĩa là nếu x bằng 1 và y bằng 2 thì gán ký tự ‘A’ cho biến result. Trong ví dụ này, toán tử logic “&&” được sử dụng để “nối” 2 điều kiện lại, bạn hoàn toàn có thể sử dụng nhiều toán tử logic khác nếu cần thiết.

Trong trường hợp bạn muốn thực thi nhiều câu lệnh cùng lúc nếu một điều kiện nào đó thỏa thì bạn cần đặt tất cả các câu lệnh đó trong 1 khối như bên dưới:

If (điều kiện) { Statement1; Statement2; … }

“If ( điều kiện ) statement1; else statement2; ”: nếu điều kiện đúng thì thực hiện statement1, ngược lại thực thi statement2. Việc đặt các statement và else..trên cùng 1 dòng hay trên những dòng khác nhau đều không ảnh hưởng đến kết quả. Tương tự trường hợp trên, nếu có nhiều statements thì cần đặt chúng trong 1 khối.

If (điều kiện) { Statement1; Statement2; … } else { Statement1; Statement2; … }

Ngoài ra, bạn cũng có thể đặt nhiều cấu trúc if…else… lồng vào nhau.

Cấu trúc switch: trong trường hợp có nhiều khả năng có thể xảy ra cho 1 biểu thức (hay 1 biến), ứng với mỗi khả năng bạn cần chương trình thực hiện một việc nào đó, khi này bạn nên sử dụng cấu trúc switch. Cấu trúc này được trình bày như bên dưới.

switch (biểu thức) { case hằng_số_1: các statement1; break; case hằng_số_2: các statement2; break; … default:

Page 41: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 41

các statement khác; }

Hãy xét 1 ví dụ bạn kết nối 2 chip AVR với nhau, 1 chip làm Master sẽ ra các lệnh điều khiển chip Slaver, chip Slaver nhận mã lệnh từ Master và thực hiện các công việc được thoả hiệp trước. Giả sử mã lệnh được lưu trong biến Command, dưới đây là chương trình ví dụ cách xử lí của chip Slaver ứng với từng mã lệnh.

switch (Command) { case 1: PWM=255; ON_Motor(); break; case 2: PWM=0; OFF_Motor();; break; … default: Get_Cmd(); break; }Ngoài ra, bạn cũng có thể đặt nhiều cấu trúc if…else… lồng vào nhau.

Nếu Command=1, gán giá trị 255 cho biến PWM và gọi chương trình con ON_Motor(). Trong trường hợp này, break được sử dụng, break nghĩa là thoát khỏi cấu trúc điều khiển hiện tại ngay lập tức, như vậy sau khi thực hiện 2 lệnh, switch kết thúc mà không cần xét đến các trường hợp khác. Bây giờ, nếu Command=2, gán giá trị 0 cho biến PWM và gọi chương trình con OFF_Motor(), trong tất cả các trường hợp còn lại (default), thực hiện chương trình con Get_Cmd().

“while (điều kiện ) statement1;”: là một cấu trúc lặp (Loop), ý nghĩa của cấu trúc while là khi điều kiện còn đúng thì sẽ thực hiện statement1 (hoặc các statements nếu chúng được đặt trong 1 khối {} nh ư trong trường hợp của if được giới thiệu ở trên). Cẩn thận, bạn rất dễ rơi vào một vòng lặp “không lối thoát” với while nếu điều kiện luôn luôn đúng.

“for (bi ểu_thức_1; biểu_thức_2; biểu_thức_3) statement;”: là một cấu trúc lặp khác, trong cấu trúc for, biểu_thức_1 thường được hiểu là khởi tạo, biểu_thức_2 là điều kiện và biểu_thức_3 là biểu thức được thực hiện sau. Cấu trúc for này tương đương với cấu trúc while sau:

biểu_thức_1; while (biểu_thức_2){ statement;

Page 42: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 42

biểu_thức_3; }

Các biểu thức trong cấu trúc for có thể vắng mặt trong cấu trúc nhung các dấu “;” thì không được bỏ. Nếu bạn viết for( ; ; ) tương đương với vòng lặp vô tận while (1).

Cấu trúc for thường được dùng để thực hiện 1 hay những công việc nào đó trong số lần nào đó, ví dụ bên dưới thực hiện xuất các giá trị từ 0 đến 200 ra PORTB, sau mỗi lần xuất sẽ gọi lệnh delay trong 65000 chu kỳ máy.

for (uint8_t i=0; i<=200; i++){ PORTB=i; _delay_loop_2(65000); }

Chú ý, bạn có thể thực hiện việc khai báo 1 biến (xem phần khai báo biến bên dưới) ngay trong cấu trúc for nếu biến lần đầu được sử dụng. Ví dụ trên được hiểu như sau: khai báo 1 biến i kiểu byte không âm, gán giá trị khởi đầu cho i=0 (chỉ thực hiện 1 lần duy nhất), kiểm tra điều kiện i<=200 (nhỏ hơn hoặc bằng 200), nếu điều kiện còn đúng, thực hiện 2 statements trong block {}, sau đó quay về để thực hiện i++ (tăng i thêm 1) rồi lại kiểm tra điều kiện i<=200 và quá trình lặp lại. Như thế đoạn code trong {} được thực thi khoảng 201 lần trước khi biến i bằng 201 và điều kiện i<=200 sai.

2.2 Hàm (Functions).

Ngôn ngữ C bao gồm tập hợp của rất nhiều hàm, mỗi hàm thực hiện một chức năng cụ thể, các hàm trong C thường được thiết kết rất nhỏ gọn, để có các hàm phức tạp người dùng cần tự tạo ra. Hàm C cho AVR được định nghĩa trong thư viện avr-libc, ngoài các hàm C thông thường, avr-libc còn chứa rất nhiều các hàm riêng dùng riêng cho chip AVR, các hàm này được khai báo trong các file header riêng, để sử dụng hàm nào, bạn cần #include file header tương ứng (tham khảo tài liệu “avr-libc user manual” để biết thêm chi tiết, trong tài liệu này, khi cần sử dụng một hàm nào tôi sẽ nói rõ file header cần thiết).

Ví dụ: _delay_loop_2(65000) là một hàm được định nghĩa trong file “delay.h” (trong thư mục C:\WinAVR\avr\include\util), hàm này thực hiện việc delay khoảng 65000 chu kỳ máy. Có 4 hàm delay bạn có thể sử dụng sau khi include file đó là:

• _delay_loop_1(uint8_t __count) : delay theo một số lần chu kỳ máy nhất định (biến __count), số lượng chu kỳ delay là số 8 bit (từ 0 đến 255).

• _delay_loop_2(uint16_t __count) : delay theo một số lần chu kỳ máy nhất định (biến __count), số lượng chu kỳ delay là số 16 bit (từ 0 đến 65535). (Chú ý: thực chất 2 hàm delay trên được định nghĩa trong file header “delay_basic.h”).

Page 43: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 43

• _delay_us(double __us): delay 1 microsecond. • _delay_ms(double __ms): delay 1 milisecond.

Chú ý: để dùng 2 hàm _delay_us và _delay_ms cần định nghĩa tần số xung clock trong Makefile (biến F_CPU), sử dụng 2 hàm này trực tiếp thường cho kết quả không như mong muốn, tôi sẽ trình bày cách sử dụng 2 hàm này trong ví dụ bên dưới.

Main : một chương trình C cho AVR phải bao gồm 1 chương trình chính main, tất cả các nội dung chính sẽ được đặt bên trong chương trình chính. Cấu trúc chương trình chính có thể như sau:

int main(void){ //noi dung chinh return 0; //gia tri tra ve cho chuong trinh chinh }

Trong đó, int là kiểu giá trị trả về của main, từ khóa void nói rằng chương trình chính của chúng ta không cần bất kỳ tham số nào kèm theo.

Còn rất nhiều các vấn đề liên quan đến C cho AVR, chúng ta sẽ tìm hiểu trong lúc viết các ví dụ cụ thể.

III. Ví d ụ minh họa.

Để minh họa các khái niệm và phương pháp lập trình C cho AVR, tôi sẽ giải thích ví dụ quét LED viết bằng C mà chúng ta thực hiện trong bài hướng dẫn WinAVR. Đoạn code được trình bày trong List 1.

List 1. ví dụ quét LED bằng C.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

//file: main.c //Description: AVR1 by GCC, "Cung hoc AVR" Series #include <avr/io.h> #include <util/delay.h> unsigned char val=1; int main(void){ DDRB=0xFF; //set PORTB as output lines while(1){ PORTB=val; _delay_loop_2(65000); val*=2; if (!val) val=1; } return 0; }

Page 44: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 44

Trước hết là preprocessor đính kèm các file khi biên dịch, #include là đính kèm file header io.h, file này thực ra không phải là file chứa các thông tin về chip nhưng nó sẽ làm một nhiệm vụ trung gian là đính kèm 1 file khác tương ứng với biến MCU trong Makefile, ví dụ trong Makefile, MCU=atmega8 thì dòng “#include ” được thực thi, file iom8.h được tự động đính kèm kèm vào và file iom8.h mới thực chất chứa các định nghĩa cho chip ATmega8 (các định nghĩa về địa chỉ thanh ghi, kích thước bộ nhớ,…). Điều này giúp bạn không cần nhớ hết tất cả các file header của từng chip AVR. Nếu “không an tâm”, bạn có thể thêm dòng #include iom8.h sau khi include io.h (điều này không thật sự cần thiết). Ngoài ra, mỗi lần include file io.h sẽ có 4 file header khác được tự động đính kèm là “avr/sfr_defs.h”, “avr/portpins.h”, “avr/common.h”, và “avr/version.h”. Tóm l ại bạn cần (hoặc phải) include file io.h và khai báo loại chip AVR trong file Makefile (dùng MFile, như hướng dẫn ở trên) là có thể an tâm viết chương trình C cho AVR.

- Dòng thứ 4 include file header delay.h để sử dụng lệnh delay như đã đề cập ở trên.

- Dòng 5 : khai báo 1 biến tên val trong bộ nhớ SRAM, kiểu của val là unsigned char là kiểu dữ liệu 8 bit không dấu có khoảng giá trị từ 0 đến 255. Biến val được dùng làm biến tạm để chứa giá trước khi xuất ra PORTB. Biến trong C được khai báo bằng cách đặt kiểu biến trước sau đó tên biến. Một số kiêu dữ liệu cơ bản trong C được tóm tắt trong bảng 6.

Bảng 6 các kiểu dữ liệu trong C.

Tên kiểu dữ liệu (Data type) Số byte Khoảng dữ liệu (Range)

char 1 –127 to 127 or 0 to 255

unsigned char 1 0 to 255

signed char 1 –127 to 127

int 2 –32,767 to 32,767

unsigned int 2 0 to 65,535

signed int 2 Như kiểu int

short int 2 Như kiểu int

unsigned short int 2 0 to 65,535

signed short int 2 Như kiểu short int

long int 4 –2,147,483,647 to 2,147,483,647

signed long int 4 Như kiểu long int

unsigned long int 4 0 to 4,294,967,295

long long int 8 –(263–1) to 263–1 (C99 only)

Page 45: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 45

Tên kiểu dữ liệu (Data type) Số byte Khoảng dữ liệu (Range)

signed long long int 8 same as long long int (C99 only)

unsigned long long int 8 0 to 264–1 (C99 only)

float 4 6 digits of precision

double 8 10 digits of precision

long double 12 10 digits of precision

Một số kiểu dữ liệu thông dụng nhất là char (1 byte), int (2 byte) và float. Từ khóa unsigned được thêm trước 1 kiểu dữ liệu nguyên để chỉ định các số nguyên dương, khi đó khoảng giá trị nguyên sẽ được tăng lên gần 2 lần. Ví dụ char chỉ các số nguyên từ -127 đến 127 thường được dùng để chỉ mã ASCII của các ký tự trong bảng mã ASCII, nhưng unsigned char sẽ bao gồm các số nguyên dương từ 0 đến 255 và thường được dùng khi làm việc với các thanh ghi 8 bit.

Ngoài ra, avr-libc còn định nghĩa một số kiểu dữ liệu thay thế, chúng ta có thể dùng các kiểu dữ liệu này thay cho các kiểu thông thường, xem tóm tắt như bên dưới.

Một khai báo uint8_t val tương đương usigned char val, sử dụng kiểu khai báo nào là do thói quen của người sử dụng. Chú ý là theo mặc định, một biến mới được khai báo theo cách thông thường như trên sẽ được đặt trong SRAM, như các bạn đã biết SRAM trong AVR tương đối nhỏ vì thế nên khai báo và sử dụng hợp lí biến, đừng khai báo quá nhiều biến nếu bạn không sử dụng hết, đừng khai báo kiểu biến quá lớn so với giá trị thật sử dụng, tuy nhiên cũng không được khai báo kiểu dữ liệu có kích thước quá nhỏ so với giá trị mà biến đó có thể vươn tới. Sử dụng bộ nhớ chương trình (flash program memory) để lưu trữ dữ liệu không đổi là một kỹ thuật khác để tiết kiệm bộ SRAM, tôi sẽ đề cập vấn đề này trong 1 bài khác.

Cuối cùng về việc khai báo biến, một biến có thể được gán giá trị khởi tạo ngay lúc khai báo như trong trường hợp của chúng ta, biến val=1 lúc được khai báo.

- Dòng 6 “int main(void){” bắt đầu chương trình chính.

Page 46: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 46

- Dòng 7: “DDRB=0xFF” gán giá trị hexadecimal 0xFF (11111111) cho thanh thi điều khiển của Port B, DDRB, Port B khi đó sẽ trở thành Port xuất

- Dòng 8 “while (1){”: bắt đầu 1 vòng lặp vô tận.

- Dòng 9 và dòng 10: xuất val ra PORTB và gọi lệnh delay.

- Bạn cần chú ý 11 và 12, 2 dòng này có chức năng “xoay” giá trị của biến val để xuất ra PORTB tạo hiệu ứng xoay vòng. val*=2 được hiểu là val=val*2, đây là 1 kiểu viết thu gọn của C, nếu toán hạng thứ nhất và kết quả trả về là cùng 1 biến, chúng ta có thể bỏ bớt 1 tên biến và di chuyển toán tử về bên phải toán tử gán “=”. Ví dụ: i = i + 6 được rút gọn thành i + = 6.

Như thế sau câu lệnh val*=2 giá trị của val được tăng lên 2 lần. Ý nghĩa thật sự của việc gấp đôi biến val là gì? Hãy nhìn vào giá trị nhị phân của val, lúc khai báo val, chúng ta gán cho val = 1 hay val = 00000001 (nhị phân), sau khi gấp đôi lần thứ nhất, val = 2=00000010, tiếp tục gấp đôi lần thứ hai, val = 4=00000100…có thể bạn đã thấy chuyện gì xảy ra? Đây là câu trả lời: “ trong thao tác với số nhị phân, gấp đôi một số nghĩa là di chuyển số đó sang trái 1 vị trí”…Quá trình gấp đôi sẽ tiếp diễn đến lúc val = 128=10000000, nếu tiếp tục gấp đôi, bạn nghĩ val = 256 ? Tuy nhiên bạn nhớ rằng chúng ta đã khai báo biến val có kiểu unsigned char (8 bits), trong khi đó 256=100000000 (9 bits), nếu gán val = 256, chỉ có 8 bits thấp (00000000) của 256 sẽ được gán cho val, kết quả là val = 0. Nói một cách khác, sau khi val=128, val = 0, câu lệnh: “ if (!val) val=1; ” sẽ giúp cho quá trình quét lặp quay lại từ đầu nếu val = 0. Mọi thứ đã rõ.

Cuối cùng vì chương trình chính của chúng ta có kiểu int (int main…) chúng ta cần “trả về” một giá trị nào đó, “return 0;” thực hiện trả về 0 (bạn có thể trả về giá trị nào tùy ý).

Page 47: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 47

Thiết lập Fuse Bits

Nội dung Các bài cần tham khảo trước

1. JTAGEN.

2. OCDEN.

3. BODEN.

4. EESAVE

5. BOOT LOADER

6. NGUỒN XUNG GIỮ NHỊP

Cấu trúc AVR.

Mạch nạp.

Thảo luận: Thiết lập sai Fuse bits

AVR có sẵn một số mạch điện và các thiết bị hỗ trợ bên trong, việc “điều khiển” các mạch điện này được thực hiện thông qua các Fuse bits. Ví dụ bên trong các chip AVR có bộ tạo dao động cho chip, nếu muốn sử dụng hoặc vô hiệu hóa bộ tạo dao động này chúng ta sẽ set các Fuse bits điều khiển nguồn xung clock(cụ thể ở phần sau). Như thế, Fuse bits cũng giống như các “cầu chì” hay các “công tắc cứng” nối AVR với các mạch điện hỗ trợ. Vì là các “công tắc cứng” nên chúng phải được set riêng biệt, không set được bằng lệnh "mềm".

Mỗi loại AVR có số lượng mạch điện hỗ trợ khác nhau và vì thế số lượng Fuse bits sẽ khác nhau. Vị trí các Fuse bits cũng khác nhau trên mỗi dòng chip tuy nhiên tên gọi thì như nhau. Tôi sẽ dùng chip ATmega32 làm minh họa. Chip ATmega32 có 16 Fuse bits được bố trí trong 2 byte gọi là “Fuse High Byte” và “Fuse Low Byte”. Vị trí các Fuse bits không quan trọng (vì chúng ta dùng phần mềm hỗ trợ set từng Fuse bit) nhưng tên gọi và chức năng thì cần khảo sát. Bảng 1 tóm tắt các bits trong Fuse High Byte và bảng 2 tóm tắt các bits trong Fuse Low Byte.

Page 48: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 48

Bảng 1. Fuse High Byte

Bảng 2. Fuse Low Byte

Đa số các chương trình nạp chip đều hỗ trợ nạp Fuse bits. Các Fuse được nạp độc lập đối với file chương trình. Các phần mềm nạp như PonyProg, phần mềm nạp trong CodevisionAVR, Bascom, ICCAVR…hỗ trợ set từng Fuse bit một trong khi một số chương trình như avrdude chỉ hỗ trợ nạp các byte Fuse, nếu muốn sử dụng các chương trình nạp này để nạp Fuse bạn cần tính toán giá trị 2 byte Fuse trước. Một chú ý rất quan trọng là đối với các Fuse bits, gán giá tr ị 0 cho 1 Fuse bit đồng

Page 49: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 49

nghĩa với Fuse bit đó được lập trình (programmed), trong khi 1 nghĩa là không được lập trình (unprogrammed).

Tôi sẽ sử dụng phần mềm PonyProg để làm minh họa nạp Fuse bits cho chip ATmega32. Trước khi nạp Fuse bits bạn cần chọn device và loại mạch nạp trong PonyProg (xem lại bài Mạch nạp). Để nạp Fuse bits bạn hãy chọn menu “Command/Security and Configuration Bits…” hoặc nhấn “Ctrl+S” (mạch nạp phải được nối sẵn với máy tính và mạch AVR). Nhấn nút “Read” để đọc các cấu hình Fuse bits trên chip của bạn, nếu đây là lần đầu tiên chip ATmega32 của bạn được nạp Fuse bits thì bạn sẽ thu được kết quả cấu hình các Fuse bits như trong hình 1.

Hình 1. Cấu hình Fuse bits mặc định trên chip ATmega32.

Chúng ta sẽ lần lượt khảo sát các Fuse bit theo nhóm chức năng của chúng.

1. JTAGEN (JTAG Enable): trên AVR có tích hợp sẵn bộ JTAG, đó là một module giao tiếp với phần cứng của chip. Nhìn chung, JTAG thường được dùng để kiểm tra hoạt động của chip. Trên AVR, JTAG có thể được dùng để nạp chương trình nhưng phổ biến hơn là dùng để debug lỗi chương trình (gỡ rối chương trình). Module JTAG làm việc thông qua 4 chân TCK, TMS, TDO và TDI, trên chip ATmega32 4 chân lần lần lượt là PC2, PC3, PC4 và PC5. Theo mặc định JTAG được kích hoạt, bit JTAGEN=0 (programmed) như trong hình 1. Vì thế với các chip ATmega32 mới mua về, các chân PC2:5 trên PORTC có thể không sử dụng để xuất nhập thông thường được. Nếu bạn không muốn sử dụng chức năng Debug trực tiếp trên chip thì hãy uncheck bit JTAGEN(uncheck tương đương unprogrammed, tương đương JTAGEN=1) để dùng các chân JTAG như các chân xuất nhập thông thường.

2. OCDEN (On Chip Debug Enable): như đã trình bày ở trên, AVR cho phép chúng ta gỡ rối chương trình trực tiếp trên chip thông qua module JTAG. Trong khi bit JTAGEN cho phép kích hoạt JTAG thì bit OCDEN cho phép thực hiện Debug trên chip (Nghĩa là cho dù đã kích hoạt JTAG bạn chưa thể dùng chức năng debug nếu chưa kích hoạt OCDEN). Nếu bạn có một mạch Debug cho AVR như mạch JTAG

Page 50: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 50

ICE của Atmel (xem bài Debug với JTAG ICE) và bạn muốn debug chương trình thì hãy set bit OCDEN bằng 0 (check vào ô OCDEN). Bạn cần nhớ rằng, khi lập trình cho bit OCDEN thì AVR sẽ hoạt động trong mode Debug, trong mode này chip sẽ ở trong trạng thái “ngủ” (Sleep mode), bạn chỉ có thể thực hiện Debug mà không thể chạy chương trình thật. Theo mặc định, OCDEN không được lập trình và chế độ Debug được vô hiệu hóa. Lời khuyên là bạn nên để bit này unprogrammed trước khi đưa chip vào sử dụng. (đừng đụng vào bit này nếu bạn không có ý định Debug trên chip).

3. BODEN (Brown-Out Detection Enable) và BODLEVEL (BOD Level): AVR có sẵn một mạch điện Brown-Out Detection, hiểu nôm na là mạch phát hiện sụt điện áp nguồn. Nếu fuse BODEN được lập trình thì mạch BOD được kích hoạt, khi đó fuse bit BODLEVEL chọn mức điện áp của BOD (mức điện áp dùng so sánh sụt nguồn). Nếu BODLEVEL=1 (unprogrammed) thì mức điện áp BOD mặc định là 2.7V, ngược lại nếu BODLEVEL được lập trình thì mức điện áp BOD là 4.0V. Khi mạch BOD được sử dụng, nếu điện áp VCC giảm xuống thấp hơn mức điện áp BOD thì 1 Reset BOD xảy ra. Nếu không thật sự cần thiết hãy để các bit này không được lập trình như mặc định. Hình 2 mô tả một sự kiện BOD trên AVR.

Hình 2. Sự kiện BOD trên AVR.

4. EESAVE (EEPROM Erase SAVE): nếu bit EESAVE được lập trình (bằng 0), thì bộ nhớ EEPROM sẽ không bị xóa khi xóa chip, ngược lại EESAVE =1 (unprogrammed) thì EEPROM sẽ bị xóa theo chip.

5. BOOT LOADER: đây là một tính năng rất hay trên các chip AVR mới (chú ý không phải dòng AVR nào cũng có Boot Loader), Boot Loader là phần bộ nhớ chương trình được kích hoạt đầu tiên khi khởi động chip. Boot Loader trên các chip AVR được bố trí phía dưới của bộ nhớ chương trình (xem lại bài 2, cấu trúc AVR). Boot Loader thường được sử dụng để ghi hoặc đọc nội dung bộ nhớ chương trình, vì thế ứng dụng phổ biến nhất của nó là update chương trình cho chip một một cách nhanh chóng mà không cần mạch nạp. Cơ chế như sau:

Page 51: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 51

-Trước hết chúng ta cần có 1 chương trình Boot Loader được nạp sẵn trong phần bộ nhớ Boot Loader (phía dưới bộ nhớ chương trình). Chương trình này có khả năng giao tiếp với máy tính (thông qua UART chẳng hạn) và đọc, ghi bộ nhớ chương trình của chip.

-Khi cần update chương trình mới cho AVR, trên máy tính có 1 chương trình giao tiếp với Boot Loader, kết nối AVR với máy tính, chương trình trên máy tính sẽ gởi nội dung cần update cho AVR, chương trình Boot Loader sẽ đọc nội dung này và ghi vào bộ nhớ chương trình của AVR. Bằng cách này chúng ta đã “nạp” chương trình cho AVR mà không cần dùng mạch nạp.

Nạp chương trình bằng Boot Loader cho phép khách hàng của bạn tự cập nhật các chức năng mới mà không cần trao chip cho bạn. Sử dụng hay không sử dụng Boot Loader sẽ được xác lập thông qua các Fuse bits BOOTRST, BOOTSZ1 và BOOTSZ0.

-BOOTRST (Select Reset Vector) : Nếu Fuse bit BOOTRST không được lập trình (bằng 1) thì khi vừa khởi động chip, con trỏ chương trình sẽ nhảy đến vị trí đầu tiên trong chương trình (0x0000) để lần lượt thực thi phần chương trình như thông thường. Nếu BOOTRST được lập trình (bằng 0) thì vị trí Reset là địa chỉ đầu của phần Boot Loader, không phải địa chỉ 0x0000 như thường lệ. Khi đó phần chương trình trong Boot Loader sẽ được thực thi thay cho chương trình chính phía trên (xem hình 3).

Hình 3. Ảnh hưởng của Fuse bit BOOTRST.

-BOOTSZ1 và BOOTSZ0 (Select Boot Size): kích thước phần bộ nhớ dành cho Boot Loader không cố định, nếu Boot Loader không được kích hoạt (fuse BOOTRST=1) thì toàn bộ bộ nhớ chương trình dành cho chương trình chính. Khi Boot Loader được kích hoạt, 2 Fuse bits BOOTSZ1 và BOOTSZ0 sẽ quyết định kích thước Boot Loader. Bảng 3 tóm tắt các kích thước của phần Boot Loader phụ thuộc vào 2 bit BOOTSZ1:0. Chú ý là kích thước tính theo INSTRUCTION WORD, với AVR 1 INSTRUCTION WORD = 2 bytes. Phải nhắc lại đối với Fuse bits, giá trị 1 nghĩa là không được lập trình (không check

Page 52: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 52

trong PonyProg). Nếu bit BOOTRST không được lập trình thì 2 bit BOOTSZ không có tác dụng.

Bảng 3. Kích thước Boot Loader.

Trong các ứng dụng lập trình thông thường, Boot Loader không được quan tâm, vì thế tối khuyên bạn nên để các Fuse bit BOOTRST, BOOTSZ1:0 như mặc định, khi nào cần sử dụng tôi sẽ nói rõ (xem bài Debug với mạch JTAG ICE).

6. Chọn Nguồn Xung giữ nhịp và thời gian khởi động (start-up times): Đây là phần rất được quan tâm khi set Fuse bits. Có đến 7 Fuse bits tham gia vào việc này đó là 4 bits CKSEL3:0, 2 bis SUT1:0 và bit CKOPT. Trong đó 2 bit SUT1:0 chủ yếu dùng để chọn thời gian khởi động, phần này không ảnh hưởng nhiều trong hầu hết các trường hợp (ít nhất là các ví dụ trong Cùng học AVR) vì thế tôi sẽ bỏ qua, chúng ta để 2 fuse bits như mặc định. Nếu start-up time thật sự ảnh hưởng đến chương trình của bạn, bạn hãy tham khảo thêm phần “System Clock and Clock Option” trong datasheet của chip. Phần này tôi chủ yếu trình bày cách chọn nguồn xung giữ nhịp cho chip.

Có tất cả 5 loại nguồn xung giữ nhịp chính cho chip nhưng để đơn giản chúng ta chỉ xét 2 trường hợp là dùng nguồn thạch anh ngoài và dùng xung giữ nhịp được tạo bởi mạch RC trong chip.

Xung giữ nhịp trong chip (xung nội): Hầu hết các chip AVR được trang bị 1 mạch tạo xung giữ nhịp RC bên trong, nếu sử dụng nguồn xung giự nhịp này chúng ta có thể bỏ qua mạch tạo xung bên ngoài. Nguồn xung giữ nhịp được tạo ra bên trong chip được cố định ở 1 trong 4 mức : 1MHz, 2 MHz, 4 Mhz và 8 MHz. Các Fuse bits CKSEL3:0 quyết định việc chọn nguồn xung này. Bảng 4 tóm tắt cách phối hợp các Fuse bits CKSEL để chọn nguồn xung nội.

Bảng 4. Chọn xung giữ nhịp nội bằng các Fuse bits CKSEL.

Page 53: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 53

(Nomial frequency: tần số danh nghĩa, giá trị thực có thể khác do sai số)

Đối với chip ATmega32, nguồn xung nội 1MHz được set mặc định trên các chip mới. Xem lại hình 1 bạn thấy CKSEL3=0 (được checked), CKSEL2=0 (được checked), CKSEL1=0 (được checked), CKSEL0=1 (không check). Các hình 4, 5, 6 và 7 bên dưới gợi ý bạn cách chọn nguồn xung nội bằng phần mềm nạp PonyProg, chú ý sau khi chọn các bits bạn phải nhấn bút “Write” để ghi vào chip.

Hình 4. Chọn nguồn xung nội 1MHz (đồng thời tắt JTAG, Boot Loader, BOD).

Hình 5. Chọn nguồn xung nội 2MHz (đồng thời tắt JTAG, Boot Loader, BOD).

Page 54: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 54

Hình 6. Chọn nguồn xung nội 4MHz (đồng thời tắt JTAG, Boot Loader, BOD).

Hình 7. Chọn nguồn xung nội 8MHz (đồng thời tắt JTAG, Boot Loader, BOD).

Xung giữ nhịp từ mạch thạch anh bên ngoài (Crystal): dùng xung nội có nhược điểm là tấn số xung đã được giữ cố định trong 4 mức và tấn số cao nhất có thể đạt là 8MHz trong khi AVR cho phép làm việc ở 16Mhz, mặc khác sai số cũng tương đối lớn khi xùng xung nội. Dùng thạch anh để tạo xung giữ nhịp là một giải pháp tốt, có thể tạo một mạch thạch anh đơn giản và nối với 2 chân XTAL1 và XTAL2 của AVR như trong hình 8.

Page 55: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 55

Hình 8. Mạch tạo xung ngoài bằng thạch anh.

Để “báo” cho AVR biết là chúng ta muốn sử dụng thạch anh ngoài làm mạch tạo xung, hãy set các Fuse bits CKSEL3:0 thành 1 trong 2 giá trị: 1111 hoặc 1010 (nhị phân). Trong trường hợp này, Fuse bit CKOPT có tác dụng chọn giữa 2 chế độ khuyếch đại, chế độ CKOPT = 0 (programmed) thích hợp với thạch anh có tần số lớn nhất là 16MHz và CKOPT=1 (unprorgammed) khi tần số thạch anh nhỏ hơn hoặc bằng 8MHz. Các hình 9 và 10 gợi ý cách set Fuse bits để chọn nguồn xung nhịp là mạch thạch anh ngoài với các tần số lớn nhất 8MHz và lớn nhất 16MHz.

Hình 9. Chọn xung giữ nhịp từ thạch anh ngoài với tần số lớn nhất là 8MHz.

Hình 10. Chọn xung giữ nhịp từ thạch anh ngoài với tần số lớn nhất là 16MHz.

Sau khi đã chọn các Fuse bits, việc cuối cùng và rất quan trọng là ghi các Fuse bits này vào chuip bằng cách nhấn nút “Write” (PonyProg).

Đối với các chương trình nạp chip khác, Fuse bits cũng được set tương tự.

Page 56: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 56

G.Edit Phần mềm biên tập Graphic LCD

GIỚI THI ỆU G.EDIT

G.Edit - Graphic LCD Editor : là phần mềm biên tập cho các loại Graphic LCD loại chấm không màu. Xử lí hình ảnh:

- G.Edit cho phép nhập hầu hết các định dạng file ảnh màu hay đen trắng.

- G.Edit hỗ trợ "Auto Resize" để tự động thay đổi kích thước hình ảnh khớp với kích thước Graphic LCD.

- G.Edit cho phép nhận dạng biên dạng vật thể trong ảnh trước khi chuyển sang hình ảnh cho Graphic LCD.

- Có thể tùy chọn mức độ xám (Gray level) trước khi chuyển sang hình ảnh cho Graphic LCD.

Xử lí chữ viết:

- Chức năng "Text Input" cho phép nhập chữ trực tiếp từ bàn phím, chữ được "trộn" với hình ảnh.

- Có thể tùy chọn Font cho chữ nhập vào.

Vẽ trên G.Edit:

- Có thể tự vẽ hoặc xóa các "chấm" trên màn hình Graphic LCD ảo.

- Kết quả tạm thời được xem trên Previewer.

Điều khiền kết quả:

- Kết quả có thể được lưu lại bằng định dạng "lcd".

- Xuất kết quả trực tiếp trong một cửa sổ "Text", kết quả được sắp xếp thành các phần tử của một mảng .

- Cho phép đảo kết quả hiển thị (chấm trắng thành chấm đen và ngược lại).

Page 57: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 57

Hình 1. Giao diện phần mềm G.Edit.

FontGen - Font Generator: là một công cụ biên tập font trong G.Edit (xem hình 2).

Page 58: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 58

Hình 2. FontGen.

Chức năng của FontGen:

- Tùy chọn fontface và fontname.

- Biên tập từng ký tự nhập vào, kết quả hiển thị trực tiếp.

- Cân chỉnh trái-phải, lên-xuống.

- Chỉnh sửa trực tiếp trên cửa sổ hiển thị ký tự (thêm chấm, xóa chấm...).

- Tự động tạo một "Font Set" cho tất cả các ký tự có mã ascii từ 33 đến 127.

SỬ DỤNG CƠ BẢN G.EDIT

- Menu file cho phép nhập hình ảnh vào G.Edit (Import Bitmap), mở một file "lcd" trước đó (Open lcd) hay lưu kết quả thành file "lcd" (Sace lcd file). Hãy xem hình 3.

Page 59: AVR-Ho tro phan mem

Copyright © 2010 Cùng học AVR Thanhtam Ho - www.hocavr.com

Created by QuocHuy Hoang

[email protected] Page 59

Hình 3. Menu file trong G.Edit.

- Thay đổi Font chữ nhập vào bằng menu "Text Font".

- Chạy công cụ FontGen từ menu " Font Generator" trong menu "Tool".

- Nhập chữ vào vùng "Text Input" trong giao diện chính.

- Để xem kết quả trên Graphic LCD, nhấn nút công cụ "Convert to LCD Data".

- Xem mảng kết quả hãy nhấn "Update the Results".

...Và còn nhiều chức năng khác, bạn hãy khám phá khi sử dụng G.Edit.

HẠN CHẾ CỦA PHIÊN BẢN DEMO

Phiên bản Demo cung cấp cho bạn một công cụ cần thiết để tạo các hình ảnh khi học sử dụng Graphic LCD. Tuy nhiên, với phiên bản Demo mà tôi cung cấp miễn phí, một số chức năng được kể bên trên có thể không được tìm thấy. Dưới đây là một vài hạn chế của phiên bản Demo.

- Không có chức năng dò tìm cạnh vật thể trong ảnh.

- Không được canh chỉnh vị trí ảnh trên Graphic LCD.

- Không thay đổi được Font chữ nhập vào.

- Không sử dụng được tiện ích FontGen.

- Kết quả biên tập luôn bao gồm dòng chữ "hocavr.com" ở một góc nhỏ của Graphic LCD.

Phiên bản Demo chỉ được sử dụng cho mục đích học tập (Education), tác giả không chịu trách nhiệm nếu có bất kỳ trục trặc nào xảy ra cho phiên bản Demo.

Nếu chấp nhận các hạn chế và quy định trên, bạn có thể Download bản Demo của phần mềm ở đây.