AVR– Lập trình C cho AVR: ngắt và timer/counter

Đây là thứ3 trong loạt bài cùng học AVR. Nếu bài 1 và bài 2 giới thiệu một cách chung nhất vềAVR thì kểtừbài 3 tôi sẽgiới thiệu lập trình điều khiển peripheral (thiết bịngoại vi hay các chức năng mởrộng tích hợp sẵn trên các chip AVR). Do là các thiết bịngoại vi mởrộng nên không phải tất cảcác chip AVR đều có tất cảcác thiết bịnày, ví dụchip AVR AT90S2313, AT90S8515 không có bộchuyển đổi Analog-Digital (ADC) và giao tiếp TWI (I2C) Tuy nhiên, các chip thuộc dòng Mega có khá nhiều thiết bịngoại vi phục vụcho các ứng dụng đo lường, điều khiển Chúng ta sẽtiếp tục sửdụng chip Atmega8 đểkhảo sát, trong quá trình khảo sát, nếu có sựkhác biệt giữa Atmega8 và các chip mới hơn (nhưAtmega16, Atmega32, Atmega64, Atmega128 ) tôi sẽnói rõ đểbạn rõ. Một sựkhác biệt lớn giữa AVR3 so với các bài viết trước là tôi sẽhướng dẫn lập trình bằng C mà cụthểlà bằng AVR-GCC (được tích hợp trong WinAVR). Các bạn xem phần II đểbiết rõ hơn. Sau bài này, tôi hy vọng bạn sẽ: - Cài đặt và sửdụng WinAVR, Programmer Notepad. - Hiểu được một sốhàm cơbản trong thưviện avr-libc. - Hiểu vềINTERRUPT (ngắt), cách sửdụng ngắt bằng C và cảASM. - Cải tiến ví dụtrong bài 2 bằng Interrupt.

pdf27 trang | Chia sẻ: maiphuongtt | Lượt xem: 5085 | Lượt tải: 3download
Bạn đang xem trước 20 trang tài liệu AVR– Lập trình C cho AVR: ngắt và timer/counter, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com CÙNG HỌC AVR AVR3– LẬP TRÌNH C CHO AVR: NGẮT VÀ TIMER/COUNTER Thoả thuận: tài liệu này thuộc quyền sở hữu của tác giả, bạn có thể tự do tham khảo tài liệu nhưng không được phép sử dụng để in thành sách báo, đăng lên các diễn đàn hay website, nhưng bạn có thể dùng đường link để hướng tới tài liệu. Liên hệ tác giả qua email: thanhtam.h@gmail.com. I. Bạn sẽ đi đến đâu. Đây là thứ 3 trong loạt bài cùng học AVR. Nếu bài 1 và bài 2 giới thiệu một cách chung nhất về AVR thì kể từ bài 3 tôi sẽ giới thiệu lập trình điều khiển peripheral (thiết bị ngoại vi hay các chức năng mở rộng tích hợp sẵn trên các chip AVR). Do là các thiết bị ngoại vi mở rộng nên không phải tất cả các chip AVR đều có tất cả các thiết bị này, ví dụ chip AVR AT90S2313, AT90S8515 không có bộ chuyển đổi Analog-Digital (ADC) và giao tiếp TWI (I2C)…Tuy nhiên, các chip thuộc dòng Mega có khá nhiều thiết bị ngoại vi phục vụ cho các ứng dụng đo lường, điều khiển…Chúng ta sẽ tiếp tục sử dụng chip Atmega8 để khảo sát, trong quá trình khảo sát, nếu có sự khác biệt giữa Atmega8 và các chip mới hơn (như Atmega16, Atmega32, Atmega64, Atmega128…) tôi sẽ nói rõ để bạn rõ. Một sự khác biệt lớn giữa AVR3 so với các bài viết trước là tôi sẽ hướng dẫn lập trình bằng C mà cụ thể là bằng AVR-GCC (được tích hợp trong WinAVR). Các bạn xem phần II để biết rõ hơn. Sau bài này, tôi hy vọng bạn sẽ: - Cài đặt và sử dụng WinAVR, Programmer Notepad. - Hiểu được một số hàm cơ bản trong thư viện avr-libc. - Hiểu về INTERRUPT (ngắt), cách sử dụng ngắt bằng C và cả ASM. - Cải tiến ví dụ trong bài 2 bằng Interrupt. II. 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com - 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. 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: 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 ) (hey, bạn có thể viết code cho avr-gcc bằng AVRStudio, Eclipse IDE hay ngay cả với Windows Notepad…makes sense). 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 (là các chip AVR trong trường hợp của chúng ta), 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. III. 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 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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. Vùng Project File Editor Kết quả biên dịch AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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). 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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. 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) //code 1 //file: main.c //Description: AVR1 by GCC, "Cung hoc AVR" Series #include #include 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. 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). AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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 AVR1 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 (<congrat ^.^). Lưu Project của bạn. Như thế tôi đã giới thiệu cách hoạt động cùng với pn và MFile lập trình C cho AVR, phần tiếp theo chúng ta tìm hiểu một số điểm cơ bản về C cho AVR thông qua việc giải thích ví dụ trên. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com IV. C cho AVR. 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ể 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ì ích ra tôi sẽ giải thích những gì tôi viết. 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 “#”, 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; } AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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ử “--“ . 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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”. 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com 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. 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. AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com - 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: 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 thảo 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; } 1 2 3 4 5 6 7 8 9 10 11 12 13 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(). AUTO.NLU For more details and questions, contact me: thanhtam.h@gmail.com - “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; 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, cho 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), 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. 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 dung cần tự tạo ra. Hàm C cho AVR được định nghĩa trong thư vi
Tài liệu liên quan