SPI 功能使用方法 SPI 功能使用方法 1 適用產品: 1.1 SM59R16A2/ SM59R08A2 1.2 SM59R16A5/ SM59R09A5/SM59R05A5/SM59R16A3/ SM59R09A3 /SM59R05A3 1.3 SM59R04A2/ SM59R04A1/ SM59R03A1/ SM59R02A1 2 SPI 使用概述: SPI 通信使用 4 個引腳,分別為: z z SPI_MOSI: 做為master時資料輸出;做為slave時資料輸入 SPI_MISO: 做為master時資料輸入;做為slave時資料輸出 z SPI_CLK: SPI的時脈信號由master主控產生;資料 (輸出及輸入) 和時脈同步 z SPI_SS: 此引腳唯有做為slave mode時有做用;做為master mode,此引腳當做GPIO使用 = 0: master致能slave = 1: master禁能slave Master MOSI MISO CLK IO IO 3 Slave 2 Slave 1 MOSI MISO CLK MOSI MISO CLK SS SS P4SPI (SPI function pin assignment)說明: SM59R16A5/SM59R16A3 P4SPI (SPI function pin assignment) ○ SM59R09A5/SM59R09A3 ○ SM59R05A5/SM59R05A3 ○ SM59R16A2 × SM59R08A2 × SM59R04A2/SM59R04A1 ○ SM59R03A1 ○ SM59R02A1 ○ Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 1 Ver A 2010/06 SPI 功能使用方法 ○:表示該型號可以使用 P4SPI 功能 ×:表示該型號不可使用 P4SPI 功能 Notice:所有系列的 Package type DIP-40 沒有 P4,所以沒有用此功能 P4SPI (SPI function pin assign)說明 Mnemonic AUX Description Direct Bit 7 Auxiliary register 91h BRS Bit 6 Bit 5 Bit 4 Serial interface 0 and 1 P4CC P4SPI P4UR1 Bit 3 Bit 2 Bit 1 Bit 0 RESET P4IIC P0KBI - DPS 00H 內建SPI,可直接經由軟體設定指定其腳位至P1或P4,避免和其它特殊功能腳位重複,並提高硬體規 劃的相容性。 P4SPI: P4SPI = 0 – SPI function on P1. SS – P1.4 MOSI – P1.5 MISO – P1.6 CLK – P1.7 P4SPI = 1 – SPI function on P4. SS – P4.0 MOSI – P4.1 MISO – P4.2 CLK – P4.3 4 SPI 相關的特殊暫存器 SPI Special Function Register (SFR) SPI Direct Bit 7 Bit 6 Bit 5 SPI function Auxiliary register 91h BRS P4CC SPIC1 SPI control register 1 F1h SPIEN SPIMSS SPIC2 SPI control register 2 F2h SPIFD SPIS SPI status register F5h - SPITXD SPI transmit data buffer F3h SPITXD[7:0] 00H SPIRXD SPI receive data buffer F4h SPIRXD[7:0] 00H AUX Description Mnemonic: AUX 7 6 5 BRS P4CC P4SPI P4SPI Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 RESET P4UR 1 P4IIC P0KBI - DPS 00H SPISS SPICKP SPICKE P TBC[2:0] - SPIBR[2:0] 08H RBC[2:0] 00H SPIMLS SPIOV SPITXIF SPITDR SPIRXIF SPIRDR SPIRS 4 P4UR1 3 P4IIC 2 P0KBI 1 - Address: 91h 0 Reset DPS 00H Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 2 Ver A 2010/06 40H SPI 功能使用方法 P4SPI: P4SPI = 0 – SPI function on P1. P4SPI = 1 – SPI function on P4. P4SPI setting SPI_SS P1.4 0 P4.0 1 Mnemonic: SPIC1 7 6 5 SPIEN SPIMSS SPISSP SPI_MOSI P1.5 P4.1 4 SPICKP SPI_MISO P1.6 P4.2 Address: F1h 3 2 1 0 SPICKE SPIBR[2:0] SPI_CLK P1.7 P4.3 Reset 08h SPIEN: SPI 模組致能旗標: “1” – 致能 “0” – 禁能 SPIMSS: 主從模式選擇旗標(Master or Slave mode Select) “1” – MCU 做為 Master mode. “0” – MCU 做為 Slave mode. SPISSP: (SS)引腳致能狀態旗標;當 MCU 為 slave 時,可由旗標設定 Slave Select (SS)引腳致能狀態 (slave mode used only) “1” – 高準位致能 high active. “0” – 低準位致能 low active. SPICKP: 時脈閒置準位旗標(master mode used only) “1” – 時脈信號閒置時為高準位(SCK high during idle), Ex : “0” – 時脈信號閒置時為低準位(SCK high during idle), Ex : SPICKE: 時脈取樣旗標 Clock sample edge select. “1” – 正緣取樣 data latch in rising edge “0” – 負緣取樣 data latch in falling edge. * 為確保資料取樣的正確性,無論使用正緣或負緣取樣,時脈及資料同步時皆需有足夠的準備時間 (set-up time)及保持時間(hold time),時序產生如下圖: sufficient set-up time sufficient hold time SPIBR[2:0]: SPI 鮑率選擇(master mode used only), Fosc 為晶振頻率: SPIBR[2:0] Baud rate Fosc/4 0:0:0 Fosc/8 0:0:1 Fosc/16 0:1:0 Fosc/32 0:1:1 Fosc/64 1:0:0 Fosc/128 1:0:1 Fosc/256 1:1:0 Fosc/512 1:1:1 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 3 Ver A 2010/06 SPI 功能使用方法 Mnemonic: SPIC2 7 6 5 SPIFD TBC[2:0] 4 3 - 2 1 RBC[2:0] Address: F2h 0 Reset 00h SPIFD: 全雙工模式致能旗標(Full-duplex mode enable) “1” : 全雙工模式致能 “0” : 全雙工模式禁能 當該旗標致能時,TBC[2:0]和RBC[2:0]會被清除並保持為零,SPI全雙工模式僅允許8位元通訊. Master透過MOSI引腳做資料輸出,slave時透過MISO回傳資料,SPI的時脈信號由master主控產 生;所有資料 (輸出及輸入) 皆和時脈同步。 Input Shift register SPIRXD Output Shift register SPITXD Clock Generator MISO MISO MOSI MOSI SCK SCK SyncMos Master Output Shift register SPITXD Input Shift register SPIRXD SyncMos Slave TBC[2:0]: SPI 傳送元位計數旗標(SPI transmitter bit counter) 可設定 1~8 位元通訊,但全雙工模式僅允許 8 位元通訊。 TBC[2:0] Bit counter 8 bits output 0:0:0 1 bit output 0:0:1 2 bits output 0:1:0 3 bits output 0:1:1 4 bits output 1:0:0 5 bits output 1:0:1 6 bits output 1:1:0 7 bits output 1:1:1 RBC[2:0]: SPI 接收元位計數旗標(SPI receiver bit counter) 可設定 1~8 位元通訊,但全雙工模式僅允許 8 位元通訊。 RBC[2:0] Bit counter 8 bits input 0:0:0 1 bit input 0:0:1 2 bits input 0:1:0 3 bits input 0:1:1 4 bits input 1:0:0 5 bits input 1:0:1 6 bits input 1:1:0 1:1:1 7 bits input Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 4 Ver A 2010/06 SPI 功能使用方法 Mnemonic: SPIS 7 6 5 SPIMLS SPIOV 4 SPITXIF 3 SPITDR 2 SPIRXIF Address: F5h 0 Reset SPIRS 40h 1 SPIRDR SPIMLS: MSB or LSB output /input first “1” : 最高位元先傳送 (MSB output/input first)。 “0” : 最低位元先傳送 (LSB output/input first)。 SPIOV: 溢位旗標(Overflow flag) “1” : 當 SPIRDR 已設定(SPIRXD 原有資料未被讀取)且下一筆資料正寫入 SPIRXD 時,SPIOV 將被設定為”1”,告知 SPIRXD 資料以有損毀。 “0” : 當 SPIRDR 清為零時,SPIOV 則由硬體清除。 SPITXIF: 傳送中斷旗標(Transmit Interrupt Flag) “1” : 當 SPITXD 的資料已載入移位暫存器,由硬體設定為”1” 。 “0” : 傳送資料完成後必須由軟體清除。 SPITDR: 資料傳送位元(Transmit Data Ready) “1”: 當程序為傳送模式時,資料儲存至 SPITXD 後,由軟體設定此旗標為”1” ,告知 SPI module 允許傳出資料。 “0”: 當 SPI module 由 SPITXD 完成傳送時(或 SPITXD 被載至移位暫存器時),此旗標則由硬體自 動清除。 SPIRXIF: 接收中斷旗標(Receive Interrupt Flag) “1” : 當 SPIRXD 被載入新一筆資料後,由硬體設定為”1” 。 “0” : 接收資料完成後必須由軟體清除。 SPIRDR: 資料接收位元(Receive Data Ready) “1” : SPI module接收資料時,SPIRDR由硬體自動設定為”1”,以告知MCU完成接收並儲存至 SPIRXD;當新的一筆資料寫入SPIRXD,而SPIRDR未清除時,SPIRXD原有的資料將被覆寫,產 生overflow “0” : 由 SPIRXD 讀取資料後,必須由軟體清除此旗標。 SPIRS: 接收開始位元(Receive Start) “1” : 由軟件設為”1”,告知 SPI 模組 SPIRXD 開始接收資料(即 SPI_CLK 開始送 clock)。 “0” : 當資料接收完成,由硬體清為”0” Mnemonic: SPITXD 7 6 5 4 3 SPITXD[7:0] 2 1 0 Address: F3h Reset 00h SPITXD[7:0]: 傳送資料緩衝器(Transmit data buffer) Mnemonic: SPIRXD 7 6 5 4 3 SPIRXD[7:0] 2 1 Address: F4h 0 Reset 00h SPIRXD[7:0]: 接收資料緩衝器(Receive data buffer) Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 5 Ver A 2010/06 SPI 功能使用方法 5 SPI 中斷 5.1 向量表(Interrupt vectors table) Interrupt Vector Address Interrupt Number *(use Keil C Tool) IE0 – External interrupt 0 0003h 0 TF0 – Timer 0 interrupt 000Bh 1 IE1 – External interrupt 1 0013h 2 TF1 – Timer 1 interrupt 001Bh 3 RI0/TI0 – Serial channel 0 interrupt 0023h 4 TF2/EXF2 – Timer 2 interrupt 002Bh 5 PWMIF – PWM interrupt 0043h 8 SPIIF – SPI interrupt 004Bh 9 ADCIF – A/D converter interrupt 0053h 10 KBIIF – keyboard Interface interrupt 005Bh 11 LVIIF – Low Voltage Interrupt 0063h 12 IICIF – IIC interrupt 006Bh 13 RI1/TI1 – Serial channel 1 interrupt 0083h 16 Interrupt Request Flags *See Keil C about C51 User’s Guide about Interrupt Function description 5.2 中斷相關暫存器(Interrupt SFR) Mnemonic IEN0 IEN1 IEN2 IRCON IP0 IP1 Description Interrupt Enable 0 register Interrupt Enable 1 register Interrupt Enable 2 register Interrupt request register Interrupt priority level 0 Interrupt priority level 1 Direct Bit 7 Bit 6 Bit 5 Interrupt Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 RESET A8h EA - ET2 ES0 ET1 EX1 ET0 EX0 00h B8h EXEN2 - IEIIC IELVI IEKBI IEADC IESPI IEPWM 00h 9Ah - - - - - - - ES1 00h C0H EXF2 TF2 IICIF LVIIF KBIIF ADCIF SPIIF PWMIF 00H A9h - - IP0.5 IP0.4 IP0.3 IP0.2 IP0.1 IP0.0 00h B9h - - IP1.5 IP1.4 IP1.3 IP1.2 IP1.1 IP1.0 00h *如果需要使用中斷程序,可參考以下設置: (1) SPI 中斷致能設罝: IEN0 |= 0x80; IEN1 |= 0x02; //Enable interrupt All //Enable interrupt SPI Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 6 Ver A 2010/06 SPI 功能使用方法 (2) SPI 中斷程序表示: void SPI_interrupt(void) interrupt 9 { //IRCON_SPIIF = 0; //Clear interrupt flag If(SPIS&=0x04) { SPIS &= (~0x04); //Clear TXIF bit } { SPIS &= (~0x20; //Clear RXIF bit } Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 7 Ver A 2010/06 SPI 功能使用方法 6 以下為兩顆 MCU 分別當做 SPI master 及 slave 通訊的流程圖 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 8 Ver A 2010/06 SPI 功能使用方法 7 SPI master 及 slave 通訊的範例程式 7.1 Master 傳資料(0xFF~0x00)至 Slave 7.2 Slave 接受後,以相同的資料回傳給 Master 7.3 Master 接受 Slave 回傳的資料後,做資料比較,相同則表示通訊正確,不相同則反之 Description Main program Master: //=================================================================== // // S Y N C M O S T E C H N O L O G Y // //=================================================================== #include #include #include #include "..\h\SM59R16A2.h" "..\h\SM59R16A2_extradef.h" "..\LCD\LCD16x2.h" "..\MISC\delay.h" #define Control_Byte #define SPI_SS #define SPITDR=1 0xA0 P1_0 SPIS |= 0x08 /* void SPI_interrupt(void) interrupt 9 { IRCON_SPIIF = 0; //Clear interrupt flag }*/ void SPI_Init(void) { SPIC1 = 0xD8; //SPIC1 |= 7; SPIC2 = 0x00; SPIS = 0x40; } //SPI Enable/ master/ NC/ idle hi/ rising latch //BR=(Fosc/512) //SPI full-duplex disable /8-bit communicate //MSB send first void SPI_TX( unsigned char DATA) { SPITXD = DATA; SPIS |= 0x08; while( !(SPIS&SPI_TXIF) ); SPIS &= (~SPI_TXIF); } unsigned char SPI_RX(void) { unsigned char Temp; SPIS |= 0x01; while( !(SPIS&SPI_RXIF) ); Temp = SPIRXD; SPIS |= 0x02; SPIS &= (~SPI_RXIF); return Temp; } //Load to Buffer //SPITDR //TX completed //Clear TXIF bit //Receive Start //RX completed //Load from Buffer //Receive Data Ready //Clear RXIF bit void main() { unsigned long Err =0, counter =1; unsigned char TxData, RxData,j; LCD_Init(); SPI_Init(); Delay10mSec(1); //must wait for LCD stable Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 9 Ver A 2010/06 SPI 功能使用方法 while(1) { for(TxData=0xFF; TxData>0; TxData--) { PrintLcdStrLX( 1, 0, "M_TX: PrintLcdStrLX( 2, 0, "M_RX: "); "); SPI_SS = 0; SPI_TX( TxData ); //for(j=0; j<0; j++); RxData = SPI_RX(); SPI_SS = 1; //CS //TX //Dealy time //RX //CS SetCursorAddr(1, 6); SetCursorAddr(2, 6); PrintLcdHex( TxData ); PrintLcdHex( RxData ); counter++; SetCursorAddr(1, 12); PrintLcdDec( counter ); if(TxData!=RxData) Err++; SetCursorAddr(2, 12); PrintLcdDec( Err ); P2=TxData; //result } } } Description Main program Slave: //=================================================================== // // S Y N C M O S T E C H N O L O G Y // //=================================================================== #include "..\h\SM59R16A2.h" #include "..\h\SM59R16A2_extradef.h" #include "..\LCD\LCD16x2.h" #include "..\MISC\delay.h" void SPI_Init(void) { SPIC1 =0x98; //SPI Enable/ slave/ Low active / NC / rising latch/ NC NC NC SPIC2 =0x00; //SPI full-duplex disable /8-bit communicate SPIS =0x40; //MSB send first } void SPI_TX( unsigned char DATA) { SPITXD = DATA; //Load to Buffer SPIS |= 0x08; //SPITDR while( !(SPIS&SPI_TXIF) ); //TX completed SPIS &= (~SPI_TXIF); //Clear TXIF bit Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 10 Ver A 2010/06 SPI 功能使用方法 } unsigned char SPI_RX(void) { unsigned char Temp; SPIS |= 0x01; while( !(SPIS&SPI_RXIF) ); Temp = SPIRXD; SPIS |= 0x02; SPIS &= (~SPI_RXIF); return Temp; } //Receive Start //RX completed //Load from Buffer //SPIRDR //Clear RXIF bit void main() { unsigned long Err =0, counter =1; unsigned char TxData=0, RxData=0,j; LCD_Init(); SPI_Init(); Delay10mSec(1); //must wait for LCD stable while(1) { RxData = SPI_RX(); SPI_TX( RxData ); P2 = RxData; } //RX //TX //result } 8 SPI 全雙工說明,使用兩顆 SM59R04A2 分別當做 SPI master 及 slave 做通訊,以下是範例程序的通 訊協定: MOSI (Master) Check Ready 0x55 Master Receive CMD DB1 DB2 DB10 Checksum High byte Checksum low byte MISO (Slave) Slave Receive ACK Ready 0x55 Slave Receive DB1 DB2 DB10 Checksum High byte Checksum low byte 9 SPI master 及 slave 全雙工通訊範例程式 9.1 Master 不斷送 Ready Byte(0x55),直到 Slave 同樣回傳 Ready Byte (0x55)做確認 Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 11 Ver A 2010/06 SPI 功能使用方法 9.2 待兩方確認後,Master 會送 command byte(0x0A 或 0x0B) 9.3 兩方資料長度定為 10-Byte 9.4 Master 送出資料固定為 0x00~0x09 9.5 Slave 送出的資料則依據收到 Master 的 command byte 有所不同 9.5.1 當command byte=0x0A,slave送出資料為0x00~0x09 9.5.2 當command byte=0x0B,slave送出資料為0x10~0x19 9.6 資料送出完成後,master 及 slave 會互傳該次所接收到的資料的 checksum Description Main program Master: //========================================================================= // // S Y N C M O S T E C H N O L O G Y // //========================================================================= // SM59R04A2 SPI Master full-duplex ,8-bit communication // System clock = 22.1184 MHz //========================================================================= #include "SM59R04A2.h" #define #define #define #define #define #define #define #define #define #define #define #define SPI_RxStart SPI_RDR SPI_RXIF SPI_TDR SPI_TXIF SPI_Overflow SPI_MSB_LSB CMD_0A CMD_0B CMD_Ready finetune SPI_SS 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x0A 0x0B 0x55 15 P1_0 // for timing finetune // slave select bit SPI_Intrrupt=1; unsigned char temx; void Delay1mSec(unsigned int NTime) ; void Delay_tune(unsigned char tune); void SPI_Init(void); unsigned char SPI_RX(void); void SPI_TX( unsigned char DATA); unsigned char SPI_full_duplex(unsigned char DATA); void SPI_communication(unsigned char command); void SPI_interrupt(void) interrupt 9 { while(!((SPIS & SPI_RDR)==SPI_RDR)); while((SPIS & SPI_TDR)==SPI_TDR); SPIS &= 0xE9; // RDR set 1 by H/W // TDR clr 0 by H/W // Clear SPITXIF & SPIRXIF & SPIRDR SPI_Intrrupt = 0; } //========================================================================= //Freq = 22.1184 MHz, @ 64-pin demo board //========================================================================= void Delay1mSec(unsigned int NTime) { Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 12 Ver A 2010/06 SPI 功能使用方法 unsigned int i, j; for(i=0; i<NTime; i++) for(j=0; j<1300; j++); } void Delay_tune(unsigned char tune) { unsigned char i; for(i=0; i<tune; i++); } void SPI_Init(void) { SPIC1 = 0xD8; //SPI Enable/ master/ NC/ idle hi/ rising latch SPIC2 = 0x80; //SPI full-duplex ,8-bit communication only //SPIC2 = 0x00; //SPI half-duplex ,8-bit communication SPIS = 0x40; //MSB send first SPIS |= 0x01; // RX Start //SPIS &= 0xFE;// Receive Stop //SPIC1 |= 0; //SPIC1 |= 1; //SPIC1 |= 2; SPIC1 |= 3; //SPIC1 |= 4; //SPIC1 |= 5; //SPIC1 |= 6; //SPIC1 |= 7; // // } IEN0 IEN1 //BR=(Fosc/4) //BR=(Fosc/8) //BR=(Fosc/16) //BR=(Fosc/32) //BR=(Fosc/64) //BR=(Fosc/128) //BR=(Fosc/256) //BR=(Fosc/512) |= 0x80; |= 0x02; // EA=1 // IESPI=1 unsigned char SPI_RX(void) { SPI_SS = 0; SPITXD = 0xFF; // SPIS |= 0x01; // // SPI_Intrrupt = 1; // while(SPI_Intrrupt); while(!((SPIS & SPI_RDR)==SPI_RDR));// SPIS &= 0xE9; // temx = SPIRXD; SPI_SS = 1; Delay_tune(finetune); return temx; clear SPITXD, useless RX Start // send SPI CLK RDR set 1 by H/W Clear SPITXIF & SPIRXIF & SPIRDR // CS, must wait slave } void SPI_TX( unsigned char DATA) { SPI_SS = 0; SPITXD = DATA; SPIS |= SPI_TDR; // SPI_Intrrupt = 1; // while(SPI_Intrrupt); while((SPIS & SPI_TDR)==SPI_TDR); SPIS &= 0xE9; SPI_SS = 1; Delay_tune(finetune); // Load to TX Buffer // set SPITDR, TX proceed // TDR clr 0 by H/W // Clear SPITXIF & SPIRXIF & SPIRDR // CS, must wait slave } Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 13 Ver A 2010/06 SPI 功能使用方法 unsigned char SPI_full_duplex(unsigned char DATA) { SPI_SS = 0; SPITXD = DATA; // Load to TX Buffer SPIS |= SPI_TDR; // set SPITDR, TX proceed // SPI_Intrrupt = 1; // while(SPI_Intrrupt); while(!((SPIS & SPI_RDR)==SPI_RDR));// RDR set 1 by H/W while((SPIS & SPI_TDR)==SPI_TDR); // TDR clr 0 by H/W SPIS &= 0xE9; // Clear SPITXIF & SPIRXIF & SPIRDR temx = SPIRXD; SPI_SS = 1; Delay_tune(finetune); return temx; // CS, must wait slave } void SPI_communication(unsigned char command) { unsigned char RxData_H=0, RxData_L=0, TxData=0, loop=0, temp=0, ready=0; unsigned int checksum=0; SPI_TX(CMD_Ready); ready = SPI_RX(); // check slaver ready, send 0x55 // receive ready_byte, wait 0x55 if(ready == CMD_Ready) { SPI_TX(command); checksum=0; // send command 0x0A or 0x0B for(loop=0x00; loop<0x10; loop++) { checksum += SPI_full_duplex(loop); } RxData_H = SPI_full_duplex((unsigned char)(checksum>>8)); // send checksum high byte RxData_L = SPI_full_duplex((unsigned char)checksum); // send checksum low byte ready=0; } Delay_tune(50); // useless } void main() { Delay1mSec(100); //SPI_Intrrupt = 1; IFCON |= 0x80; SPI_Init(); Delay1mSec(1); // wait system stable // // set 1T // // must wait SPI init while(1) { SPI_communication(CMD_0A); SPI_communication(CMD_0B); } } Description Slave: //========================================================================= // // S Y N C M O S T E C H N O L O G Y Main program // //========================================================================= // SM59R04A2 SPI slave full-duplex ,8-bit communication Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 14 Ver A 2010/06 SPI 功能使用方法 // System clock = 22.1184 MHz //========================================================================= #include "SM59R04A2.h" #define #define #define #define #define #define #define #define #define #define SPI_RxStart SPI_RDR SPI_RXIF SPI_TDR SPI_TXIF SPI_Overflow SPI_MSB_LSB CMD_0A CMD_0B CMD_Ready unsigned unsigned unsigned unsigned 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x0A 0x0B 0x55 char TxData=0x10, RxData=0, RxBuf[5]; int loop=0, checksum=0; char RxData_H=0, RxData_L=0; char cmd=0, ready=0; void Delay1mSec(unsigned int NTime); void Delay_tune(unsigned char tune); void Init_SPI(void); void SPI_TX( unsigned char DATA); unsigned char SPI_RX(void); void Delay1mSec(unsigned int NTime) { unsigned int i, j; for(i=0; i<NTime; i++) for(j=0; j<1300; j++); } void Init_SPI(void) { SPIC1 = 0x98; //SPI Enable/ slave/ Low active / NC / rising latch SPIC2 = 0x80; //SPI full-duplex ,8-bit communication only //SPIC2 = 0x00; //SPI half-duplex ,8-bit communication SPIS = 0x40; //MSB send first SPIS |= 0x01; //Receive Start SPITXD = 0xFF; IEN0 IEN1 |= 0x80; |= 0x02; // EA=1 // IESPI=1 } void SPI_TX( unsigned char DATA) { SPITXD = DATA; // Load to TX Buffer SPIS |= SPI_TDR; // set SPITDR, TX proceed while((SPIS & SPI_TDR)==SPI_TDR); // 1:Loading ; 0: finish while(!((SPIS & SPI_TXIF)==SPI_TXIF)); // TX completed SPIS &= 0xE9; // Clear SPITXIF & SPIRXIF & SPIRDR //SPIS &= (~SPI_TXIF); // Clear TXIF bit } unsigned char SPI_RX(void) { unsigned char Temp; SPITXD = 0xFF; // clear SPITXD, useless // SPIS |= 0x01; // Receive Start while(!((SPIS & SPI_RDR)==SPI_RDR)); // RX receive while(!((SPIS & SPI_RXIF)==SPI_RXIF)); // RX completed Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 15 Ver A 2010/06 SPI 功能使用方法 // // // Temp = SPIRXD; SPIS &= 0xE9; SPIS &= (~SPI_RDR); SPIS &= (~SPI_RXIF); SPIS &= 0xFE; return Temp; // // // // // Load from Buffer Clear SPITXIF & SPIRXIF & SPIRDR RX Data Ready Clear RXIF bit Receive Stop } unsigned char SPI_full_duplex(unsigned char DATA) { SPITXD = DATA; // SPIS |= SPI_TDR; // while((SPIS & SPI_TDR)==SPI_TDR); // while(!((SPIS & SPI_RDR)==SPI_RDR));// SPIS &= (~SPI_RDR); // return SPIRXD; Load to TX Buffer set SPITDR, TX proceed TDR clr 0 by H/W RDR set 1 by H/W RX Data Ready } void SPI_ISR(void) interrupt 9 { while(!((SPIS & SPI_RDR)==SPI_RDR));// RDR set 1 by H/W ready = SPIRXD; // SPI cmd receive ready SPIS &= 0xE9; // Clear SPITXIF & SPIRXIF & SPIRDR if(ready==CMD_Ready) { SPI_TX(CMD_Ready); cmd = SPI_RX(); checksum = 0; switch (cmd) { case CMD_0A: // When cmd = 0x0A for(loop=0x00; loop<0x10; loop++) { checksum+= SPI_full_duplex(loop); } break; case CMD_0B: // When cmd = 0x0B for(loop=0x10; loop<0x20; loop++) { checksum+= SPI_full_duplex(loop); } break; default: // When cmd error occur for(loop=0; loop<3; loop++) { checksum+= SPI_full_duplex(0xAA); } break; } RxData_H = SPI_full_duplex((unsigned char)(checksum>>8)); RxData_L = SPI_full_duplex((unsigned char)(checksum)); } SPIS &= 0xE9; SPITXD = 0xFF; //SPIIF=0; // Clear SPITXIF & SPIRXIF & SPIRDR // clear SPITXD, useless } void main() { Delay1mSec(100); // wait system stable Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 16 Ver A 2010/06 SPI 功能使用方法 IFCON |= 0x80; Init_SPI(); // set 1T while(1) {} } Specifications subject to change without notice, contact your sales representatives for the most recent information. ISSFA-0177 17 Ver A 2010/06