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