//==============================软件硬件I2C模式分割线===============================
#ifdef HARD_IIC // Begin of Hard I2C
/*
* IIC_Init(IIC_MODE iic_mode, UCSSELx ucsselx)
* 初始化I2C
*
* 参数:
* iic_mode --IIC主从模式设置
* |__ Slave
* |__ Master
* |
* ucsselx --IIC时钟信号选择
* |__ UCLKI
* |__ ACLK
* |__ SMCLK
* 输出:
* 无
*
*/
void IIC_Init(IIC_MODE iic_mode, UCSSELx ucsselx)
{
_disable_interrupts();
P1SEL |= BIT6 + BIT7; // GPIO 配置为USCI_B0功能
P1SEL2|= BIT6 + BIT7; // GPIO 配置为USCI_B0功能
// Own address is a 7-bit address | Address slave with 7-bit address | Single master environment
switch(iic_mode)
{
case Slave:
UCB0CTL0 = UCMODE_3 + UCSYNC; //同步通信I2C从机状态
break;
case Master:
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; //同步通信I2C主机状态
break;
}
switch(ucsselx)
{
case UCLKI:
UCB0CTL1 = UCSSEL_0 + UCSWRST; // Use UCLKI,USCI Software Reset
break;
case ACLK:
UCB0CTL1 = UCSSEL_1 + UCSWRST; // Use ACLK,USCI Software Reset
break;
case SMCLK:
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK,USCI Software Reset
break;
}
UCB0BR0 =IIC_BAUDRATE_DIV ; // 除了分频系数,实际波特率还与时钟有关
UCB0BR1 = 0; // 这一级别的分频一般不启用
//UCB0I2CSA = SLAVE_ADDR; // I2C从机地址,可在宏定义中修改
UCB0CTL1 &= ~UCSWRST; // 开启I2C
_enable_interrupts();
}
/*
* uint8 IIC_Read_Bytes(uint8 Addr, uint8 *Data, uint8 Num)
* 硬件IIC主机读多个字节
*
* 参数:
* Addr --硬件IIC从机地址
* |
* Data --数组首地址
* |
* Num --读出数组的长度
* 输出:
* 无
*
*/
uint8 IIC_Read_Bytes(uint8 Addr, uint8 *Data, uint8 Num)
{
uint8 TimeOut = 0;
uint8 i = 0;
UCB0CTL1 |= UCSWRST;
UCB0CTL1 &= ~UCSWRST; // 开启I2C
TimeOut = IIC_TIME_OUT;
while((UCB0STAT & UCBBUSY) && (TimeOut--)); // 确保总线不忙
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
// 设置IIC从设备地址,
UCB0I2CSA = Addr;
UCB0CTL1 &= ~UCTR; // IIC RX Module
UCB0CTL1 |= UCTXSTT; // IIC模块为接收模式,启动START信号
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTT) && (TimeOut--)); // 判断UCTXSTT是否自动硬件置0
for(i=0;i<Num;i++)
{
while((!(IFG2 & UCB0RXIFG)) && (TimeOut--)); // 判断UCB0RXIFG是否自动硬件置0
Data[i] = UCB0RXBUF;
}
// 发送IIC STOP 信号
UCB0CTL1 |= UCTXSTP;
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
return 1;
}
/*
* uint8 IIC_Write_OneByte(uint8 Addr, uint8 Val)
* 硬件IIC主机写一个字节
*
* 参数:
* Addr --硬件IIC从机地址
* |
* Val --待写入的值
* 输出:
* 无
*
*/
uint8 IIC_Write_OneByte(uint8 Addr, uint8 Val)
{
uint8 TimeOut = 0;
UCB0CTL1 |= UCSWRST;
UCB0CTL1 &= ~UCSWRST; // 开启I2C
TimeOut = IIC_TIME_OUT;
while((UCB0STAT & UCBBUSY) && (TimeOut--)); // 确保总线不忙
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
// 设置I2C从设备地址,
UCB0I2CSA = Addr;
UCB0CTL1 |= UCTR + UCTXSTT; // IIC模块为发送模式,启动START信号
TimeOut = IIC_TIME_OUT;
while((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
UCB0TXBUF = Val;
TimeOut = IIC_TIME_OUT;
while((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
// 清除IIC发送缓冲空的中断标志,发送IIC STOP信号
IFG2 &= ~UCB0TXIFG;
UCB0CTL1 |= UCTXSTP; // 发送IIC STOP 信号
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
return 1;
}
/*
* uint8 IIC_Write_Bytes(uint8 Addr, const uint8 *Data, uint8 Num)
* 硬件IIC主机写多个字节
*
* 参数:
* Addr --硬件IIC从机地址
* |
* Data --数组首地址
* |
* Num --写入数组的长度
* 输出:
* 无
*
*/
uint8 IIC_Write_Bytes(uint8 Addr, const uint8 *Data, uint8 Num)
{
uint8 TimeOut = 0;
uint8 i = 0;
UCB0CTL1 |= UCSWRST;
UCB0CTL1 &= ~UCSWRST; // 开启I2C
TimeOut = IIC_TIME_OUT;
while((UCB0STAT & UCBBUSY) && (TimeOut--)); // 确保总线不忙
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
// 设置IIC从设备地址
UCB0I2CSA = Addr;
UCB0CTL1 |= UCTR + UCTXSTT; // IIC模块为发送模式,启动START信号
TimeOut = IIC_TIME_OUT;
while((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
for(i=0;i<Num;i++)
{
UCB0TXBUF = Data[i];
TimeOut = IIC_TIME_OUT;
while((!(IFG2 & UCB0TXIFG)) && (TimeOut--));
}
// 清除IIC发送缓冲空的中断标志,发送 IIC STOP 信号
IFG2 &= ~UCB0TXIFG;
UCB0CTL1 |= UCTXSTP; // 发送IIC STOP 信号
TimeOut = IIC_TIME_OUT;
while((UCB0CTL1 & UCTXSTP) && (TimeOut--)); // 确保STOP
return 1;
}
#endif // End of Hard IIC |