1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Tổng quan về CCS

14 450 8

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 14
Dung lượng 254 KB

Nội dung

Sau này khi ngôn ngữ C ra đời, nhu cầu dụng ngôn ngữ C để thay cho ASM trong việc mô tả các lệnh lập trình cho Vi điều khiển một cách ngắn gọn và dễ hiểu hơn đã dẫn đến sự ra đời của nhi

Trang 1

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 56

I Tổng quan về CCS

I.1 Tại sao sử dụng CCS?

- Sự ra đời của một loại vi điều khiển đi kèm với việc phát triển phần mềm ứng dụng cho việc lập trình cho con vi điều khiển đó Vi điều khiển chỉ hiểu và làm việc với hai con số 0 và

1 Ban đầu để việc lập trình cho VĐK là làm việc với dãy các con số 0 và 1

- Sau này khi kiến trúc của Vi điều khiển ngày càng phức tạp, số lượng thanh ghi lệnh nhiều lần, việc lập trình với dãy các số 0 và 1 không còn phù hợp nữa, đòi hỏi ra đời một ngôn ngữ mới thay thế Và ngôn ngữ lập trình Assembly Ở đây ta không nói nhiều đến Assmebly Sau này khi ngôn ngữ C ra đời, nhu cầu dụng ngôn ngữ C để thay cho ASM trong việc mô tả các lệnh lập trình cho Vi điều khiển một cách ngắn gọn và dễ hiểu hơn đã dẫn đến sự ra đời của nhiều chương trình soạn thảo và biên dịch C cho Vi điều khiển : Keil C, HT-PIC, MikroC, CCS…Đồ án này sử dụng CCS để lập trình vì tính năng mạnh và lập trình đơn giản hơn so với MBLab

I.2 Giới thiệu về CCS

CCS là trình biên dịch lập trình ngôn ngữ C cho Vi điều khiển PIC của hãng Microchip Chương trình là sự tích hợp của 3 trình biên dịch riêng biệt cho 3 dòng PIC khác nhau đó là:

- PCB cho dòng PIC 12 bit opcodes

- PCM cho dòng PIC 14 bit opcodes

- PCH cho dòng PIC 16 và 18 bit

Tất cả 3 trình biên dịch này được tích hợp lại trong một chương trình bao gồm cả trình soạn thảo văn biên dịch là CCS

Giống như nhiều trình biên dịch C khác cho PIC, CCS giúp cho người sử dụng nắm bắt nhanh được vi điều khiển PIC và sử dụng PIC trong các dự án Các chương trình điều khiển sẽ được thực hiện nhanh chóng và đạt hiệu quả cao thông qua việc sử dụng ngôn ngữ lập trình cấp cao – Ngôn ngữ C

II.Viết một chương trình trong CCS:

Đây là ví dụ về cấu trúc 1 chương trình trong CCS :

#include < 16F877 h >

#device PIC6f877 *=16 ADC=10

#use delay(clock=20000000)

Int16 a,b;

Trang 2

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 57

{ }

#INT_TIMER1

Void xu_ly_ngat_timer ( )

{ }

Void Main ( )

{ }

Đầ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

Một chương trình C có thể được viết luô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( ) ; 1/ Hàm có trả về trị

Ví dụ : int xu_ly ( int a , int b)

{

Return (a+b) ; }

Hàm trên sẽ trả về tổng (a+b) khi sử dụng , ví dụ tính bằng 2 biến e ,f , chương trình như sau ( trong hàm main() ) :

Main()

{ Int e ,f ,g ;

e=7 ;

f= 4;

g = xu_ly(e ,f ); }

- Mỗi hàm con nên được viết để thực hiện 1 chức năng chuyên biệt nào đó Bên trong 1 hàm con có thể gọi 1 hay nhiều hàm khác Cách thức hoạt động như viết 1 chương trình C trên máy tính

Trang 3

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 58

- Nếu chương trình lớn hơn nữa có thể làm file c rất dài và do đó rất khó kiểm soát, nên sẽ cần phân chia ra các file c trong đó file chính chứa hàm main sẽ được biên dịch Các file c khác chứa các hàm phục vụ chuyên biệt như : cho LCD , Trong file chính chỉ cần thêm dòng

#include < file x.c > là tất cả hàm cần dùng chứa trong file x sẽ được biên dịch vào file hex chung Các ví dụ trong thư mục của CCS nếu có sử dụng LCD sẽ chèn 1 dòng #include < lcd.c> và do đó sẽ gọi được các hàm trong file này mà không cần phải viết lại Điều này có nghĩa là ta có thể viết các file c chứa mã tổng quát có thể dùng chung cho nhiều project, tức là tái sử dụng mã , thay vì phải viết lại chuyên biệt cho từng project Đây là cách làm chuyên nghiệp cho những project lớn

III Sử dụng các biến và hàm, các cấu trúc lệnh, hiển thị tiền xử lí

III.1.Các khai báo và sử dụng biến, hằng, mảng

Các loại biến sau được hỗ trợ :

Int1 số 1 bit = true hay false ( 0 hay 1)

Int8 số nguyên 1 byte ( 8 bit)

Int16 số nguyên 16 bit

Int32 số nguyên 32 bit

Char ký tự 8 bit

Float số thực 32 bit

Short mặc định như kiểu int1

Byte mặc định như kiểu int8

Int mặc định như kiểu int8

Long mặc định như kiểu int16

III.2 Các cấu trúc lệnh ( Statement )

Gồm các lệnh như :

_while (expr) stmt : xét điều kiện trước rồi thực thi biểu thức sau

_ 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

Trang 4

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 59

III.3.Chỉ thị tiền xử lí

#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, phải tự thêm vào trong mã ASM

#INCLUDE :

Cú pháp : #include <filename>

Hay #include “ filename”

Trang 5

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 60

Filename : tên file cho thiết bị *.h , *.c Nếu chỉ định file ở đường dẫn khác thì thêm đường dẫn vào Luôn phải có để khai báo chương trình viết cho VĐK nào, và luôn đặt ở dòng đầu tiên

#BIT , #BYTE , #LOCATE Và # DEFINE:

#BIT id = X Y

Với id : tên biến X : biến C ( 8,16,32,…bit) hay hằng số địa chỉ thanh ghi Y : vị trí bit trong x -> tạo biến 1 bit đặt ở byte x vị trí bit y, tiện dùng kiểm tra hay gán trị cho bit thanh ghi Điểm khác biệt so với dùng biến 1 bit từ khai báo int1 là : int1 tốn 1 bit bộ nhớ, đặt ở thanh ghi đa mục đích nào đó do CCS tự chọn, còn #BIT thì không tốn thêm bộ nhớ do id chỉ là danh định đại diện cho bit chỉ định ở biến x, thay đổi giá trị id ( 0 / 1 ) sẽ thay đổi giá trị bit tương ứng Y thay đổi trị X

#BYTE id = x

X: địa chỉ id : tên biến C Gán tên biến id cho địa chỉ (thanh ghi ) x, sau đó muốn gán hay kiểm tra địa chỉ x chỉ cần dùng id Không tốn thêm bộ nhớ, tên id thường dùng tên gợi nhớ chức năng thanh ghi ở địa chỉ đó Lưu ý rằng giá trị thanh ghi có thể thay đổi bất kỳ lúc nào do hoạt động chương trình nên giá trị id cũng tự thay đổi theo giá trị thanh ghi đó Không nên dùng id cho thanh ghi đa mục đích như 1 cách dùng biến int8 vì CCS có thể dùng các thanh ghi này bất kỳ lúc nào cho chương trình

# LOCATE id = x

Làm việc như #byte nhưng có thêm chức năng bảo vệ không cho CCS sử dụng địa chỉ đó vào mục đích khác

Sử dụng #LOCATE để gán biến cho 1 dãy địa chỉ kề nhau ( cặp thanh ghi ) sẽ tiện lợi hơn thay vì phải dùng 2 biến với #byte

# DEFINE id text

Text : chuỗi hay số Dùng định nghĩa giá trị VD :

#define a 12345

# DEVICE :

# DEVICE chip option chip : tên VĐK sử dụng , không dùng tham số này nếu đã khai báo tên chip ở # include option : toán tử tiêu chuẩn theo từng chip:

* = 5 dùng pointer 5 bit ( tất cả PIC )

* = 8 dùng pointer 8 bit ( PIC14 và PIC18 )

* = 16 dùng pointer 16 bit ( PIC14 ,PIC 18) ADC = x sử dụng ADC x bit ( 8 , 10 , bit tuỳ chip ) , khi dùng hàm read_adc( ) , sẽ trả về giá trị x bit

Trang 6

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 61

ICD = true : tạo mã tương thích debug phần cứng Microchip

HIGH_INTS = TRUE : cho phép dùng ngắt ưu tiên cao

_Khai báo pointer 8 bit , bạn sử dụng được tối đa 256 byte RAM cho tất cả biến chương trình _Khai báo pointer 16 bit , bạn sử dụng được hết số RAM có của VDK

_Chỉ nên dùng duy nhất 1 khai báo #device cho cả pointer và ADC

VD : #device * = 16 ADC = 10

# ORG :

# org start , end

# org segment

#org start , end { } Start , end: bắt đầu và kết thúc vùng ROM dành riêng cho hàm theo sau ,

hoặc để riêng không dùng

# USE :

# USE delay ( clock = speed ) Speed : giá trị OSC mà bạn dùng VD: dùng thạch anh dao động 40Mhz thì : #use delay( clock = 40000000) _Chỉ khi có chỉ thị này thì trong chương trình bạn mới được dùng hàm delay_us ( ) và delay_ms( ) #USE fast_io ( port) Port : là tên port :từ A-G ( tuỳ chip ) _Dùng cái này thì trong chương trình khi dùng các lệnh io như output_low() , nó sẽ set chỉ với 1 lệnh , nhanh hơn so với khi không dùng chỉ thị này –b -

- Trong hàm main( ) bạn phải dùng hàm set_tris_x( ) để chỉ rõ chân vào ra thì chỉ thị trên mới

có hiệu lực , không thì chương trình sẽ chạy sai _Không cần dùng nếu không có yêu cầu gì đặc biệt VD : # use fast_io( A )

#USE I2C ( options ) _Thiết lập giao tiếp I2C Option bao gồm các thông số sau, cách nhau bởi dấu phẩy : Master : chip ở chế độ master

Slave : chip ở chế độ slave

SCL = pin : chỉ định chân SCL

SDA = pin : chỉ định chân SDA

ADDRESS =x : chỉ định địa chỉ chế độ slave

FAST : chỉ định FAST I2C

SLOW : chỉ định SLOW I2C

RESTART_WDT : restart WDT trong khi chờ I2C_READ( )

FORCE_HW : sử dụng chúc năng phần cứng I2C ( nếu chip hỗ trợ )

NOFLOAT_HIGH : không cho phép tín hiệu ở float high, tín hiệu được lái từ thấp lên cao SMBUS : bus dùng không phải bus I2C, nhưng là cái gì đó tương tự

#use I2C (slave , sda= pin_C4 , scl= pin_C3 , address = 0xa00 , FORCE_HW )

Trang 7

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 62

#USE RS232 ( options ) _Thiết lập giao tiếp RS232 cho chip ( có hiệu lực sau khi nạp chương trình cho chip, không phải giao tiếp RS232 đang sử dụng để nạp chip )

Option bao gồm :

BAUD = x : thiết lập tốc độ baud rate : 19200 , 38400 , 9600 ,

PARITY = x : x= N ,E hay O , với N : không dùng bit chẵn lẻ

XMIT = pin : set chân transmit ( chuyển data)

RCV = pin : set chân receive ( nhận data ) _Các thông số trên hay dùng nhất , các tham số khác sẽ bổ sung sau

VD :

#use rs232(baud = 19200,parity = n, xmit = pin_C6, rcv = pin_C7)

* Một số chỉ thị tiền xử lý khác :

#CASE : cho phép phân biệt chữ hoa / thường trong tên biến, dành cho những ai quen lập trình C #OPT n :với n=0 – 9 : chỉ định cấp độ tối ưu mã, không cần dùng thì mặc định là 9 ( very tối ưu ) #PRIORITY ints : với ints là danh sách các ngắt theo thứ tự ưu tiên thực hiện khi có nhiều ngắt xảy ra đồng thời, ngắt đứng đầu sẽ là ngắt ưu tiên nhất, dùng ngắt nào đưa ngắt đó vô Chỉ cần dùng nếu dùng hơn 1 ngắt Xem cụ thể phần ngắt VD : #priority int_CCP1, int_timer1 // ngắt CCP1 ưu tiên nhất

IV.Các hàm xử lí số, xử lí Bit, Delay

IV.1 Các hàm xử lý số

Bao gồm các hàm: Sin() cos() tan() Asin() acos() atan() Abs() : lấy trị tuyệt đối Ceil( ) :làm tròn theo hướng tăng Floor ( ) :làm tròn theo hướng giảm Exp ( ) : tính e^x Log ( ) : Log10 ( ) : Pow ( ) : tính luỹ thừa Sqrt ( ) :căn thức _Các hàm này chạy rất chậm trên các VDK không

có bộ nhân phần cứng ( PIC 14 ,12 ) vì chủ yếu tính toán với số thực và trả về cũng số thực (

32 bit ) và bằng phần mềm

IV.2 Các hàm xử lý bit và phép toán

Shift_right ( address , byte , value ) / Right

Dịch phải (trái ) 1 bit vào 1 mảng hay 1 cấu trúc Địa chỉ có thể là địa chỉ mảng hay địa chỉ trỏ tới cấu trúc ( kiểu như &data) Bit 0 byte thấp nhất là LSB

Bit_clear ( var , bit )

Bit_set ( var , bit )

Bit_clear ( ) dùng xóa ( set = 0 ) bit được chỉ định bởi vị trí bit trong biến var

Bit_set ( ) dùng set=1 bit được chỉ định bởi vị trí bit trong biến var

var : biến 8 , 16 , 32 bit bất kỳ

Trang 8

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 63

bit : vị trí clear ( set ) : từ 0-7 ( biến 8 bit) , 0-15 ( biến 16 bit ) , 0-31 (biến 32 bit ) _Hàm không trả về trị

VD : Int x; X=11 ; //x=1011 Bit_clear ( x ,1 ) ; // x= 1001b = 9

Bit_test ( var , bit ) :

- Dùng kiểm tra vị trí bit trong biến var

Hàm trả về 0 hay 1 là giá trị bit đó trong var

var : biến 8, 16 ,32 bit

bit : vị trí bit trong var

Swap ( var ) : _var : biến 1 byte

- Hàm này tráo vị trí 4 bit trên với 4 bit dưới của var, tương đương var =( var>>4 ) Hàm không trả về trị

Make8 ( var , offset ) :

- Hàm này trích 1 byte từ biến var

var : biến 8,16,32 bit offset là vị trí của byte cần trích ( 0,1,2,3)

Hàm trả về giá trị byte cần trích VD :

Int16 x = 1453 ; // x=0x5AD

Y = Make(x, 1) ; //Y= 5 = 0x05

Make16 ( varhigh , varlow ) :

- Trả về giá trị 16 bit kết hợp từ 2 biến 8 bit varhigh và varlow Byte cao là varhigh , thấp là varlow

Make32 ( var1 , var2 , var3 , var4 ) :

- Trả về giá trị 32 bit kết hợp từ các giá trị 8 bit hay 16 bit từ var1 tới var4 Trong đó var2 đến var4 có thể có hoặc không Giá trị var1 sẽ là MSB , kế tiếp là var2 , Nếu tổng số bit kết hợp ít hơn 32 bit thì 0 được thêm vào MSB cho đủ 32 bit VD:

Int a=0x01 , b=0x02 , c=0x03 , d=0x04 ; // các giá trị hex

Int32 e ;

e = make32 ( a , b , c , d ); // e = 0x01020304

e = make32 ( a , b , c , 5 ) ; // e = 0x01020305

e = make32 ( a, b, 8 ); // e = 0x00010208

e = make32 ( a ,0x1237 ) ; // e = 0x00011237

IV.3 Các hàm Delay

Để sử dụng các hàm delay , cần có khai báo tiền xử lý ở đầu file , VD : sử dụng OSC

20 Mhz , cần khai báo : #use delay ( clock = 20000000 )

Trang 9

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 64

Hàm delay không sử dụng bất kỳ timer nào Chúng thực ra là 1 nhóm lệnh ASM để khi thực thi từ đầu tới cuối thì xong khoảng thời gian mà bạn quy định Tuỳ thời gian delay yêu cầu dài ngắn mà CCS sinh mã phù hợp có khi là vài lệnh NOP cho thời gian rất nhỏ Hay

1 vòng lặp NOP Hoặc gọi tới 1 hàm phức tạp trong trường hợp delay dài Các lệnh nói chung

là vớ vẩn sao cho đủ thời gian quy định là được Nếu trong trong thời gian delay lại xảy ra ngắt thì thời gian thực thi ngắt không tính vào thời gian delay, xong ngắt nó quay về chạy tiếp các dòng mã cho tới khi xong hàm delay Do đó thời gian delay sẽ không đúng

Có 3 hàm phục vụ :

1 / delay_cycles (count ) Count : hằng số từ 0 – 255, là số chu kỳ lệnh 1 chu kỳ lệnh bằng 4 chu kỳ máy

- Hàm không trả về trị Hàm dùng delay 1 số chu kỳ lệnh cho trước VD :

delay_cycles ( 25 ) ; // với OSC = 20 Mhz , hàm này delay 5 us

2 / delay_us ( time ) Time : là biến số thì = 0 – 255 , time là 1 hằng số thì = 0 -65535 _Hàm không trả về trị

- Hàm này cho phép delay khoảng thời gian dài hơn theo đơn vị us

- Quan sát trong C / asm list bạn sẽ thấy với time dài ngắn khác nhau, CSS sinh mã khác nhau

3 / delay_ms (time ) Time = 0-255 nếu là biến số hay = 0-65535 nếu là hằng số

- Hàm không trả về trị

- Hàm này cho phép delay dài hơn nữa

V Xử lí ADC, Các hàm I/O

V.1 Xử lý ADC

PIC có nhiều chân phục vụ xử lý ADC với nhiều cách thức khác nhau Để dùng ADC , bạn phải có khai báo #DEVICE cho biết dùng ADC mấy bit ( tuỳ chip hỗ trợ, thường là 8 hay

10 bit hoặc hơn) Bạn cần lưu ý là: 1 VDK hỗ trợ ADC 10 bit thì giá trị vào luôn là 10 bit, nhưng chia cho 4 thì còn 8 bit Do đó 1 biến trở chiết áp cấp cho ngõ vào ADC mà bạn chọn chế độ 10 bit thì sẽ rất nhạy so với chế độ 8 bit ( vì 2 bit cuối có thay đổi cũng không ảnh hưởng giá trị 8 bit cao và do đó kết quả 8 bit ADC ít thay đổi ), nếu chương trình có chế độ kiểm tra ADC để cập nhật tính toán hay dùng ngắt ADC, thì nó sẽ chạy hoài thôi Dùng ADC

8 bit sẽ hạn chế điều này Do đó mà CCS cung cấp chọn lựa ADC 8 hay 10 bit tùy mục đích

sử dụng

V.2 Các hàm vào ra trong IC

1 / Output_low ( pin ) , Output_high (pin ) :

_Dùng thiết lập mức 0 ( low, 0V ) hay mứ c 1 ( high , 5V ) cho chân IC , pin chỉ vị trí chân

Trang 10

SVTH: Lê Cao Thượng – Trần Thành Nghĩa Trang 65

_Hàm này sẽ đặt pin làm ngõ ra, xem mã asm để biết cụ thể

_Hàm này dài 2-4 chu kỳ máy Cũng có thể xuất xung dùng set_tris_X() và #use fast_io VD : chương trình sau xuất xung vuông chu kỳ 500ms, duty =50% ra chân B0 ,nối B0 với 1 led sẽ làm nhấp nháy led

#include <16F877.h>

#use delay( clock=20000000)

Main()

{ while(1)

{ output_high(pin_B0) ;

Delay_ms(250) ; // delay 250ms

Output_low (pin_B0);

Delay_ms (250 ); } }

2 / Output_bit ( pin , value ) :

Pin : tên chân ; Value : giá trị 0 hay 1

- Hàm này cũng xuất giá trị 0 / 1 trên pin, tương tự 2 hàm trên Thường dùng nó khi giá trị ra tuỳ thuộc giá trị biến 1 bit nào đó, hay muốn xuất đảo của giá trị ngõ ra trước đó

3 / Output_float ( pin ) :

- Hàm này set Pin như ngõ vào

4 / Input ( pin ) :

- Hàm này trả về giá trị 0 hay 1 là trạng thái của chân IC Giá trị là 1 bit

5 / Output_X ( value ) :

- X là tên port có trên chip Value là giá trị 1 byte

- Hàm này xuất giá trị 1 byte ra port Tất cả chân của port đó đếu là ngõ ra

6 / Input_X ( ) : _X : là tên port ( a, b ,c ,d e )

- Hàm này trả về giá trị 8 bit là giá trị đang hiện hữu của port đó

7 / Port_B_pullups ( value ) : _Hàm này thiết lập ngõ vào port B pullup Value =1 sẽ kích hoạt tính năng này và value =0 sẽ ngừng

- Chỉ các chip có port B có tính năng này mới dùng hàm này

8 / Set_tris_X ( value ) : Hàm này định nghĩa chân IO cho 1 port là ngõ vào hay ngõ ra Chỉ được dùng với #use fast_IO Sử dụng #byte để tạo biến chỉ đến port và thao tác trên biến này chính là thao tác trên port

Value là giá trị 8 bit Mỗi bit đại diện 1 chân và bit=0 sẽ set chân đó là ngõ vào, bit= 1 set chân đó là ngõ ra

Ngày đăng: 07/09/2017, 08:50

TỪ KHÓA LIÊN QUAN

w