I / _ GIỚI THIỆU:
_Đây là tài liệu hướng dẫn sử dụng CCS lập trình ngôn ngữ C cho vi điều khiển PIC của Microchip .
Tác giả tên TRẦN XUÂN TRƯỜNG , SV K2001 ,ĐH BK HCM . Là thành viên txt2203 trên diễn
đàn diendandientu.com , thành viên txt trên diễn đàn picvietnam.com . Mọi đóng góp ý kiến về
tài liệu hãy email đến đòa chỉ : . Rất cám ơn mọi đóng góp ý kiến của các bạn
yêu thích lập trình vi xử lý đối với tài liệu này .
II / _ VÀI VẤN ĐỀ VỀ TÀI LIỆU NÀY :
_Tài liệu hướng dẫn lập trình C cho PIC sử dụng phần mềm CCS các phiên bản . Tài liệu cũng giải
thích cách thức hoạt động của 1 số module của VĐK để các bạn nắm rõ hơn hoạt động VĐK nhằm
sử dụng hàm và viết chương trình 1 cách chính xác .
_Tài liệu này không chủ ý thay thế hoàn toàn HELP của CCS , nó chỉ là phần cô đọng , là hướng
dẫn và giải thích cơ bản viết 1 chương trình bắt đầu từ đâu , giới thiệu 1 số hàm và cách hoạt động ,
1 số vấn đề khi lập trình , . . . do đó nó không đầy đủ , bạn nên đối chiếu tài liệu này với HELP
tiếng Anh để nắm rõ vấn đề , đồng thời học cả tiếng Anh dễ dàng .
_CCS có phần “ common questions “ – những câu hỏi thường gặp và trả lời , chưa được dòch ở đây
dù nó rất quan trọng , nhiều bạn hay bỏ qua , không để ý . Bạn nên xem nó .
_Trang web đi kèm là những cập nhật sửa lỗi và nâng cấp qua các phiên bản .
_Tài liệu trình bày về các vấn đề sau :
_ Chương 0 : Giới thiệu CCS . Viết 1 chương trình C trong CCS như thế nào . Công cụ mô
phỏng . CCS tích hợp MPLAB .
CHƯƠNG 0 :
HƯỚNG DẪN SỬ DỤNG CCS – VIẾT CHƯƠNG
TRÌNH C TRONG CCS
I / _ GIỚI THIỆU CCS :
_CCS là trình biên dòch dùng ngôn ngữ C lập trình cho VĐK . Đây là ngôn ngữ lập trình đầy sức
mạnh , giúp bạn nhanh chóng trong việc viết chương trình hơn so với ngôn ngữ Assembly .
_Mã lệnh được tối ưu khi biên dòch .
_Tuy nhiên C không phải là vạn năng , có thể thực hiện mọi thứ như ý muốn . Trong 1 số trường
hợp , nó có thể sinh mã chạy sai (tham khảo các cải tiến ở các version CCS trên web
: info.CCS.com
hoặc trang web đi kèm ).
_CCS chứa rất nhiều hàm phục vụ cho mọi mục đích và có rất nhiều cách lập trình mã cho cùng 1
vấn đề dẫn đến khác nhau tốc độ thực thi mã , độ dài chương trình . Sự tối ưu là do kỹ năng lập trình
C của bạn .
_CCS C có đủ khả năng để bạn không cần phải chèn thêm bất kỳ dòng lệnh ASSEMBLY nào , và
mặc dù vẫn cho phép bạn phối hợp ASSEMBLY cùnh với C , tuy nhiên CCS sẽ không bảo đảm
chương trình chạy chính xác .
_CCS cung cấp các công cụ tiện ích giám sát hoạt động chương trình như : C/ASM list : cho phép
xem mã ASM của file bạn biên dòch , giúp bạn quản lý mã và nắm được các thức mã sinh ra và nó
chạy như thế nào , là công cụ rất quan trọng , bạn có thể gỡ rối chương trình và nắm được hoạt động
_Muốn xem trước mã sinh ra khi hiệu chỉnh bất kỳ điều gì , chọn :
_Tuỳ thuộc loại PIC muốn lập trình mà mục FUSES sẽ có thêm nhiều hay ít tuỳ chọn , VD 18F4431: _Để ý bên dưới là 1 dãy tab các lựa chọn các thông số khác:
_chú ý 2 nút mũi tên có thể mở thêm nhiều mục khác .
_Sau khi hiệu chỉnh như ý muốn , OK để hoàn thành . III / _ CCS TÍCH HP TRONG MPLAB – VIẾT MÃ VÀ MÔ PHỎNG :
_Công cụ mô phỏng cho PIC 16Fxxx. . đa năng nhất chỉ có thể là PIC Simulator IDE 5x , hỗ trợ 38
loại PIC 16Fxxx . Có cả Oscilocope , INT ảo , . . . và nhiều chức năng khác với giao diện tuyệt đẹp ,
dễ dùng . Hoạt động độc lập , lấy file HEX để mô phỏng . Có dòch ngược ra Assemble . Có bộ lập
trình BASIC và Assemble rất hay và dễ dùng , dù khá đơn giản nhưng đủ để viết các chương trình
nhỏ chất lượng . Bạn nên thử qua . Khuyết điểm : thiếu 1 vài module mô phỏng như : chức năng
PWM không có tác dụng .
_ Mô phỏng với PIC 18 , PIC 12 , và nhiều loại PIC 16 mà IDE trên không hỗ trợ ? Bạn có thể dùng
CCS tích hợp trong MPLAB dưới dạng plugin . Để có được tính năng này , sau khi cài đặt CCS , phải
cài tiếp CCS_plugin_for_MPLAB6xx .
_Bạn có thể soạn mã CCS trong môi trường MPLAB và cho phép mô phỏng mã C lẫn mã
ASSEMBLY dòch ngược của nó , tương tự như lập trình và mô phỏng với MPLAB C18 .
_Quan trọng : 1 số VĐK mà MPLAB không hỗ trợ mô phỏng hết cacù chức năng của nó , bạn nên
xem kỹ trong phần HELP của MPLAB , mục SIM để có chi tiết . Hoặc vào Debug->Setting…->chọn
tab Limitations . Bỏ qua phần này có thể khiến bạn lầm tưởng chương trình viết sai trong khi nó
không hỗ trợ mô phỏng . Cho tới hiện tại , tôi chưa biết cách mô phỏng chưỗi xung đi vào PIC , từ
_Mục Other files : dùng để thêm vào các file phục vụ cho dự án như các file C , file text , . . .Các
file này có thể được biên dòch mà cũng có thể không , và dùng để ghi các chú giải , sơ đồ thuật toán
, . . .
_Để biên dòch dự án , chọn :
_Biên dòch xong , cửa sổ Output hiện ra :
6
_lưu ý : các cảnh báo ( warning ) là có thể bỏ qua , trình biên dòch vẫn tạo ra file hex . Nhưng lỗi
error nếu có thì không thể bỏ qua , vì nó không thể tạo file hex được . hãy nhấn kép vào dòng
warning hay error nào thì sẽ nhảy đến vò trí phát sinh nó .
_Để mô phỏng : _Sau khi chọn MPLAB SIM , thanh toolbar sau hiện ra :
_Chọn RUN khi mô phỏng chương trình sẽ chạy liên tục .
_Chọn animate
để xem chương trình mô phỏng dòng lệnh liên tục theo 1 mức thời gian đònh
trước cho 1 lệnh . Để hiệu chỉnh khoảng thời gian để nhảy 1 lệnh , vào debugger->setting . . .Chọn
Tab như bên dưới :
7
_Để giám sát thanh ghi bộ nhớ , chọn tên thanh ghi rồi nhấn Add SFR :
Tên thanh ghi sẽ thêm vào vùng bên dưới .
_Để giám sát tên biến c trong chương trình của mình , chọn tên biến và nhấn Add symbol.
MPLAB cho phép tới 4 khung Watch làm việc . thường ta chỉ cần 1 .
_Để loại bỏ biến hay thanh ghi bất kỳ khỏi việc giám sát , chọn nó và nhấn nút Delete trên bàn
phím.
_Nhấn chuột phải trên vùng giám sát để có các lựa chọn thêm , trong đó có mục Properties , tuy
nhiên chúng không quan trọng trừ khi có những yêu cầu đặc biệt .
_Click chuột phải lên vùng này : Sẽ đổ xuống menu sau , cho phép hiển thò nội dung biến theo dạng số hex, thập phân , nhò phân , . .
_Click kép vào ô giá trò để hiệu chỉnh giá trò biến nếu muốn .
_Lưu ý là khi reset lại để mô phỏng từ đầu , Watch không tự cập nhật . Phải đóng nó rồi mở lại .
8 / _Special function Register : cho phép giám sát các thanh ghi chức năng đặc biệt .
9 / _ Simulator Trace : ghi lại toàn bộ tiến trình thực thi mã từ lúc reset đến lúc dừng .Rất tuyệt vời
khi muốn xem chương trình có độ dài bao nhiêu chu kỳ lệnh , hay quan sát 1 vòng lặp thực thi xong
thì mất bao nhiêu thời gian , xem chương trình chạy như thế nào , . . .Lưu ý là cửa sổ sẽ không cập
9
nhật trong lúc đang mô phỏng , mà phải đóng nó lại rồi mở lại thì nó mới update kết quả mới .
Ngoài ra nhấn chuột phải lên cửa sổ sẽ cho nhiều lựa chọn tuỳ biến hay .
{ . . .
. . .
}
_Đầu tiên là các chỉ thò tiền xử lý : # . . . có nhiệm vụ báo cho CCS cần sử dụng những gì trong
chương trình C như dùng VXL gì , có dùng giao tiếp PC qua cổng COM không , có dùng ADC
không , có dùng DELAY không , có biên dòch kèm các file hay không . . .
_Các khai báo biến .
_Các hàm con do ta viết : xu_ly_ADC () , . . .
_ Các hàm phục vụ ngắt theo sau bởi 1 chỉ thò tiền xử lý cho biết dùng ngắt nào.
_Chương trình chính . 10
11
_Một chương trình C có thể được viết luôn tuồn trong hàm main () , nếu chúng rất ngắn và đơn giản
. Nhưng khi chương trình bắt đầu dài ra , phức tạp lên 1 chút thì phải phân chia trong các hàm con .
Các hàm này có thể là :
1/ Hàm không trả về trò . Ví dụ :
Void xu_ly( )
{
z= x+y ;
}
Hàm trên chỉ thực hiện các lệnh trong thân hàm , khi gọi hàm này chỉ đơn giản viết :
Xu_ly( ) ;
2/ Hàm có trả về trò . Ví dụ :
int xu_ly ( int a , int b)
{
. . . . . .
12
CHƯƠNG 1 :
C
C
A
A
Ù
Ù
C
C
H
HS
S
Ư
Ư
Û
ÛD
D
U
H
A
A
Ø
Ø
M
M,
,C
C
A
A
Ù
Ù
C
CC
C
A
A
Á
Á
U
C
C
H
H
Ỉ
ỈT
T
H
H
Ị
ỊT
T
I
I
E
E
À
À
N
NX
long mặc đònh như kiểu int16
_Thêm signed hoặc unsigned phía trước để chỉ đó là số có dấu hay không dấu .Khai báo như trên
mặc đònh là không dấu . 4 khai báo cuối không nên dùng vì dễ nhầm lẫn . Thay vào đó nên dùng 4
khai báo đầu . VD :
Signed int8 a ; // số a là 8 bit dấu ( bit 7 là bit dấu ).
Signed int16 b , c , d ;
Signed int32 , . . .
_Phạm vi biến :
Int8 :0 , 255 signed int8 : -128 , 127
Int16 : 0 ,2^15-1 signed int16 : -2^15 , 2^15-1
Int32 : 0 , 2^32-1 signed int32 : -2^31 , 2^31-1
_Khai báo hằng : VD :
Int8 const a=231 ;
_Khai báo 1 mảng hằng số :
VD : Int8 const a[5] = { 3,5,6,8,6 } ; //5 phần tử , chỉ số mảng bắt đầu từ 0 : a[0]=3
_Một mảng hằng số có kích thước tối đa tuỳ thuộc loại VĐK:
*NếuVĐK là PIC 14 ( VD :16F877 ) : bạn chỉ được khai báo 1 mảng hằng số có kích thước tối đa là
256 byte .
Các khai báo sau là hợp lệ :
Int8 const a[5]={ . . .}; // sử dụng 5 byte , dấu . . . để bạn điền số vào
Int8 const a[256]={ . . .}; // 256 phần tử x 1 byte = 256 byte
Int16 const a[12] = { . . . }; // 12 x 2= 24 byte
Int16 const a[128] = { . . . }; // 128 x 2= 256 byte
13
_Bạn có thể ép kiểu , thường là tiết kiệm ram , hay muốn tiết kiệm thời gian tính , . . .. VD :
Int8 a =8 , b=200;
Int16 c ;
C= ( int16) a * b ;
// c= 1600 , a chuyển sang 16 bit , 16bit*8bitỈ b tự động chuyển sang 16 bit , kết quả là 16 bit trong
c , lưu ý biến a , b vẫn là 8 bit .
_8bit * 8bit Ỉ phép nhân là 8 bit , KQ là 8 bit
_16bit * 8 bit Ỉ phép nhân là 16 bit , KQ là 16 bit
_32bit * 16 bit Ỉ phép nhân là 32 bit , KQ là 32 bit
_16bit * 16 bit Ỉ phép nhân là 16 bit , KQ là 16 bit
. . . v . v . . .
_Có thể ép kiểu kết quả : VD : 16b*8bỈ16bit , nếu gán vào biến 8 bit thì KQ sẽ cắt bỏ 8 bit cao .
B ) _ Phạm vi sử dụng biến :
_Giống như C trong lập trình C cho máy tính . Biến có thể được khai báo như toàn cục hay cục bộ
.Biến khai báo trong hàm sẽ là cục bộ và sẽ chỉ dùng được trong hàm đó , kể cả trong hàm main()
.Ngoài ra còn có thể khai báo ngay trong 1 khối lệnh , và cũng chỉ tồn tại trong khối lệnh đó . Do
vậy nếu dùng MPLAB để mô phỏng , thì khi nhảy vào hàm hay khối lệnh có chứa khai báo biến đó
thì biến đó mới có giá trò , có khi nhảy ra ngoài hàm thì biến đó sẽ là” out of scope” khi ta quan sát
chúng trong cửa sổ Watch.
_Chi tiết về phạm vi biến xem tài liệu lập trình C trên máy tính .
_CCS có hỗ trợ cả con trỏ , tuy nhiên ít dùng .
_CCs không hỗ trợ lập trình hướng đối tượng như C++ . Tuy vậy CCS có hỗ trợ các biến cấu trúc .
3 / _ Các phép toán , sự thực thi và vấn đề tối ưu mã , chương trình:
Ỉ chỉ cần lập bảng tra sin trong đó là các giá trò sin là số nguyên = ( y + 1) * 128 ;
II / _ CÁC CẤU TRÚC LỆNH : ( statement )
_Gồm các lệnh như while . . do , case , . . .
STATEMENTS
STATEMENT EXAMPLE
if (expr) stmt; [else stmt;]
if (x==25)
x=1;
else
x=x+1;
while (expr) stmt;
while (get_rtcc()!=0)
putc(‘n’);
do stmt while (expr);
do {
putc(c=getc());
} while (c!=0);
for (expr1;expr2;expr3) stmt;
for (i=1;i<=10;++i)
printf(“%u\r\n”,i);
switch (expr) {
case cexpr: stmt; //one or more case
[default:stmt]
... }
do stmt while (expr) : thực thi biểu thức rồi mới xét điều kiện sau .
_Return : dùng cho hàm có trả về trò , hoặc không trả về trò cũng được , khi đó chỉ cần dùng: return
; ( nghóa là thoát khỏi hàm tại đó ) .
_Break : ngắt ngang ( thoát khỏi ) vòng lặp while. _Continue : quay trở về đầu vòng lặp while .
16
III / _ CHỈ THỊ TIỀN XỬ LÝ :
_Xem chi tiết tất cả ở phần HELP , mục pre_processor . Ở đây sẽ giới thiệu 1 số chỉ thò thường dùng
nhất :
1 /_ #ASM và #ENDASM :
_Cho phép đặt 1 đoạn mã ASM giữa 2 chỉ thò này , Chỉ đặt trong hàm . CCS đònh nghóa sẵn 1 biến 8
bit _RETURN_ để bạn gán giá trò trả về cho hàm từ đoạn mã Assembly.
_C đủ mạnh để thay thế Assmemly . Vì vậy nên hạn chế lồng mã Assembly vào vì thường gây ra
xáo trộn dẫn đến sau khi biên dòch mã chạy sai , trừ phi bạn nắm rõ Assembly và đọc hiểu mã
Assembly sinh ra thông qua mục C/Asm list .
_Khi sử dụng các biến không ở bank hiện tại , CCS sinh thêm mã chuyển bank tự động cho các biến
đó . Nếu sử dụng #ASM ASIS thì CCS không sinh thêm mã chuyển bank tự động , bạn phải tự thêm
vào trong mã ASM .
_Lưu ý : mã Assembly theo đúng mã tập lệnh VDK , không phải mã kiểu MPLAB .
_VD :
int find_parity (int data) {
int count;
#asm
movlw 0x8
movwf count
movlw 0