STM32 模拟IIC驱动MS5607气压传感器调试记录

2023-05-16

标题 STM32 模拟IIC驱动MS5607调试记录

因项目需求,需使用MS5607的作为检测气压,再此写下自己遇见的问题以及调试记录。

硬件原理图如下:
在这里插入图片描述
IIC接口总线使用了气压传感器,SHT35温度传感器,调试MS5607硬件的7位地址是0X76。所以写的地址是0xEC,读操作的地址是0XED.
在第一次写数据的时候MCU无法得到ACK回应,最后查到的问题是地址错误导致的无回馈信号,在发送正确的时序图如下:

在这里插入图片描述

MS5607操作指令:
在这里插入图片描述
复位指令:

void  MS5607BA_Reset(void)//复位
  {
  		
			u8 err=0;
			IIC_Start();

			IIC_Send_Byte(MS5607BA_ADR_Write);
			err = IIC_Wait_Ack();
	       IIC_Send_Byte(MS5607BA_RESET);//Send Reset CMD
			err = IIC_Wait_Ack();
			IIC_Stop();

      delay_ms(200);    
	

  }

获得ADC读取的数字的值

void MS5607_Send_CMD(u8  command)
{

	  u8 err=0;
	  IIC_Start();
	  IIC_Send_Byte(MS5607BA_ADR_Write);//发送器件地址  
	  err = IIC_Wait_Ack();
	  IIC_Send_Byte(command);//Prom Read CMD
	  err = IIC_Wait_Ack();
	  IIC_Stop();
	  
}

void MS5607_ADC_Answer(u8 *Data)
{

	  u8 err=0;

	  IIC_Start();

	  IIC_Send_Byte(MS5607BA_ADR_Read);//发送器件地址

	  err = IIC_Wait_Ack();
	  *Data++=IIC_Read_Byte(1); 

	  *Data++=IIC_Read_Byte(1); 

	  *Data=IIC_Read_Byte(0); 

	  IIC_Stop();
	  
}

读取PRPM 0xa0 —0xae

void MS5607BA_readPROM(void)
{   
			uint16_t value=0;u8 Promdata[2]={0};
			u8 i;
			u8 err=0;
			u8 Read_CMD=Prom_Read_CMD;


			for(i=0;i<8;i++)
		    {

				/*********CMD to read Memory address****************/
				IIC_Start();
				IIC_Send_Byte(MS5607BA_ADR_Write);//发送器件地址	
				err = IIC_Wait_Ack();
				IIC_Send_Byte(Read_CMD);//Prom Read CMD
				err = IIC_Wait_Ack();
				IIC_Stop();

				/*****Answer from MS5607-02********/
				IIC_Start();
				IIC_Send_Byte(MS5607BA_ADR_Read);//发送器件地址	

				err = IIC_Wait_Ack();

				Promdata[0] = IIC_Read_Byte(1);

				Promdata[1] = IIC_Read_Byte(0);	

				IIC_Stop();

				Cal_C[i]=Promdata[0]<<8|Promdata[1];//Read PromData Storage Value Cal_C
			  	
		        Read_CMD+=2;   //Read Next Promdata CMD


		   }
			 
		
  	 printf("\n The MS561101BA is reading PROM : \r\n");    // printf("\r\nC1 = %d\r\nC2 = %d\r\nC3 = %d\r\nC4 = %d\r\nC5 = %d\r\nC6 = %d\r\n",temp1[1],temp1[2],temp1[3],temp1[4],temp1[5],temp1[6]);  
  }

读取D1值

u32  MS5607BA_Conversion_GetPressure(void)
  {
  	   
		u8 Press_Temp[3]={0};

		u32 D1_PessTmp=0;

		MS5607_Send_CMD(MS5607BA_D1_OSR_4096);
	   delay_ms(50);  
		MS5607_Send_CMD(MS5607BA_ADC_READ); 
		delay_ms(50);  
		MS5607_ADC_Answer(Press_Temp);
		
		delay_ms(50);  

		D1_PessTmp= Press_Temp[0]<<16| Press_Temp[1]<<8|Press_Temp[2];

		return D1_PessTmp;
      
  
  }

读取D2 温度的数字值

u32  MS5607BA_Conversion_Temp(void)
  {
  	   
		u8 Tempbuf[3]={0};	

		u32 D2_Data;


		MS5607_Send_CMD(MS5607BA_D2_OSR_4096);
			   delay_ms(50); 
		MS5607_Send_CMD(MS5607BA_ADC_READ); 
			   delay_ms(50); 
		MS5607_ADC_Answer(Tempbuf);
			   delay_ms(50); 

		D2_Data= Tempbuf[0]<<16| Tempbuf[1]<<8|Tempbuf[2];

		return D2_Data;
      
  }

计算温度

char MS5607_GetTemperature (void)     //计算温度
{
	D2_Temp = MS5607BA_Conversion_Temp();      //循环读取 温度

	if(D2_Temp == 0)
		return 0;
	
		delay_ms ( 20 );

	if(D2_Temp > (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ))
		dT	= D2_Temp - (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) );  //公式 dT = D2 - TREF = D2 - C5 * 2^8
	else
	{
		dT	= (  ( uint32_t ) Cal_C[5] * (0x00000001 << 8) ) - D2_Temp;   	
		dT *= -1;
	}
	Temperature	= 2000 + (( dT * Cal_C[6] ) / (0x00000001 << 23)); //算出温度值的100倍,2001表示20.01°  公式TEMP =20°C + dT * TEMPSENS =2000 + dT * C6 / 2^23

	if(Temperature<-4000) Temperature=-4000;
	if(Temperature>8500) Temperature=8500;
	return 1;
}

计算温度补偿压力

char MS5607_GetPressure (void)  //计算温度补偿压力
{
	
	
	D1_Pess = MS5607BA_Conversion_GetPressure();   //循环读取 D1 D2

	if(D1_Pess == 0)

		return 0;
	
	 delay_ms ( 20 );
	
	OFF	=  ( ( float)Cal_C[2] * (0x00000001 << 17) ) + ( ( float ) Cal_C[4] * dT ) / 64.0;    //公式 OFF = OFFT1 + TCO *dT = C2 *2^17 +(C4 *dT )/ 2^6
	SENS 		= ( ( float ) Cal_C[1] * (0x00000001 << 16) ) + ( ( float ) Cal_C[3] * dT ) / 128.0; //公式SENS = SENST1 + TCS* dT= C1 * 2^16 + (C3 * dT )/ 2^7

	//温度补偿部分    逻辑看芯片手册   
	
	if ( Temperature < 2000 ) // second order temperature compensation when under 20 degrees C
	{
		T2 = ( dT * dT ) / (( u32 )0x0000000001 << 31);
		OFF2 		= 61 *  (( Temperature - 2000 ) * ( Temperature - 2000 )) / 16;
		SENS2		= 2 * (( Temperature - 2000 ) * ( Temperature - 2000 )) ;
		if ( Temperature < -1500 )
		{
			OFF2 		= OFF2 + 15 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
			SENS2		= SENS2 + 8 * (( Temperature + 1500 ) * ( Temperature + 1500 )) ;
		}
	}
	else		//(Temperature > 2000)
	{
		T2 = 0;
		OFF2 		= 0;
		SENS2		= 0;
	}

	Temperature = Temperature - T2;
	OFF			= OFF - OFF2;
	SENS 		= SENS - SENS2;
	
	
	Press = ( D1_Pess * SENS / (0x00000001 << 21) - OFF ) / (0x00000001 << 15); //公式 P = D1 * SENS - OFF = (D1 * SENS / 2^21 - OFF) / 2^15

    MS5607TempPress.Pressure=(float)Press/100;//单位  mbar 
	MS5607TempPress.Temperature=(float)Temperature/100;//单位  ℃
        

	if(MS5607TempPress.Temperature<-40)MS5607TempPress.Temperature=-40;
	if(MS5607TempPress.Temperature>85)  MS5607TempPress.Temperature=85;
	if(MS5607TempPress.Pressure<10) 		MS5607TempPress.Pressure=10;
	if(MS5607TempPress.Pressure>1200) 	 MS5607TempPress.Pressure=1200;

		
	return 1;
}

开始的时候全速运行的时候读数有问题,最后发现两个命令之间时间太短没有延迟时间,单步调试时好的。在进行修改了延迟时间后全速运行是可行的,在折腾了一天后终于可以检测到温度压力以及湿度的值。
温湿度以及气压的值如下变量的所示:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 模拟IIC驱动MS5607气压传感器调试记录 的相关文章

  • 51单片机 数码管中断操作

    实践目的 1 掌握中断的概念和思想 2 掌握51单片机中断系统和相关软硬件设计 实践内容 1 利用单片机的P0口接数码管的字段脚 P1 0脚接共阴极 P3 2 P3 3引脚接独立按键产生外部中断信号 编写程序 当程序正常运行时数码管显示H字
  • 处理器指令周期执行时间

    我的猜测是 no operation 内在 ARM 指令应花费 1 168 MHz 来执行 前提是每个NOP在一个时钟周期内执行 我想通过文档验证这一点 有关处理器指令周期执行时间的信息是否有标准位置 我试图确定 STM32f407IGh6
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • STM32超声波——HC_SR04

    文章目录 一 超声波图片 二 时序图 三 超声波流程 四 单位换算 五 取余计算 六 换算距离 七 超声波代码 一 超声波图片 测量距离 2cm 400cm 二 时序图 1 以下时序图要先提供一个至少10us的脉冲触发信号 告诉单片机我准备
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • HAL 锁定和解锁函数如何使用以及为什么?

    我试图理解另一位程序员编写的代码 它使用了I C http en wikipedia org wiki I C2 B2C通信以将数据写入 STM32 微控制器的 EEPROM 一般来说 我理解他的代码是如何工作的 但我不明白他为什么使用HA
  • 解决KEIL编译慢问题

    两种方案 使用v6版本的ARM Compiler 如果v6版本编译不过 必须使用v5版本的 则可以勾选掉Browse Information选项 提升很明显 1分多钟能优化到几秒 看代码量 但是这个有个弊端 在KEIL中会影响函数跳转 建议
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • 通过JTAG恢复STM32 MCU磨掉的标记

    我有一块可能带有 STM32 MCU 的板 我想为该板制作定制固件 因为库存板有很多问题 不幸的是 电路板制造商很友善地磨掉了所有标记 有没有办法通过 jtag 获取设备 系列 ID 并将其交叉引用到型号 我能找到的一切都是关于获取芯片的唯
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • 在 Contiki 程序中使用 malloc

    考虑以下 Contiki 程序 include
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE

随机推荐