STM32F103模拟IIC读取二氧化碳传感器ACD10

本文详细介绍了如何使用奥松ACD10二氧化碳传感器模块通过IIC通信进行数据读取,包括IO口配置、IIC通信协议实现和实际项目中的逻辑分析。重点讲解了如何设置PA0与PA1作为SDA和SCL,并提供了关键函数如IIC_Start、IIC_WriteByte和IIC_ReadByte的实现。同时,分享了在100KHz时钟限制下的注意事项和CRC校验过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        最近项目用到了二氧化碳气体检测,选择了奥松二氧化碳传感器模块(模块资料,可在文章最后连接下载),该模块有串口通信和IIC通信,由于项目中串口被其他资源占用,于是只能使用IIC通信读取二氧化碳数据。

        本篇文章做个项目记录,程序为项目实测验证,有需求网友可以借阅!

        二氧化碳传感器IIC通信IO口使用的是PA0与PA1,其配置如下:

1、IO口配置

PA1---SDA   

PA0---SCL

#define SDA_OUT {GPIOA->CRL &= 0XFFFFFF0F; GPIOA->CRL |= 0X00000070;}  //配置GPIOA 1 为开漏输出
#define SDA_IN  {GPIOA->CRL &= 0XFFFFFF0F; GPIOA->CRL |= 0X00000040;}  //配置GPIOA 1 为浮空输入

#define SCL_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET)  //PA0
#define SCL_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET)
#define SDA_H HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET)  //PA1
#define SDA_L HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET)

2、 程序

//注意这里的延时IIC_delay() 要让IIC频率低于100Khz
void IIC_Start(void)
{
	SDA_OUT;
	
	SDA_H;
	IIC_delay();
	SCL_H;
	IIC_delay();
	SDA_L;
	IIC_delay();
	SCL_L;
	IIC_delay();
}

void IIC_WriteByte(uint8_t data)
{
	uint8_t i=0;
	SDA_OUT;
	for(i=0;i<8;i++)
	{
		SCL_L;
		IIC_delay();
		if(data&0x80)
		{
			SDA_H;
		}
		else
		{
			SDA_L;
		}
	
		SCL_H;
		IIC_delay();
		data<<=1;
	}
	SCL_L;
	IIC_delay();
	SDA_IN;
	IIC_delay();
}

uint8_t IIC_ReadByte()
{
	uint8_t Byte,i,a;
	Byte = 0;
	SCL_L;
	SDA_IN;
	IIC_delay();
	
	for(i=0;i<8;i++)
	{
		SCL_H;
		IIC_delay();
		a = 0;
		if((GPIOA->IDR&0x0002)==0x0002)
			a=1;
		Byte = (Byte << 1) | a;
		SCL_L;
		IIC_delay();
	}
	SDA_IN;
	IIC_delay();
	return Byte;
}

uint8_t Receive_ACK()
{
	uint8_t CNT;
	CNT = 0;
	SCL_L;
	SDA_IN;
	IIC_delay();
	SCL_H;
	IIC_delay();
	while((((GPIOA->IDR&0x0002)==0x0002))&& CNT < 200) //(GPIOA->IDR&0x0020)==0x0020
	{
		CNT++;
	}
	if(CNT >= 200)
	{
		return 1;//无应答
	}
	SCL_L;
	IIC_delay();
	
	return 0;
}

void Send_ACK()//主机回复应答信号
{
	SDA_OUT;
	
	SCL_L;
	IIC_delay();
	SDA_L;
	IIC_delay();
	SCL_H;
	IIC_delay();
	SCL_L;
	IIC_delay();	
}

void Send_NOT_ACK()//主机不应答
{
	SDA_OUT;
	
	SCL_L;
	IIC_delay();
	SDA_H;
	IIC_delay();
	SCL_H;
	IIC_delay();
	SCL_L;
	IIC_delay();
	SDA_L;
	IIC_delay();
}

void IIC_Stop(void)//SLK高电平,DIO变高  为停止信号
{
	SDA_OUT;
	
	SDA_L;
	IIC_delay();
	SCL_H;
	IIC_delay();
	SDA_H;
	IIC_delay();
}


uint8_t  Calc_CRC8(uint8_t *dat, uint8_t Num)
{
	uint8_t i,byte,crc=0xFF;
	for(byte=0; byte<Num; byte++)
	{
		crc^=(dat[byte]);
		for(i=0;i<8;i++)
		{
			if(crc & 0x80) crc=(crc<<1)^0x31;
			else crc=(crc<<1);
		}
	}
	return crc;
}



uint32_t ACD10_Read_Data(void)
{
	uint8_t Byte[6],CRC_Byte[3];
	
	IIC_Start();
	IIC_WriteByte(0X54);
	
	if(Receive_ACK()==1) 
		return 1;
	IIC_WriteByte(0X03);
	if(Receive_ACK()==1) 
		return 1;
	IIC_WriteByte(0X00);
	if(Receive_ACK()==1) 
		return 1;
	IIC_Stop();
	
	HAL_Delay(10);
	
	IIC_Start();
	IIC_WriteByte(0X55);
	if(Receive_ACK()==1) 
		return 1;
	
	Byte[0] = IIC_ReadByte();
	Send_ACK();
	Byte[1] = IIC_ReadByte();
	Send_ACK();
	CRC_Byte[0] = IIC_ReadByte();
	Send_ACK();
	Byte[2]=IIC_ReadByte();
	Send_ACK();
	Byte[3]=IIC_ReadByte();
	Send_ACK();
	CRC_Byte[1]=IIC_ReadByte();
	Send_ACK();
	Byte[4]=IIC_ReadByte();
	Send_ACK();
	Byte[5]=IIC_ReadByte();
	Send_ACK();
	CRC_Byte[2]=IIC_ReadByte();
	Send_NOT_ACK();
	IIC_Stop();
	
	if((Calc_CRC8(Byte,2)!=CRC_Byte[0])||(Calc_CRC8(Byte+2,2)!=CRC_Byte[1])||(Calc_CRC8(Byte+4,2)!=CRC_Byte[2]))
	return 2;//CRC校验出错
	
	CO2Data = 0;//这里要清0,官网给出的程序未清0,(由于CO2Data是全局变量),导致CO2浓度值非常高
	
	CO2Data=(CO2Data|Byte[0])<<8;
	CO2Data=(CO2Data|Byte[1])<<8;
	CO2Data=(CO2Data|Byte[2])<<8;
	CO2Data=(CO2Data|Byte[3]);
	
	return 0;
}

3、逻辑分析仪数据

IIC发出写指令

需要注意一下:程序写的是地址是0X54,但上图片的Address Write:2A ,不要被这个给迷惑(本人从这里就被迷惑了一小会,脑子短路了),其实是这样的,程序中的0X54包含了IIC 的最低位的写指令,而逻辑分析仪把这个最低位分析为Wr,其它7位为地址,所以出现2A。

IIC读---CO2模块返回的数据

IIC时钟 

这个二氧化碳传感器的IIC时钟最大为100Khz,太大读取数据有错误,所以贴个图片,提醒自己不要忽略。

 相关资料下载如下:

 (5条消息) 奥松ACD10二氧化碳传感器资料-单片机文档类资源-CSDN文库

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

billjiang2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值