18-08-2009, 01:25 AM | #1 |
Nhập môn đệ tử
Tham gia ngày: Jul 2008
Bài gửi: 9
: |
Đoạn chương trình giao tiếp SPI
Chào anh em trong Forum. Tui có đoạn chương trình giao tiếp SPI như sau:
Code Slave 16F877A: Code:
int nhan; //................... set_tris_d (0x00); output_d(0x00); setup_spi(spi_slave|spi_l_to_h); enable_interrupts(INT_SSP); enable_interrupts(Global); nhan = spi_read (); output_d(nhan); //Hiển thị giá trị nhận được từ Master 2) Khi chưa nối SCK, SDI, SDO với Master thì Port D đã hiển thị (10101010). Tui không hiểu vì sao nữa? Nhờ anh em chỉ giáo Thank! thay đổi nội dung bởi: phamminhtuan, 18-08-2009 lúc 10:41 AM. Lý do: Định dạng code |
18-08-2009, 06:39 PM | #2 |
Super Moderator
Tham gia ngày: Feb 2006
Bài gửi: 150
: |
Vì SPI bạn cấu hình là Slave, đọc dữ liệu từ Master bạn phải dùng hàm spi_data_is_in() trước.
Đối với đoạn code của bạn, khi gọi spi_read() thì CCS dịch ra như sau: MOVFF SSP1BUF, _yourvar Không có lệnh kiểm tra cờ nào cả, do đó cho dù có nối hay chưa thì nó đọc được kết quả hiển thị ra PortD không có gì lạ cả. Bạn có thể dịch thử trong MPLAB, view->program memory để xem Disassember Vì bạn post code không đủ, nên nếu nói thiếu thì thiếu nhiều, ví dụ bạn khởi tạo ngắt, hàm ngắt của bạn ở đâu ..., Bạn có thể tham khảo 2 ví dụ của CCS là EX_SPI.C và EX_SPI_SLAVE.C trong thư mục [C:\Program Files\PICC\Examples] nếu cài CCS ở ổ C |
22-08-2009, 12:32 PM | #3 | |
Nhập môn đệ tử
Tham gia ngày: Jul 2008
Bài gửi: 9
: |
Trích:
Tuy nhiên, mình sử dụng ngắt chứ ko sử dụng thuật toán thăm dò: data=spi_data_is_in()... Mình Post 2 đoạn Code, bạn nào cần thì tham khảo nha, truyền-nhận ngon lắm!!! Master Code: Code:
#include <16f877a.h> #include <def_877a.h> #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #use fast_io(b) #use fast_io(c) #use fast_io(d) #include <lcd_lib_4bit.c> //********************************* int8 data; //********************************* void main() { output_high(pin_c2); data = 0b00110010; //Thử một giá trị để truyền setup_spi( SPI_MASTER | SPI_L_TO_H); delay_ms(1000); while(1) { output_low(pin_c2); //Chân C2 dùng Select chip spi_write(data); output_high(pin_c2); delay_us(10);//Tao tre giua 2 lan truyen } } //******************************* Slave Code: Code:
#include <16f877a.h> #include <def_877a.h> #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #use fast_io(b) #use fast_io(c) #use fast_io(d) #include <lcd_lib_4bit.c> //************************* int8 data; //************************* #int_ssp void ssp_isr(void) { data = spi_read(); output_d(data); //Hiển thị ra Port D } //************************* void main() { setup_spi(SPI_SLAVE|SPI_L_TO_H); clear_interrupt(INT_SSP); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); while(1) { //Ko làm gì, đợi Data đến } } //************************ thay đổi nội dung bởi: falleaf, 22-08-2009 lúc 06:48 PM. |
|
19-10-2009, 07:04 PM | #4 |
Nhập môn đệ tử
Tham gia ngày: Oct 2009
Bài gửi: 1
: |
Mình mới học về PIC có tham khảo về phần SPI, mình viết 1 chương trình để điều khiển led đơn, nhưng ko hiểu sao nó ko chạy vì trình độ còn kém, mong bạn giúp mình: salve kết nối 8led ở portb.
Chương trình Master: #include <16F877A.h> #fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT #use delay(clock=4000000) void main(void) { int i=0; setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4); enable_interrupts(GLOBAL); enable_interrupts(INT_SSP); delay_ms(1000); spi_write(i); } Chương trình Slave: #include <16F877A.h> #fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT #use delay(clock=4000000) void main(void) { int i,j=0; output_b(0x00); setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_CLK_DIV_4); enable_interrupts(GLOBAL); enable_interrupts(INT_SSP); while(!j) { j=spi_data_is_in(); } i=spi_read(); while(1) { output_b(0xff); delay_ms(100); output_b(i); delay_ms(100); } } |
23-03-2011, 12:22 AM | #5 |
Đệ tử 4 túi
|
Cám ơn bạn success.tl mình đã copy chương trìh của bạn và về mô phỏng cho chạy thử .hình như là code phan MASTER thiếu lệnh set_tris_c(0x00); trong hàm main thì phải ,tưong tự trong SLAVE cũng thiếu lệnh set_tris_d(0x00); trong main .Vi mình thử bỏ 2 hàm này ra chương trình không chạy!
Mình đã dựa cva2o chưong trình trên và viết lại cái của mình:giao tiếp giữa 1 MASTER và 2 SLAVE CODE SLAVE: Code:
#include <16f877a.h> #include <def_877a.h> #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #use fast_io(b) #use fast_io(c) #use fast_io(d) #define SS PIN_A5 //#include <lcd_lib_4bit.c> //************************* int8 data; //************************* #int_ssp void ssp_isr(void) { if(input(SS)==0) { data = spi_read(); //doc tin hieu tu MASTER set_tris_b(0); //thiet lap PORTB la cong xuat du lieu output_b(data); //Hien thi ra port B delay_us(10); } } //************************* void main() { set_tris_a(0xff); setup_spi(SPI_SLAVE|SPI_L_TO_H|spi_clk_div_16 ); clear_interrupt(INT_SSP); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); while(1) { //Khong lam gi ,cho data den } } //************************ CODE MASTER Code:
#include <16f877a.h> #include <def_877a.h> #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #use fast_io(b) #use fast_io(c) #use fast_io(d) #define SS1 pin_C1 //chan chon chip cho 2 SLAVE #define SS2 pin_C2 //********************************* int8 data,i,j; //********************************* void change_data() //dich tung bit trong bien data { i++; if(i<=8)data=(data<<1) ; //dich 8 lan gia tri cua data else { data=0x01; j=1; } } void send_data() //gui du lieu den SLAVE { while(1) { spi_write(data); change_data(); delay_ms(100); //Tao tre giua 2 lan truyen if (j==1) break; //sau 8 lan quet de truyen du lieu den SLAVE ,thoat khoi vong lap } } void main() { data = 0x01; //gia tri dau cua bien data set_tris_c(0); set_tris_e(0); setup_spi( SPI_MASTER | SPI_L_TO_H|spi_clk_div_16 ); delay_ms(100); While(1) { output_low(SS1); //chon SLAVE 1 de gui du lieu output_high(SS2); send_data(); j=0; i=0; output_low(SS2); //chon SLAVE 2 de gui du lieu output_high(SS1); send_data() ; j=0; i=0; } } //******************************* http://www.mediafire.com/?85a3byc85v2ag4h
__________________
My blog: http://autumnneverreturn.blogspot.com/ Đối thủ khó chiến thắng nhất là bản thân !!! thay đổi nội dung bởi: hcmut.khoamaisi, 23-03-2011 lúc 12:28 AM. |
16-04-2011, 03:03 AM | #6 |
Nhập môn đệ tử
Tham gia ngày: Mar 2011
Bài gửi: 1
: |
mấy bạn ơi,mình đã gởi dữ liệu theo chuẩn spi được rùi ,nhưng giờ muốn gởi kí tự từ máy tính xuống con master ,rồi chuyển sang hiển thị 2 con led 7 đoạn ở con slave ,ai làm được chỉ mình với
|
20-05-2011, 04:21 PM | #7 |
Nhập môn đệ tử
Tham gia ngày: Jul 2009
Bài gửi: 8
: |
mình thấy code trên chưa có truyền từ slave về master nhỉ.bạn nào làm rồi có thể up code lên tham khảo không
|
11-01-2012, 03:44 AM | #8 |
Đệ tử 2 túi
Tham gia ngày: Nov 2010
Bài gửi: 38
: |
Cám ơn success.tl 1 bài rất hay, giúp ích nhiều cho mình. Cũng cám ơn khoamaisi, 1 project good
thay đổi nội dung bởi: ngdnhanbk, 11-01-2012 lúc 04:22 AM. |
26-03-2012, 09:06 PM | #9 |
Nhập môn đệ tử
Tham gia ngày: Mar 2012
Bài gửi: 4
: |
bạn hcmut.khoaimasi ,bạn ơi hàm #include <def_877a.h>
không có trong project hả,bạn có thể gửi lên được không. cám ơn bạn nhiều!@! |
17-12-2012, 09:13 PM | #10 |
Nhập môn đệ tử
Tham gia ngày: Sep 2009
Bài gửi: 1
: |
truyen nhan spi
Dear all!
Bạn nào có code spi mà truyền nhận dữ liệu 2 chiều ko, master gui malenh xuống slave, slave send len master data,mình truyền 1 chiều từ master xuống slave thì ok, nhưng chiều ngược lại thì ko được,. Mong mọi người giúp đỡ. |
02-01-2013, 07:22 AM | #11 |
Nhập môn đệ tử
Tham gia ngày: Sep 2011
Bài gửi: 1
: |
[help]-truyền dữ liệu spi với 2 vi đk pic
Chào các anh, chị trong room. đệ đang làm bài toán về spi.nhưng ko hiểu sao mô phỏng ko chạy được.ý tưởng đệ làm như sau:
* master + đọc phím bấm gửi kí tự (A-B-C-D) + mỗi lần bấm phím (1-2-3-4) led của master(1-2-3-4) và led của slave(5-6-7-8) sẽ sáng. + kí thị gửi và nhận đều được hiện thị trên 2 lcd của master và slave * slave +đọc phím bấm gửi kí tự (W-X-Y-Z) + mỗi lần bấm phím (1-2-3-4) led của slave(1-2-3-4) và led của master(5-6-7-8) sẽ sáng. + kí thị gửi và nhận đều được hiện thị trên 2 lcd của slave và master. Sau đây là chương trình. 1.Chương trình cho Master [CODE]#include <16f877A.h> #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #include <lcd_lib_4bit.c> #use spi(DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3,BITS=16) // ------------------ int i=0,mode=0; char OUT,IN; //----------------- void docphim(); void led_1(); void sent_spi(); void spi(); //----------------- #INT_RTCC void docphim() { set_timer0(100); if(input_state(pin_A0)==0) i=1; if(input_state(pin_A0)==1&&i==1) { i=0; mode++; } } //--------------- #INT_SSP void spi() { IN=spi_read(OUT); delay_ms(10); if(IN=="W") { output_d(0xef);// SANG LED 5 LCD_PutCmd(0xc8); LCD_PutChar("W"); } if(IN=="X") { output_d(0xdf);// SANG LED 6 LCD_PutCmd(0xc8); LCD_PutChar("X"); } if(IN=="Y") { output_d(0xbf);// SANG LED 7 LCD_PutCmd(0xc8); LCD_PutChar("Y"); } if(IN=="Z") { output_d(0x7f);// SANG LED 8 LCD_PutCmd(0xc8); LCD_PutChar("Z"); } } //---------------- void sent_spi() { docphim(); switch(mode) { case 0:LCD_PutCmd(0x87);LCD_PutChar(" "); output_d(0xff); // tat het led break; case 1:OUT="A"; LCD_PutCmd(0x87);LCD_PutChar(OUT); delay_ms(10); spi_write(OUT); output_d(0xfe);// led 1 sang break; case 2:OUT="B"; LCD_PutCmd(0x87);LCD_PutChar(OUT); delay_ms(10); spi_write(OUT); output_d(0xfd);// led 2 sang break; case 3:OUT="C"; LCD_PutCmd(0x87);LCD_PutChar(OUT); delay_ms(10); spi_write(OUT); output_d(0xfb);// led 3 sang break; case 4:OUT="D"; LCD_PutCmd(0x87);LCD_PutChar(OUT); delay_ms(10); spi_write(OUT); output_d(0xf7);// led 4 sang break; default:mode=0; break; } } //----------------- void main() { setup_spi(spi_master|spi_l_to_h|spi_clk_div_16); enable_interrupts(INT_SSP); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_BIT ); set_timer0(100); enable_interrupts(int_RTCC); enable_interrupts(GLOBAL); LCD_Init(); LCD_PutCmd(0x80);LCD_PutChar("M-GUI:"); LCD_PutCmd(0xC0);LCD_PutChar("M-NHAN:"); while(true) { sent_spi(); spi(); } } [CODE] 2.Chương trình cho Slave [CODE]#include <16f877A.h> #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,NOLVP, NOCPD, NOWRT #use delay(clock=20M) #include <lcd_lib_4bit.c> #use spi(DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3,BITS=16) //------------- char OUT,IN; int i=0,mode=0; //------------- void docphim(); void led_2(); void sent_spi(); void spi(); //---------------- #INT_RTCC void docphim() { set_timer0(100); if(input_state(pin_A0)==0) i=1; if(input_state(pin_A0)==1&&i==1) { i=0; mode++; } } //--------------------- #INT_SSP void spi() { IN=spi_read(OUT); delay_ms(10); if(IN=="A") { output_d(0xef);// led 5 sang LCD_PutCmd(0xc8); LCD_PutChar("A"); } if(IN=="B") { output_d(0xdf);// led 6 sang LCD_PutCmd(0xc8); LCD_PutChar("B"); } if(IN=="C") { output_d(0xbf);// led 7 sang LCD_PutCmd(0xc8); LCD_PutChar("C"); } if(IN=="D") { output_d(0x7f);// led 8 sang LCD_PutCmd(0xc8); LCD_PutChar("D"); } } //--------------- void sent_spi() { docphim(); switch(mode) { case 0:LCD_PutCmd(0x87);LCD_PutChar(" "); output_d(0xff); // tat het led break; case 1:OUT="W"; LCD_PutCmd(0x87);LCD_PutChar(OUT); spi_write(OUT); delay_ms(10); output_d(0xfe);// led 1 sang break; case 2:OUT="X"; LCD_PutCmd(0x87);LCD_PutChar(OUT); spi_write(OUT); delay_ms(10); output_d(0xfd);// led 2 sang break; case 3:OUT="Y"; LCD_PutCmd(0x87);LCD_PutChar(OUT); spi_write(OUT); delay_ms(10); output_d(0xfb);// led 3 sang break; case 4:OUT="Z"; LCD_PutCmd(0x87);LCD_PutChar(OUT); spi_write(OUT); delay_ms(10); output_d(0xf7);// led 4 sang break; default:mode=0; break; } } //---------------- void main() { setup_spi(spi_slave|spi_l_to_h|spi_clk_div_16); enable_interrupts(INT_SSP); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_BIT ); set_timer0(100); enable_interrupts(int_RTCC); enable_interrupts(GLOBAL); LCD_Init(); LCD_PutCmd(0x80);LCD_PutChar("S-GUI:"); LCD_PutCmd(0xC0);LCD_PutChar("S-NHAN:"); while(true) { sent_spi(); spi(); } } [CODE] 3.Đệ biên dịch k có lỗi, thuật toán không phức tạp , khá dễ hiểu.Để nạp trên Protues, thì sau khi bấm phím để Master truyền qua slave....nhưng đợi mãi mà Slave không thấy nhận để hiện thị LCD và đèn sáng. Mong các huynh chỉ bảo thêm....đệ đang nghiên cứu pic ...nên còn hơi non..hiii thay đổi nội dung bởi: DT2K50, 02-01-2013 lúc 07:24 AM. Lý do: CHƯA BIẾT CHO VÀO THẺ CODE |
17-01-2013, 11:09 AM | #12 | |
Nhập môn đệ tử
Tham gia ngày: Aug 2010
Bài gửi: 3
: |
Trích:
Bạn viết hàm kiểm tra ký tự A trong ct ngắt là if(IN=="A") nên slave không nhận được, bạn nên sửa lại là if(IN==65), khi nhận B thì là 66.. |
|
17-01-2013, 11:24 AM | #13 | |
Nhập môn đệ tử
Tham gia ngày: Aug 2010
Bài gửi: 3
: |
Trích:
#INT_SSP void ngat() { i=spi_read(); } void main(void) { int i,j=0; output_b(0x00); setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_CLK_DIV_4); enable_interrupts(GLOBAL); enable_interrupts(INT_SSP); while(1) { output_b(0xff); delay_ms(100); output_b(i); delay_ms(100); } |
|
|
|