《单片机spi作为从设备通信总结》由会员分享,可在线阅读,更多相关《单片机spi作为从设备通信总结(4页珍藏版)》请在金锄头文库上搜索。
1、单片机的 SPI 作为从设备进行通信这里运行的实例是单片机作为从设备,采用 ARM9 作为主设备进行 SPI 通信。ARM9作为主设备,SPI 的通信速率最低为 500K,单片机采用 NEC 的 78F1166,晶振采用11.0592MHz 时 SPI 通信速率可以达到 500K。速率匹配上没有问题。主从设备之间采用的通信协议为 DL/645.这里有一个问题,协议的收发数据帧的长度是不确定的。这就涉及到主设备需要读多少个字节的数据。根据实际应用。645 规约实际通信时数据帧不会超过 100 个字节。所以这里解决的方案是,主设备发送命令后,等待200ms 后主设备开始抄读数据。这里之所以等待 2
2、00MS,是因为从设备需要准备数据。以下是从设备的应用程序: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 gCsi01T
3、xLen; /* csi01 send data length */Unsigned short gCsi01TxCnt; /* csi01 send data count */#define BUFFERLEN 200unsigned char SPI_RX_BufferBUFFERLEN;unsigned char TxFlag,RxFlag;unsigned char Data;unsigned long count = 0;void CSI01_Init( void )/* CSI01 initial setting */ ST0 |= SAU_CH1_STOP_TRG_ON; /*
4、CSI01 disable */CSIMK01 = 1; /* INTCSI01 disable */CSIIF01 = 0; /* INTCSI01 IF clear */SIR01 = SAU_SIRMN_FECTMN | SAU_SIRMN_PECTMN | SAU_SIRMN_OVCTMN; /* error flag clear */SMR01 = SAU_SMRMN_INITIALVALUE | SAU_CLOCK_MODE_TI0N | SAU_TRIGGER_SOFTWARE | SAU_CSI | SAU_BUFFER_EMPTY;/SAU_TRANSFER_END;SCR0
5、1 = SAU_RECEPTION_TRANSMISSION | SAU_TIMING_4 | SAU_MSB | SAU_LENGTH_8;SDR01 = 0;SO0 /* CSI01 SO initial level */SOE0 |= SAU_CH1_OUTPUT_ENABLE; /* CSI01 output enable */* INTCSI01 priority low */CSIPR101 = 0;CSIPR001 = 0;/* SI01 pin setting */PM4 |= 0x10;/* SO01 pin setting */P4 |= 0x20;PM4 /* SCK01
6、 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(RECE
7、IVING);/启动后还没有接收数据/=void CSI01_Stop( void )ST0 |= SAU_CH1_STOP_TRG_ON; /* CSI01 disable */CSIMK01 = 1; /* INTCSI01 disable */CSIIF01 = 0; /* INTCSI01 IF clear */=unsigned char SPI_Send_Data(unsigned char *Buffer,unsigned char Lenth)gpCsi01TxAddress = Buffer;gCsi01TxCnt = Lenth - 1;SMR01 |= 0x0001;/a
8、dd by haoljSIO01 = Buffer0;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
9、= gCsi01RxCnt;OSTimeDly(1); elseSetReceiveFlag(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)
10、SMR01 /add by haoljSIO01 = 0xee;SetSendFlag(SENDEND);gpCsi01RxAddress = SPI_RX_Buffer;gCsi01RxCnt = 0;return ;Data = SIO01;gpCsi01TxAddress+;SIO01 = *gpCsi01TxAddress;gCsi01TxCnt-;else Data = SIO01;SIO01 = 0xee;if(gpCsi01RxAddress - SPI_RX_Buffer) BUFFERLEN) *gpCsi01RxAddress = Data;gpCsi01RxAddress
11、 +;gCsi01RxCnt +;SetReceiveFlag(RECEIVING);elseSetReceiveFlag(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);