STM32与测温芯片ADT7410通过模拟IIC通信
【摘要】 ADT7410是一款基于SOIC封装的高精度数字温度传感器。它内部具有带隙温度参考源以及13位ADC,可以提高0.0625摄氏度的温度精度。 他的通信接口是IIC总线。I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。两根线是SDA(串行数据线)和SCL(串行时钟线) 根据数据手册,iic通信时序如下 按照他的通信时序...
ADT7410是一款基于SOIC封装的高精度数字温度传感器。它内部具有带隙温度参考源以及13位ADC,可以提高0.0625摄氏度的温度精度。 他的通信接口是IIC总线。I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。两根线是SDA(串行数据线)和SCL(串行时钟线) 根据数据手册,iic通信时序如下
按照他的通信时序,实现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; } i
2c_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; } r
ead_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;
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)