會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





PIC18F4580 SPI問題
新會員
註冊日期:
2016/03/19 16:26
所屬群組:
註冊會員
文章: 13
等級: 2; EXP: 38
HP : 0 / 34
MP : 4 / 120
離線
各位好,小弟目前使用兩個PIC18F4580,一個當Master,另一個當Slave來做SPI傳輸

目前遇到的問題是Slave端常常接不到Master端的數值,用示波器查看訊號都有到腳位,但是Slaver本身程式卻沒有反應,但是有時候卻又接的到資料

後來發現只要加入 while( !DataRdySPI() ); 再去接資料就會有時候接不到資料

想請問各位,DataRdySPI()的用法不能和UART的DataRdyUSART()一樣用While去等帶資料然後接收嗎?

以下是我的程式
//Master//
#include <p18f4580.h> // p18cxxx.h must have current processor
#include "CAN18XX8.h" // Purpose of using AN738 Subroutine !!
#include <delays.h>
#include <usart.h>
#include <spi.h>
#include <timers.h>

#pragma config OSC=IRCIO7,PWRT = ON, WDT=OFF, BOREN=OFF, BORV=1, LVP=OFF, PBADEN=OFF,MCLRE=ON
//Default:Fosc=1MHz

void isr_high (void);
void isr_low (void);
void spi_initial (void);

unsigned char test1=0;

void main ()
{
ADCON0 = 0x00; //關閉預設ADC
ADCON1 = 0x0F; //將AN0~AN10轉成DIO

TRISEbits.RE2=0; //CS
TRISCbits.RC3=0; //SCK, master=0, slave=1
TRISCbits.RC4=1; //SDI
TRISCbits.RC5=0; //SDO

PORTEbits.RE2=1;

PORTD = 0x00;
TRISD = 0;

OSCCON = 0x7c; //將內部振盪器設為8MHz(Default = 1MHz)
OSCTUNE =0x40; //開啟PLL,將內部震盪器倍頻至32MHz

RCONbits.IPEN = 0; //Interrupt Priority Enable bit
INTCONbits.GIEL = 0; //1 = Enables all low-priority peripheral interrupts
INTCONbits.GIEH = 0; //Enables all high-priority interrupts

spi_initial();

while(1)
{
if( test1<255 )
test1++;
else
test1=0;

PORTD = test1;

PORTEbits.RE2=0;

WriteSPI( 20 );
WriteSPI( test1 );
WriteSPI( 10 );
WriteSPI( 0 );
WriteSPI( 50 );

PORTEbits.RE2=1;

Delay10KTCYx(1000);
}
}

void spi_initial (void)
{
OpenSPI(SPI_FOSC_64, MODE_00, SMPMID); //master
// OpenSPI(SLV_SSOFF, MODE_00, SMPMID); //slave

SSPCON1bits.CKP = 0;
}


//Slave//
#include <p18f4580.h> // p18cxxx.h must have current processor
#include "CAN18XX8.h" // Purpose of using AN738 Subroutine !!
#include <delays.h>
#include <usart.h>
#include <spi.h>
#include <timers.h>

#pragma config OSC=IRCIO7,PWRT = ON, WDT=OFF, BOREN=OFF, BORV=1, LVP=OFF, PBADEN=OFF,MCLRE=ON
//Default:Fosc=1MHz

void isr_high (void);
void isr_low (void);
void spi_initial (void);

unsigned char test1=0;
unsigned char incoming_data[5];
unsigned char spi_rx_index;

void main ()
{
ADCON0 = 0x00; //關閉預設ADC
ADCON1 = 0x0F; //將AN0~AN10轉成DIO

// TRISEbits.RE2=0; //CS
TRISAbits.RA5=1; //SS
TRISCbits.RC3=1; //SCK, master=0, slave=1
// TRISCbits.RC4=1; //SDI
TRISCbits.RC5=0; //SDO

PORTD = 0xff;
TRISD = 0;

OSCCON = 0x7c; //將內部振盪器設為8MHz(Default = 1MHz)
OSCTUNE =0x40; //開啟PLL,將內部震盪器倍頻至32MHz

spi_initial();

while(1)
{

}
}
//****************************
//低優先中斷
//****************************
#pragma code low_vector=0x18 //設定低優先權中斷向量位址 0x18,並將控制權轉移給低優先權中斷服務函數
void interrupt_low (void)
{
_asm GOTO isr_low _endasm //轉移控制權到中斷服務函數(isr_low)
}
#pragma code

#pragma interruptlow isr_low //來指明該函數為低優先權中斷服務函數
void isr_low (void)
{
PIR1bits.SSPIF=0;

// while( !DataRdySPI() );
LATD = ReadSPI();

}

void spi_initial (void)
{
// OpenSPI(SPI_FOSC_64, MODE_00, SMPMID); //master
OpenSPI(SLV_SSOFF, MODE_00, SMPMID); //slave

RCONbits.IPEN = 1; //Interrupt Priority Enable bit
INTCONbits.GIEL = 1; //1 = Enables all low-priority peripheral interrupts
INTCONbits.GIEH = 1; //Enables all high-priority interrupts

PIR1bits.SSPIF=0; //Master Synchronous Serial Port Interrupt Flag bit
PIE1bits.SSPIE=1; 1; //Master Synchronous Serial Port Interrupt Enable bit
IPR1bits.SSPIP=0; //Master Synchronous Serial Port Interrupt Priority bit

SSPCON1bits.CKP = 0;
}

3月11日 02:17:06
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
線上教學影片
網頁捷徑
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project