STM32视频教程

IIC通信的软件实现-下

作者:陈广
日期:2023-04-24


视频播放地址

点击播放

gx21m15.c源码

#include "gx21m15.h"
#include "main.h"
#include "tim.h"
#include "bit_banding.h"

#define SDA PBout(11)
#define SCL PBout(10)
#define Read_SDA PBin(11)

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

//将PB11设置为输出状态
void Set_SDA_Output_State()
{
	GPIO_InitStruct.Pin = LL_GPIO_PIN_11;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

//将PB11设置为输入状态
void Set_SDA_Input_State()
{
	GPIO_InitStruct.Pin = LL_GPIO_PIN_11;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

//将PB10设置为输出状态
void Set_SCL_Output_State()
{
	GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

//将PB10设置为输入状态
void Set_SCL_Input_State()
{
	GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//开始一次会话
void Begin_Session()
{
	Set_SDA_Output_State();
	Set_SCL_Output_State();
	SDA = 1;
	SCL = 1;
	Delay_us(2);
	SDA = 0;
	Delay_us(2);
	SCL = 0;
}
//结束一次会话
void End_Session()
{
	Set_SDA_Output_State();
	SDA = 0;
	Delay_us(2);
	SCL = 1;
	Delay_us(1);
	SDA = 1;
	Delay_us(1);
	Set_SDA_Input_State();
	Set_SCL_Input_State();
}
//发送一个字节
void Write_Byte(uint8_t txByte)
{
	Set_SDA_Output_State();
	SCL = 0;
	for(int i=7; i>=0; i--)
	{
		if(txByte & (1<<i))
		{
			SDA = 1;
		}
		else
		{
			SDA = 0;
		}
		Delay_us(1);
		SCL = 1;
		Delay_us(2);
		SCL = 0;
		Delay_us(1);
	}
}
/*  等待从机返回ACK
 *  返回值:0表示返回的是NACK,1表示返回的是ACK  */
uint8_t Wait_ACK()
{
	Set_SDA_Input_State();
	Delay_us(1);
	SCL = 1;
	Delay_us(1);
	if(Read_SDA)
	{
		return 0;
	}
	else
	{
		SCL = 0;
		return 1;
	}
}
//发送一个响应
void Send_ACK()
{
	SCL = 0;
	Set_SDA_Output_State();
	SDA = 0;
	Delay_us(2);
	SCL = 1;
	Delay_us(2);
	SCL = 0;
}
//发送一个非响应
void Send_NACK()
{
	SCL = 0;
	Set_SDA_Output_State();
	SDA = 1;
	Delay_us(2);
	SCL = 1;
	Delay_us(2);
	SCL = 0;
}
//读取一个字节
uint8_t Read_Byte()
{
	Set_SDA_Input_State();
	uint8_t recvByte = 0;
	for(int i=7; i>=0; i--)
	{
		SCL = 0;
		Delay_us(2);
		SCL = 1;
		Delay_us(1);
		if(Read_SDA)
		{
			recvByte |= 1 << i;
		}
	}
	return recvByte;
}
//获取并返回温度值
float Read_Temperature()
{
	uint8_t MSByte, LSByte;
	Begin_Session();
	Write_Byte(0x91);
	if(Wait_ACK())
	{
		MSByte = Read_Byte();
		Send_ACK();
		LSByte = Read_Byte();
		Send_NACK();
	}
	End_Session();
	uint16_t val = (LSByte >> 5) | (MSByte << 3);
	if(val & (1 << 10))
	{	//此时温度为负数
		return -0.125f * ((~val & 0x3FF) + 1);
	}
	else
	{   //此时温度为正数
		return val * 0.125f;
	}
}
;

© 2018 - IOT小分队文章发布系统 v0.3