📄 i2c_master.c
字号:
#include "io430.h"
#include "in430.h"
#include "I2C_master.h"
unsigned char byteCtr; // byte number control
unsigned char *receive_field; // pointer to the store
unsigned char *transmit_field; // pointer to the data
//initialize clock
void I2C_Clock(void)
{
BCSCTL1 |= XTS; // ACLK = LFXT1 = HF XTAL
BCSCTL3 |= LFXT1S1; // 3 ?16MHz crystal or resonator
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (unsigned char i = 0xFF; i > 0; i--); // Time for flag to set
}
while (IFG1 & OFIFG); // OSCFault flag still set?
BCSCTL2 |= SELM_3 + SELS; // MCLK = SMCLK = LFXT1=7.3728MHz
}
//initialize I2C communication
void I2C_Init(unsigned char slave_address, unsigned char prescale)
{
P3SEL |= SDA_PIN + SCL_PIN; // select I2C module
UCB0CTL1 = UCSWRST; // enable SW reset => STOP
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Master + I2C + Synchronous
UCB0CTL1 = UCSSEL_2 + UCSWRST; // set BRCLK = SMCLK + SW reset
UCB0BR0 = prescale; // set lower byte of prescale
UCB0BR1 = 0; // set higher byte of prescale
UCB0I2CSA = slave_address; // set slave address
UCB0CTL1 &= ~UCSWRST; // clear SW reset => RESUME
UCB0I2CIE = UCNACKIE; // enable NACK interrupt
}
//initialize I2C receive
void I2C_Receive_Init(unsigned char slave_address, unsigned char prescale)
{
I2C_Init(slave_address,prescale); // initial basic I2C parameters
IE2 = UCB0RXIE; // enable RX interrupt
}
//initialize I2C transmit
void I2C_Transmit_Init(unsigned char slave_address, unsigned char prescale)
{
I2C_Init(slave_address,prescale); // initial basic I2C parameters
IE2 = UCB0TXIE; // enable TX interrupt
}
//start I2C receive
void I2C_Receive(unsigned char byteCount, unsigned char *field)
{
receive_field = field;
if ( byteCount == 1 ) // receive 1 byte
{
byteCtr = 0 ; // 0 remaining byte
_DINT(); // disable GIE
UCB0CTL1 |= UCTXSTT; // send start and address
while (UCB0CTL1 & UCTXSTT); // check start sent
UCB0CTL1 |= UCTXSTP; // send stop
_EINT(); // enable GIE
}
else // receive more than 1 byte
{
byteCtr = byteCount - 2; // total - 2 remaining byte due to byte receive first than interrupt
UCB0CTL1 |= UCTXSTT; // send start and address
}
}
//start I2C transmit
void I2C_Transmit(unsigned char byteCount, unsigned char *field)
{
transmit_field = field; // pass the address
byteCtr = byteCount; // pass the send count
UCB0CTL1 |= UCTR + UCTXSTT; // I2C transmiter + send start and address
}
//check the finish of communication
void I2C_Not_Ready(void)
{
while (UCB0STAT & UCBBUSY); //loop when unfinish
}
// the interrupt vector of I2C state change of USCI_B0
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
if (UCB0STAT & UCNACKIFG) // check NACK
{
UCB0CTL1 |= UCTXSTP; // send stop
UCB0STAT &= ~UCNACKIFG; // clear NACK flag
}
}
// the interrupt vector of both receive and transmit of USCI_B0 I2C
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if (IFG2 & UCB0RXIFG) // check I2C receive
{
if ( byteCtr == 0 ) // remain 1 byte
{
UCB0CTL1 |= UCTXSTP; // send stop
*receive_field = UCB0RXBUF; // store received
receive_field++; // point to next store
}
else // remain more bytes
{
*receive_field = UCB0RXBUF; // store received
receive_field++; // point to next store
byteCtr--; // minus the total receive count
}
}
if (IFG2 & UCB0TXIFG) // check I2C transmit
{
if (byteCtr == 0) // no more bytes
{
UCB0CTL1 |= UCTXSTP; // send stop
IFG2 &= ~UCB0TXIFG; // clear TX flag
}
else // remain more than 1 bytes
{
UCB0TXBUF = *transmit_field; // send data
transmit_field++; // point to next byte
byteCtr--; // minus the total send count
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -