资源描述
单片机的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 shortgCsi01RxLen;/* csi01 receive data length */Unsigned shortgCsi01RxCnt;/* csi01 receive data count */Unsigned char*gpCsi01TxAddress;/* csi01 send buffer address */Unsigned shortgCsi01TxLen;/* csi01 send data length */Unsigned shortgCsi01TxCnt;/* 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;/* 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;SCR01 = SAU_RECEPTION_TRANSMISSION | SAU_TIMING_4 | SAU_MSB | SAU_LENGTH_8;SDR01 = 0;SO0&= SAU_CH1_DATA_OUTPUT_1;/* 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 &= 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;/* 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;/add by haolj SIO01 = 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 = 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+;SIO01 = *gpCsi01TxAddress;gCsi01TxCnt-; else 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);
展开阅读全文