STM32学习-IIC
立即下载
资源介绍:
STM32学习-IIC
/**
******************************************************************************************
* @file myiic.c
* @author 加州大溪没
* @brief
******************************************************************************************
**/
/* Includes -------------------------------------------------- */
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/my_iic/myiic.h"
/* End Includes -------------------------------------------------- */
/* Functions -------------------------------------------------- */
/** @brief 对IIC硬件配置进行初始化
* @param None
* @note None
* @retval None
*/
void IIC_Init()
{
GPIO_InitTypeDef gpio_init_struct;
/* 开启时钟 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/*配置SCL SDA,开漏输出模式,此处SCL和SDA使用的都是B口*/
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
gpio_init_struct.Pin = SCL_PIN | SDA_PIN;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SCL_PORT, &gpio_init_struct);
/* 释放总线 */
SCL(1);
SDA(1);
}
/** @brief 产生一个IIC通信开始信号
* @param None
* @note SDA --- 1
* \
* \
* ----- 0
* SCL ---------- 1
* @retval None
*/
void IIC_Start()
{
SDA(1);
IIC_Delay();
SCL(1);
IIC_Delay();
SDA(0);
IIC_Delay();
SCL(0); //钳住SCL线,为后面的操作做准备
IIC_Delay();
}
/** @brief 产生一个IIC通信停止信号
* @param None
* @note SDA --- 1
* /
* /
* ----- 0
* SCL ---------- 1
* @retval None
*/
void IIC_Stop()
{
SDA(0);
IIC_Delay();
SCL(1);
IIC_Delay();
SDA(1);
IIC_Delay();
}
/** @brief 发送一个应答 / 未应答信号
* @param AckBit:1 未应答
* 0 应答
* @note SDA -------------- 0 / 1
* SCL ---- 1
* / \
* / \
* --- --- 0
* @retval None
*/
void IIC_SendAck(uint8_t AckBit)
{
SDA(AckBit);
IIC_Delay();
SCL(1);
IIC_Delay();
SCL(0);
IIC_Delay();
}
/** @brief 接收一个应答 / 未应答信号
* @param None
* @note SDA -------------- 0 / 1
* SCL ---- 1
* / \
* / \
* --- --- 0
* @retval AckBit:接收到的应答 / 未应答信号
*/
uint8_t IIC_ReceiveAck()
{
uint8_t AckBit;
SDA(1);
IIC_Delay();
SCL(1);
IIC_Delay();
AckBit = SDA_READ;
IIC_Delay();
SCL(0);
IIC_Delay();
return AckBit;
}
/** @brief 发送一个字节的数据
* @param data:待发送的数据
* @note SDA -------------- 0 / 1
* SCL ---- 1
* / \
* / \
* --- --- 0
* @retval None
*/
void IIC_Send_Byte(uint8_t data)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
SDA(data & (0X80 >> i)); //一位一位发送数据
IIC_Delay();
SCL(1);
IIC_Delay();
SCL(0);
IIC_Delay();
}
}
/** @brief 发送一个字节的数据
* @param None
* @note SDA -------------- 0 / 1
* SCL ---- 1
* / \
* / \
* --- --- 0
* @retval Receive_Data:接收到的一字节的数据
*/
uint8_t IIC_Receive_Byte()
{
uint8_t i, Receive_Data = 0x00;
SDA(1);
IIC_Delay();
for(i = 0; i < 8; i++)
{
SCL(1);
IIC_Delay();
if(SDA_READ)
Receive_Data |= (0x80 >> i); //一位一位接收数据
SCL(0);
IIC_Delay();
}
return Receive_Data; //返回读取到的数据
}
/** @brief 发送一个字节的数据
* @param addr: 从机的地址
* reg: 从机寄存器地址
* @note 读操作,AD+R末位为1
* 写操作,AD+W末位为0
* 只读一次:
* Master S AD+W RA DATA P
* Slave ACK ACK ACK
* 读多次:
* Master S AD+W RA DATA DATA P
* Slave ACK ACK ACK ACK
* @retval Data_Temp:IIC读取操作读取到的数据,可以连读
*/
void IIC_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
IIC_Start();
IIC_Send_Byte(addr);
IIC_ReceiveAck();
IIC_Send_Byte(reg);
IIC_ReceiveAck();
IIC_Send_Byte(data);
IIC_ReceiveAck();
IIC_Stop();
}
/** @brief 接收一个字节的数据
* @param addr: 从机的地址
* reg: 从机寄存器地址
* @note 读操作,AD+R末位为1
* 写操作,AD+W末位为0
* 只读一次:
* Master S AD+W RA S AD+R NACK P
* Slave ACK ACK ACK DATA
* 读多次:
* Master S AD+W RA S AD+R ACK NACK P
* Slave ACK ACK ACK DATA DATA
* @retval Data_Temp:IIC读取操作读取到的数据,可以连读
*/
uint8_t IIC_Read(uint8_t addr, uint8_t reg)
{
uint8_t Data_Temp = 0;
IIC_Start();
IIC_Send_Byte(addr);
IIC_ReceiveAck();
IIC_Send_Byte(reg);
IIC_ReceiveAck();
IIC_Start();
IIC_Send_Byte(addr | 0x01);
IIC_ReceiveAck();
Data_Temp = IIC_Receive_Byte();
IIC_SendAck(1);
IIC_Stop();
return Data_Temp;
}
/* END OF FILE ********************************************************** */