stm32使用IIC通讯读取压力传感器数据

        I2C总线是各种总线中使用信号线最少,并具有自动寻址、多主机和仲裁等功能的总线。因此,使用I2C总线设计计算机系统十分方便灵活,体积也小,因而在各类实际应用中得到广泛应用。        

        I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。

        本文采用IIC读取压力传感器的压力和温度数据。

        由压力传感器数据手册得到其从机地址、IIC通信图、IIC命令序列以及其数据处理公式。

1、从机地址。

可知其从机IIC地址为0x28。

2、IIC通信图。

可知该传感器通信顺序。

3、IIC命令序列。

该传感器为快速配置,故2中通信命令只需执行2. Start Pressure ( to wake sensor from Sleep mode and read Pressure only )或3. Read Data ( with examples of reading pressure, pressure plus 8 bits of temperature and pressure plus 11 bits of temperature )。

4、数据处理公式。

代码如下:

1、IIC.H

#ifndef __IIC_H
#define __IIC_H
#include "sys.h"



 
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}


//IO操作函数	 
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //输入SDA 
#define INT        PBin(5)  //输入INT

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号
  
#endif

2、IIC.C

#include "iic.h"
#include "delay.h"

 
//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD ;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
	IIC_SCL=1; 
	delay_us(4);
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}
//等待应答信号到来

u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 
//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
	delay_us(2);
	IIC_SDA=1;
	delay_us(2);
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);   
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

3、DLV.H

#ifndef __DLV
#define __DLV

#include "sys.h"
#include "iic.h"


//压力传感器从地址
#define Pressure_Adress 0x28 //压力传感器默认地址
#define OSdig 0        //压力数据补偿

extern u8 Pressure_Data[4];

void IIC_Readdlv(void);              //通过IIC读取压力传感器数据
float pressure_data(int a);        //计算压力传感器数据




#endif

4、DLV.C

#include "dlv.h"
#include "delay.h"
#include "math.h"


u8 Pressure_Data[4] = {0,0,0,0};

void IIC_Readdlv(void)
{               //读取传感器数据

	u8 adress;
	int i = 1;
	adress = Pressure_Adress;
	adress_w = (adress<<1) | 0x01;
	
	if(INT == 1)
	{
	  while(i)
		{
			IIC_Start();
			IIC_Send_Byte(adress_w);
			IIC_Wait_Ack();
			Pressure_Data[0] = IIC_Read_Byte(1);
			Pressure_Data[1] = IIC_Read_Byte(1);
			Pressure_Data[2] = IIC_Read_Byte(1);
			Pressure_Data[3] = IIC_Read_Byte(0);
			IIC_Stop();
			if((Pressure_Data[0]&0xC0) == 0)i = 0;		
		}
	}
}



float pressure_data(int a)
{          //a == 1输出压力,a == 0输出温度
	u16 pressure = 0,temperature = 0;
	float fpressure = 0,ftemperature = 0,i = 1,compensation = 0;
	
	while(i)
	{
		 IIC_Readdlv();
		 if((Pressure_Data[0]&0xC0) == 0X00)
			i = 0;			
    }
	

	pressure = (Pressure_Data[0] & 0x3F);
	pressure = pressure<<8;
	pressure += Pressure_Data[1];
	fpressure = 1.25 * (((pressure*1.0)-OSdig)/(16384)) * 60;

			
	temperature = Pressure_Data[2];
	temperature = temperature<<8;
	temperature += (Pressure_Data[3] & 0xE0);
	temperature = temperature>>5;
	ftemperature = ((temperature*1.0)/(2047))*200 - 50;
		
	if(a == 1)
	{
		return fpressure;
	}
	else
	{
		return ftemperature;
	}
}


  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是ASDX ACX015PA7A3压力传感器STM32上通过模拟IIC接口读取C语言代码示例: ```c #include "stm32f10x.h" #include <stdio.h> #define SDA GPIO_Pin_7 // 设置SDA引脚 #define SCL GPIO_Pin_6 // 设置SCL引脚 GPIO_InitTypeDef GPIO_InitStructure; void IIC_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = SDA | SCL; // 设置SDA和SCL引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 将引脚设置为开漏输出模式 GPIO_Init(GPIOA, &GPIO_InitStructure); } void IIC_Start(void) { GPIO_SetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); GPIO_ResetBits(GPIOA, SDA); GPIO_ResetBits(GPIOA, SCL); } void IIC_Stop(void) { GPIO_ResetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); GPIO_SetBits(GPIOA, SDA); } void IIC_SendByte(uint8_t byte) { uint8_t i; for(i = 0; i < 8; i++) { if((byte & 0x80) == 0x80) GPIO_SetBits(GPIOA, SDA); else GPIO_ResetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); GPIO_ResetBits(GPIOA, SCL); byte <<= 1; } } uint8_t IIC_ReadByte(void) { uint8_t i; uint8_t byte = 0; GPIO_SetBits(GPIOA, SDA); for(i = 0; i < 8; i++) { byte <<= 1; GPIO_SetBits(GPIOA, SCL); if(GPIO_ReadInputDataBit(GPIOA, SDA) == 1) byte |= 0x01; GPIO_ResetBits(GPIOA, SCL); } return byte; } void IIC_SendAck(void) { GPIO_ResetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); GPIO_ResetBits(GPIOA, SCL); } void IIC_SendNack(void) { GPIO_SetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); GPIO_ResetBits(GPIOA, SCL); } uint8_t IIC_ReadAck(void) { uint8_t ack; GPIO_SetBits(GPIOA, SDA); GPIO_SetBits(GPIOA, SCL); ack = GPIO_ReadInputDataBit(GPIOA, SDA); GPIO_ResetBits(GPIOA, SCL); return ack; } void IIC_WriteReg(uint8_t addr, uint8_t reg, uint8_t value) { IIC_Start(); IIC_SendByte(addr << 1); if(IIC_ReadAck() == 0) { IIC_SendByte(reg); if(IIC_ReadAck() == 0) { IIC_SendByte(value); IIC_ReadAck(); } } IIC_Stop(); } uint8_t IIC_ReadReg(uint8_t addr, uint8_t reg) { uint8_t value; IIC_Start(); IIC_SendByte(addr << 1); if(IIC_ReadAck() == 0) { IIC_SendByte(reg); IIC_ReadAck(); IIC_Start(); IIC_SendByte((addr << 1) | 0x01); IIC_ReadAck(); value = IIC_ReadByte(); IIC_SendNack(); } IIC_Stop(); return value; } int main(void) { IIC_Init(); // 初始化模拟IIC uint8_t addr = 0x28; // 设置传感器的IIC地址 uint8_t reg = 0x00; // 设置传感器的寄存器地址 uint8_t value; while(1) { value = IIC_ReadReg(addr, reg); // 读取传感器数据 printf("Pressure value: %d\n", value); // 输出读取到的压力值 delay(500); // 延时500毫秒 } return 0; } ``` 这段代码基于STM32的库函数实现了通过模拟IIC接口读取ASDX ACX015PA7A3压力传感器数据。首先在程序中定义了SDA和SCL引脚,并在IIC_Init函数中初始化这两个引脚。接着定义了IIC_Start、IIC_Stop、IIC_SendByte、IIC_ReadByte、IIC_SendAck、IIC_SendNack和IIC_ReadAck等IIC通信所需的函数。在主函数中,定义了传感器的IIC地址和要读取的寄存器地址,然后循环调用IIC_ReadReg函数读取传感器数据,并输出到终端。最后通过延时函数控制循环频率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值