STM32与测温芯片ADT7410通过模拟IIC通信

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: STM32与测温芯片ADT7410通过模拟IIC通信

ADT7410是一款基于SOIC封装的高精度数字温度传感器。它内部具有带隙温度参考源以及13位ADC,可以提高0.0625摄氏度的温度精度。 他的通信接口是IIC总线。I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。两根线是SDA(串行数据线)和SCL(串行时钟线) 根据数据手册,iic通信时序如下

image.png

按照他的通信时序,实现iic通信如下

#include "stm32f10x_gpio.h" #define GPIO_PORT_I2C GPIOC/* GPIO端口 / #define RCC_I2C_PORT RCC_APB2Periph_GPIOC/ GPIO端口时钟 / #define I2C_SCL_PIN     GPIO_Pin_0 / 连接到SCL时钟线的GPIO / #define I2C_SDA_PIN     GPIO_Pin_13 / 连接到SDA数据线的GPIO */

#define I2C_SCL_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SCL_PIN)/* SCL = 1 / #define I2C_SCL_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SCL_PIN)/ SCL = 0 */

#define I2C_SDA_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SDA_PIN)/* SDA = 1 / #define I2C_SDA_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SDA_PIN)/ SDA = 0 */

#define I2C_SDA_READ()  GPIO_ReadInputDataBit(GPIO_PORT_I2C, I2C_SDA_PIN)/* 读SDA口线状态 */

extern void delay(unsigned int num);

typedef struct { char  (*init) (void); float (*read_temperature)(void);

}IIC_SIMULATION_T;

extern IIC_SIMULATION_T *IIC_Simulation;

#include "DeviceSimulationIICDriver.h"

/*


  • 函 数 名: i2c_Delay
  • 功能说明: I2C总线位延迟,最快400KHz
  • 形    参:无
  • 返 回 值: 无

*/ static void i2c_Delay(void) { uint8_t i;

/*  下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。 CPU主频72MHz时,在内部Flash运行, MDK工程不优化 循环次数为10时,SCL频率 = 205KHz 循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us

IAR工程编译效率高,不能设置为7 */ for (i = 0; i < 10; i++); }

/*


  • 函 数 名: i2c_Start
  • 功能说明: CPU发起I2C总线启动信号
  • 形    参:无
  • 返 回 值: 无

/ void i2c_Start(void) { / 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */ I2C_SCL_1(); I2C_SDA_1(); i2c_Delay(); I2C_SDA_0(); // i2c_Delay(); // I2C_SCL_0(); // i2c_Delay(); }

/*


  • 函 数 名: i2c_Start
  • 功能说明: CPU发起I2C总线停止信号
  • 形    参:无
  • 返 回 值: 无

/ void i2c_Stop(void) { / 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */ I2C_SCL_1(); I2C_SDA_0(); i2c_Delay(); I2C_SDA_1(); }

/*


  • 函 数 名: i2c_SendByte
  • 功能说明: CPU向I2C总线设备发送8bit数据
  • 形    参:_ucByte : 等待发送的字节
  • 返 回 值: 无

*/ void i2c_SendByte(uint8_t _ucByte) { uint8_t i;

/* 先发送字节的高位bit7 / for (i = 0; i < 8; i++) { I2C_SCL_0(); i2c_Delay(); if (_ucByte & 0x80) { I2C_SDA_1(); } else { I2C_SDA_0(); } i2c_Delay(); I2C_SCL_1(); i2c_Delay(); I2C_SCL_0(); if (i == 7) { I2C_SDA_1(); // 释放总线 } _ucByte <<= 1; / 左移一个bit */ i2c_Delay(); } }

/*


  • 函 数 名: i2c_ReadByte
  • 功能说明: CPU从I2C总线设备读取8bit数据
  • 形    参:无
  • 返 回 值: 读到的数据

*/ uint8_t i2c_ReadByte(void) { uint8_t i; uint8_t value;

/* 读到第1个bit为数据的bit7 */ value = 0; I2C_SCL_1(); i2c_Delay(); for (i = 0; i < 8; i++) { value <<= 1; I2C_SCL_1(); i2c_Delay(); if (I2C_SDA_READ()) { value++; } I2C_SCL_0(); i2c_Delay(); } return value; }

/*


  • 函 数 名: i2c_WaitAck
  • 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
  • 形    参:无
  • 返 回 值: 返回0表示正确应答,1表示无器件响应

*/ uint8_t i2c_WaitAck(void) { uint8_t re;

I2C_SDA_1(); /* CPU释放SDA总线 / i2c_Delay(); I2C_SCL_1(); / CPU驱动SCL = 1, 此时器件会返回ACK应答 / i2c_Delay(); if (I2C_SDA_READ()) / CPU读取SDA口线状态 */ { re = 1; } else { re = 0; } I2C_SCL_0(); i2c_Delay(); return re; }

/*


  • 函 数 名: i2c_Ack
  • 功能说明: CPU产生一个ACK信号
  • 形    参:无
  • 返 回 值: 无

/ void i2c_Ack(void) { I2C_SDA_0(); / CPU驱动SDA = 0 / i2c_Delay(); I2C_SCL_1(); / CPU产生1个时钟 / i2c_Delay(); I2C_SCL_0(); i2c_Delay(); I2C_SDA_1(); / CPU释放SDA总线 */ }

/*


  • 函 数 名: i2c_NAck
  • 功能说明: CPU产生1个NACK信号
  • 形    参:无
  • 返 回 值: 无

/ void i2c_NAck(void) { I2C_SDA_1(); / CPU驱动SDA = 1 / i2c_Delay(); I2C_SCL_1(); / CPU产生1个时钟 */ i2c_Delay(); I2C_SCL_0(); i2c_Delay(); }

/*


  • 函 数 名: i2c_CfgGpio
  • 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
  • 形    参:无
  • 返 回 值: 无

*/ void iic_init(void) { GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE); /* 打开GPIO时钟 */

GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  /* 开漏输出 */ GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);

/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */ i2c_Stop(); }

/*


  • 函 数 名: i2c_CheckDevice
  • 功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
  • 形    参:_Address:设备的I2C总线地址
  • 返 回 值: 返回值 0 表示正确, 返回1表示未探测到

*/ uint8_t i2c_CheckDevice(uint8_t _Address) { uint8_t ucAck;

// i2c_CfgGpio();/* 配置GPIO */

i2c_Start(); /* 发送启动信号 */

/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 / i2c_SendByte(_Address | 0); ucAck = i2c_WaitAck(); / 检测设备的ACK应答 */

i2c_Stop(); /* 发送停止信号 */

return ucAck; }

static float read_temperature() { float num,read_h,read_l; i2c_Start(); i2c_SendByte((0x48<<1)); if (i2c_WaitAck() != 0) { return 0; } i2c_SendByte(0x00); if (i2c_WaitAck() != 0) { return 0; } // i2c_Stop(); i2c_Start(); i2c_SendByte((0x48<<1)|1); if (i2c_WaitAck() != 0) { return 0; } read_h=i2c_ReadByte(); i2c_Stop(); // if (i2c_WaitAck() != 0) // { // return 0; // } i2c_Start(); i2c_SendByte((0x48<<1)); if (i2c_WaitAck() != 0) { return 0; } i2c_SendByte(0x01); if (i2c_WaitAck() != 0) { return 0; }

// i2c_Stop(); i2c_Start(); i2c_SendByte((0x48<<1)|1); if (i2c_WaitAck() != 0) { return 0; } read_l=i2c_ReadByte(); i2c_Stop(); num=read_h*256+read_l; if(num<32768) {

num=num/128; } else {

num=(num-65536)/128;

} delay_ms(10); //  delay(999); //  delay(999); return num;

}

static char adt7410_init() {

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);

GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);

//  GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN; //  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;

//  GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure); // //  GPIO_InitStructure.GPIO_Pin =  I2C_SDA_PIN; //  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

//  GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);

i2c_Stop();

i2c_Start(); i2c_SendByte(0x48<<1); if (i2c_WaitAck() != 0) { return 1; }

i2c_SendByte(0x03); if (i2c_WaitAck() != 0) { return 1; } i2c_SendByte(0xc0); if (i2c_WaitAck() != 0) { return 1; } i2c_Stop(); return 0;

}

IIC_SIMULATION_T  IIC_init = { .init             = adt7410_init, .read_temperature = read_temperature, };

IIC_SIMULATION_T *IIC_Simulation=&IIC_init;



相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
221 0
|
4月前
stm32f407探索者开发板(十六)——串行通信原理讲解-UART
stm32f407探索者开发板(十六)——串行通信原理讲解-UART
241 0
|
6月前
STM32--SPI通信与W25Q64(2)
STM32--SPI通信与W25Q64(2)
|
6月前
|
存储 传感器 芯片
STM32--SPI通信与W25Q64(1)
STM32--SPI通信与W25Q64(1)
183 0
|
6月前
|
存储 传感器
【STM32基础 CubeMX】uart串口通信
【STM32基础 CubeMX】uart串口通信
341 0
|
芯片
STM32速成笔记(五)—串口通信
本文介绍了串口通信的概念,用途以及一些相关概念。介绍了如何进行printf重定向,如何根据接收到的特定信息,执行特定操作。此外,本文以通过上位机发送特殊指令控制LED亮灭的小项目,给出了详细的配置方法和程序设计。
204 0
STM32速成笔记(五)—串口通信
|
定位技术
激光雷达A1M8与STM32通信
激光雷达A1M8与STM32通信
195 0
|
缓存 数据格式
STM32串口通信配置(USART1+USART2+USART3+UART4)
STM32串口通信配置(USART1+USART2+USART3+UART4)
276 0
|
传感器
STM32通过IIC协议控制MPU6050
根据B站UP主“江科大自动化协”的教程总结
120 0