SPI 功能使用方法

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 SPI_MOSI: 做为master时数据输出;做为slave时数据输入
z
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
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-0178
17
Ver A 2010/06