View
35
Download
0
Category
Preview:
DESCRIPTION
SG8v1
Citation preview
SG8v1 – ICDRECHướng dẫn sử dụng trình biên dịch
SG8v1 và IDE iFast.
Tài liệu kỹ thuật Thay đổi gần nhất ngày 03/01/2013
MỤC LỤC
1. Đặc tả ngôn ngữ lập trình......................................................................................11.1.Cấu trúc chương trình...............................................................................................1
1.2.Các thành phần cơ bản..............................................................................................11.2.1. Các từ khóa..................................................................................................................11.2.2. Các định danh (Identifier).............................................................................................21.2.3. Hằng số........................................................................................................................2
1.3.Khai báo và kiểu biến.................................................................................................31.3.1. Các lớp phạm vi (storage class)...................................................................................31.3.2. Định danh kiểu và định tính kiểu (type specifier / type qualifier ) ................................31.3.3. Khai báo thể (declarators)............................................................................................4Trong ví dụ trên thì những phần được in đậm chính là khai báo thể, những phần được gạch dưới chính là định tính kiểu, các phần còn lại chính là định danh kiểu.........................51.3.4. Khai báo cấu trúc. ........................................................................................................61.3.5. Khai báo kiểu hợp nhất ...............................................................................................61.3.6. Khai báo enum.............................................................................................................61.3.7. Khai báo mảng ............................................................................................................71.3.8. Khai báo con trỏ. .........................................................................................................71.3.9. Bộ khởi tạo...................................................................................................................71.3.10. Dùng typedef để định nghĩa kiểu................................................................................8
1.4.Các biểu thức.............................................................................................................9
1.5.Tập lệnh....................................................................................................................101.5.1. Lệnh Null “;”................................................................................................................101.5.2. Lệnh biểu thức............................................................................................................111.5.3. Lệnh break..................................................................................................................111.5.4. Lệnh khối ...................................................................................................................111.5.5. Lệnh continue ............................................................................................................111.5.6. Lệnh if.........................................................................................................................111.5.7. Lệnh else if.................................................................................................................111.5.8. Lệnh switch và case...................................................................................................121.5.9. Lệnh do-while ...........................................................................................................121.5.10. Lệnh while................................................................................................................121.5.11. Lệnh for.....................................................................................................................131.5.12. Lệnh goto và các lệnh có nhãn................................................................................131.5.13. Lệnh return...............................................................................................................131.5.14. Lệnh __asm, __endasm ..........................................................................................13
1.6.Hàm...........................................................................................................................151.6.1. Định nghĩa hàm..........................................................................................................151.6.2. Khai báo hàm ............................................................................................................151.6.3. Lệnh gọi hàm .............................................................................................................161.6.4. Truyền tham số ..........................................................................................................16
1.7.Chú thích ..................................................................................................................16
1.8.Chỉ thị tiền tiền xử lý................................................................................................181.8.1. Chỉ thị #define.............................................................................................................181.8.2. Các chỉ thị #if, #else, #endif.......................................................................................181.8.3. Các chỉ thị #ifdef và #ifndef........................................................................................18
2. Thư viện tích hợp..................................................................................................192.1.Định địa chỉ tuyệt đối...............................................................................................19
2.2.Các hằng số và biến tích hợp..................................................................................19
2.3.Các hàm và chỉ thị của SG8V1 ...............................................................................202.3.1. Truy xuất cổng............................................................................................................202.3.2. Bộ nhớ........................................................................................................................21
i
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
2.3.3. Cấu hình stack............................................................................................................212.3.4. Các hàm chờ..............................................................................................................222.3.5. Các ngắt.....................................................................................................................222.3.6. Bộ định giờ.................................................................................................................242.3.7. Bộ ghi và so sánh (Capture/Compare) (CC)..............................................................272.3.8. Bộ điều chế độ rộng xung (PWM)..............................................................................272.3.9. Giao tiếp SPI..............................................................................................................282.3.10. Giao tiếp I2C.............................................................................................................292.3.11. Giao tiếp UART.........................................................................................................312.3.12. Các hàm chuỗi..........................................................................................................34
3. Các chức năng và hạn chế của trình biên dịch.................................................35
4. Môi trường phát triển tích hợp (IDE)..................................................................364.1.Giới thiệu..................................................................................................................36
4.2.Hướng dẫn cài đặt iFast..........................................................................................374.2.1. Cài đặt iFast trên Windows........................................................................................374.2.2. Cài đặt trên Ubuntu/Debian........................................................................................41
4.3.Các tính năng chính của iFast.................................................................................424.3.1. Giao diện của iFast....................................................................................................424.3.2. Tổng quan về dự án...................................................................................................444.3.3. Tạo một dự án mới.....................................................................................................444.3.4. Mở một dự án có sẵn.................................................................................................454.3.5. Đóng dự án.................................................................................................................454.3.6. Tổng quan về tập tin nguồn........................................................................................454.3.7. Mở một tập tin mã nguồn có sẵn................................................................................464.3.8. Tạo mới một tập tin nguồn. .......................................................................................464.3.9. Thêm tập tin có sẵn vào dự án. .................................................................................464.3.10. Các thao tác trên tập tin nguồn................................................................................464.3.11. In tập tin nguồn ........................................................................................................47
4.4.Cấu hình trình biên dịch C.......................................................................................474.4.1. Cấu hình trình liên kết................................................................................................484.4.2. Cấu hình đường dẫn của các trình biên dịch và trình thực thi...................................494.4.3. Các cấu hình khác......................................................................................................51
4.5.Cấu hình chức năng tô màu cú pháp......................................................................51
4.6.Cấu hình chức năng phím tắt..................................................................................52
5. Phụ Lục..................................................................................................................53
ii
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1. Đặc tả ngôn ngữ lập trình
Ngôn ngữ lập trình được hỗ trợ bởi trình biên dịch tích hợp trong iFast có cú pháp và các
thành phần dựa vào tiêu chuẩn ANSI-C.
1.1. Cấu trúc chương trình
Một chương trình được cấu thành thành bởi 4 thành phần sau đây:
▪ Chú thích (Comment)
▪ Chỉ thị tiền xử lý (Preprocessor Directive)
▪ Định nghĩa dữ liệu (Data Definition)
▪ Định nghĩa hàm (Function Definition)
Mỗi chương trình phải chứa một hàm main(), vì đó là nơi mà vi xử lý bắt đầu thực thi
chương trình. Ngoài hàm main() ra thì chương trình cũng có thể có nhiều hàm khác tùy theo
mục đích người lập trình và các hàm này sẽ được gọi thông qua hàm main() hoặc các hàm
khác nó.
Một chương trình có một hoặc nhiều tập tin nguồn, các tập tin này chính là tập tin đầu vào của
trình biên dịch.
1.2. Các thành phần cơ bản
Một ngôn ngữ lập trình được cấu thành từ các thành phần cơ bản gọi là token. Một token có
thể là từ khóa, định danh, hằng số, chuỗi ký tự, dấu chấm hay dấu phẩy.
1.2.1. Các từ khóa
Sau đây là danh sách các từ khóa được trình biên dịch sử dụng. Người dùng không được đặt tên biến/hàm trùng với các từ khóa này.
▪ Các kiểu: void, char, short, int, long, signed, unsigned, enum, struct, union.
▪ Các từ định tính (qualifiers) : const, volatile.
▪ Các lớp phạm vi (storage class): global, static, extern, typedef.
▪ Các câu lệnh (statements): break, case, continue, default, do, for, goto, if, return, switch, while.
Trình biên dịch SG8V1 không có hỗ trợ kiểu bit nhưng người dùng có thể khai báo kiểu bit
theo dạng sau :
Đặc tả ngôn ngữ lập trình 1
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
typedef union { struct { unsigned char a:1; unsigned char b:1; unsigned char c:1; unsigned char d:1; };} _bits_t;
volatile _bits_t _bits;
Kiểu _bits_t có các trường a, b, c, d tương ứng với bit 0 đến bit 3. Ta có thể tương tác
với các bit này tương tự như sau:
_bits.a = 1;
1.2.2. Các định danh (Identifier).
Định danh là tên của các biến, các kiểu, các hàm, và các nhãn trong chương trình. Các định
danh trong cùng một chương trình phải không được trùng nhau. Theo tiêu chuẩn của ANSI-
C , trình biên dịch phân biệt định danh theo chữ hoa/ chữ thường. Ví dụ, định danh abcd sẽ
khác với định danh abcD.
Kí tự đầu tiên của một định danh phải là một kí tự chữ cái hoặc dấu gạch dưới, không được là
chữ số.
▪ Định danh: [_a-zA-Z][_0-9a-zA-Z]*
1.2.3. Hằng số
Bất kỳ chữ số, ký tự, chuỗi ký tự nào cũng có thể được dùng làm hằng số trong chương trình:
▪ Số nguyên
▫ Hằng số hệ thập phân: 0 hay [1-9][0-9]*
▫ Hằng số hệ thập lục phân: 0x[0-9A-F]+
▫ Hằng số hệ nhị phân: 0b[0-1]+
▪ Kí tự
Hằng số kí tự là một kí tự thuộc bảng mã ASCII được đặt trong hai dấu ngoặc đơn (' ').
▪ Chuỗi kí tự
Là một dãy các ký tự được đặt trong hai dấu ngoặc kép (" ").
Ví dụ:
const char str[] = “ICDREC”;
Đặc tả ngôn ngữ lập trình 2
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.3. Khai báo và kiểu biến.
Mục này miêu tả phương thức khai báo và khởi tạo các biến, các hàm, và các kiểu:
[lớp_phạm_vi] [định_tính_kiểu] định_danh_kiểu danh_sách_khai_báo_thể;
Trong đó, danh_sách_khai_báo_thể là một danh sách có một hoặc nhiều khai báo thể
được tách nhau bởi dấu phẩy:
khởi_tạo_khai_báo_thể
//hoặc
khởi_tạo_khai_báo_thể_1, khởi_tạo_khai_báo_thể_2, ... , khởi_tạo_khai_báo_thể_n
khởi_tạo_khai_báo_thể có 2 dạng: khai_báo_thể chưa khởi tạo và khải báo thể có
khởi tạo giá trị.
khai_báo_thể
khai_báo_thể = bộ_khởi_tạo
1.3.1. Các lớp phạm vi (storage class)
Các từ khóa trong lớp phạm vi là:
staticexterntypedef
Biến toàn cục là biến được khai báo bên ngoài tất cả các hàm hay biến được khai báo với từ
khóa extern. Những biến còn lại được xem như là biến cục bộ.
Các biến được khai báo bên ngoài tất cả các hàm mặc định có thuộc tính toàn cục. Nếu các
biến được khai báo với từ khóa đều là biến toàn cục. Biến được khai báo bên trong hàm là
biến cục bộ.
1.3.2. Định danh kiểu và định tính kiểu (type specifier / type qualifier )
Định danh kiểu được dùng để xác định kiểu biến hay kiểu hàm. Nó có thể là một trong các từ
khóa sau: void, (signed/unsigned) char, (signed/unsigned) int, (signed/unsigned) short, (signed/unsigned) long.
Ngoài các từ khóa được quy định như trên, ta có thể tạo ra định danh kiểu cho riêng mình
bằng việc sử dụng các từ khóa struct, union, enum, typedef. Ví dụ:
Đặc tả ngôn ngữ lập trình 3
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
struct user{ char name[64]; char password[32];}
typedef int* p_int;
Trong hai ví dụ trên, sau khi được khai báo thì user và p_int trở thành hai định danh kiểu mới và ta có thể sử dụng chúng như các định danh kiểu được quy định bên trên.
Giới hạn của các định danh kiểu dành cho số nguyên như char, int, short, long được thể hiện trong bảng dưới đây:
Giới hạn
Định danh kiểu Kích cỡ (bit) Unsigned Signed
char 8 0 tới 255 -128 tới 127
int/short 16 0 tới 65535 -32768 tới 32767
long 32 0 tới 4294967295 -2147483648 tới 2147483647
Bảng 1: Bảng liệt kệ các định danh kiểu.
Các định tính kiểu (type qualifier) được dùng để quyết định thuộc tính của các định danh. Đó
chỉ có thể là một trong ba thuộc tính sau: const, volatile hay restrict.
Nếu một biến có được khai báo với định tính kiểu const thì có nghĩa là nội dung của biến
này sẽ không thể bị thay đổi.
Một biến được định nghĩa với kiểu volatile thì nó sẽ không được tối ưu hóa bởi trình biên
dịch và trình biên dịch sẽ tạo ra mã để đọc nội dung của nó từ bộ nhớ thay vì đọc giá trị từ
một thanh ghi CPU khi có thể. Những đối tượng thường được gán định tính kiểu volatile
là các ngắt hay những biến có thể bị thay đổi bởi chương trình khác …
Thực thể được chỉ đến bởi một con trỏ p có thuộc tính restrict thì bất kỳ tham chiếu nào
đến thực thể này đều phải thông qua con trỏ p này. Như vậy thực thể này chỉ có thể có một
con trỏ là p.
1.3.3. Khai báo thể (declarators).
Các dạnh của khai báo thể:
định_danh định_danh [ biểu_thưc_hằng_số ]định_danh ( danh_sách_đối_số )định_danh ( danh_sách_kiểu_đối_số )
* định_danh * định_danh [ biểu_thưc_hằng_số ]* định_danh ( danh_sách_đối_số )* định_danh ( danh_sách_kiểu_đối_số )
Đặc tả ngôn ngữ lập trình 4
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Trong những công thức trên thì biểu_thưc_hằng_số, danh_sách_đối_số và
danh_sách_kiểu_đối_số không bắt buộc phải có mặt.
Khi một khai báo thể (declarators) chỉ chứa định danh thì nó sẽ có kiểu cơ bản do định danh
kiểu quyết định. Nếu dấu hoa thị (*) xuất hiện bên trái định danh, thì kiểu của khai báo thể
chuyển thành kiểu con trỏ. Nếu có dấu ngoặc vuông ([ ]) đặt ngay sau định danh thì kiểu của
khai báo thể chuyển thành kiểu mảng. Nếu theo sau định danh là một cặp dấu ngoặc đơn thì
kiểu của khai báo thể chính là kiểu hàm.
Ví dụ:
const int a;restrict int *b;char c[6];int get_max(int a, int b);
Trong ví dụ trên thì những phần được in đậm chính là khai báo thể, những phần được gạch dưới chính là định tính kiểu, các phần còn lại chính là định danh kiểu.
Đặc tả ngôn ngữ lập trình 5
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.3.4. Khai báo cấu trúc.
Khai báo kiểu cấu trúc được dùng để tạo ra một kiểu mới từ một hoặc nhiều kiểu đã định
nghĩa.
struct đinh_danh { danh_sách_phần_tử } struct định_danh
Ví dụ:
struct a {int x;char y;
} var1;
struct a var2;
1.3.5. Khai báo kiểu hợp nhất
Khai báo kiểu hợp nhất được dùng để tạo ra một kiểu mới từ một hoặc nhiều kiểu đã định
nghĩa. Hệ thống sẽ không cấp phát vùng nhớ cho tới khi một biến được khai báo với kiểu kiểu
hợp. Vùng nhớ của biến kiểu hợp nhất chính là vùng nhớ của phần tử lớn nhất của nó. Khi
buộc phải lưu một phần tử có kích thước nhỏ hơn, biến kiểu hợp nhất sẽ chứa những vùng
nhớ thừa. Tất cả các phần tử đều được lưu trữ chung một vùng nhớ và cùng một địa chỉ bắt
đầu. Giá trị được lưu trong biến kiểu hợp nhất sẽ bị chép đè lên mỗi khi có một giá trị mới
được gán cho phần tử khác của biến. Cấu trúc để khai báo biến kiểu hợp nhất như sau:
union định_danh { danh_sách_phần_tử } union định_danh
Ví dụ:
union{ struct{
unsigned int icon : 8; unsigned int color : 4; } window; int screenval;};
Trong ví dụ trên thì cấu trùng typedef để định nghĩa kiểuúc hợp nhất sẽ có kích thước bằng với kích thước của biến window và bằng 4 byte (kiểu int có kích thước là 2 byte và window có hai phần tử kiểu int).
1.3.6. Khai báo enum
Enum là kiểu liệt kê. Khai báo enum dùng để liệt kê một tập hợp các hằng số nguyên được đặt
tên. Một biến kiểu enum chứa một trong các giá trị được định nghĩa bởi kiểu đó.
enum định_danh { danh_sách_tên_hằng_số }
Đặc tả ngôn ngữ lập trình 6
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Ví dụ:
enum direction {UP,DOWN,RIGHT,LEFT
}
Trong ví dụ trên, nếu không chỉ rõ thì UP có giá trị bằng 0 và các hằng số tiếp theo sẽ có giá trị tăng dần đều với mỗi bước bằng 1 đơn vị (DOWN bằng 2, RIGHT bằng 3, LEFT bằng 4).
1.3.7. Khai báo mảng
Khai báo mảng dùng để đặt tên mảng cũng như định ra số lượng và kiểu cho các thành phần
của nó. Các biến kiểu mảng được xem như một con trỏ chỉ đến kiểu của các phần tử mảng.
Định dạng của một mạng có 2 dạng sau:
định_danh[]định_danh[biểu_thức_hằng_số]
Vùng nhớ cấp cho kiểu mảng chính là vùng nhớ để chứa tất cả các phần tử của nó. Các phần
tử của một mảng được lưu trữ tại các vị trí bộ nhớ kề nhau và tăng dần từ phần tử đầu tiên đến
phần tử cuối. Ví dụ:
int a_int[5];
1.3.8. Khai báo con trỏ.
Khai báo con trỏ dùng để đặt tên biến con trỏ và kiểu của đối tượng mà biến con trỏ đó chỉ
đến. Một biến kiểu con trỏ thực chất chỉ chứa địa chỉ vùng nhớ của biến mà con trỏ đó chỉ tới.
* định_danh
Ví dụ:
char *p; const int *pi;
Lưu ý: trình biên dịch SG8V1 khônùng typedef để định nghĩa kiểug hỗ trợ con trỏ hàm.
1.3.9. Bộ khởi tạo
Bộ khởi tạo là một giá trị hoặc một chuỗi các giá trị được cấp phát cho biến đang được khai
báo. Người dùng có thể khởi tạo giá trị của biến bằng cách cung cấp một bộ khởi tạo cho khai
báo thể trong quá trình khai báo biến. Giá trị hoặc các giá trị của bộ khởi tạo sẽ được gán cho
các biến theo thứ tự tương ứng.
▪ Khởi tạo biến kiểu số
Dùng biểu thức hằng số để khởi tạo giá trị cho biến kiểu số. Ví dụ
Đặc tả ngôn ngữ lập trình 7
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
const int a = (3 * 1024)ùng typedef để định nghĩa kiểu;int *b = &a;
▪ Khởi tạo kiểu tổ hợp
Bộ khởi tạo kiểu tổ hợp dùng danh ùng typedef để định nghĩa kiểusách các biểu thức
hằng số cách nhau bởi dấu phẩy để gán các giá trị cho từng phần tùng typedef để định
nghĩa kiểuử có trong các biến kiểu tổ hợp như là kiểu mảng, kiểu cấu trúc, kiểu hợp
nhất .v.v... Các phần tử của bộ khởi tạo được đặt trong cặp dấu ngoặc nhọn ({ }). ùng
typedef để định nghĩa kiểuùng typedef để định nghĩa kiểu
Nếu chiều dài của bộ khởi tạo kiểùng typedef để định nghĩa kiểuuùng typedef để định
nghĩa kiểu tổ hợp nhỏ hơn chiều dài của mảng thì các phần tử thừa ra sẽ không được
khởi tạo.
Nếu kích cỡ một mảng không được định rõ thì số lượng phần tử trong bộ khởi tạo sẽ
xác định kích cỡ của nó. Nếu bộ khởi tạo kiểu tổ hợp có nhiều phần tử hơn kiểu
mảng/cấu trúc mà nó khởi tạo thì trong quá trình biên dịch sẽ phát sinh ra lỗi.
int x[ ] = { 0, 1, 2 };struct list {int i, j;char m[2];
} y = {1, 2,{'a', 'b'}
};
▪ Khởi tạo chuỗi
Ta có thể khởi tạo một mảng ký tự bằng một chuỗi. Ví dụ như lệnh sau:
char s[ ] = "abc";
Khởi tạo biến s thành một mảng ký tự bốn phần tử với phần tử thứ tư là ký tự null
được chèn tự động vào để đánh dấu vị trí kết thúc chuỗi.
1.3.10. Dùng typedef để định nghĩa kiểu
Từ khóa typedef đóng vai trò như lớp phạm vi và khai báo thể để khai báo một kiểu mới. Ta
có thể dùng khai báo typedef để tạo ra một tên ngắn gọn và ý nghĩa hơn cho các kiểu đã
khai báo trước đó.
typedef struct club {char name[30];int size, year;
} GROUP;
typedef GROUP * PG;
Kiểu PG được khai báo như một con trỏ chỉ tới kiểu GROUP và kiểu GROUP này lại chính là từ
khóa tương đương cho cấu trúc club.
Đặc tả ngôn ngữ lập trình 8
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.4. Các biểu thức
Một biểu thức là một dãy các toán tử và các toán hạng được dùng để thực thi các nhiệm vụ
như: tính toán một giá trị, xác định một đối tượng hoặc một hàm .v.v...
Toán hạng bao gồm các hằng số, định danh, chuỗi, lệnh gọi hàm, biểu thức truy xuất phần tử,
và các biểu thức phức tạp được tạo thành thông qua việc kết hợp các toán hạng với các toán tử
hoặc các toán hạng đặt trong các dấu hoặc đơn.
Biểu thức cơ bản có thể là một định danh, hằng số, chuỗi kí tự hay một biểu thức đặt trong
cặp dấu ngoặc đơn.
Toán tử Miêu tả Chú ý
Toán tử unary
– Phủ định số học. Các toán hạng phải là kiểu nguyên.
~ Lấy bù (tương đương với NOT). Toán hạng phải là kiểu nguyên.
! Phép phủ định logic.
-- Toán tử giảm (dùng cho cả tiền tố và hậu tố). Toán hạng phải là kiểu số nguyên hoặc kiểu con trỏ. Một con trỏ bị giảm sẽ chỉ đến đối tượng trước đó.
++ Toán tử tăng (dùng cho cả tiền tố và hậu tố). Toán hạng phải là kiểu số nguyên hoặc kiểu con trỏ. Một con trỏ được tăng sẽ chỉ đến đối tượng tiếp theo.
* Toán tử gián tiếp truy xuất một giá trị một cách gián tiếp thông qua một con trỏ
& Toán tử địa chỉ cung cấp địa chỉ toán hạng của nó
Không được hỗ trợ địa chỉ của biến kiểu bit.
(type) Toán tử ép kiểu.
Toán tử số học
+ Toán tử cộng. Mỗi toán hạng có thể là một số nguyên (i), kiểu dấu chấm động (f) hoặc một con trỏ (p).
Không hỗ trợ (p+p).
- Toán tử trừ. Một toán hạng có thể hoặc là một số nguyên (i), kiểu dấu chấm động (f) hoặc một con trỏ (p).
Không hỗ trợ (p+p).
* Toán tử nhân.
/ Toán tử chia.
% Toán tử chia lấy dư. Không hỗ trợ kiểu dấu chấm động
Toán tử bit và toán tử dịch
& Toán tử AND.
| Toán tử OR
Đặc tả ngôn ngữ lập trình 9
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Toán tử Miêu tả Chú ý
^ Toán tử XOR.
<< Toán tử dịch trái.
>> Toán tử dịch phải.
Toán tử logic
&& Toán tử AND logic.
|| Toán tử OR logic.
Toán tử so sánh
< Toán hạng đầu nhỏ hơn toán hạng thứ hai.
> Toán hạng đầu lớn hơn toán hạng thứ hai.
<= Toán hạng đầu nhỏ hơn hoặc bằng với toán hạng thứ hai.
>= Toán hạng đầu lớn hơn hoặc bằng với toán hạng thứ hai.
== Toán hạng đầu bằng với toán hạng thứ hai.
!= Toán hạng đầu không bằng với toán hạng thứ hai.
Toán tử gán
= Toán tử này gán giá trị của toán hạng bên phải cho toán hạng bên trái.
x= Thay đổi và gán giá trị trong một phép tính với x là bất kì toán tử số học hoặc toản tử cấp bit nào.
Bảng 2: Danh sách các toán tử.
1.5. Tập lệnh
Các lệnh quyết định dòng thực thi của chương trình. Tập lệnh gồm có lệnh null, lệnh biểu
thức, lệnh break, lệnh khối, lệnh break, lệnh continue,các lệnh vòng lập, các lệnh rẻ nhánh,
lệnh return và lệnh dùng để chèn hợp ngữ vào chương trình. Phần này sẽ miêu tả tập lệnh
được trình biên dịch hỗ trợ.
1.5.1. Lệnh Null “;”
Lệnh null là một lệnh chỉ có đấu chấm phẩy; nó có thể xuất hiện bất cứ nơi nào mà một lệnh
được phép xuất hiện. Lệnh này sẽ bị bỏ qua và không biên dịch. Lệnh null được viết như sau:
;
Đặc tả ngôn ngữ lập trình 10
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.5.2. Lệnh biểu thức
Khi một lệnh biểu thức được thi hành, thì kết quả của biểu thức đó sẽ được tính toán.
biểu_thức;
Ví dụ:
y = ( f( x ) + 3 ); /* A function-call expression */
Trong lệnh này, biểu thức gọi hàm f(x), lấy giá trị trả về của hàm này cộng 3 và sau đó gán kết
quả cuối cùng vào biến y.
1.5.3. Lệnh break
Lệnh break kết thúc việc thực thi các vòng lặp do, for, while hoặc cấu trúc switch trực tiếp chứa nó. Quyền điều khiển sẽ được đưa về cho lệnh tiếp theo gần vòng lặp/cấu trúc này nhất.
break;
1.5.4. Lệnh khối
Một lệnh khối thường dùng làm phần thân của một lệnh khác, chẳng hạn như lệnh if, do, for, while. Một lệnh ghép được cấu thành từ một hay nhiều câu lệnh được đặt giữ một cặp dấu ngoặc nhọn ({ }).
{ danh_sách_lệnh }
1.5.5. Lệnh continue
Lệnh continue chuyển quyền điều khiển cho lần duyệt tiếp của vòng lặp do, for hoặc while trực tiếp chứa nó, và bỏ qua các lệnh còn lại trong phần thân của vòng lặp này.
continue;
1.5.6. Lệnh if
Lệnh if điều khiểu việc rẻ nhánh có điều kiện. Phần thân của một lệnh if được thi hành nếu giá trị của biểu thức khác không. Cú pháp của lệnh if có 2 dạng.
if ( biểu_thức ) lệnh hoặcif ( biểu_thức ) lệnh else lệnh
1.5.7. Lệnh else if
if ( biểu_thức_1 ) lệnh_1 else if ( biểu_thức_2 ) lệnh_2...else if ( biểu_thức_n-1 ) lệnh_n-1 else lệnh_n
Đặc tả ngôn ngữ lập trình 11
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Nếu biểu_thức_1 đúng thì thực hiện lệnh_1 và thoát khỏi cấu trúc if
Ngược lại nếu biểu_thức_2 đúng thì thực hiện lệnh_2 và thoát khỏi cấu trúc if
…
Ngược lại nếu biểu_thức_n-1 đúng thì thực hiện lệnh_n-1 và thoát khỏi cấu trúc if
Ngược lại thì thực hiện lệnh_n.
1.5.8. Lệnh switch và case
Lệnh switch và case cho phép người dùng điều khiển các hoạt động rẻ nhánh và có điều
kiện phức tạp. Lệnh switch chuyển quyền điều khiển đến một lệnh trong phần thân của nó.
switch ( biểu_thức )
nhãn: (nếu có)case biểu_thức_hằng_số_1 : danh_sách_lệnh_1case biểu_thức_hằng_số_2 : danh_sách_lệnh_2...case biểu_thức_hằng_số_n-1 : danh_sách_lệnh_n-1default: danh_sách_lệnh_n
Quyền điều khiển sẽ được chuyển đến các lệnh case có giá trị bằng với giá trị của biểu thức
trong lệnh switch. Lệnh switch có thể chứa vô số lệnh case nhưng các hằng số của các
lệnh case này không được phép trùng nhau. Lệnh switch sẽ so sánh giá trị của biểu thức
trong nó với giá trị của từng lệnh case cho tới khi không còn lệnh case nào để so sánh nữa
thì nó sẽ thi hành danh_sách_lệnh_n trong lệnh default. Khi thi hành
danh_sách_lệnh_i, nếu trong danh_sách_lệnh_i không có lệnh break thì sẽ tiếp tục
thực hiện các danh_sách_lệnh_i+1 cho đến danh_sách_lệnh_n hoặc gặp lệnh break
trong các khối lệnh đó thì kết thúc hàm switch.
1.5.9. Lệnh do-while
Lệnh do-while dùng để lặp lại một lệnh hoặc một lệnh khối cho đến khi biểu thức điều kiện
không đúng nữa.
do lệnh while ( biểu_thức );
(biểu_thức) trong lệnh do-while được tính toán sau khi vòng lặp được thực thi. Cho nên,
vòng lặp do-while luôn được thi hành ít nhất một lần.
1.5.10. Lệnh while
Lệnh while dùng lặp để lại một lệnh hoặc một lệnh khối khi biểu thức (biểu_thức) điều
kiện thỏa.
while ( biểu_thức ) statement;
Lệnh while kết thúc khi có một lệnh break, goto, hay return trong phần thân của lệnh
này được thi hành. Sử dụng lệnh continue trong vòng lặp while để ngưng lần lặp hiện tại
Đặc tả ngôn ngữ lập trình 12
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
và chuyển tới lần lặp tiếp theo.
1.5.11. Lệnh for
Lệnh for dùng để lặp lại một lệnh hoặc một lệnh khối với một số lần cụ thể. Phần thân của
lệnh for không được thi hành hoặc thi hành nhiều lần cho đến khi điền kiện lặp (không bắt
buộc) không thỏa nữa. Ta có thể dùng các biểu thức trong lệnh for để khởi tạo và thay đổi
giá trị của biểu thức trong suốt quá trình thực thi của lệnh for.
for ( biểu_thức_khởi_tạo; biểu_thức_điều_khiện; biểu_thức_vòng_lập )
lệnh
Lệnh for đang thực thi sẽ kết thúc khi thi hành một lệnh break, goto, hay return trong
phần thân của nó. Sử dụng lệnh continue trong vòng lặp for để ngưng lần lặp hiện tại và
chuyển tới lần lặp tiếp theo.
1.5.12. Lệnh goto và các lệnh có nhãn.
Lệnh goto chuyển điểu khiển đến một nhãn. Nhãn này phải nằm trong cùng một hàm với
lệnh goto và phải được đính kèm với một lệnh nào đó.
nhãn:lệnh_có_nhãn... goto nhãn;
lệnh_có_nhãn chỉ có ý nghĩa với lệnh goto. Lệnh này sẽ được thực thi như lệnh bình
thường.
1.5.13. Lệnh return
Lệnh return kết thúc việc thực thi một hàm và trả lại quyền điều khiển cho hàm gọi nó.
Lệnh return cũng trả về một giá trị cho hàm gọi nó.
return [biểu_thức] ;
Giá trị của biểu thức (nếu có) được trả về cho hàm gọi nó. Nếu lệnh return không có biểu
thức phía sau nó thì giá trị trả về sẽ không được xác định. Giá trị của biểu thức biểu_thức
(nếu có) sẽ được chuyển đổi thành kiểu trả về của hàm.
1.5.14. Lệnh __asm, __endasm
Các lệnh này cho phép chèn trực tiếp các lệnh hợp ngữ vào các chương trình nguồn của mình.
Người dùng có thể sử dụng các biến toàn cục cho các lệnh hợp ngữ này.
__asmCác_lệnh_hợp_ngữ
__endasm;
Đặc tả ngôn ngữ lập trình 13
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Trình biên dịch hiểu các lệnh hợp ngữ chuẩn cũng như các lệnh riêng của SG8V1( tham khảo
datasheet SG8V1 để biết thêm chi tiết).
Đặc tả ngôn ngữ lập trình 14
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.6. Hàm
Hàm là đơn vị cơ bản cấu thành một chương trình. Hàm thường được thiết kế để thi hành một
nhiệm vụ cụ thể, và tên của hàm thường phản ánh nhiệm vụ của hàm đó. Hàm phải được định
nghĩa và khai báo trong chương trình. Phần này miêu tả cách khai báo, định nghĩa một hàm và
cách gọi các hàm.
1.6.1. Định nghĩa hàm
Định nghĩa hàm dùng để đặt tên, định kiểu trả về của hàm, kiểu và số lượng các tham số.
Định nghĩa hàm cũng bao gồm phần thân của hàm với các biến cục bộ được khái báo bên
trong hàm và các lệnh mà hàm đó thi hành.
định_danh_kiểu khai_báo_thể_hàm lệnh_khối
Trong đó:
▪ khai_báo_thể_hàm là:
khai_báo_thể ( danh_sách_tham_số)
▪ danh_sách_tham_số là:
khai_báo_tham_số
hoặc
khai_báo_tham_số_1, khai_báo_tham_số_2, … , khai_báo_tham_số_n
định_danh_kiểu và khai_báo_thể_hàm được dùng để chỉ ra kiểu trả về và tên của hàm.
khai_báo_thể_hàm là sự kết hợp của một định danh dùng để nêu tên của hàm và cặp dấu
ngoặc tròn ngay sau định danh này.
Lệnh khối chính là phần thân của hàm. Lệnh này chứa các khai báo biến cục bộ, những nhân
tố được khai báo bên ngoài và các lệnh mà nó phải thực thi.
1.6.2. Khai báo hàm
Khai báo hàm đứng trước định nghĩa hàm. Nó dùng để nêu tên, kiểu trả về, lớp phạm vi, và
các thuộc tính khác của một hàm. Theo nguyên mẫu, khai báo hàm cũng phải thiết lập các
kiểu và các định danh cho các tham số của hàm.
định_danh_kiểu khai_báo_thể_hàm;
Trong đó:
▪ khai_báo_thể_hàm là:
khai_báo_thể ( danh_sách_tham_số)
▪ danh_sách_tham_số là:
Đặc tả ngôn ngữ lập trình 15
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
khai_báo_tham_số
hoặc
khai_báo_tham_số_1, khai_báo_tham_số_2, … , khai_báo_tham_số_n
Theo nguyên mẫu, khai báo hàm có định dạng tương tự như định nghĩa hàm, chỉ khác nhau là
khai báo hàm kết thúc bởi dấu chấm phẩy ngay sau dấu ngoặc đơn đóng.
Ví dụ khai báo hàm theo nguyên mẫu:
int add( int a, int b );
Ví dụ khai báo hàm khuyết (không theo nguyên mẫu):
int add( int, int );
1.6.3. Lệnh gọi hàm
Lệnh gọi hàm là một biểu thức dùng để truyền quyền điều khiển, các tham số đến một hàm.
Nó có dạng:
tên_hàm ( danh_sách_biểu_thức )
Trong đó, danh_sách_biểu_thức là một danh sách các biểu thức (tách bởi dấu phẩy). Các
giá trị của biểu thức là các tham số truyền đến hàm. Nếu hàm không trả về một giá trị thì hàm
đó nên được khai báo như hàm trả về kiểu void.
1.6.4. Truyền tham số
Một tham số có thể là bất kì giá trị nào có kiểu cơ bản, cấu trúc, hợp nhất, hoặc con trỏ. Có
hai cách truyền tham số:
▪ Truyền tham trị: lúc này trình biên dịch sẽ sao chép giá trị của tham số vào một vùng
nhớ tạm để hàm dùng. Hàm không biết vị trí vùng nhớ thực tế của tham số truyền
vào. Vì thế hàm có thể dùng bản sao này mà không ảnh hưởng đến bản gốc của nó.
▪ Truyền tham biến: truyền tham biến chính là truyền các con trỏ cho phép hàm truy
xuất biến một cách gián tiếp. Do một con trỏ chỉ đến một biến mà con trỏ chứa địa
chỉ của biến này nên hàm có thể dùng địa chỉ này để truy xuất giá trị của biến. Tham
số con trỏ cho phép một hàm truy xuất các mảng, mặc dù các mảng không thể truyền
trực tiếp như một tham số vào hàm.
1.7. Chú thích
Một chú thích có thể xuất hiện bất cứ nơi nào trong một tập tin. Chú thích là các ký tự giữa
hai dấu /* và */ cũng như các ký tự ngay sau dấu (//) đến khi kết thúc dòng. Chú thích sẽ bị bỏ
qua và không được biên dịch.
Đặc tả ngôn ngữ lập trình 16
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
/* chú_thích... */
Hoặc
lệnh; // chú_thích
Đặc tả ngôn ngữ lập trình 17
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
1.8. Chỉ thị tiền tiền xử lý
1.8.1. Chỉ thị #define
Chỉ thị #define dùng để cung cấp tên cho một hằng số hoặc định nghĩa một macro trong
chương trình. Định dạng của chỉ thị này như sau:
#define định_danh chuỗi_kí_tựhoặc#define định_danh( danh_sach_định_danh ) chuỗi_kí_tự
Chỉ thị #define thay thế định_danh xuất hiện sau chỉ thị này bằng chuỗi_kí_tự. Ngoài
ra nếu định danh trong chỉ thị này được khai báo như một hàm (tức có kèm theo tham số đặt
trong danh sách_định_danh) thì ngoài việc thay định_danh bằng chuỗi_kí_tự, chỉ
thị này còn thay thế giá trị của từng tham số vào định_danh tương ứng của nó trong chuỗi
bất kỳ.
Một chỉ thị #define mà không có chuỗi_kí_tự sẽ loại bỏ toàn bộ những định_danh
xuất hiện sau chỉ thị này ra khỏi tập tin nguồn. Tuy nhiên, định_danh vẫn được xem như đã
được định nghĩa và có thể được sử dụng trong các chỉ thị #if và #ifdef.
1.8.2. Các chỉ thị #if, #else, #endif
Các chỉ thị #if, #else và #endif quyết định đoạn mã nào sẽ được tham gia vào quá trình
biên dịch. Nếu biểu_thức_hằng_số có giá trị khác 0 thì đoạn_mã_1 sẽ được dịch. Bằng
không thì đoạn_mã_2 sẽ được dịch.
#if biểu_thức_hằng_sốđoạn_mã_1
[#else đoạn_mã_2]
#endif
1.8.3. Các chỉ thị #ifdef và #ifndef
Các chỉ thị #ifdef và #ifndef có chức năng như chỉ thị #if nếu được sử dụng cùng từ
khóa defined. Ví dụ như:
#ifdef định_danh#ifndef định_danh//tương đương với #if defined định_danh#if !defined định_danh
Cặp từ khóa #ifdef và #ifndef theo thứ tự chỉ yêu cầu trình biên dịch kiểm tra xem
định_danh đã được định nghĩa bằng chỉ thị #define hay chưa được định nghĩa.
Đặc tả ngôn ngữ lập trình 18
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
2. Thư viện tích hợp
2.1. Định địa chỉ tuyệt đối
Định địa chỉ tuyệt đối cung cấp cách đọc và ghi dữ liệu cổng, cách tương tác với các chức
năng thanh ghi đặt biệt (SFR) như thanh ghi timer, capture .v.v... Ví dụ:
__sfr __at(0x03) STATUS;
Khai báo một biến có tên là STATUS (là một thanh ghi chức năng đặt biệt), tương ứng với
thanh ghi tại địa chỉ 0x03. Một khi được khai báo thì nó có thể gán trực tiếp giá trị vào thanh
ghi này.
STATUS = 0x34;
Ngoài phương pháp định địa chỉ tuyệt đối, người dùng có thể dùng kiểu hợp nhất để truy xuất
giá trị kiểu bit của một thanh ghi. Ví dụ:
#define STATUS_ADDR 0x0003typedef union { struct { unsigned char C:1; unsigned char DC:1; unsigned char Z:1; unsigned char NOT_PD:1; unsigned char NOT_TO:1; unsigned char RP0:1; unsigned char RP1:1; unsigned char IRP:1; };} __STATUS_bits_t;
volatile __STATUS_bits_t __at(STATUS_ADDR) STATUS_bits;...STATUS_bits.C = 1;
2.2. Các hằng số và biến tích hợp.
Tất cả các thanh ghi chức năng đặc biệt (SFR) cũng như các cổng và các chân theo datasheet
SG8V1 được khai báo trong tập tin sg8v1.h. Như vậy, người dùng có thể dễ dàng sử dụng
chúng trực tiếp.
char *p = PORTA;
Đối với tám thanh ghi PORTX và DIRX mà X là A, B, C hoặc D thì người dùng có thể sử dụng
các chân của nó theo ví dụ sau đây:
PORTA_bits.PINi = 0; // i is between 0 and 7.
Thư viện tích hợp 19
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Tham khảo datasheet SG8V1 cho biết thêm các chi tiết về các thanh ghi và các chân.
Mỗi ngắt (interrupt) có một nhãn tương ứng.
Nguồn ngắt Sự kiện gây ra Nhãn ngắt
Timers Thanh ghi timer bị tràn.
INT_TIMER0INT_TIMER1INT_TIMER2INT_TIMER3
Ngắt ngoài Giá trị của các chân ngắt ngoại vi thay đổi.
INT_EXT0INT_EXT1INT_EXT2INT_EXT3
CC Compare hoặc Capture INT_CC
UART1
Truyền dữ liệu khi bộ đệm dữ liệu rỗng INT_TBE1
Nhận dữ liệu khi bộ đệm dữ liệu đầy. INT_RDA1
UART2
Truyền dữ liệu khi bộ đệm dữ liệu rỗng INT_TBE2
Nhận dữ liệu khi bộ đệm dữ liệu đầy. INT_RDA2
SPITruyền hoặc nhận dữ liệu INT_SPI
I2C
Truyền hoặc nhận dữ liệu INT_I2C
Xung đột bus dữ liệu INT_BUSCOL
Bảng 3: Các nhãn ngắt
2.3. Các hàm và chỉ thị của SG8V1
2.3.1. Truy xuất cổng
▪ Ghi một số nguyên 8 bit đến cổng X với X là A, B, C, hoặc D.
void output_X(unsigned char);
▪ Đọc một số nguyên 8 bit từ cổng X với X là A, B, C, hoặc D.
unsigned char input_X();
▪ Thiết lập trạng thái mức cao cho các chân của cổng X.
void output_high(PIN_Xi);
Thư viện tích hợp 20
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
▪ Thiết lập trạng thái mức thấp cho các chân của cổng X.
void output_low(PIN_Xi);
▪ Đảo trạng thái các chân của cổng X.
void output_toggle(PIN_Xi);
▪ Cấu hình hướng xuất/nhập của cổng X.
void set_tris_X(unsigned char);
▪ Lấy giá trị cấu hình hướng xuất/nhập của cổng X
unsigned char get_tris_X();
Để đọc hoặc ghi một cổng X, các hàm này (output_X, input_X) sửa đổi các thành
ghi định hướng tương ứng. Ví dụ, trong hàm input_B(), phải có một lệnh TRISB =
0xFF; hơn nữa, khi đọc hay thay đổi giá trị của một chân, những hàm này sẽ thay đổi
bit tương ứng trong thanh ghi định hướng. Các nhãn chân (PIN_Xi) được khai báo
thành các hằng số tích hợp.
2.3.2. Bộ nhớ
▪ Đọc một byte dữ liệu từ một vị trí trong RAM
unsigned char read_bank(bank, offset);
Tham số bank có giá trị từ 1 đến 4; một bank bắt đầu tại offset 0.
▪ Ghi một giá trị (kiểu 8-bit) vào một vị trí RAM
void write_bank(bank, offset, value);
Các tham số bank và offset thì giống như trong hàm read_bank, còn value là
số nguyên 8 bit
2.3.3. Cấu hình stack
▪ Chỉ thị tiền xử lý #use stack cho phép người dùng thiết lập kích thước của vùng stack
của SG8V1.
#use stack size;
▪ Nếu người dùng không sử dụng chỉ thị này, thì kích thước vùng mặc định của stack
là 256 byte.
Thư viện tích hợp 21
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
2.3.4. Các hàm chờ
▪ Chỉ thị tiền xử lý #use delay:
#use delay(clock=speed);
cho trình biên dịch biết tốc độ của bộ xử lý và cho phép người dùng sử dụng hàm
tích hợp: delay_ms(). Hằng số speed nằm trong khoảng từ 1.000.000 đến
14.000.000 ( 1MHz đến 14MHz).
▪ Chờ một khoảng thời gian cụ thể
void delay_ms(unsigned int time);
Time được chỉ định với đơn vị miligiây. Cách hoạt động của hàm này là thực thi một
số lệnh hợp ngữ để tạo ra độ trễ tương ứng.
▪ Chờ theo chu kỳ
void delay_5cycles(unsigned char count);
void delay_10cycles(unsigned char count);
void delay_100cycles(unsigned char count);
void delay_1kcycles(unsigned char count);
void delay_10kcycles(unsigned char count);
void delay_100kcycles(unsigned char count);
Các hàm này tạo mã để thực thi số lượng cụ thể các lệnh hợp ngữ nhằm tạo ra độ trễ
ứng với số chu kỳ được chỉ định (1-255). Một chu kỳ thực thi lệnh hợp ngữ bằng với
bốn chu kỳ dao động.
Độ trễ có thể bị sai lệch (dài hơn) so với yêu cầu nếu một ngắt được phục vụ trong suốt
quá trình chờ. Nói cách khác, thời gian dành cho các hàm phục vụ ngắt (ISR) sẽ không
được tính vào thời gian chờ.
2.3.5. Các ngắt
▪ Cho phép hay vô hiệu hóa quyền ưu tiên của ngắt
#enable_int_priority//or #disable_int_priority
Theo mặc định thì quyền ưu tiên của ngắt sẽ được bật.
▪ Cho phép hay vô hiệu hóa các cấp độ ngắt
void enable_interrupt_level(level); //andvoid disable_interrupt_level(level);
Thư viện tích hợp 22
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
level có thể là một trong những giá trị: GLOBAL, HIGH, LOW, EXTERNAL, hoặc
PERIPHERAL. Cấp độ HIGH/LOW có thể chỉ dùng khi quyền ưu tiên ngắt được bật,
ngược lại, cấp độ EXTERNAL/PERIPHERAL chỉ được dùng khi quyền ưu tiên ngắt bị
vô hiệu hóa.
▪ Cho phép hay vô hiệu hóa các ngắt
void enable_interrupts(interrupts); //andvoid disable_interrupts(interrupts);
interrupts là bit được tính bằng cách hợp (phép OR) các nhãn ngắt.
▪ Định nghĩa hàm con phục vụ ngắt (ISR):
#int_xxxxhandler_definition
Chỉ thị này đứng ngay trước một định nghĩa hàm; và hàm này được gọi bất kỳ lúc
nào ngắt xxxx xảy ra. Ví dụ:
#int_timer0void int_timer0_handler() {statements
}
Trình biên dịch sẽ tạo ra mã để nhảy đến hàm này khi ngắt tương ứng xảy ra. Hàm
con này sẽ tự động xóa cờ ngắt khi đã phục vụ ngắt. Để ngăn không cho xóa cờ ngắt
thì phải thêm noclear sau #int_xxxx
#int_timer0 noclear
Một chỉ thị ngắt mà sau nó là từ khóa high hoặc low giúp trình biên dịch biết được
độ ưu tiên của ngắt này là cao hay thấp tương ứng. Mặc định, nếu không khai báo các
chỉ thị này thì quyền ưu tiên là cao (high).
#int_timer0 highvoid int_timer0_handler() {statements
}
▪ Thiết lập quyền ưu tiên giữa các ngắt
#int_priority interrupt_list
interrupt_list là một danh sách chứa một hoặc nhiều ngắt được tách nhau bởi
dấu phẩy và được sắp xếp theo thứ tự ưu tiên từ cao đến thấp (từ trái qua phải).
Chỉ thị này phân quyền ưu tiên một cách trực quan và trái ngược với tùy chọn high|
low trong định nghĩa ISR phía trên. Nó vẫn hoạt động mặc dù quyền ưu tiên ngắt bị
vô hiệu hóa do chỉ thị #disable_int_priority, tức là theo mặc định tất cả các
ngắt có quyền ưu tiên cao.
Thư viện tích hợp 23
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Khi quyền ưu tiên ngắt ( phần cứng ) được bật và interrupt_list chứa các ngắt
có quyền ưu tiên cao lẫn thấp, thì interrupt_list được xem như hai danh sách
riêng biệt, một cho các ngắt mức ưu tiên cao và một cho các ngắt mức ưu tiên thấp;
và trình biên dịch cho rằng chỉ thị #int_priority đã được cung cấp cho từng danh
sách. Chúng sẽ được sắp xếp theo từng danh sách riêng biệt.
▪ Xóa các cờ ngắt
void clear_interrupt_flags(interrupts);
interrupts là bit được tính bằng cách hợp (phép OR) các nhãn ngắt.
▪ Chọn sự kiện ngắt theo cạnh lên hoặc theo cạnh xuống đối với các ngắt ngoài.
void ext_int_edge(external_int, ext_type);
Trong đó:
▫ external_int là một trong bốn ngắt ngoài, và▫ ext_type là H_TO_L hoặc L_TO_H.
2.3.6. Bộ định giờ
▪ Cấu hình timer0 (tức là RTCC):
void setup_timer0(mode);
Với mode là một trong những hằng số hay hợp (phép OR) các hằng số thuộc nhóm
một và nhóm hai:
▫ RTCC_INTERNAL, RTCC_EXT_L_TO_H, RTCC_EXT_H_TO_L.
▫ RTCC_DIV_2, RTCC_DIV_4, RTCC_DIV_8, RTCC_DIV_16, RTCC_DIV_32, RTCC_DIV_64, RTCC_DIV_128, RTCC_DIV_256, (cấu hình tiền tỉ lệ, ví dụ: 1:2, 1:4,...)
▫ RTCC_OFF (vô hiệu hóa timer0).
Ví dụ:
setup_timer0(RTCC_DIV_2 | RTCC_EXT_L_TO_H);
Thư viện tích hợp 24
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 1: Sơ đồ khối của Timer0
▪ Thiết lập giá trị đếm của timer0:
void set_timer0(unsigned char n);
▪ Lấy giá trị đếm của timer0:
unsigned char get_timer0();
▪ Cấu hình timer1:
void setup_timer1(mode);
Với mode là một trong những hằng số hay hợp (phép OR) các hằng số thuộc hai
nhóm khác nhau:
▫ T1_OFF, T1_INTERNAL, T1_EXTERNAL, T1_EXTERNAL_SYNC
▫ T1_DIV_BY_1, T1_DIV_BY_2, T1_DIV_BY_4, T1_DIV_BY_8 (cấu hình tiền tỉ lệ. Ví dụ: 1:1, 1:2,...).
Ví dụ:
setup_timer1(T1_INTERNAL | T1_DIV_BY_4);
▪ Thiết lập giá trị đếm của timer1:
void set_timer1(unsigned int n);
▪ Lấy giá trị đếm của timer1:
unsigned int get_timer1();
Thư viện tích hợp 25
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 2: Sơ đồ khối của Timer1
Hình 3: Sơ đồ khối của Timer2
▪ Cấu hình timer2:
void setup_timer2(mode, period, postscale);
Với:
▫ mode là một trong những hằng số sau: T2_OFF, T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16, T2_DIV_BY_64. Hàm này vô hiệu hóa hay khởi động timer2 với một tỉ lệ chia xung (clock divisor) nhất định.
▫ Period là một số nguyên 10-bit được dùng để quyết định khi nào giá trị của đồng hồ phải được đưa về 0. Giá trị của nó (0-1024) được gán cho thanh ghi PR2.
▫ postscale là một trong các hằng số sau: T2_POST_SCALER_BY_n với n nằm trong khoảng 1 và 16.
▪ Thiết lập giá trị của timer2:
void set_timer2(unsigned int n);
▪ Lấy giá trị của timer2:
unsigned int get_timer2();
▪ Các hàm setup_timer3, set_timer3, get_timer3 dùng để điều khiển timer3
cũng được định nghĩa giống như những hàm dành cho timer2.
▪ Cấu hình WDT:
void setup_wdt(mode);
Với mode là một trong số những hằng số sau: WDT_ON, WDT_OFF, WDT_DIV_2, WDT_DIV_4, WDT_DIV_8, WDT_DIV_16, WDT_DIV_32, WDT_DIV_64,
WDT_DIV_128, WDT_DIV_256. Hàm này khởi động/vô hiệu hóa WDT hoặc gán
cho nó một giá trị tiền tỉ lệ nào đó.
▪ Xóa WDT (nhằm tránh việc khởi động lại watchdog):
void clr_wdt();
Thư viện tích hợp 26
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 4: Sơ đồ khối của WDT
2.3.7. Bộ ghi và so sánh (Capture/Compare) (CC)
▪ Cấu hình CC:
void setup_cc(mode);
Với mode là một trong tám hằng số số được chia làm hai nhóm sau:
Chế độ ghi:▫ CC_CAPTURE_FE: ghi khi gặp cạnh đi xuống (CCMOD[2:0] = 000),
▫ CC_CAPTURE_RE: ghi khi gặp cạnh đi lên (CCMOD[2:0] = 001),
▫ CC_CAPTURE_DIV_4: ghi sau mỗi bốn nhịp (CCMOD[2:0] = 010),
▫ CC_CAPTURE_DIV_16: ghi sau mỗi 16 nhịp (CCMOD[2:0] = 011);
Chế độ so sánh:
▫ CC_COMPARE_SET_ON_MATCH: xuất ra tín hiệu cao khi so sánh (CCMOD[2:0] = 100),
▫ CC_COMPARE_CLR_ON_MATCH: xuất ra tín hiệu thấp khi so sánh (CCMOD[2:0] = 101),
▫ CC_COMPARE_INT: bật ngắt khi so sánh (CCMOD[2:0] = 110),
▫ CC_COMPARE_TOGGLE: đảo trạng thái tín hiệu đầu ra khi so sánh (CCMOD[2:0] = 111).
Hàm này cấu hình chân RD6 thành chân xuất (nhập) khi sử dụng chế độ so sánh (chế
độ ghi) bằng cách gán bit DIRD[6] bằng một (gán bằng 0).
▪ Khởi động/vô hiệu hóa CC:
void cc(state);
Với state có thể dùng một trong hai giá trị CC_ON hay CC_OFF. Theo đó, hàm này
gán hằng số CCEN thành 0 hay 1 tương ứng.
▪ Thiết lập giá trị thanh ghi CC:
void set_cc_value(unsigned int n);
▪ Lấy giá trị thanh ghi CC:
unsigned int get_cc_value();
2.3.8. Bộ điều chế độ rộng xung (PWM)
Vi xử lý SG8v1 có hai bộ PWM (PWM1 and PWM2) với các tính năng tương tự nhau. Để cấu
hình chúng thì người dùng cần dùng các hàm sau:
▪ Cấu hình PWM1:
void setup_pwm1(mode, duty);
Với
Thư viện tích hợp 27
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
▫ mode có thể là T2_CLOCK hay T3_CLOCK ,
▫ duty là một số nguyên 0-bit (từ 0 tới 1023) dùng để quyết định tải của PWM1.
Hàm này sẽ chọn đồng hồ của PWM1 từ timer2 hay timer3 bằng cách gán bằng
một hay xóa bit PWM1TS. Để cấu hình được tải của PWM1, hàm này sẽ gán duty vào
PWM1RH:PWM1RL và thiết lập hướng xuất của PORTC[2] bằng cách cấu hình bit
DIRC[2].
▪ Khởi động/vô hiệu hóa PWM1:
void pwm1(state);
Với state có thể là PWM_ON hay PWM_OFF. Hàm này thay đổi bit PWM1ON.
▪ Cấu hình PWM2:
void setup_pwm2(mode, duty);
Với
▫ mode có thể là T2_CLOCK hay T3_CLOCK ,
▫ duty là một số nguyên 0-bit (từ 0 tới 1023) dùng để quyết định tải của PWM2.
Hàm này sẽ chọn đồng hồ của PWM2 từ timer2 hay timer3 bằng cách gán bằng
một hay gán bằng không bit PWM2TS. Để cấu hình được tải của PWM2, hàm này sẽ
gán duty vào PWM2RH:PWM2RL và thiết lập hướng xuất của PORTC[3] bằng cách
cấu hình bit DIRC[3].
▪ Khởi động/vô hiệu hóa PWM2:
void pwm2(state);
Với state có thể là PWM_ON hay PWM_OFF. Hàm này thay đổi bit PWM2ON.
2.3.9. Giao tiếp SPI
▪ Người dùng có thể cấu hình SPI như sau:
void setup_spi(mode);
Trong đó, mode có thể là một trong những hằng số sau, hay hợp (phép OR) chúng:
▫ Thiết lập thiết bị: SPI_MASTER, SPI_SLAVE, SPI_DISABLED;
▫ Chọn cực của đồng hồ: SPI_HIGH, SPI_LOW;
▫ Chọn loại đồng hồ SPI: SPI_FALLING_EDGE, SPI_RISING_EDGE.
▫ Thiết lập chế độ SPI:
Nếu một thiết bị được thiết lập như thiết bị chủ, chế độ SPI mode là một trong những hằng số sau: SPI_CLK_DIV_4, SPI_CLK_DIV_16, SPI_CLK_DIV_64, SPI_CLK_T2;
Nếu một thiết bị được thiết lập như là thiết bị nô lệ, chế độ SPI có thể là một trong những hằng số sau: ENABLE_SS, DISABLE_SS.
Thư viện tích hợp 28
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hàm này sẽ phải thiết lập bit SPICON bằng một.
Ví dụ:
setup_spi(SPI_MASTER | SPI_HIGH | SPI_CLK_DIV_64);//orsetup_spi(SPI_SLAVE | SPI_HIGH | ENABLE_SS);
▪ Gởi một byte thông qua SPI:
void spi_write(unsigned char value);
Hàm này sẽ chiếm 8 chu kỳ đồng hồ.
▪ Nhận một byte thông qua SPI:
unsigned char spi_read();
Hàm này chiếm một chu kỳ đồng hồ và trả về giá trị được đọc bởi SPI. Tham số
parameter out_data không phải là thông số bắt buộc. Ví dụ như:
in_data = spi_read(out_data);// does the same thing as spi_write(out_data);in_data = spi_read();
If chưa nhận được dữ liệu thì spi_read sẽ tiếp tục chờ.
▪ Kiểm tra xem dữ liệu đã sẵn sàng hay chưa:
bool spi_data_is_in();
Hàm này sẽ trả về giá trị true nếu dữ liệu được nhận thông qua SPI.
2.3.10. Giao tiếp I2C
▪ Để sử dụng giao tiếp I2C và các hàm liên quan thì chỉ thị sau phải được sử dụng:
#use i2c(options)
Trong đó options là danh sách các cấu hình được phân cách bởi các dấu phẩy (,):
▫ Cấu hình thiết bị dưới dạng thiết bị master hay slave: I2C_MASTER, I2C_SLAVE;
▫ Thiết lập tốc độ I2C: I2C_STANDARD, I2C_FAST;
▫ speed=n, cấu hình tốc độ I2C trong chế độ master ở tốc độ n (Kb/s), n phải nhỏ
hơn hoặc bằng 400Kb/s. Nên nhớ rằng tốc độ chuẩn tương ứng của chế độ
I2C_STANDARD và I2C_FAST là 100 và 400Kb/s;
▫ Sử dụng phần cứng cho I2C: FORCE_HW,
▫ Thiết lập chế độ địa chỉ:
Thư viện tích hợp 29
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
ADDR_7BITS: sử dụng chế độ địa chỉ 7-bit,
ADDR_10BITS: sử dụng chế độ địa chỉ 10-bit,
ADDR_7BITS_INT: sử dụng chế độ địa chỉ 7-bit với bit Start và Stop được gài ngắt,
ADDR_10BITS_INT: sử dụng chế độ địa chỉ 10-bit với bit Start và Stop được gài ngắt;
▫ address=n: nêu địa chỉ thông qua giá trị n, trong chế độ slave;
Ví dụ:
#use i2c(I2C_MASTER, I2C_FAST, ADDR_7BITS) // hay#use i2c(I2C_SLAVE, ADDR_7BITS, address=0xa0)
Bit I2CON phải được cấu hình nếu chỉ thị (#use i2c) được sử dụng.Các tùy chọn địa
chỉ như addr_7bits, addr_10bits, addr_7bits_int, addr_10bits_int
chỉ có thể được dùng chỉ khi bit I2C được cấu hình thành slave.
▪ Khởi động I2C trong chế độ master:
void i2c_start();
Hàm này phát động một điều kiện khởi động và đồng hồ được thiết lập ở mức thấp
cho tới khi hàm i2c_write được gọi. Nếu một hàm i2c_start khác được gọi
trong cùng một hàm trước khi hàm i2c_stop được sử dụng thì một lệnh khởi động
lại đặt biệt sẽ được phát động.
▪ Ngưng I2C trong chế độ master:
void i2c_stop();
Hàm này phát động một điều kiện ngưng cho I2C.
▪ Nhận một byte thông qua giao thức I2C:
unsigned char i2c_read(bit ack);
Tham số tùy chọn ack theo mặc định là 1.
Trong chế độ chủ thì hàm này sẽ tạo ra xung còn trong chế độ slave thì nó sẽ chờ
xung.
▪ Gởi một byte thông qua giao thức I2C:
unsigned char i2c_write(unsigned char data);
Giá trị trả về là một byte đại diện cho bit ack (0 là ack, 1 là không ack) hay một xung
đột trong chế độ đa-master (giá trị trả về bằng 2). Giá trị trả về chẳng có ý nghĩa gì
nếu I2C đang trong chế độ slave.
Thư viện tích hợp 30
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Trong chế độ chủ thì hàm này sẽ tạo ra một xung với dữ liệu. Còn trong chế độ nô lệ
thì nó sẽ chờ một xung từ chủ. Bit bên phải của lần ghi đâu tiền kể từ lúc bắt đầu sẽ
quyết định hướng truyền dữ liệu (0 nghĩa là từ chủ đến nô lệ)
▪ Kiểm tra xem liệu phần cứng đã nhận một byte trong bộ đệm hay chưa:
bit i2c_poll();
Khi giá trị trả về bằng 1 thì lệnh i2c_read sẽ lập tức trả về byte mà nó nhận được.
2.3.11. Giao tiếp UART
▪ Để có thể sử dụng UART (tức RS232) cũng như các hàm liên quan thì người dùng
phải sử dụng chỉ thị sau:
#use rs232(options)
Thư viện tích hợp 31
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 5: Sơ đồ khối của bộ truyền UART
Hình 6: Sơ đồ khối của bộ nhận UART
Chỉ thị này cho trình biên dịch biết tốc độ xung (baud rate) và các chân dùng cho
việc xuất/nhập tuần tự. Chỉ thị này cho phép sử dụng các hàm tích hợp như getc,
putc, puts và printf (xem bên dưới); và nó có tác dụng cho tới khi gặp một chỉ
thị RS232 khác.
Chỉ thị #use delay phải xuất hiện trước khi chỉ thị RS232 có thể được sử dụng.
Nếu tốc độ xung bị sai lệch quá 3% giá trị mong muốn thì người dùng sẽ gặp một
thông báo lỗi. Biến RS232_ERRORS là biến chỉ-đọc và nó là một bản sao của thanh
ghi URXCON trừ việc bit sô 0 được dùng để chỉ ra lỗi mất dữ liệu.
Tham số options là một danh sách các tùy chọn sau (được phân cách bởi dấu
phẩy):
▫ baud=x: gán tốc độc xung bằng x,
▫ uart=n: chọn UART n,
▫ enable=pin: chân được nêu trong tùy chọn này sẽ có giá trị cao trong suốt quá
trình truyền,
▫ invert: đảo cực của các chân tuần tự.
▫ parity=x: với x có thể là một trong các giá trị: N, E hay O,
▫ timeout=x: thiết lập thời gian hàm getc() phải chờ một byte với đơn vị là
miligiây. Nếu không nhận được bất kỳ kí tự nào trong khoảng thời gian này thì giá
trị trả về của getc() sẽ là 0.
Ví dụ:
#use rs232(baud=115200,parity=N,bits=8)
▪ Nhận một ký tự:
char getc();
Hàm này chờ một ký tự thông qua chân nhận và trả về ký tự này.
▪ Truyền một ký tự:
void putc(char c);
Hàm này gởi một ký tự thông qua chân gởi.
▪ Gởi một chuỗi ký tự :
void puts(char *c);
Hàm này gởi một mảng ký tự (kết thúc bằng ký tự null) bằng cách liên tục gọi hàm
putc.
Thư viện tích hợp 32
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
▪ Xuất một chuỗi:
void printf(string);//or void printf(format_string, values...);
Hàm này tính toán chuỗi được xuất ra từ tham số format_string và các giá trị
tương ứng và gởi chuỗi này qua chân xuất.
Luật định dạng được dựa theo chuẩn ANSI-C (đối với hàm printf) với một số kiểu
biến bị hạn chế. Ký tự % được dùng trong tham số format_string để chỉ ra một
giá trị biến cần phải được định dạng và xuất ra.
Luật định dạng có cấu trúc tổng %nt với:
▫ n là một số tùy ý từ 1 đến 9 nhằm nêu ra số lượng ký tự cần được xuất ra.
▫ t là kiểu và có thể nhận một trong các giá trị sau:
c Character
b Bit
u Unsigned int
d Signed int
s String
Lu Long unsigned int
Ld Long signed int
x Hex int (lower case)
X Hex int (upper case)
Lx Hex long int (lower case)
LX Hex long int (upper case)
Bảng 4: Các luật định dạng được dựa theo chuẩn ANSI-C cho hàm printf
Ví dụ:
format value = 0x12 value = 0xfe
%b 10010 11111110
%03u 018 254
%u 18 254
%2u 18 * (undefined)
%d 18 -2
%x 12 fe
%X 12 FE
%4X 0012 00FE
Bảng 5: Biểu diễn số theo các luật định dạng trong hàm printf
Thư viện tích hợp 33
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
2.3.12. Các hàm chuỗi
▪ Lấy độ dài của chuỗi:
unsigned short strlen(char *);
▪ Nối các chuỗi với nhau:
char * strcat(char *, char *);
▪ Sao chép chuỗi:
void strcpy(char * dest, char * src);
Thư viện tích hợp 34
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
3. Các chức năng và hạn chế của trình biên dịch
Khả năng và hạn chế của trình biên dịch có thể gói gọn như sau:
▪ Dịch và liên kết nhiều tập tin nguồn với những cấu hình tối ưu khác nhau.
▪ Những tập tin không được dùng tới sẽ được thông báo tới người dùng thông qua tab
Compiler. Tính năng này chỉ áp dụng cho biến cục bộ.
▪ Không hỗ trợ biến kiểu bit.
▪ Con trỏ:
▫ Kích thước con trỏ là 3 byte.
▫ Không hỗ trợ con trỏ hàm.
▫ Không hỗ trợ con trỏ kiểu bit .
▪ Hỗ trợ các toán tử cộng, trừ, nhân, chia hết, chia lấy dư (+, -, *, /, %).
▪ Hỗ trợ thuật toán đệ quy khi dịch với tùy chọn --call-soft-stack.
▪ Khoản tác dụng của biến:
▫ Các biến được khai báo ngoài hàm được mặc định xem như biến toàn cục.
▫ Một biến toàn cục có thể được sử dụng trong một hàm khi và chỉ khi nó được khai
báo trước hàm này trong cùng một tập tin nguồn. Bằng không thì người dùng phải
sử dụng từ khóa extern để khai báo biến này.
▫ Biến cục bộ phải được khái báo trước khi được sử dụng để tránh gây ra lỗi khi
biên dịch dự án.
▪ Biến cục bộ sẽ được giải phóng khi hàm kết thục.
▫ Trình biên dịch phân phát một vùng stack để chứa biến cục bộ.
▫ Mỗi lần gọi hàm thì vi xử lý sẽ dùng một vùng stack để chứa vị trí trả về, thông
số, giá trị trả về và giá trị của các biến tạm nằm trong hàm.
Các chức năng và hạn chế của trình biên dịch 35
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
4. Môi trường phát triển tích hợp (IDE).
4.1. Giới thiệu.
Môi trường phát triển tích hợp chính thức của vi xử lý SG8V1 được gọi là iFast. iFast là một
phần mềm nhỏ gọn, dễ sử dụng mà vẫn đầy đủ tính năng của một môi trường phát triển tích
hợp hiện đại. Các tính năng đáng chú ý của phần mềm là:
▪ Tô màu từ khóa.
▪ Thu gọn cấu trúc mã nguồn.
▪ Giao diện tab.
▪ Gợi ý từ khóa.
▪ Chuyển đổi giữa tập tin mã nguồn và tập tin header.
▪ Tìm một từ khóa trong các tập tin dự án.
▪ Tìm định nghĩa của hàm.
Được viết dành riêng cho trình biên dịch của SG8V1 nên iFast là môi trường tốt nhất để lập
trình cho hai vi xử lý này. Người dùng có thể dễ dàng viết, biên dịch và nạp một chương trình
vào trong SG8V1 chỉ với phần mềm iFast. Ngoài ra, iFast cũng có sẵn một bộ tạo mã nguồn
mẫu nhằm giúp người mới sử dụng phần mềm có thể nhanh chóng nắm bắt được cách hoạt
động của nó.
Mục đích của chương này là giởi thiệu các tính năng của phần mềm nhằm giúp người dùng có
thể nắm được cách tạo dự án mới, cấu hình các tính năng của trình biên dịch, biên dịch mã
nguồn thành mã máy và nạp mã máy này vào vi xử lý.
Hiện nay, iFast chỉ hỗ trợ cho các hệ điều hành sau đây:
▪ Windows 7/XP
▪ Ubuntu/Debian
▪ Redhat/CentOS
Ngoài ra, theo chính sách của trung tâm ICDREC thì iFast sẽ được cung cấp miễn phí cho
người dùng.
Môi trường phát triển tích hợp (IDE). 36
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
4.2. Hướng dẫn cài đặt iFast.
iFast có thể được cài đặt trên nhiều hệ điều hành khác nhau như hệ điều hành Windows 7/XP,
Ubuntu/Debian, Redhat/CentOS. Nhưng phần này chỉ hướng dẫn cách cài đặt trên hệ điều
hành Windows XP và Ubuntu/Debian.
4.2.1. Cài đặt iFast trên Windows
Nhấn đôi vào tập tin cài đặt iFast. Tên tập tin này là “Setup_iFast.exe”, giao diện “Welcome”
sẽ hiện ra như hình dưới.
Sau đó, nhấn nút “Next”, màn hình hiển thị hộp thoại bảng quyền như Hình 8
Môi trường phát triển tích hợp (IDE). 37
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 7: Hộp thoại chào mừng của trình cài đặt iFast
Chọn ô “I accept the terms of the License Agreement” để chấp chận giấy phép bản quyền, sau
đó nhấn nút “Next” để tiếp tục cài đặt. Hộp thoại tùy chọn cài đặt cho iFast sẽ hiện ra như
Hình 9.
Môi trường phát triển tích hợp (IDE). 38
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 8: Giao ước giữ iFast với người dùng
Hình 9: Hộp thoại chọn thành phần cài đặt
Trong đó, ô “SG8V1 Compiler Suite” có nghĩa là cài đặt thêm trình biên dịch SG8V1, ô
“Links in Start Menu” có nghĩa là cài đặt thêm biểu tưởng iFast trên thanh “Start Menu” của
Windows, ô “Links in Desktop” nghĩa là cài đặt thêm biểu tượng trên trên desktop của
Windows. Theo mặc định thì cả ba ô này đều được chọn. Nhấn nút “Next” để tiếp tục cài đặt,
màn hình xuất hiện giao diện chọn thư mục cài đặt chương trình iFast.
Nếu ở Windows 7 thì thư mục cài đặt mặc định là “C:\Program files(x86)\icdrec\ifast”.
Người dùng có hai lựa chọn trong giai đoạn này:
▪ Nếu muốn hủy bỏ cài đặt thì nhấn nút “Cancel”.
▪ Nếu muốn thay đổi đường dẫn cài đặt thì nhấn nút “Browse...” và chọn thư mục cài
đặt mới cho iFast.
Sau đó nhấn nút “Install” thì hộp thoại thể hiện chi tiết quá trình cài đặt chương trình sẽ xuất hiện như Hình 11.
Môi trường phát triển tích hợp (IDE). 39
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 10: Hộp thoại chọn đường dẫn cài đặt
Sau khi quá trình cài đặt hoàn tất, màn hình hiển thị một hộp thoại như Hình 12.
Môi trường phát triển tích hợp (IDE). 40
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 11: Hộp thoại thể hiện quá trình cài đặt iFast
Hình 12: Giao diện hộp thoại cài đặt khi quá trình cài đặt hoàn tất.
Khi nhấn nút “Next” thì hộp thoại hoàn thành cài đặt sẽ xuất hiện như Hình 13.
Nhấn nút “Finish” để hoàn tất quá trình cài đặt iFast. Nếu người dùng chọn ô “Run Program”
thì sau khi nhấn nút “Finish”, iFast sẽ được khởi động ngay lập tức.
4.2.2. Cài đặt trên Ubuntu/Debian
Nhấn phím Alt+F2, gõ “gnome-terminal” để mở terminal. Sau đó, di chuyển đến thư mục
chứa tập tin cài đặt iFast. Trên Debian 6 (32bit), tên tập tin này là “iFast-Debian6.0.6-
32bit.run”. Gõ lệnh “./ iFast-Debian6.0.6-32bit.run” để bắt đầu thực hiện cài đặt. Terminal sẽ
hiển thị như sau:
root@debian:~/Desktop$ ./iFast-Debian6.0.6-32bit.runCopying to a temporary location... Creating directory iFast-Debian6.0.6-32bit Verifying archive integrity... All good. Uncompressing iFast IDE by software team of ICDREC Center.............................................................................................................................................................................................................. Check share library for ifast ...pass. Do you want to install sg8-cc compiler? (y/n)
Nếu muốn cài cặt thêm trình biên dịch SG8V1 thì gõ “y” rồi nhấn Enter để thực hiện quá trình
cài đặt. Sau khi quá trình cài đặt thành công, terminal sẽ hiển thị như sau:
Môi trường phát triển tích hợp (IDE). 41
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 13: Hộp thoại thông báo quá trình cài đặt iFast đã thành công.
installing iFast IDE Install iFast IDE successfully installing sg8-cc compiler Install sg8cc compiler successfully
4.3. Các tính năng chính của iFast.
Người sử dụng có thể dùng iFast để thực hiện các thao tác như tạo dự án mới, thêm tập tin mã
nguồn vào dự án, cấu hình các chức năng của trình biên dịch dành cho dự án, biên dịch ra mã
máy và nạp mã máy vào vi xử lý mà mình muốn. Đây là phần sẽ hướng dẫn giúp cho người
dùng thành thạo các thao tác kể trên.
4.3.1. Giao diện của iFast.
Giao diện của iFast được thiết kế nhằm giúp người dùng có thể dễ dàng quản lý dự án của
mình. Giao diện của nó thừa hưởng bố cục quen thuộc của các môi trường phát triển lâu năm
trên thị trường nhắm giúp người dùng không phải mất thời gian làm quen với bố cục mới.
Hình 14 mô tả giao diện của một dự án được phát triển bằng iFast.
Môi trường phát triển tích hợp (IDE). 42
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 14: Giao diện của iFast
Giao diện của iFast được chia làm bốn phần chính:
▪ Phần số một (đen) bao gồm hai tab là Project và Symbol. Tab Project liệt kể tất cả
các tập tin được sử dụng trong dự án và chỉ có những tập tin liệt kê ở đây cùng với
các thư viện mới được tham gia trong quá trình dịch dự án ra mã máy. Tab Symbol
thì liệt kê tất cả các hàm, biến, cấu trúc dữ liệu dùng trong dự án. Khi người dùng
nhấn đôi vào tên một hàm, biến hay cấu trúc dữ liệu thì iFast sẽ tự động nhảy tới vị
trí khai báo tương ứng của nó trong dự án. Chức năng này giúp người dùng dễ dàng
quản lý một dự án lớn với nhiều hàm/biến.
▪ Phần số hai (đỏ) chính là trình biên tập mã nguồn của iFast với các chức năng chính
như tô màu từ khóa, hỗ trợ giao diện tab, thu gọn mã nguồn và gợi ý từ khóa. Đối với
những người chưa quen với những tính năng kể trên thì có thể tham khảo bảng mô tả
dưới đây:
▫ Tô màu từ khóa: giúp người dùng dễ dàng nắm bắt được ý tưởng của dự án bằng
cách tô màu các từ khóa của ngôn ngữ lập trình, các bình luận cũng như các hằng
số trong mã nguồn.
▫ Giao diện tab: thay vì hiển thị mỗi tập tin được người dùng mở trong từng cửa số
riêng biệt, iFast sẽ hiển thị mỗi tập tin bằng một tab ở góc trên-trái của trình biên
tập mã nguồn. Điều này giúp người dùng dễ dàng di chuyển nhanh chóng giữa các
tập tin quan trọng trong dự án, giúp tiết kiệm một cách đáng kể thời gian và công
sức dùng để phát triển dự án.
▫ Thu gọn mã nguồn: giúp người dùng nhanh chóng nắm bắt được cách mã nguồn
được tổ chức bằng cách giấu phần thân của các hàm, các vòng lặp, các câu cú
pháp điều kiện ...
▫ Gợi ý từ khóa: rút gọn thời gian phát triển dự án và tiết kiệm công sức của người
sử dụng bằng cách đề nghị tất cả các từ khóa, tên hàm, tên biến dựa vào những gì
mà người dùng đang gõ trong trình biên dịch mã nguồn. Đây chính là chức năng
cần thiết nhất mà bất kỳ trình biên tập mã nguồn nào cũng phải có.
▪ Phần số ba (xanh dương) là nơi chứa các tab thông tin của iFast. Nơi đây sẽ hiển thị
các thông tin về các hoạt động của iFast và trình biên dịch. Nơi đây rất quan trọng
với người dùng vì nó hiển thị các lỗi ngữ pháp trong mã nguồn khi người dùng muốn
dịch dự án ra mã máy.
▪ Phần số bốn (xanh lá cây) là nơi chứa thanh công cụ của iFast. Người dùng có thể sử
dụng tất cả các chức năng hiện có của chương trình thông qua phần này.
Môi trường phát triển tích hợp (IDE). 43
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
4.3.2. Tổng quan về dự án
Dự án là một tập hợp các tập tin dùng để tạo ra mã máy bằng một trình biên dịch thích hợp.
Ngoài ra, tập tin dự án của iFast còn lưu các cấu hình của môi trường phát triển và trình biên
dịch nhắm giúp người dùng cá nhân hóa dự án của mình. Tất cả các tập tin dự án đều có phần
mở rộng mặc định là “.ifast”.
4.3.3. Tạo một dự án mới
Người dùng có thể tạo ra một dự án mới bằng cách truy cập vào Project→New. Khi đó một
hộp thoại với tiêu đề Create New Project sẽ được hiển thị như trong hình 15 và người dùng
chỉ việc chọn loại dự án mà mình mong muốn. Sau khi chọn dự án mà mình mong muốn, một
hộp thoại khác sẽ hiện ra như hình 16 để người dùng có thể đặt tên và nêu ra vị trí mà mình
muốn lưu dự án trên. Một khi tất cả các bước trên đã được thực thi thì một hộp thoại tổng kết
những thông tin về dự án sắp được tạo sẽ hiện ra để người dùng duyệt lại. Người dùng chỉ
việc bấm Finish để chương trình tạo ra một dự án mới.
Môi trường phát triển tích hợp (IDE). 44
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 15: Hộp thoại tạo dự án mới.
4.3.4. Mở một dự án có sẵn.
Một dự án có sẵn có thể được mở bằng cách truy cập Project→Menu. Sau đó thì một hộp
thoại sẽ xuất hiện để người dùng có thể duyệt tới nơi chứa tập tin dự án mà mình mở. Khi tập
tin dự án được mở thì iFast sẽ hiển thị giao diện gần đây nhất của nó.
4.3.5. Đóng dự án.
Để đóng một dự án đang mở, người dùng chỉ việc sử dụng Project→Close. Nếu trong dự án
có một tập tin nào đó chưa được lưu thì một hộp thoại sẽ xuất hiện và yêu cầu người dùng lưu
tập tin này lại. Sau đó, cho dù người dùng có lưu tập tin này lại hay không thì dự án cũng sẽ
được đó.
4.3.6. Tổng quan về tập tin nguồn.
Các tập tin nguồn là những tập tin chứa mã của dự án mà người dùng đang phát triển. Những
tập tin này giúp bạn điều khiển vi xử lý để thực thi những thao tác mà mình mong muốn.
Giống như bất kỳ môi trường phát triển nào, iFast cho phép người dùng thêm hay bớt các tập
tin nguồn ra khỏi dự án. Điều này cho phép người dùng có thể tận dụng các tập tin nguồn cũ
từ những dự án trước đây vào dự án mới, giúp tiết kiệm thời gian và công sức để hoàn thành
dự án mới.
Môi trường phát triển tích hợp (IDE). 45
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 16: Hộp thoại thông tin về dự án.
4.3.7. Mở một tập tin mã nguồn có sẵn.
Để mở một tập tin mã nguồn có sẵn thì người dùng phải truy cập vào File→Open (phím tắt
Ctrl + O) hay chọn nút Open An Exisitng File trên thanh công cụ và một hộp thoại sẽ hiện lên
để bạn chọn tập tin mà mình muốn mở. Khi đã chọn đươc tập tin mong muốn, người dùng chỉ
cần bấm Open để mở tập tin này. Ngoài ra thì nhấn đôi vào một tập tin được liệt kê trong tab
Project của cũng sẽ mở tập tin đó ra. Tập tin được iFast mở sẽ hiện ra trong một tab ở góc
trên-trái của trình biên tập mã nguồn được tích hợp trong iFast.
4.3.8. Tạo mới một tập tin nguồn.
Người dùng có hai phương án để tạo ra một tập tin mã nguồn mới. Đó là tập tin nguồn theo
mẫu và không theo mẫu. Để tạo ra một tập tin nguồn không theo mẫu thì người dùng chỉ việc
truy cập vào File→New. Còn nếu muốn tạo ra một tập tin nguồn mới theo mẫu thì người dùng
phải truy cập vào File→New (with template) và chọn mẫu mà mình mong muốn.
4.3.9. Thêm tập tin có sẵn vào dự án.
Nếu người dùng chỉ mở một tập tin có sẵn thì việc đó không đồng nghĩa với việc tập tin này
sẽ được thêm vào dự án. Để thêm một tập tin vào dự án, người dùng chỉ việc truy xuất vào
Project→Add files. Sau đó một hộp thoại sẽ hiện ra và yêu cầu người dùng chỉ ra tập tin mà
mình muốn thêm vào dự án. Một khi đã chọn được một tập tin và bấm Open, tập tin này sẽ
hiện ra trong tab Project của dự án.
4.3.10. Các thao tác trên tập tin nguồn.
Ngoài những chức năng thông thường của trình biên tập, trình biên tập mã nguồn được tích
hợp trong iFast còn có thêm một số chức năng giúp người dùng có thể tiết kiệm công sức và
thời gian để phát triển dự án. Các tính năng đó như sau:
▪ Tổ hợp phím Alt+L hay Search→Go sẽ di chuyển dấu nháy tới dòng chỉ định. Chức
năng này rất hữu ích khi người dùng sử dụng một trình biên dịch bên ngoài iFast và
gặp lỗi.
▪ Chức năng tự động thụt đầu dòng cũng rất hữu ích với mọi dự án. Nó sẽ tự động thụt
dấu nháy vào một đoạn được quy định trước khi người dùng xuống dòng trong một
hàm, câu điều kiện hay vòng lặp. Chức năng này có thể được bật/tắt thông qua
Editor→Auto-identation.
▪ Tìm ngoặc nhọn tương ứng cũng là một chức năng rất hay của iFast. Bất cứ khi nào
dấu nháy được di chuyển lại gần một dấu ngoặc nhọn thì iFast sẽ tô màu xanh cả hai
dấu ngoặc tương ứng với nhau. Tính năng này giúp người dùng có thể dễ dàng kiểm
soát được vùng ảnh hưởng của dấu ngoặc nhọn trong các hàm điều kiện, vòng lặp
phức tạp.
Môi trường phát triển tích hợp (IDE). 46
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
4.3.11. In tập tin nguồn
Để in một nội dung của một tập tin nguồn ra giấy, người dùng chỉ việc truy cập vào
File→Print hay nút Print trên thanh công cụ. Để thay đổi cấu hình máy in hiện tại, người dùng
cần phải truy cập vào File→Page Setup. Điều này sẽ mở ra một hộp thoại như hình 17. Hộp
thoại này cho phép bạn chọn máy in nào để in, kích thước giấy và chiều in.
4.4. Cấu hình trình biên dịch C.
Các cờ của trình biên dịch mà người dùng có thể thay đổi là:
▪ [--Werror]: xem tất cả các cảnh báo tương đương như lỗi. Điều này có nghĩa là trình
biên dịch sẽ không hoàn tất quá trình dịch khi gặp bất kỳ cảnh báo nào.
▪ [--debug]: Cho phép xuất các ký tự dùng cho việc gỡ rối.
▪ [--std-c89]: Biên dịch dựa theo chuẩn ANSI-89.
▪ [--std-sdcc89]: Biên dịch dựa theo chuẩn ANSI-89 được mở rộng bởi SG8v1.
▪ [--call-soft-stack]: Dùng stack phần mềm cho các lệnh gọi hàm.
▪ [--no-reg-asm]: vô hiệu hóa chức năng tối ưu thanh ghi của trình biên dịch hợp ngữ.
▪ [--funsinged-char]: Biến từ khóa char thành kiểu biến không dấu.
▪ [--dump-raw]: Xuất ra cấu trúc RAW sau lần duyệt đầu tiên.
▪ [--dump-gcse]: Xuất ra cấu trúc GCSE sau lần duyệt đầu tiên.
▪ [--dump-loop]: Xuất ra cấu trúc LOOP sau lần duyệt đầu tiên.
Môi trường phát triển tích hợp (IDE). 47
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 17: Hộp thoại để cấu hình máy in trong iFast.
▪ [--dump-deadcode]: Xuất ra cấu trúc DEADCODE sau lần duyệt đầu tiên.
▪ [--dump-liverange]: Xuất ra cấu trúc LIVERANGE sau lần duyệt đầu tiên.
▪ [--dump-regpack]: Xuất ra cấu trúc REGPACK sau lần duyệt đầu tiên.
▪ [--dump-reassign]: Xuất ra cấu trúc REASSIGN sau lần duyệt đầu tiên.
▪ [--dump-tree]: Xuất ra cấu trúc TREE sau lần duyệt đầu tiên.
▪ [--dump-all]: Xuất ra cấu trúc sau lần duyệt đầu tiên.
▪ [--i-code-in-asm]: Thêm các chú thích “i code ...” trong các tập tin hợp ngữ được
dịch ra từ tập tin c.
4.4.1. Cấu hình trình liên kết.
Để cấu hình trình liên kết (linker) thì người dùng chỉ việc thực hiện các thao tác giống y như
việc cấu hình cờ của trình biên dịch, chỉ khác là người dùng phải chọn tab Linker Settings
thay cho Compiler Settings.
Trong tab Linker Settings gồm hai mục là danh sách các thư viện mà trình liên kết sẽ dùng
trong quá trình tạo ra mã máy và các bảng cấu hình cờ của trình liên kết.
Để thêm một thư viện mới để phục vụ cho trình biên dịch thì người dùng chỉ việc bấm nút
Môi trường phát triển tích hợp (IDE). 48
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 18: Hộp thoại cấu hình tính năng của trình biên dịch C
Add và chọn tập tin thư viện mà mình mong muốn. Sau đó, đường dẫn của thư viện này sẽ
xuất hiện trong ô Linker Libraries.
4.4.2. Cấu hình đường dẫn của các trình biên dịch và trình thực thi.
Để có thể sử dụng các trình biên dịch và trình liên kết được tích hợp trong iFast, người dùng
phải chỉ ra được đường dẫn của những chương trình này thông qua tab Toolchain executable.
Có năm đường dẫn cần phải được chỉ rõ là đường dẫn của trình biên dịch C, trình biên dịch
C++, trình biên dịch hợp ngữ, trình liên kết dành cho thư viện tĩnh và trình liên kết dành cho
thư viện động.
Ngoài ra cách tự dò đường dẫn một cách thủ công, iFast còn hỗ trợ việc dò tìm đường dẫn tự
động thông qua nút Auto-detect.
Môi trường phát triển tích hợp (IDE). 49
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 19: Hộp thoại dùng để cấu hình trình liên kết
4.4.3. Các cấu hình khác.
Ngoài các các cài đặt dành cho trình biên dịch cũng như trình liên kết, người dùng cũng có thể
cấu hình một số chức năng linh tinh như hiển thị toàn bộ nội dung được trả về bởi trình biên
dịch trong quá trình dịch và tự động bật tab thông tin lên khi dịch.
Môi trường phát triển tích hợp (IDE). 50
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 21: Hộp thoại dùng cho việc cấu hình các chức năng khác
Hình 20: Cấu hình đường dẫn của trình biên dịch/trình liên kết
4.5. Cấu hình chức năng tô màu cú pháp.
Chức năng tô màu cú pháp giúp sẽ tô màu các từ khóa của ngôn ngữ lập trình giúp ta nhanh chóng nắm bắt được cách sử dụng. Để cấu hình tính năng này, truy cập vào thực đơn Edit → Preferences và chọn thẻ Syntax Highlighting. Tại đây, ta có thể tùy ý điều chỉnh màu sắc và kiểu chữ (in nghiêng/in đậm) cho các thành phần của một tập tin nguồn như chỉ thị, hằng số, chú thích, toán tử …. Các ngôn ngữ mà iFast có hỗ trợ chức năng tô màu cú pháp là C/C++ và Assembly. Ngoài ra người dùng có thể thay đổi màu của một số thành phần chung như lề, số dòng ...
4.6. Cấu hình chức năng phím tắt.
Nhằm giúp người dùng có thể thao tác một cách nhanh chóng, iFast có kèm theo chức năng phím tắt cho các chức năng quan trọng/thường sử dụng của chương trình như đóng/mở một tập tin...
Để có thể thay đổi cấu hình dành cho tính năng này thì ta phải truy cập vào thực đơn Edit → Preferences và chọn thẻ Key bindings. Tại đây có một danh sách các chức năng của chương trình và các phím tắt tương ứng. Bấm đúp vào chức năng mà ta muốn đổi phím tắt rồi nhấn một tổ hợp phím tắt mới để gán cho chức năng này. Trong trường hợp tổ hợp phím tắt mới đã được gán cho chức năng khác thì iFast sẽ hiện một bảng thông báo và yêu cầu người dùng quyết định xem tổ hợp phím mới này sẽ dùng cho chức năng nào.
Môi trường phát triển tích hợp (IDE). 51
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Hình 22: Hộp thoại cấu hình chức năng tô màu cú pháp.
5. Phụ Lục.
Trong tài liệu này có dùng một số từ viết tắt chuyên ngành. Mục này dùng để giải thích các từ
viết tắt trên nhằm giúp đọc giả nhanh chóng hiểu được tài liệu:
UART: Universal Asynchronous Receiver Transmitter (Bộ Thu Phát Bất Đồng Bộ Toàn Hệ
Thống)
I2C: Inter Intergrated-Circuit (Giao Tiếp Liên Mạch-Tích-Hợp)
SPI: Serial Peripheral Interface (Giao Tiếp Ngoại Vi Tuần Tự)
IDE: Intergrated Development Environment (Môi Trường Phát Triển Tích Hợp)
CC: Capture/Compare (Bộ Ghi và So Sánh)
PWM: Pulse-Width Modulation (Điều Chế Độ Rộng Xung).
SFR: Special Function Register (Thanh Ghi Có Chức Năng Đặc Biệt)
Phụ Lục. 52
Trung Tâm Đào Tạo và Thiết Kế Vi Mạch ICDREC
Recommended