PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 18-08-2009, 01:25 AM   #1
success.tl
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
Hỏi: 1) Đoạn Code trên đã thiết lập đầy đủ chưa? Có cần bổ sung gì ko?
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
success.tl vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-08-2009, 06:39 PM   #2
phamminhtuan
Super Moderator
 
phamminhtuan's Avatar
 
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
phamminhtuan vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-08-2009, 12:32 PM   #3
success.tl
Nhập môn đệ tử
 
Tham gia ngày: Jul 2008
Bài gửi: 9
:
Trích:
Nguyên văn bởi phamminhtuan View Post
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
Cảm ơn bạn phamminhtuan, theo ý kiến của bạn thì mình đã làm được rồi!
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.
success.tl vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 19-10-2009, 07:04 PM   #4
dragon2005
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);
}
}
dragon2005 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-03-2011, 12:22 AM   #5
hcmut.khoamaisi
Đệ tử 4 túi
 
hcmut.khoamaisi's Avatar
 
Tham gia ngày: Dec 2009
Nơi Cư Ngụ: TPHCM
Bài gửi: 79
:
Send a message via Yahoo to hcmut.khoamaisi
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;
}
}
//*******************************
link mô phỏng và cả project:
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.
hcmut.khoamaisi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-04-2011, 03:03 AM   #6
tuanspkt1188
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
tuanspkt1188 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-05-2011, 04:21 PM   #7
longthophi
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
longthophi vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 11-01-2012, 03:44 AM   #8
ngdnhanbk
Đệ 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.
ngdnhanbk vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-03-2012, 09:06 PM   #9
sonlamnguyenw
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!@!
sonlamnguyenw vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 17-12-2012, 09:13 PM   #10
sukichan
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 đỡ.
sukichan vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-01-2013, 07:22 AM   #11
DT2K50
Nhập môn đệ tử
 
DT2K50's Avatar
 
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
File Kèm Theo
File Type: rar MO PHONG VA THU VIEN LCD.rar (35.8 KB, 55 lần tải)

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
DT2K50 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 17-01-2013, 11:09 AM   #12
toila83
Nhập môn đệ tử
 
Tham gia ngày: Aug 2010
Bài gửi: 3
:
Trích:
Nguyên văn bởi DT2K50 View Post
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


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..
toila83 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 17-01-2013, 11:24 AM   #13
toila83
Nhập môn đệ tử
 
Tham gia ngày: Aug 2010
Bài gửi: 3
:
Trích:
Nguyên văn bởi dragon2005 View Post
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);
}
}
Trong chương trình slave bạn có sử dụng delay, nếu trong thời gian delay mà con master có gửi dữ liệu đến slave cũng đâu có nhận được dù bạn có sử dụng thuật toán thăm dò.Bạn nên sử dụng ngắt :

#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);
}
toila83 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 07:39 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam