Ngôn ngữ để viết chương trình cho vi điều khiển AVR thường rất đa dạng. Từ những ngôn ngữ cấp thấp như ASM tới những ngôn ngữ câp cao như basic, pascal, C & C++, ngôn ngữ đồ họa. Khi sử dụng ngôn ngữ cấp thấp để viết chương trình giúp ta có thể hiểu rõ cấu trúc của vi điều khiển tuy nhiên lại mất nhiều thời gian khi ta xây dựng các ứng lớn. Với ngôn ngữ bậc cao có ưu điểm là giúp ta xây dựng các chương trình một cách nhanh chóng, rút ngắn thời gian xây dựng các ứng dụng. Trong các ngôn ngữ bậc cao thì ngôn ngữ C được sử dụng rất rộng dãi trong lập trình cho các dòng vi điều khiển nói chung và dòng AVR nói riêng.
Trình biên dịch giúp ta dịch các file đã viết thành ngôn ngữ mấy để nạp vào vi điều khiên. Hiện nay, có rất nhiều trình biên dịch cho vi điều khiển AVR, mỗi trình dịch có thể sử dụng một hoặc nhiều ngôn ngữ để viết như WINavr; Codevision, ICCAVR, MikroC(C); Bacom, AvrFast(basic), Flowcode(ngôn ngữ đồ họa).
3.1. Cơ bản về ngôn ngữ C
Ngôn ngữ lập trình C là ngôn ngữ khá mạnh và được nhiều người sử dụng. Lập trình bằng ngôn ngữ cấp cao như C giúp xây dựng các ứng dụng nhanh chóng và dễ dàng hơn. Sau đây sẽ giới thiệu một cách cơ bản nhất về cách viết chương trình cho AVR sử dụng ngôn ngữ C.
Một chương trình C cho AVR thường bao gồm những thàn phần cơ bản như: chú thích (comments), biểu thức (expressions), câu lệnh (statements), khối (blocks), các toán tử, cấu trúc điều khiển (flow controls), hàm (function)….
Chú thích (comments): Chú thích là những đoạn trong chương trình dùng để giải thích hay bình phẩm những gì ta làm trong chương trình, phần chú thích không được biên dịch vì vậy nó không có bất kỳ ảnh hưởng nào dến hoạt động của chương trình. Có hai cách để tạo phần chú thích trong C là chú thích theo từng dòng bằng cách đặt ở đầu dòng chú thích dấu “//” và chú thích block bằng cách kẹp đoạn cần chú thích vào giữa /*…*/.
Tiền xử lý (preprocessor): là một tiện ích của ngông 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 bắt đầu bằng dấu “#”, trong ngôn ngữ C có hai preprocessor được sử dụng phổ biến nhât đó là #include và #define. Preprocessor #include dùng để chỉ định 1 file được đính kèm trong quá trình xử lý, và #define dùng để định nghĩa một chuỗi thay thế hoặc 1 macro.
Biểu thức (expressions): là một phần của các câu lệnh, biểu thúc có thể bao gồm các biến, các toán tử, gọi hàm…. Biểu thức trả về một giá trị đơn. Biểu thức không phải là một câu lệnh hoàn chỉnh.
Câu lệnh (statements): là một dòng lệnh hoàn chỉnh có thể bao gồm các từ khóa (key words), các biểu thức các câu lệnh khác và được kết thúc bằng dấu “;”.
Khối (blocks): là sự kết hợp của nhiều câu lệnh để cùng thực hiện một nhiệm vụ nào đó. Khối được kẹp giữa hai dấu mở khối “{” và đóng khối “}”.
Toán tử (operators): là những ký hiệu báo cho trình biên dịch biết nhũng nhiệm vụ cần thực hiện(toán tử đại số, toán tử logic và quan hệ …).
Cấu trúc điều khiển (flow controls): Các cấu trúc điều khiển cho phép chương trình thực hiện đúng theo ý tưởng của người viết chương trình. Các cấu trúc điều khiển thường dùng trong lập trình C:
-“If (điều kiện) câu lệnh;” Nếu điều kiện là đúng thì thực hiện câu lệnh tiếp theo sau, câu lệnh có thể được viết cùng dòng hay dòng sau từ khóa if. Điều kiện 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 thông qua các toán tử quan hệ
AND(&&), OR(||), … Điều kiện được cho là đúng khi nó khác 0 .
Trong trường hợp cần thực thi nhiều câu lệnh khi một điều kiện nào đó thỏa mãn ta có thể đặt các câu lệnh đó trong một khối:
If (điều kiện) {
Câu lệnh 1; Câu lệnh 2; …
}
-“If (điều kiện) câu lệnh 1; else câu lệnh 2;”: Nếu điều kiện đúng thì thực hiện câu lệnh 1, nếu không đúng thì thực hiện câu lệnh 2. Việc đặt else và các câu lệnh trên cùng 1 dòng hay khác dòng không làm thay đổi ý nghĩa của cấu trúc.
Nếu cần thực hiện nhiều câu lệnh thì các câu lệnh cần được dặt trong 1 khối: If (điều kiện) { Câu lệnh 1; Câu lệnh 2; … } Else { Câu lệnh 1; Câu lệnh 2; … }
-Trong trường hợp có nhiều khả năng xảy ra cho 1 biểu thức (hay một biến) với mỗi khả năng lại cần thực hiện một công việc nào đó, ta có thể sử dụng cấu trúc switch:
Switch (biểu thức) { Case hằng _số_1: Các câu lệnh 1; Break; Case hằng_số_2: Các câu lệnh 2; Break; Defaul: Các câu lệnh khác; }
Cấu trúc switch hoạt động theo cách thức sau: Đầu tiên chương trình tính giá trị của biểu thức sau đó lần lượt đem so sánh với các giá trị hằng số đặt phía sau từ khóa case. Biểu thức có giá trị bằng hằng số nào thì thực hiện các câu lệnh trong case đó dến khi tìm thấy từ khóa break. Có thể đặt bao nhiêu case tùy ý. Nếu giá trị của biểu thức không tương ứng với các hằng số thì chương trình thực hiện các câu lệnh trong phần defaul: (nếu có phần này).
-Cấu trúc lặp While: “while (điều kiện) câu lệnh 1”. Ý nghĩa của cấu trúc lặp while là thực hiện câu lệnh 1 (hoặc 1 khối câu lệnh đặt trong dấu “{}”) khi điều kiện còn đúng.
-Cấu trúc lặp for : “for (biểu thức 1; biểu thức 2; biểu thức 3) câu lệnh”. Trong đó biểu thức 1 là biểu thức khởi tạo, biểu thức 2 là điều kiện, biểu thức 3 là biểu thức thực hiện sau. Biểu thức 1 được thực hiện 1 lần sau đó chương trình kiểm tra điêu kiện qua biểu thức 2, nếu điều kiện đúng câu lệnh được thực hiện, sau đó thực hiện biểu thức 3 rồi lại quay lại kiểm tra điều kiện. Cứ như vậy tới khi điều kiện không còn đúng nữa thì chương trình thoát khỏi vòng lặp. Chú ý khi sử dụng vòng lặp for là các biểu thức trong cấu trúc for có thể không có nhưng các dấu “;” thì bắt buộc phải có.
Hàm (functions): Trong C có rất nhiều hàm, mỗi hàm dùng để thực hiện một chức năng cụ thể. Các hàm trong C thường được thiết kế nhỏ gọn, để có những hàm phức tạp người dùng cần tự tạo ra.
Các từ khóa (key words): Từ khóa là những từ quy định của ngôn ngữ C như tên các kiểu dữ liệu (char, int, unsigned int, …); tên các cấu trúc điều khiển (if, while, for, …). Cần chú ý không được đặt tên biến trùng với từ khóa.
Các kiểu dữ liệu thường dùng khi lập trình C cho vi điều khiển: Tên kiểu dữ liệu Số byte Khoảng dữ liệu
Char 1 - 127 đến 127 hoặc 0 đến 255 Unsigned char 1 0 đến 255 Signed char 1 - 127 đến 127 Int 2 - 32767 đến 32767 Unsigned int 2 0 đến 65353 Singed int 2 - 32767 đến 32767 Short int 2 - 32767 đến 32767
Unsigned short int 2 0 đến 65353 Singed short int 2 - 32767 đến 32767
Long int 4 - 2147483647 đến 2147483647
Unsigned long int 4 0 đến 4294967295
Singed long int 4 - 2147483647 đến 2147483647 Long long int 8 - (2^63 – 1) đến (2^63 – 1) Unsigned long long int 8 0 đến (2^64 – 1 )