PDA

View Full Version : Vài thủ thuật với CCS C


phamminhtuan
24-06-2008, 10:46 AM
Mình thấy rất nhiều bạn đã viết chương trình cho PIC bằng C, cụ thể là CCS-C nhưng vẫn không thể tận dụng được ưu thế của ngôn ngữ cấp cao mà thay vào đó là sử dụng C như ASM, chỉ tận dụng được các lệnh rẽ nhánh cơ bản. Trong quá trình viết chương trình cho PIC bằng CCS-C, mình rút ra vài kinh nghiệm khá hay, chia sẻ cho các bạn nào quan tâm. Tất nhiên là chương trình không đòi hỏi tốc độ tốt như viết cho ASM.

[1] F1 Phím này cực kỳ lợi hại, nhấn thử là biết ngay.:D

[2] Tận dụng tối đa các thư viện dựng sẵn của CCS C cho việc giao tiếp với IC ngoại vi, vì cơ bản việc giao tiếp này không khó, và chỉ có 1 cách duy nhất theo như hoạt động của IC đó, việc gì phải viết lại nhỉ, trong khi người ta đã viết tốt lắm rồi. Tuy nhiên, nếu muốn nâng cao khả năng lập trình cũng nên xem qua người ta viết cái gì nhé :). Các thư viện này ở thử mục [C:\Program Files\PICC\Drivers]

[3] Tận dụng các hàm như bit_test(), bit_set(),bit_clear(), input(), output_x(), output_bit(), setup_...() và các chỉ dẫn setup, lệnh setup mà không cần phải quan tâm nhiều đến thanh ghi, các hàm này sử dụng với các định nghĩa sẵn có, được định nghĩa trong các file header, ví dụ nếu #include<16f877a.h> thì file đó nằm ở thử mục [C:\Program Files\PICC\Devices\16f877a.h]

[4] Sử dụng hàm printf và hàm sprintf

Hàm printf có thể xuất 1 chuỗi ký tự có định dạng ra UART, tuy nhiên nó có chức năn buffer ra 1 hàm, có nghĩa là xuất các ký tự ascii ra 1 hàm.
Ví dụ như sau, ta có hàm lcd_putc() trong thư viện LCD.C của CCS như sau:

void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
hàm này có chức năng gởi 1 ký tự ASCII ra LCD nếu gặp ký tự '\f' thì xóa lcd, '\n' thì xuống dòng, '\b' trở về đầu dòng.

Vậy để xuất ra LCD giá trị của ADC vừa đọc được trong biến adcresult (kiểu int16), nếu theo phương pháp thông thường, phải chuyển đổi biến này sang ascii rồi dùng lcd_putc() gởi từng ký tự đó ra. Vậy sử dụng hàm printf thì sao:

printf(lcd_putc,"\fGia tri ADC:\n\bHEX:%lx DEC:%lu",adcresult,adcresult);
đầu tiên, '\f' xóa trắng LCD, in ra dòng chữ "Gia tri ADC:" ở dòng 1, gặp '\n' Xuống dòng, gặp '\b' trở về đầu dòng, gặp %lx chuyển giá trị adcresult ra dạng HEX 16bit (ký tự ascii), gặp %lu chuyển giá trị adcresult ra dạng nguyên 16 bit (ký tự ascii).


Hàm sprintf() cũng tương tự, nhưng buffer cho chuỗi, ví dụ:

char str[32];
sprintf(str,"\fGia tri ADC:\n\bHEX:%lx DEC:%lu",adcresult,adcresult);
[5] Sử dụng kiểu cấu trúc, union. Điều này cải thiện đáng kể cách quản lý và sự tiện lợi cho dữ liệu. Ví dụ:

struct Queue{
char name[10];
int16 year;
int8 month;
int8 day;
int8 hour;
int8 minute;
int8 second
char note[20];
};
struct Queue schedule[2];

//truy xuất như sau

sprintf(schedule[0].name,"Lich 1");
schedule[0].year = 2008;
schedule[0].day = 30;
//.....

//nâng cao hơn 1 xíu có thể dùng cấu trúc trong cấu trúc

struct plan {
char name[10];
Queue date;
char job[120];
}

//sử dụng như sau
struc plan myplan;
sprintf(myplan.name,"study pic"); //:D
myplan.date.day = 30;
myplan.date.month = 2;
sprintf(myplan.job,"self-teach"); //:D
***************************** Mình cập nhật tiếp ở đây luôn************************************

[6] Sử dụng nhiều cổng RS232, SPI hay I2C

CCS C cung cấp khả năng tạo ra số lượng các cổng RS232, SPI hay I2C trên bất kỳ I/O nào của PIC nhờ thư viện phần mềm. Vậy khi nào thì các bạn có thể sử dụng phần cứng của PIC cho các cổng đó, hay nhận diện các cổng trên PIC như thế nào. Đó là định nghĩa stream, và FORCE_HW.
Một vài ví dụ cụ thể, ví dụ sau về sử dụng 3 cổng RS232, trong đó 1 cổng sử dụng phần cứng, 2 cổng tạo ra bởi thư việc của CCS C

//Cổng rs232A, xây dựng bằn phần mềm
#use rs232(stream=rs232A, baud=9600, xmit=PIN_A2,rcv=PIN_A3)

//Cổng rs232B, xây dựng bằng phần mềm
#use rs232(stream=rs232B, baud=9600, xmit=PIN_B4,rcv=PIN_B5)

//Cổng rs232C, llà phần cứng UART của PIC
#use rs232(stream=rs232C, baud=9600, UART1)

//sử dụng như sau
if(kbhit(rs232A)) {
printf(rs232B,"Nhan duoc tin hieu tu thang RS232A");
} else if(kbhit(rs232C)) {
printf(rs232B,"Nhan duoc tu thang RS232C");
}

// Ngoài ra còn một các khác để cài đặt RS232 cho phần cứng
//linh động mà không phụ thuộc vào chỉ dẫn #use rs232

setup_uart(9600, rs232C);
Tương tự như vậy, với I2C và SPI, sử dụng các chỉ dẫn #use SPI và #use I2C

[7] ADC của PIC và con trỏ dữ liệu. nếu *=16 thì trình dịch sẽ tự cấu hình con tror là 16 bit nếu truy xuất đến vùng RAM ngoài 0xFF
Nếu bạn muốn sử dụng ADC của PIC như ADC 8 bit, thì có thể thêm chỉ dẫn như sau, để ý, mặc định adc của PIC sử dụng 8 bit thôi nhé:

#include<16f877a.h>
#device *=16, adc=8

//và có thể sử dụng như sau
int8 result;
result = read_adc(ADC_READ_ONLY);
nhưng nếu dùng ADC 10 bit thì biến result phải khai báo 16 bit

#device *=16, adc =10
//sử dụng
int16 result;
result = read_adc()

david
24-06-2008, 11:15 AM
Chưa có gì mới cả !

phamminhtuan
24-06-2008, 11:19 AM
Chưa có gì mới cả !

Bạn cũng tham gia đi nhé, thì sẽ có nhiều điều mới :)

tmtm
24-06-2008, 06:43 PM
Em đang tìm hiểu CCSC. Biết hỏi câu này chắc ko đúng chủ đề lắm nhưng anh Phamminhtuan có thể nói qua cho em về chức năng Serial port monitor trong thanh công cụ tool của CCSC 4.069 được ko? Đọc Help nhưng chưa hiểu lắm.

thuandt2085
26-06-2008, 11:30 PM
các bác cho em mạn phép hỏi có sách nói về ngôn ngữ ccs này ko ?cảm ơn các bác nhiều

namqn
27-06-2008, 01:29 AM
các bác cho em mạn phép hỏi có sách nói về ngôn ngữ ccs này ko ?cảm ơn các bác nhiều
Nếu bạn không ngại tiếng Anh, luôn luôn có tài liệu hướng dẫn của CCS C cho bạn đọc. CCS không phải là ngôn ngữ, nó là tên của một công ty viết ra CCS C, là một trình biên dịch ngôn ngữ C.

Thân,

bien_van_khat
28-06-2008, 03:36 PM
Từ phiên bản 4.068, thằng PCW của CCS cho phép debug/program = ICD2 của microchip, phamminhtuan có thời gian viết tut về cái này cho anh em tham khảo luôn.

phamminhtuan
29-06-2008, 06:57 PM
Từ phiên bản 4.068, thằng PCW của CCS cho phép debug/program = ICD2 của microchip, phamminhtuan có thời gian viết tut về cái này cho anh em tham khảo luôn.

Nói thật là em không có cả cái ICD2 để mà vọc nữa, lấy đâu ra mà viết tutorial :D, hay là bác ...

picpen
30-06-2008, 01:39 AM
các bác cho em hỏi ??? để mở rộng cổng (tăng số cổng) của pic 16f877a ,em kết nối phần cứng như sau :
- port_D của pic nối với cổng đầu vào của ic 8255
- dùng ic định địa chỉ là 74hc138n ,3 chân điều khiển A,B,c của 74hc138n
được nối với các chân , RC5,RC6,RC7
- chân ra Y4 của 74hc138 nối với chân CS của 8255

Em không biết sử dụng những lệnh nào ? để giao tiếp với 8255 và sử dụng các cổng PA,PB,PC của 8255 ,các bác chỉ em phần này nhé , em dùng ccs để soạn thảo
THANKS...................

falleaf
30-06-2008, 01:59 AM
Nói thật là em không có cả cái ICD2 để mà vọc nữa, lấy đâu ra mà viết tutorial :D, hay là bác ...

Qua R&P lấy một cái về test, khi nào rảnh thì mang lại trả. Đơn giản.

NTC, em cho Tuấn mượn một cái ICD2 LE nhé.

Chúc vui

phamminhtuan
30-06-2008, 03:50 AM
Nói thật là em không có cả cái ICD2 để mà vọc nữa, lấy đâu ra mà viết tutorial :D, hay là bác ...

Qua R&P lấy một cái về test, khi nào rảnh thì mang lại trả. Đơn giản.

Chúc vui
:confused:, ý em là không phải vậy, mà là bien_van_khat đã từng làm ICD2 rồi, vậy hay là anh ấy viết luôn cái tut cho mọi người. Nhưng mà dù sao cũng cám ơn anh, bữa nào rảnh em chạy qua chỗ anh Chính ...mượn nó về vọc thử :rolleyes:

manhha2799
13-07-2008, 03:18 PM
-Nếu gặp ký tự '\f' thì xóa lcd, '\n' thì xuống dòng, '\b' trở về đầu dòng.
-Cho em hỏi nếu gặp '\r' thì sẽ làm gì?

david
13-07-2008, 07:36 PM
\r là để kết thúc chuỗi ký tự,mã ASCII của nó là 0x0D

phamminhtuan
15-07-2008, 10:38 PM
\r là để kết thúc chuỗi ký tự,mã ASCII của nó là 0x0D

Đúng là trong C thì như thế, nhưng trong thư viện của LCD không định nghĩa cho kỹ tự \r, bạn có thể xem chi tiết trong thư viện lcd.c của CCSC, trong thư mục [C:\Program Files\PICC\Drivers] nếu bạn cài đặt CCSC mặc định

tampic
17-11-2008, 02:09 AM
Từ phiên bản 4.068, thằng PCW của CCS cho phép debug/program = ICD2 của microchip, phamminhtuan có thời gian viết tut về cái này cho anh em tham khảo luôn.

Mình đang tìm bản CCS 4.068 mà không thấy đâu cả, bạn có cho mình xin đg Link đc kg ?
Cảm ơn bạn nhiều !

nguyen_doubleH
17-11-2008, 09:30 PM
mình dang tim hiểu về pic nhưng ko hiểu mấy.
mình nhận đề tài sử dụng pic dể đếm sản phẩm ht ra 3 led7đoạn ai biết chỉ mình với

bongbk
08-04-2011, 03:25 AM
cho e hoi hàm nay la gi lcd_send_byte()
ai có các hàm lcd trong ccs share e với

headman8x
06-05-2011, 12:43 PM
-Nếu gặp ký tự '\f' thì xóa lcd, '\n' thì xuống dòng, '\b' trở về đầu dòng.
-Cho em hỏi nếu gặp '\r' thì sẽ làm gì?

'\r' sẽ cho phép căn lề trái 1 tab .

bạn xem lại C cơ bản để hiểu thêm!

headman8x
06-05-2011, 12:54 PM
cho e hoi hàm nay la gi lcd_send_byte()
ai có các hàm lcd trong ccs share e với

cho mình hỏi bạn đã cài đặt CCS C chưa vậy ?? nếu bạn cài đặt rồi, thì sẽ có sẵn thư viện lcd mà trình biên dịch cung cấp cho bạn và khi bạn muốn sử dụng nó chỉ việc dung dòng lệnh "#include <lcd.c>" vào là okie.
bạn muốn biết chi tiết hãy vào đường dẫn như sau:
"C:\Program Files\PICC\Drivers\LCD".

dcn_dt
20-07-2012, 03:28 AM
Lâu quá không ai ghé đây nhỉ. Em thuộc lớp sinh sau đẻ muộn. Giờ mới lần mò Pic & CCS. Em có nhiều điều muốn hỏi "dần dần". Ai ghé qua thì giúp em với. Em viết Avr thì em viết Lcd như thế này.


unsigned char M[16];

#define LcdPort PORTB
#define LcdPin PINB
#define LcdDDR DDRB

#define LcdRS PORTB.0
#define LcdRW PORTB.1
#define LcdEN PORTB.2
unsigned char LcdBusy(void)
{
unsigned char BF;
LcdDDR &=0x0F;//High 4 bit are input
//LcdPort=0xF7;//R Pull-Up Enable

LcdRS=0;
LcdRW=1;

BF=0;
LcdEN=1;
delay_us(10);
BF=LcdPin&0x80;
LcdEN=0;
delay_us(10);

LcdEN=1;
delay_us(10);
LcdEN=0;
delay_us(10);

if(BF==0x80)return(1);
else return(0);
}

//----------------
void LcdWr(unsigned char D)
{
LcdDDR|=0xF0;//High 4bit are Output
delay_us(10);
LcdPort=((LcdPort&0x0F)|(D&0xF0));
LcdEN=1;
LcdEN=0;
//--
LcdPort=((LcdPort&0x0F)|((D<<4)&0xF0));
LcdEN=1;
LcdEN=0;
}

//----------------
void LcdWrData(unsigned char LcdData)
{
while(LcdBusy());
//delay_ms(200);
LcdRS=1;
LcdRW=0;
LcdWr(LcdData);
//LcdRW=1;
}

//----------------
void LcdWrCmd(unsigned char LcdCmd)
{
while(LcdBusy());
//delay_ms(200);
LcdRS=0;
LcdRW=0;
LcdWr(LcdCmd);
//LcdRW=1;
}

//----------------
void LcdWrStr(char *s)
{
while(*s)
{
LcdWrData(*s);
s++;
}
}
void LcdInit(void)
{
LcdWrCmd(0x02);
LcdWrCmd(0x0c);
LcdWrCmd(0x28);
LcdWrCmd(0x03);
LcdWrCmd(0x01);
}

unsigned int k=123;
void main(void)
{
LcdInit();
LcdWrCmd(0xC0);
sprintf(&M[0],"Display:%d ",k); LcdWrStr(&M[0]);
while(1);
}



cái em muốn hỏi là: %d gọi là cái gì (Em ko biết tên nên mới "tả" nó thế).
trong CCS em muốn hiển thị các dạng số thực, số nguyên, số hexa... thì dùng cái %gì đựoc ạ. nó có ở mục nào trong help không?
//mong mọi nguời giúp đỡ

thanhsang056
20-07-2012, 11:37 AM
mấy anh ơi có thư viện lcd 8bit nào không cho em xin với, mà có thể thay đổi được các chân của nó nữa

toancdt
20-07-2012, 01:59 PM
mấy anh ơi có thư viện lcd 8bit nào không cho em xin với, mà có thể thay đổi được các chân của nó nữa

thư viện 8bit+4bit+mô phỏng http://www.mediafire.com/?42agjc1s2lynfaa

dangvanchanh
22-11-2012, 04:36 PM
thanks các thánh!