Microchip C18 有內置支持 PIC18F4550 SPI串列外設介面函數庫模塊 (spi.h),衹需要用包括 spi 頭文件 (
功能 –CloseSPI (禁止SSP 模組)
原型:void CloseSPI ( void );
說明:該函數禁止SSP 模組。相關引腳恢復為普通I/O 口功能。由TRISC 和LATC 負責實現I/O 控制。
檔案名:closespi.c
範例:CloseSPI();
功能 –DataRdySPI (確定SSPBUF 中是否有資料)
原型:unsigned char DataRdySPI ( void );
說明:該函數確定 SSPBUF 寄存器中是否有資料位元組可讀。
返回值:如果 SSPBUF 寄存器中沒有資料,為0 ;如果 SSPBUF 寄存器中有資料,則為1。
檔案名:dtrdyspi.c
範例:while (!DataRdySPI());
功能 –getsSPI (從SPI 匯流排讀取一個資料串)
原型:void getsSPI ( unsigned char *rdptr,unsigned char length );
參數:rdptr - 指向存放從SPI 器件中讀取資料的位址的指標。
length - 要從SPI 器件中讀取資料的位元組數。
說明:該函數從SPI 匯流排讀取一個預定義長度的資料串。
檔案名:getsspi.c
範例:unsigned char wrptr(10); getsSPI(wrptr, 10);
功能 –OpenSPI (初始化 SSP 模組)
原型:void OpenSPI ( unsigned char sync_mode, unsigned char bus_mode, unsigned char smp_phase);
參數: sync_mode - 取下列值之一,在spi.h 中定義:
SPI_FOSC_4 | SPI 主模式, clock = FOSC/4 |
SPI_FOSC_16 | SPI 主模式, clock = FOSC/16 |
SPI_FOSC_64 | SPI 主模式, clock = FOSC/64 |
SPI_FOSC_TMR2 | SPI 主模式, clock = TMR2 輸出/2 |
SLV_SSON SPI | 從模式,使能/SS 引腳控制 |
SLV_SSOFF SPI | 從模式, 禁止/SS 引腳控制 |
bus_mode - 取下列值之一,在spi.h 中定義:
MODE_00 | 設置SPI 匯流排為模式 0,0 |
MODE_01 | 設置SPI 匯流排為模式 0,1 |
MODE_10 | 設置SPI 匯流排為模式 1,0 |
MODE_11 | 設置SPI 匯流排為模式 1,1 |
smp_phase - 取下列值之一,在spi.h 中定義:
SMPEND | 在輸出資料的末端進行輸入資料採樣 |
SMPMID | 在輸出資料的中間進行輸入資料採樣 |
說明:該函數設置供SPI 匯流排器件使用的SSP 模組。
檔案名:openspi.c
範例:OpenSPI(SPI_FOSC_16, MODE_00, SMPEND);
功能 –putsSPI (向SPI 匯流排寫一個資料串)
原型:void putsSPI( unsigned char *wrptr );
參數:wrptr -指向要寫到SPI 匯流排的值的指標。
說明:該函數向SPI 匯流排器件寫一個資料串。當在資料串中讀到一個空字元時函數終止(空字元不會寫到匯流排)。
檔案名:putsspi.c
範例:unsigned char wrptr[] = “Hello!”; putsSPI(wrptr);
功能 –getcSPI / ReadSPI (從SPI 匯流排上讀取一個位元組)
原型:unsigned char ReadSPI( void );
說明:該函數啟動一個SPI 匯流排週期,來採集一位元組資料。
返回值: 該函數返回在SPI 讀週期內讀取的一位元組資料。
檔案名:readspi.c
範例:char x; x = ReadSPI();
功能 –putcSPI / WriteSPI (向SPI 匯流排寫一個位元組)
原型:unsigned char WriteSPI(unsigned char data_out );
參數:data_out - 要寫到SPI 匯流排的值。
說明:該函數寫一個位元組的資料,然後檢查是否有寫衝突。
返回值:如果沒有發生寫衝突,為 0 ;如果發生寫衝突,則為 -1。
檔案名:writespi.c
範例:WriteSPI(‘a’);
下面的例子說明了如何使用SSP 模組與Microchip 的25C080 SPI 電可擦除記憶體進行通訊。
#include #include // FUNCTION Prototypes void main(void); void set_wren(void); void busy_polling(void); unsigned char status_read(void); void status_write(unsigned char data); void byte_write(unsigned char addhigh, unsigned char addlow, unsigned char data); void page_write(unsigned char addhigh, unsigned char addlow, unsigned char *wrptr); void array_read(unsigned char addhigh, unsigned char addlow, unsigned char *rdptr, unsigned char count); unsigned char byte_read(unsigned char addhigh, unsigned char addlow); // VARIABLE Definitions unsigned char arraywr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,0}; //25C040/080/160 page write size unsigned char arrayrd[16]; unsigned char var; #define SPI_CS LATCbits.LATC2 //************************************************** void main(void) { TRISCbits.TRISC2 = 0; SPI_CS = 1; // ensure SPI memory device // Chip Select is reset OpenSPI(SPI_FOSC_16, MODE_00, SMPEND); set_wren(); status_write(0); busy_polling(); set_wren(); byte_write(0x00, 0x61, 'E'); busy_polling(); var = byte_read(0x00, 0x61); set_wren(); page_write(0x00, 0x30, arraywr); busy_polling(); array_read(0x00, 0x30, arrayrd, 16); var = status_read(); CloseSPI(); while(1); } void set_wren(void) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_WREN); //send write enable command SPI_CS = 1; //negate chip select } void page_write (unsigned char addhigh, unsigned char addlow, unsigned char *wrptr) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_WRITE); //send write command var = putcSPI(addhigh); //send high byte of address var = putcSPI(addlow); //send low byte of address putsSPI(wrptr); //send data byte SPI_CS = 1; //negate chip select } void array_read (unsigned char addhigh, unsigned char addlow, unsigned char *rdptr, unsigned char count) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_READ); //send read command var = putcSPI(addhigh); //send high byte of address var = putcSPI(addlow); //send low byte of address getsSPI(rdptr, count); //read multiple bytes SPI_CS = 1; } void byte_write (unsigned char addhigh, unsigned char addlow, unsigned char data) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_WRITE); //send write command var = putcSPI(addhigh); //send high byte of address var = putcSPI(addlow); //send low byte of address var = putcSPI(data); //send data byte SPI_CS = 1; //negate chip select } unsigned char byte_read (unsigned char addhigh, unsigned char addlow) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_READ); //send read command var = putcSPI(addhigh); //send high byte of address var = putcSPI(addlow); //send low byte of address var = getcSPI(); //read single byte SPI_CS = 1; return (var); } unsigned char status_read (void) { SPI_CS = 0; //assert chip select var = putcSPI(SPI_RDSR); //send read status command var = getcSPI(); //read data byte SPI_CS = 1; //negate chip select return (var); } void status_write (unsigned char data) { SPI_CS = 0; var = putcSPI(SPI_WRSR); //write status command var = putcSPI(data); //status byte to write SPI_CS = 1; //negate chip select } void busy_polling (void) { do { SPI_CS = 0; //assert chip select var = putcSPI(SPI_RDSR); //send read status command var = getcSPI(); //read data byte SPI_CS = 1; //negate chip select } while (var & 0x01); //stay in loop until !busy } |
2011 年 06 月 19 日 天氣報告
氣溫:29.3 度 @ 22:00
相對濕度:百分之83%
天氣:天色大致良好
請問~ 用這個SPI的函示庫,這樣我街角可以更改? SCK、CS、SI、SO
回覆刪除在 PIC18F4550 的 SPI 硬件連接是已定好,SCK (RB1)、SDI (RB0)、SDO (RC7),但 CS (Chip Select) 是可以自由選擇。
回覆刪除你好 ~ 我有個問題想請問
回覆刪除有兩塊相同的MCU 要進行SPI傳送和接收
傳送端:
void main()
{
Init_INTCON ();
Init_GPIO ();
Init_SPI();
while(1)
{
for(int i = 0; i<256;i++)//讓LED從1開始亮
{
PORTD = i;
spi_w(i);
delay_ms(20);
}
}
}
unsigned char spi_w(unsigned char data)
{
SSPBUF = data; //start transmit
while (!SSP1IF); //wait for transmission complete
SSP1IF = 0;
return(SSPBUF);
}
接收端 :
void main()
{
Init_GPIO ();
Init_SPI();
Init_INTCON ();
while(1)
{
data=spi_r();
PORTD = data;
}
}
unsigned char spi_r( void )
{
SSPBUF = 0x00; // initiate bus cycle
while(!SSP1IF); // wait until cycle complete = while(SSP1IF==0)
SSP1IF = 0;
return ( SSPBUF ); // return with byte read
}
我想這樣應該會讓兩片板子的LED一起閃動
但接收端LED沒反應 我有少加甚麼嗎(假設pin角有開 SPICON 也設定正確)