📄 upsd3300_i2c.c
字号:
i2c_state=I2C_TIME_OUT; return (i2c_state); } // I2C master receive timeout else { return(i2c_state); } // Return I2C current state}/*-------------------------------------------------------------------------upsd_i2c_slave_Xmit(Data_Ptr, N_Ptr)This function is used to transmit data to master, only for slave.Data_Ptr - unsigned char* - address pointer of transmit bufferN_Ptr - unsigned char* - the length of data buffer transmitted to master. Returns:I2C_SX_END 6 //Slave Mode - transmission is completeI2C_TIME_OUT 9 //I2C Timed OutI2C_NACK 13 //I2C NACK (No Acknowledge)I2C_BUSLOST 14 //I2C bus lost-------------------------------------------------------------------------*/unsigned char upsd_i2c_slave_Xmit(unsigned char* Data_Ptr, unsigned char* N_Ptr){ EA=0; i2c_xmit_buf=Data_Ptr; // Initialize pointer to transmit buffer i2c_master = 0; i2c_xmitr = 1; // Set up for Slave transmitter S1CON &= ~STO; // Disable STOP control bit i2c_data_index=0; S1DAT = i2c_xmit_buf[i2c_data_index]; // Send first data to master i2c_data_index++; i2c_state=I2C_SX; // Set I2C current status EA=1; if(upsd_i2c_Timeout(I2C_SX,10000)==1){ S1CON&=~ENI;i2c_slave_addressed=0;i2c_state=I2C_TIME_OUT;return(i2c_state); } // I2C slave timeout return else { *N_Ptr=i2c_data_index;return(i2c_state); } // return current I2C state and the length // of the data buffer transmitted to master}/*-------------------------------------------------------------------------upsd_i2c_slave_Recv(Data_Ptr, N_Ptr)This function is used to receive data from a master while in slave mode.Data_Ptr - unsigned char* - address pointer to receive bufferN_Ptr - unsigned char* - the length of received data from the master. Returns:I2C_TIME_OUT 9 //I2C Timed OutI2C_SR_END 11 //Slave Mode - reception completeI2C_NACK 13 //I2C NACK (No Acknowledge)I2C_BUSLOST 14 //I2C bus lostI2C_SX_APP 15 //Slave to transmit data to master-------------------------------------------------------------------------*/unsigned char upsd_i2c_slave_Recv(unsigned char* Data_Ptr, unsigned char* N_Ptr){ EA=0; S1CON&=~ENI; i2c_rcv_buf=Data_Ptr; // initialize pointer to receive buffer i2c_master = 0; i2c_xmitr = 0; // Set to Slave transmitter i2c_data_index=0; i2c_state=I2C_SR; // Set I2C current status to Slave Read S1CON|=ENI; EA=1; if(upsd_i2c_Timeout(I2C_SR,10000)==1){ S1CON&=~ENI;i2c_slave_addressed=0;i2c_state=I2C_TIME_OUT; return(i2c_state); } // Slave receive timeout else { *N_Ptr=i2c_data_index; return(i2c_state); } // Return I2C current state}/*------------------------------------------------------------------------ I2C Interrupt Service RoutineThere are several types of interrupts handled by the ISR.1. The address packet has been transmitted by master or received by slave with AA=1.2. The data has been transmitted or received by master.3. The data has been transmitted or recieved by addressed slave with AA=1.4. The STOP condition has been received by addressed slave with AA=1.------------------------------------------------------------------------*/ void i2c_isr (void) interrupt I2C_VECTOR using 2 { i2c_sta=S1STA; // Store S1STA register S1STA&=~INTR; // Clear INTR flag toggle=0; //------Master transmit operation-------------------------------------------- if (i2c_master & i2c_xmitr){ // master transmitter mode if ((i2c_sta & BLOST) !=0){ // if bus lost, read dummybyte to turn to Slave mode dummybyte=S1DAT; i2c_state=I2C_BUSLOST; // Indicate the bus was lost } else if ((i2c_sta & _ACKREP) !=0){ S1CON |=STO; S1DAT=dummy; // if no ACK, send STOP condition to Bus i2c_state=I2C_NACK; // Indicate NACK (no ACK) } else { if((i2c_data_index)<=(i2c_data_len-1)) { S1DAT = i2c_xmit_buf[i2c_data_index]; //send data from Master i2c_data_index++; //increment data-pointer } else if(i2c_data_index==i2c_data_len) { S1CON |= STO; // set STO (stop bit) for last data byte to be sent S1DAT=dummy; i2c_state=I2C_MX_END; // Indicate the Master transmission is complete } } } //------Master receive operation-------------------------------------------- if (i2c_master & ~i2c_xmitr){ // master receive mode //Handle interrupt in address field if(((S1CON&AA)==0)& (i2c_data_index==0)) { if ((i2c_sta & _ACKREP) !=0){ S1CON |=STO; dummybyte=S1DAT; i2c_state=I2C_NACK; // indicate NACK (no ACK) return; } else { dummybyte=S1DAT; //dummy read if(i2c_data_len!=1)S1CON |= AA; //enable ACK to prepare to receive data from slave i2c_data_index++; return; } } //Handle reception of data else { if(i2c_data_index<i2c_data_len) { i2c_rcv_buf[i2c_data_index-1] = S1DAT; // Receive data i2c_data_index++; // Increment data-pointer if(i2c_data_index==i2c_data_len){S1CON&=~AA;} // Disable ACK to return a NACK when // master received the last byte of data. } else { S1CON |=STO; // Generate a STOP condition on Bus i2c_rcv_buf[i2c_data_index-1] = S1DAT; // Receive the last byte of data i2c_state=I2C_MR_END; // Indicate Master reception is complete } } } //------slave operation-------------------------------------------- if(i2c_master==0){ //Handle STOP interrupt if((i2c_sta&STOP)!=0){ if(i2c_slave_addressed==1){ if(i2c_xmitr==1){ i2c_state=I2C_SX_END; // Indicate slave transmission is complete i2c_slave_addressed=0; // Reset addressed flag S1CON&=~ENI; // Disable I2C to isolate slave from bus return; } else { i2c_rcv_buf[i2c_data_index] = S1DAT; // Get last byte of data from Master i2c_slave_addressed=0; // Reset addressed flag i2c_state=I2C_SR_END; // Indicate the data has been received completely S1CON&=~ENI; // Disable I2C to isolate slave from bus return; } } } //Handle Address field interrupt else if(((S1CON&ADDR)!=0)&((S1CON&AA)!=0)){ S1CON&=~ADDR; // Clear ADDR flag i2c_slave_addressed=1; // Set addressed flag bit // if received address information, identify read or write command if((i2c_sta&TX_MODE)!=0){ i2c_state=I2C_SX_APP; // Indicate slave is required to transmit data to master return; } else{ dummybyte=S1DAT; // Dummy read return; } } //Handle data field interrupt else if(i2c_slave_addressed==1) { if(i2c_xmitr==0) { i2c_rcv_buf[i2c_data_index] = S1DAT; // Get data byte from Master i2c_data_index++; // Increment data-pointer } else { if((i2c_sta &_ACKREP)!=0) { S1DAT=dummy; // Dummy write } else { S1DAT = i2c_xmit_buf[i2c_data_index]; // Send data i2c_data_index++; // Increment data-pointer } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -