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

Một phần của tài liệu Báo cáo Kỹ thuật xung số tương tự và kỹ thuật đo lường điều khiển Đề tài: CẢM BIẾN NỒNG ĐỘ CỒN (Trang 37 - 42)

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.

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; … }

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: 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 Slave, chip Slave 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 Slave ứ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;

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; 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”).

 _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ể.

Một phần của tài liệu Báo cáo Kỹ thuật xung số tương tự và kỹ thuật đo lường điều khiển Đề tài: CẢM BIẾN NỒNG ĐỘ CỒN (Trang 37 - 42)

Tải bản đầy đủ (DOCX)

(65 trang)
w