单片机的SPI作为从设备进行通信
这里运行的实例是单片机作为从设备,采用ARM9作为主设备进行SPI通信。ARM9作为主设备,SPI的通信速率最低为500K,单片机采用NEC 的78F1166,晶振采用11.0592MHz时SPI通信速率可以达到500K。速率匹配上没有问题。
主从设备之间采用的通信协议为DL/645.这里有一个问题,协议的收发数据帧的长度是不确定的。这就涉及到主设备需要读多少个字节的数据。根据实际应用。645规约实际通信时数据帧不会超过100个字节。所以这里解决的方案是,主设备发送命令后,等待200ms后主设备开始抄读数据。这里之所以等待200MS,是因为从设备需要准备数据。
以下是从设备的应用程序:
Unsigned char* gpCsi01RxAddress; /* csi01 receive buffer address */ Unsigned short gCsi01RxLen; /* csi01 receive data length */ Unsigned short gCsi01RxCnt; /* csi01 receive data count */ Unsigned char* gpCsi01TxAddress; /* csi01 send buffer address */ Unsigned short gCsi01TxLen; /* csi01 send data length */ Unsigned short gCsi01TxCnt; /* csi01 send data count */ #define BUFFERLEN 200
unsigned char SPI_RX_Buffer[BUFFERLEN]; unsigned char TxFlag,RxFlag; unsigned char Data; unsigned long count = 0;
void CSI01_Init( void ) {
/* CSI01 initial setting */
ST0 |= SAU_CH1_STOP_TRG_ON; CSIMK01 = 1; CSIIF01 = 0;
/* CSI01 disable */
/* INTCSI01 disable */ /* INTCSI01 IF clear */
/*
|
SIR01 = SAU_SIRMN_FECTMN | SAU_SIRMN_PECTMN | SAU_SIRMN_OVCTMN; SMR01
=
SAU_SMRMN_INITIALVALUE
|
SAU_CLOCK_MODE_TI0N
error flag clear */
SAU_TRIGGER_SOFTWARE | SAU_CSI | SAU_BUFFER_EMPTY;//SAU_TRANSFER_END;
SCR01 = SAU_RECEPTION_TRANSMISSION | SAU_TIMING_4 | SAU_MSB | SAU_LENGTH_8; SDR01 = 0;
SO0 &= ~SAU_CH1_DATA_OUTPUT_1; SOE0 |= SAU_CH1_OUTPUT_ENABLE; /* INTCSI01 priority low */ CSIPR101 = 0; CSIPR001 = 0; /* SI01 pin setting */ PM4 |= 0x10; /* SO01 pin setting */ P4 |= 0x20;
/* CSI01 SO initial level */ /* CSI01 output enable */
}
PM4 &= ~0x20; /* SCK01 pin setting */ PM4 |= 0x08;
//=================================================================
void CSI01_Start( void ) {
CSIMK01 = 0; /* INTCSI01 enable */
SS0 |= SAU_CH1_START_TRG_ON; /* CSI01 enable */
//gpCsi01RxAddress = SPI_RX_Buffer;//接收数据指针指向SPI_RX_Buffer第一个字节 //gCsi01RxCnt = 0;//接收数据个数清零 //gCsi01TxCnt = 0;//发送数据个数清零
//SetSendFlag(SENDEND);//启动时处于接收状态 //SetReceiveFlag(RECEIVING);//启动后还没有接收数据 }
//=================================================================
void CSI01_Stop( void ) { }
ST0 |= SAU_CH1_STOP_TRG_ON; CSIIF01 = 0;
/* CSI01 disable */
CSIMK01 = 1; /* INTCSI01 disable */
/* INTCSI01 IF clear */
//=================================================================
unsigned char SPI_Send_Data(unsigned char *Buffer,unsigned char Lenth) {
gpCsi01TxAddress = Buffer; gCsi01TxCnt = Lenth - 1; SMR01 |= 0x0001;//add by haolj SIO01 = Buffer[0]; SetSendFlag(SENDING);
while(SENDEND != Check_Send_Flag()) {
;//OSTimeDly(10); }
return Lenth; }
//=================================================================
unsigned char SPI_Receive_Data(unsigned char *Buffer,unsigned char Lenth) {
unsigned char Ack; Ack = 0;
while(Check_Receive_Flag() == RECEIVING) {
if((gCsi01RxCnt > Ack) && gCsi01RxCnt<=BUFFERLEN) {
Ack = gCsi01RxCnt; OSTimeDly(1); } else {
SetReceiveFlag(RECEIVEND); } }
memcpy(Buffer,SPI_RX_Buffer,gCsi01RxCnt); Ack = gCsi01RxCnt; gCsi01RxCnt = 0;
gpCsi01RxAddress = SPI_RX_Buffer;
return Ack; }
//=================================================================
#pragma vector = INTCSI01_vect __interrupt void MD_INTCSI01( void ) {
if( SENDING == Check_Send_Flag() )
{ if(gCsi01TxCnt == 0) {
SMR01 &= ~SAU_BUFFER_EMPTY;//add by haolj SIO01 = 0xee;
SetSendFlag(SENDEND);
gpCsi01RxAddress = SPI_RX_Buffer; gCsi01RxCnt = 0; return ; }
Data = SIO01; gpCsi01TxAddress++;
} else
SIO01 = *gpCsi01TxAddress; gCsi01TxCnt--;
{
Data = SIO01; SIO01 = 0xee;
if((gpCsi01RxAddress - SPI_RX_Buffer) < BUFFERLEN) {
*gpCsi01RxAddress = Data; gpCsi01RxAddress ++; gCsi01RxCnt ++;
SetReceiveFlag(RECEIVING); } else {
SetReceiveFlag(RECEIVEND); gpCsi01RxAddress = SPI_RX_Buffer; } }
unsigned char Check_Send_Flag(void) {
return TxFlag; }
//================================================================= unsigned char Check_Receive_Flag(void) {
return RxFlag; }
//================================================================= void SetReceiveFlag(unsigned char RFlag) {
RxFlag = RFlag; }
//================================================================= void SetSendFlag(unsigned char TFlag) {
TxFlag = TFlag; }
//================================================================= void Start_Send(unsigned char TxData) {
SIO01 = 0x00;
gpCsi01TxAddress = SPI_RX_Buffer + 1; gCsi01TxCnt = 4; SetSendFlag(SENDING); }
}
百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库单片机SPI作为从设备通信总结在线全文阅读。
相关推荐: