📄 muti_mcu_function.c
字号:
#include <iom16v.h>
#include <macros.h>
#include "muti_mcu_function.h"
static unsigned char TWI_buf[ TWI_BUFFER_SIZE ]; // Transceiver buffer
static unsigned char TWI_msgSize=0; // Number of bytes to be transmitted.
static unsigned char TWI_state = TWI_NO_STATE; // State byte. Default set to TWI_NO_STATE.
struct TWI_statusReg TWI_statusReg = {0}; // TWI_statusReg is defined in TWI_Master.h
void TWI_Master_Initialise(void)
{
TWBR = TWI_TWBR; // Set bit rate register (Baudrate). Defined in header file.
// TWSR = TWI_TWPS; // Not used. Driver presumes prescaler to be 00.
TWDR = 0xFF; // Default content = SDA released.
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins.
(0<<TWIE)|(0<<TWINT)| // Disable Interupt.
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // No Signal requests.
(0<<TWWC); //
}
void TWI_Slave_Initialise( unsigned char TWI_ownAddress )
{
TWBR = 0;
TWAR = TWI_ownAddress; // Set own TWI slave address. Accept TWI General Calls.
TWDR = 0xFF; // Default content = SDA released.
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins.
(0<<TWIE)|(0<<TWINT)| // Disable TWI Interupt.
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not ACK on any requests, yet.
(0<<TWWC); //
}
unsigned char TWI_Transceiver_Busy( void )
{
return ( TWCR & (1<<TWIE) ); // IF TWI Interrupt is enabled then the Transceiver is busy
}
unsigned char TWI_Get_State_Info( void )
{
while ( TWI_Transceiver_Busy() ); // Wait until TWI has completed the transmission.
return ( TWI_state ); // Return error state.
}
void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize,unsigned char status )
{
unsigned char temp;
while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission.
TWI_msgSize = msgSize; // Number of data to transmit.
TWI_buf[0] = msg[0]; // Store slave address with R/W setting.
if (!( msg[0] & (TRUE<<TWI_READ_BIT) )) // If it is a write operation, then also copy data.
{
for ( temp = 1; temp < msgSize; temp++ )
TWI_buf[ temp ] = msg[ temp ];
}
TWI_statusReg.all = 0;
TWI_state = TWI_NO_STATE ;
TWI_Working_status(status);
/* TWCR = (1<<TWEN)| // TWI Interface enabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag.
(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition.
(0<<TWWC); //*/
}
void TWI_Start_Transceiver(unsigned char status )
{
while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission.
TWI_statusReg.all = 0;
TWI_state = TWI_NO_STATE ;
TWI_Working_status(status);
/* TWCR = (1<<TWEN)| // TWI Interface enabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag.
(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition.
(0<<TWWC); //*/
}
unsigned char TWI_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize,unsigned char status )
{
unsigned char i;
while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission.
if( TWI_statusReg.lastTransOK ) // Last transmission competed successfully.
{
for ( i=0; i<msgSize; i++ ) // Copy data from Transceiver buffer.
{
msg[ i ] = TWI_buf[ i ];
}
if(status == TWI_slave_MCU)
TWI_statusReg.RxDataInBuf = FALSE;
}
return( TWI_statusReg.lastTransOK );
}
#pragma interrupt_handler twi_isr:18
void twi_isr(void)
{
static unsigned char TWI_bufPtr;
switch (TWSR)
{
case TWI_START: // START has been transmitted
case TWI_REP_START: // Repeated START has been transmitted
TWI_bufPtr = 0; // Set buffer pointer to the TWI Address location
case TWI_MTX_ADR_ACK: // SLA+W has been tramsmitted and ACK received
case TWI_MTX_DATA_ACK: // Data byte has been tramsmitted and ACK received
if (TWI_bufPtr < TWI_msgSize)
{
TWDR = TWI_buf[TWI_bufPtr++];
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //
(0<<TWWC); //
}else // Send STOP after last byte
{
TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully.
TWCR = (1<<TWEN)| // TWI Interface enabled
(0<<TWIE)|(1<<TWINT)| // Disable TWI Interrupt and clear the flag
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Initiate a STOP condition.
(0<<TWWC); //
}
break;
case TWI_MRX_DATA_ACK: // Data byte has been received and ACK tramsmitted
TWI_buf[TWI_bufPtr++] = TWDR;
case TWI_MRX_ADR_ACK: // SLA+R has been tramsmitted and ACK received
if (TWI_bufPtr < (TWI_msgSize-1) ) // Detect the last byte to NACK it.
{
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to read next byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after reception
(0<<TWWC); //
}else // Send NACK after next reception
{
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to read next byte
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send NACK after reception
(0<<TWWC); //
}
break;
case TWI_MRX_DATA_NACK: // Data byte has been received and NACK tramsmitted
TWI_buf[TWI_bufPtr] = TWDR;
TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully.
TWCR = (1<<TWEN)| // TWI Interface enabled
(0<<TWIE)|(1<<TWINT)| // Disable TWI Interrupt and clear the flag
(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)| // Initiate a STOP condition.
(0<<TWWC); //
break;
case TWI_ARB_LOST: // Arbitration lost
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag
(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a (RE)START condition.
(0<<TWWC); //
break;
case TWI_MTX_ADR_NACK: // SLA+W has been tramsmitted and NACK received
case TWI_MRX_ADR_NACK: // SLA+R has been tramsmitted and NACK received
case TWI_MTX_DATA_NACK: // Data byte has been tramsmitted and NACK received
// case TWI_NO_STATE // No relevant state information available; TWINT = ?? case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition
case TWI_STX_ADR_ACK: // Own SLA+R has been received; ACK has been returned
// case TWI_STX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
TWI_bufPtr = 0; // Set buffer pointer to first data location
case TWI_STX_DATA_ACK: // Data byte in TWDR has been transmitted; ACK has been received
TWDR = TWI_buf[TWI_bufPtr++];
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //
(0<<TWWC); //
break;
case TWI_STX_DATA_NACK: // Data byte in TWDR has been transmitted; NACK has been received.
// I.e. this could be the end of the transmission.
if (TWI_bufPtr == TWI_msgSize) // Have we transceived all expected data?
{
TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully.
}else // Master has sent a NACK before all data where sent.
{
TWI_state = TWSR; // Store TWI State as errormessage.
}
// Put TWI Transceiver in passive mode.
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
(0<<TWIE)|(0<<TWINT)| // Disable Interupt
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on any new requests.
(0<<TWWC); //
break;
case TWI_SRX_GEN_ACK: // General call address has been received; ACK has been returned
// case TWI_SRX_GEN_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
TWI_statusReg.genAddressCall = TRUE;
case TWI_SRX_ADR_ACK: // Own SLA+W has been received ACK has been returned
// case TWI_SRX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
// Dont need to clear TWI_S_statusRegister.generalAddressCall due to that it is the default state.
TWI_statusReg.RxDataInBuf = TRUE;
TWI_bufPtr = 0; // Set buffer pointer to first data location
// Reset the TWI Interupt to wait for a new event.
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Expect ACK on this transmission
(0<<TWWC); //
break;
case TWI_SRX_ADR_DATA_ACK: // Previously addressed with own SLA+W; data has been received; ACK has been returned
case TWI_SRX_GEN_DATA_ACK: // Previously addressed with general call; data has been received; ACK has been returned
TWI_buf[TWI_bufPtr++] = TWDR;
TWI_statusReg.lastTransOK = TRUE; // Set flag transmission successfull.
// Reset the TWI Interupt to wait for a new event.
TWCR = (1<<TWEN)| // TWI Interface enabled
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next reception
(0<<TWWC); //
break;
case TWI_SRX_STOP_RESTART: // A STOP condition or repeated START condition has been received while still addressed as Slave
// Put TWI Transceiver in passive mode.
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
(0<<TWIE)|(0<<TWINT)| // Disable Interupt
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on any new requests.
(0<<TWWC); //
break;
case TWI_SRX_ADR_DATA_NACK: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
case TWI_SRX_GEN_DATA_NACK: // Previously addressed with general call; data has been received; NOT ACK has been returned
case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted (TWEA = ??; ACK has been received
// case TWI_NO_STATE // No relevant state information available; TWINT = ?? // case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition
default:
TWI_state = TWSR; // Store TWSR and automatically sets clears noErrors bit.
// Reset TWI Interface
TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
(0<<TWIE)|(0<<TWINT)| // Disable Interupt
(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // No Signal requests
(0<<TWWC); //
}
}
//***********added by songxin****************//
//this function differ the status of the TWCR in MCU (mater or slave)
void TWI_Working_status(unsigned char status)
{
if(status == TWI_master_MCU)
{
TWCR = (1<<TWEN)| // TWI Interface enabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag.
(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition.
(0<<TWWC);
}
if(status == TWI_slave_MCU)
{
TWCR = (1<<TWEN)| // TWI Interface enabled.
(1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag.
(1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed.
(0<<TWWC);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -