Tài liệu CCS C for PIC16F877A
Mục lục
I. Tổng quan về CCS 10
1.1. Vì sao ta sử dung CCS ?
1.2. Giới thiệu về CCS ?
1.3. Một số ví dụ cho lập trình CCS .10
II.Chúng ta cùng nhau tìm hiểu lần lượt các phần sau .11
1. I/O_Delay
1.2. Input_output .11
1.3. Nháy LED PortB7 .14
1.4. Nháy Led nhiều chế độ .15
1.5. Điều khiển led sáng dồn .18
1.6. I/O + Delay _ Delay 1s RB0 18
1.7. Nháy Led RB0 .19
1.8. Delay 1s portB .21
1.9. Delay_Timer0 .22
2. ADC 25
A. Sơ đồ:
B.Code
B.1. ADC reading voltage .25
B.2. LM335_LCD 26
B.3. LM335_F877A_LCD1602 29
B.4. ADC_186 .33
3. DAC .36
3.1. DAC_1446 .36
4. Timer .37
4.1. Timer0 38
4.2. Timer1 39
4.3. Timer2 39
4.4. frequencymeter .40
5. INTERRUPT . 43
5.1. Ngắt Timer0 .44
5.2. Ngắt ngoài .48
5.3. Ngắt ngoài trên RB4-RB7 51
5.4. Giải mã bàn phím .56
5.5. Chương trình gửi ký tự ra 2x16 LCD dùng CCS C .59
5.7. Ví dụ nhỏ về ngắt ngoài 61
5.8. Ngắt ngoài và đèn 7 đoạn .62
5.9. Chương trình hiển thị phím số ra đèn 7 đoạn (không dùng interrupt) .63
5.10. Chương trình hiển thị phím số ra đèn 7 đoạn (DÙNG INTERRUPT) .64
5.11. Thay đổi tốc độ đèn led dung ngắt .65
6. Chương trình ví dụ sau mô tả cách dùng PWM do CCS cung cấp. .72
7. Tìm hiểu về LCD .76
7.1. 8bit interface .77
7.2. 4bit interface .78
7.3. LCD_lib_4bitCCS C for PIC16F877A 24/06/2008
7.4. LCD lib 8bits .80
7.5. Hiển thị LCD 8bit interface .81
7.6. Hiển thị LCD 4bit interface .86
7.7. LCD_8bit interface, có kiểm tra cờ bận. 86
7.8. LCD and Keypad drive .89
7.9.LM335_F877A_LCD1602 106
7.10. LM35_F877A_LCD1602 .107
7.11. LM335_F877A_LCD1602 .110
7.12. lcd_bargraph .113
7.13. Chương trình gửi ký tự ra 2x16 LCD dùng CCS C 113
8. LED ma trận . 118
8.1. font_ascii
8.2. font_ascii2 .120
8.3. led matrix_Ngat ngoai_COM .122
8.4. led matrix ket noi RS232 .128
8.5. led matrix (595 va 154) ket noi rs232 .132
8.6. led matrix ver 1.2 .136
8.7. 16f877a_8x16_2mau . .141
9. Động cơ .148
9.1. DC Motor
9.1.1. code
9.1.2. Position_Control .151
9.1.3. check_encoder .175
9.2. DK Step Motor .177
9.2.1. Code
9.2.2. Step_motor_F877A
9.2.3. Chương trình điều khiển động cơ bước .181
9.2.4. Điều khiển động cơ bước . .183
10. Capture . .187
10.1. Code cho CCS
10.2. Sử dụng capture newcode 188
10.3.Capture_LCD_5MH .190
10.4. Sử dụng capture_LCD .193
10.5. Sử dụng capture 195
11. SPI .196
12. Các chuẩn giao tiếp . .197
12.1. Chuẩn giao tiếp I2C
12.1.1. Master_Slave .204
12.1.1.1. I2Cmaster .204
12.1.1.2. I2Cslave .205
12.1.2. lcd1_lib
12.1.3. lcd2_lib .208
12.2. Giao tiếp RS232 210
Serial Port - lập trình giao tiếp nối tiếp .210
12.2.1. Giao tiep COM_LCD 222
12.2.2. USART-RS232 .224CCS C for PIC16F877A 24/06/2008
12.2.3. RS232TUT.H .225
12.2.4. RS232TUT .225
12.2.5. RS232TUTDlg 227
12.2.6. RS232TUTDlg.CPP .228
12.2.7. StdAfx.H .235
12.2.8. mscomm.H .
12.2.9. mscomm.CPP .237
12.2.10. Giao tiep pc va pic6f877 qua cong rs232 .244
13. Ghi đọc RAM ngoài . 246
13.1. Sơ đồ .
13.2. Code .246
Project 1: Kết nối PIC 16F877A với EEPROM 25AA640 .248
ortOpen(BOOL bNewValue)
{
static BYTE parms[] =
VTS_BOOL;
InvokeHelper(0x14, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
bNewValue);
}
BOOL CMSComm::GetPortOpen()
{
BOOL result;
InvokeHelper(0x14, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result,
NULL);
return result;
}
void CMSComm::SetRThreshold(short nNewValue)
{
static BYTE parms[] =
VTS_I2;
InvokeHelper(0x15, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
nNewValue);
}
short CMSComm::GetRThreshold()
{
short result;
InvokeHelper(0x15, DISPATCH_PROPERTYGET, VT_I2, (void*)&result, NULL);
return result;
}
void CMSComm::SetRTSEnable(BOOL bNewValue)
{
static BYTE parms[] =
VTS_BOOL;
InvokeHelper(0x16, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
bNewValue);
}
BOOL CMSComm::GetRTSEnable()
{
BOOL result;
InvokeHelper(0x16, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result,
NULL);
return result;
}
void CMSComm::SetSettings(LPCTSTR lpszNewValue)
{
static BYTE parms[] =
VTS_BSTR;
InvokeHelper(0x17, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
CCS C for PIC16F877A 24/06/2008
Thang8831
- 243 -
lpszNewValue);
}
CString CMSComm::GetSettings()
{
CString result;
InvokeHelper(0x17, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result,
NULL);
return result;
}
void CMSComm::SetSThreshold(short nNewValue)
{
static BYTE parms[] =
VTS_I2;
InvokeHelper(0x18, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
nNewValue);
}
short CMSComm::GetSThreshold()
{
short result;
InvokeHelper(0x18, DISPATCH_PROPERTYGET, VT_I2, (void*)&result, NULL);
return result;
}
void CMSComm::SetOutput(const VARIANT& newValue)
{
static BYTE parms[] =
VTS_VARIANT;
InvokeHelper(0x19, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
&newValue);
}
VARIANT CMSComm::GetOutput()
{
VARIANT result;
InvokeHelper(0x19, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&result,
NULL);
return result;
}
void CMSComm::SetInput(const VARIANT& newValue)
{
static BYTE parms[] =
VTS_VARIANT;
InvokeHelper(0x1a, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
&newValue);
}
VARIANT CMSComm::GetInput()
{
VARIANT result;
InvokeHelper(0x1a, DISPATCH_PROPERTYGET, VT_VARIANT, (void*)&result,
NULL);
return result;
}
CCS C for PIC16F877A 24/06/2008
Thang8831
- 244 -
void CMSComm::SetCommEvent(short nNewValue)
{
static BYTE parms[] =
VTS_I2;
InvokeHelper(0x1b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
nNewValue);
}
short CMSComm::GetCommEvent()
{
short result;
InvokeHelper(0x1b, DISPATCH_PROPERTYGET, VT_I2, (void*)&result, NULL);
return result;
}
void CMSComm::SetEOFEnable(BOOL bNewValue)
{
static BYTE parms[] =
VTS_BOOL;
InvokeHelper(0x1c, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
bNewValue);
}
BOOL CMSComm::GetEOFEnable()
{
BOOL result;
InvokeHelper(0x1c, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result,
NULL);
return result;
}
void CMSComm::SetInputMode(long nNewValue)
{
static BYTE parms[] =
VTS_I4;
InvokeHelper(0x1d, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms,
nNewValue);
}
long CMSComm::GetInputMode()
{
long result;
InvokeHelper(0x1d, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
12.2.10. Giao tiep pc va pic6f877 qua cong rs232
chào các bạn mình đang viết chương trình giao tiếp giữa pic6f877 và pc
chương trình trên pic viết bằng ccsc lệnh :
#include
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device 16F877*=16 ADC=8
#use delay(clock=1000000)
#use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, PARITY=N,BITS =7,STOP=2)
#include
CCS C for PIC16F877A 24/06/2008
Thang8831
- 245 -
#include
void main()
{
//int status;
char value;
lcd_init();
lcd_putc("begin");
value=getc();
putc(value);}
trên pc dùng chương trình giao tiếp viết bằng matlab( trong diễn đàn)
nhưng sao mình kô thấy nó nhận dc gì cả
có ai làm cái này rồi thì có thể giúp mình dc kô
Ban tham khao nhe
#include
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,HS
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
char c;
#INT_RDA
Receive_isr()
{
c=getc(); // nhan ky tu.
}
void main(void)
{
set_tris_b(0x00);
output_b(0x00);
enable_interrupts(INT_RDA);
enable_interrupts (GLOBAL);
while(1)
{
output_b(c);
}
}
CCS C for PIC16F877A 24/06/2008
Thang8831
- 246 -
13. Ghi đọc RAM ngoài
13.1. Sơ đồ
13.2. Code
///////////////////////////////////////////////////////////////////////////
//Chuong trinh ghi va doc RAM ngoai
//Su dung PIC16F877, chot bang 74HCS573, RAM 62256 32Kx8
//
//Cong viec can thuc hien:
//Ghi du lieu vào RAM sau moi lan bam nut,
//sau 10 lan ghi, sang LED va doc lan luot 10 gia tri do.
//
///////////////////////////////////////////////////////////////////////////
#include
#device *=16
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES RC //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or
B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=20000000)
//khai bao bien
int8 adc;
int ghi; //ghi=1:dang ghi du lieu vao RAM
int16 diachi;
#int_ext
void ngat_RB0()
{
int16 diachi; //bien dem so lan ghi vao RAM
CCS C for PIC16F877A 24/06/2008
Thang8831
- 247 -
if( diachi < 10 ) {
adc=read_adc(); //doc gia tri ADC
output_high( PIN_D7 ); //khoa RAM
//thiet lap dia chi cho RAM:
output_high( PIN_B1 ); //LE=1, cho phep xac lap 8bit
thap dia chi RAM
output_c( diachi ); //xac lap 8bit thap dia chi RAM
output_low( PIN_B1 ); //LE=0, chot 8bit thap dia chi
RAM
output_d( diachi>>8 ); //xac lap 8bit cao dia chi RAM,
//dong thoi mo RAM (RD7=0)
//ghi gia tri vao RAM:
output_low( PIN_B2 ); //chuyen sang che do ghi, WEbu=0
output_c( adc ); //ghi gia tri vao RAM
output_high( PIN_D7 ); //khoa RAM
diachi++;
}
if( diachi == 10 ) {
output_high( PIN_A5 ); //sang LED
diachi = 0;
ghi = 0; //da ghi xong, cho phep xu li
tiep
}
}
// Chuong trinh chinh
main()
{
setup_adc_ports( AN0_AN1_VSS_VREF ); //A0,A1 la ADC, VRef+ la A3
setup_adc( ADC_CLOCK_INTERNAL );
set_adc_channel(0); //chon AN0
enable_interrupts( global );
enable_interrupts( int_ext ); //chon ngat ngoai
ext_int_edge( L_TO_H ); //ngat dua vao canh len
while(true) {
ghi = 1; //dang ghi du lieu vao RAM
if( ghi == 0 ) { //du lieu da ghi xong
output_high( PIN_B2 ); //khong cho phep che do
ghi
output_low( PIN_B3 ); //chuyen sang che do doc,
OEbu=0
for( diachi=0;diachi<=10;diachi++ ) {
//thiet lap dia chi cho RAM:
output_high( PIN_B1 ); //LE=1, cho phep xac lap
8bit thap dia chi RAM
output_c( diachi ); //xac lap 8bit thap dia
chi RAM
output_low( PIN_B1 ); //LE=0, chot 8bit thap dia
chi RAM
output_d( diachi>>8 ); //xac lap 8bit cao dia chi
RAM,
//dong thoi mo RAM (RD7=0)
//doc gia tri tu RAM:
input_c(); //doc gia tri tu RAM
delay_ms(700);
output_high( PIN_D7 ); //khoa RAM
}
}
}
}
CCS C for PIC16F877A 24/06/2008
Thang8831
- 248 -
Project 1: Kết nối PIC 16F877A với EEPROM 25AA640.
Sorry mọi người là tối hôm nay em tìm mỏi cả mắt mà không thấy bất cử một thằng
EEPROM nào có chuẩn giao tiếp SPI, cho nên ở Project này em chỉ xin được làm chay thôi,
ai có điều kiện mạch thật hoặc có trình giả lập tốt thì xin test + đưa ra ý kiến cho em phát.
SPI là một chuẩn dữ liệu giao tiếp đơn giản nhất có tốc độ lớn nhất, tuy nhiên có độ an
toàn không cao khi mà dây clock bị ảnh hưởng => dẫn đến ảnh hưởng đến toàn hệ thống.
Với PIC16F877A thì có 3 chân cho chế độ SPI đó là: RC3( clock ), RC4 ( SDI ), RC5 ( SD0)
, còn chân select chíp thì lấy bất cứ một chân I/O thông thường.
Cơ chế SPI là quá trình dịch bít qua lại giữa Slave và Master qua 2 đường đây SDI, SDO.
Ứng với mỗi IC khác nhau lại cho một chuẩn truyền tiếp riêng để điều khiển quá trình truyền.
Với EEPROM 25AA640 cơ chế đó là:
Đọc byte:
Truyền lệnh 0000011 tiếp đến là truyền địa chỉ 16 byte, và đọc dữ liệu . Khi chân CS lên 1 =>
cũng là lúc báo hiệu kết thúc đường truyền.
Write byte
Viết lệnh command: 00000010, sau đó truyền địa chỉ 16 bit, rồi bắt đầu truyền dữ liệu. Quá
trình truyền kết thức khi CS = 1
PHP Code:
void main()
{
// init ban dau
OUTPUT_LOW(PIN_C2);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
OUTPUT_HIGH(PIN_C2);
delay(5);
// truyen du lieu co gia tri 0x55 xuong eeprom tai dia chi 0x0004
OUTPUT_LOW(PIN_C2);
spi_write(0x02); // command = 0x02 -> ghi du lieu
CCS C for PIC16F877A 24/06/2008
Thang8831
- 249 -
spi_write(0x00);
spi_write(0x04);
wpi_write(0x55);
OUTPUT_HIGH(PIN_C2);
delay(5);
// Doc du leu
OUTPUT_LOW(PIN_C2);
spi_write(0x03); // command -= 0x03 -> doc du lieu
spi_write(0x00);
spi_write(0x04);
wpi_read(buff);
OUTPUT_HIGH(PORTD);
delay(5);
while(1);
}
cho em hỏi về vòng lặp while
các bác có thể cho mình biết cách sử dụng vòng lặp while dc ko?
chương trình mình viết như sau nhưng vòng lặp while ko thực hiện đc
Code:
int8 a,b;
main()
{
while(a==8){
a++;
portb=00;
delay_ms(100);
portb=0xFF;
delay_ms(100);
}
TL: Bên ngoài vòng while nên khởi tạo giá trị cho biến a. Điều kiện lặp là a==8 do đó nếu giá
trị a ban đầu không phải là 8 thì vòng lặp không chạy. Nếu vòng lặp có chạy thì chỉ chạy 1 lần,
vì bên trong vòng lặp a bị thay đổi.
Code của bạn chỉ cần sửa lại thành
Code:
int8 a,b;
main()
{
a = 0;
while(a<8){
a++;
portb=00;
delay_ms(100);
portb=0xFF;
delay_ms(100);
}
CCS C for PIC16F877A 24/06/2008
Thang8831
- 250 -
File đính kèm:
tai_lieu_ccs_c_for_pic16f877a.pdf

