STM32模拟IIC协议驱动AD7991/AD7995/AD7999芯片
STM32模拟IIC协议驱动AD7991/AD7995/AD7999芯片
AD7991/AD7995/AD7999是12位/10位/8位 4通道模拟输入的AD转换芯片
通信方式采用的是:I2C
芯片供电VDD电压范围为:2.7V---5.5V
参考电压REF范围为:1.2V---VDD
模拟输入电压范围为:0-VREF
下面以AD7995为例,以STM32F103为平台对该芯片的驱动程序及电路进行说明:
1、AD电路原理图
注:这里I2C的两根SCL和SDA线需各接一个4.7K的上拉电阻。
2、芯片引脚分析
引脚标号 | 名称 | 描述 |
1 | SCL | I2C串行总线时钟 |
2 | SDA | I2C双向串行数据线 |
3 | VIN0 | 模拟输入接口0 |
4 | VIN1 | 模拟输入接口1 |
5 | VIN2 | 模拟输入接口2 |
6 | VIN3/VREF | 模拟输入接口3/参考电压输入 |
7 | GDN | 地 |
8 | VDD | 电源 |
产品标号 | I2C地址 |
AD7991-0 | 010 1000 |
AD7991-1 | 010 1001 |
AD7995-0 | 010 1000 |
AD7995-1 | 010 1001 |
AD7999-1 | 010 1001 |
3、AD7995——8bit控制字寄存器
该8位控制字寄存器只能通过I2C进行数据的写操作,用于设置AD7995的工作模式。
位 | 名称 | 描述 |
D7 | 通道CH3或VREF参考电压 | 具体看D3脚的功能描述 |
D6---D4 | 通道CH2---通道0 | 在需要打开的通道下置1 |
D3 | CH3功能选择 |
置1:CH3引脚将作为参考电压输入脚; 置0:CH3引脚将作为模拟电压输入脚,芯片将以VDD作为参考电压 |
D2 | I2c过滤使能 | 置1:忽略过滤;置0:使能过滤. 默认1 |
D1 | 位试验延时 | 默认1关闭 |
D0 | 取样延时 | 默认1关闭 |
4、AD7995——转换结果寄存器
转换结果寄存器是一个16位,只能通过I2C读操作的寄存器。用于读取AD7995的AD转换结果
位 | 名称 | 描述 |
D15---D14 | 无效位 | |
D13---D12 | 通道标号 |
表示当前转换结果是来自哪个通道。 00:通道0, 01:通道1, 10:通道2, 11:通道3 |
D11---D0 | 转换结果 |
AD7991转换结果全部来自这12位。 AD7995转换结果来自前10位,其余为0。 AD7999转换结果来自前8位,其余为0 |
5、写操作时序图
该写时序共分为2个阶段:
第一阶段。主机通过I2C向AD7995发送一个START信号,接着发送AD7995-0的地址:010 1000(详情看第2小节的设备地址),在下一个时钟脉冲(也就是第8个)的时候R/W位 设置为0,表示该命令为写操作,然后第9个时钟脉冲添加ACK信号。
第二个阶段。主机再发送8位控制字内容,然后再第9个脉冲添加ACK信号,最后发送STOP信号结束通信。
6、读操作时序图
该读时序共分为3个阶段:
第一阶段。 主机通过I2C向AD7995发送一个START信号,接着发送AD7995-0的地址:010 1000(详情看第2小节的设备地址),在下一个时钟脉冲(也就是第8个)的时候R/W位 设置为1,表示该命令为读操作,然后第9个时钟脉冲添加ACK信号。
第二阶段。主机通过I2C向AD7995发送共8个时钟脉冲,且每发送一个脉冲且脉冲处于高电平的时候,读取SDA线上信号,该信号为转换结果寄存器的高8位,然后再第9个脉冲添加ACK信号。
第三阶段。主机再通过I2C向AD7995发送共8个时钟脉冲,且每发送一个脉冲且脉冲处于高电平的时候,读取SDA线上信号,该信号为转换结果寄存器的低8位,然后再第9个脉冲添加No_ACK信号,最后发送STOP信号结束通信。
7、STM32——AD7995驱动代码
AD7995.c文件
#include "AD7995.h"
#include "delay.h"void AD7995_Init(){IIC_Init();}//初始化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 输出高
}
//产生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_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
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;
}
//不产生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++){ if((txd&0x80)>>7)IIC_SDA=1;elseIIC_SDA=0;txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0; }
}
//读2个字节,ack=1时,发送ACK,ack=0,发送nACK
u16 IIC_Read_Byte(unsigned char ack)
{unsigned char i;u16 receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;if(READ_SDA)receive|=1<<(15-i);delay_us(2); } IIC_Ack(); //发送ACK for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;if(READ_SDA)receive|=1<<(7-i);delay_us(2); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}//在AD7995指定地址读出一个数据
//ReadAddr:开始读数的地址
//返回值 :读到的数据
u16 AD7995_ReadOneByte(u8 ReadAddr)
{ u16 temp=0;ReadAddr=ReadAddr<<1|0x01; //读数据IIC_Start(); IIC_Send_Byte(ReadAddr);//发送地址IIC_Ack(); temp=IIC_Read_Byte(0); //0不继续转换 IIC_Stop();//产生一个停止条件 return temp;
}//在AD7995指定地址写入一个数据
//WriteAddr :写入数据的目的地址
//DataToWrite:要写入的数据
void AD7995_WriteOneByte(u8 WriteAddr,u8 DataToWrite)
{ WriteAddr=WriteAddr<<1; //写数据 IIC_Start(); IIC_Send_Byte(WriteAddr); //发送地址IIC_Ack(); IIC_Send_Byte(DataToWrite); //发送字节 IIC_Ack(); IIC_Stop();//产生一个停止条件 delay_ms(10);
}
AD7995.h文件
#ifndef __AD7995_H
#define __AD7995_H#include "stm32f10x.h"
#include "sys.h"#define AD7991_0 0x28
#define AD7991_1 0x29
#define AD7995_0 0x28
#define AD7995_1 0x29
#define AD7999_1 0x29//IO方向设置
#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 //IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u16 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信号void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr); //AD7995所有操作函数
void AD7995_Init();
u16 AD7995_ReadOneByte(u8 ReadAddr);
void AD7995_WriteOneByte(u8 WriteAddr,u8 DataToWrite);
#endif
STM32模拟IIC协议驱动AD7991/AD7995/AD7999芯片相关推荐
- STM32模拟SPI协议驱动AD7908芯片
最近时间,由于项目需求用到了AD7908的AD采集芯片,通过查阅其相关的技术手册之后,成功的实现了其AD采集的功能,下面分享一下我的一些经验. AD7908是一个8位高速.低功耗.8通道的ADC芯片, ...
- 【五一特刊】FPGA零基础学习:IIC协议驱动设计
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的"傻瓜式"讲解,让电子.信息.通信类专业学生.初入职场小白及打算进阶提升的职 ...
- STM32基于IIC协议的OLED模块的使用
前言 一.项目涉及的内容 项目简介 二.模块实操 1. IIC模块 1.1 IIC协议格式 1.2 开始信号与停止信号 1.3 写数据 1.3.1 硬件IIC代码编写 1.3.2 软件模拟IIC代码编 ...
- STM32模拟I2C协议获取MLX90615红外温度传感器测温数据(Open Drain管脚配置)
STM32模拟I2C协议获取MLX90615红外温度传感器测温数据(Open Drain管脚配置) STM32的GPIO管脚可以配置为Open Drain输出模式,并且有两个功能: 可以设置内部上拉, ...
- FPGA零基础学习:IIC协议驱动设计
FPGA零基础学习:IIC协议驱动设计 本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的"傻瓜式"讲解,让电子.信息.通信类 ...
- 使用STM32+硬件IIC+DMA驱动GT系列触摸屏(GT911)
使用STM32+硬件IIC+DMA驱动GT系列触摸屏(GT911) 初始化代码 /** @brief GT911 初始化程序* @param None* @retval None*/ void GT9 ...
- STM32模拟IIC驱动sht30温湿度传感器
最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了 所以拿出来分享给大家. sht30外观 驱动不是自己写的, 是采用CSDN上的一位朋友的 , ...
- STM32模拟IIC读取PCF8563
作者第一次开写博客,本着学习的态度,附上自己总结的代码,希望大家多多指点! 一.首先是对于PCF8563芯片的介绍与使用说明: PCF8563 是PHILIPS 公司推出的一款工业级内含I2C 总线接 ...
- STM32通过SPI协议驱动OLED屏
坚持就是胜利 一.SPI协议介绍 01 简介 02 SPI物理层 03 SPI基本通讯过程 二.OLED显示器介绍 01 简介 02 接口定义 03 与STM32接线图 三.汉字取模软件介绍 01 下 ...
最新文章
- React 的性能优化(一)当 PureComponent 遇上 ImmutableJS
- python invalid type promotion_17个新手常见Python运行时错误
- 屏蔽机房设计时需要注意什么 ?如何更好维护使用屏蔽机房?
- 【OS学习笔记】三十五 保护模式十:中断描述符表、中断门和陷阱门
- 网页字段位置php改变,php实现子字符串位置相互对调互换的方法
- python动态爬取知乎_python爬虫从小白到高手 Day2 动态页面的爬取
- 谈谈Intranet与Internet的区别和联系
- easyui datagrid java_java_easyui体系之DataGrid(4)[转]
- nginx配置和安装
- 人工智能数据集文本处理Onehot/TF/TFIDF矩阵的生成
- Android推送服务——百度云推送
- 3GPP 5G 常用协议规范下载整理
- 「js基础」JavaScript入门,难不难你来说
- 加州房价--决策树与随机森林
- 你的领英账号总被封?实战总结避免和解决领英帐号被封的最强攻略
- 想要创业,却没货源?答应我,别只在阿里妈妈上找了好吗
- 信息学奥赛一本通1336:寻找树根和孩子(图论算法-树)详细讲解
- js网页繁体简体转换(备忘)
- MATLAB新手简明使用教程(七)——使用matlab建立多项式以及求导,商求导乘积求导等——新手来看,保证看懂。
- Facade in Java
热门文章
- java毕业设计‘网上宠物店(附源码、数据库)
- 第五届双态IT乌镇用户大会-智能运维算法研讨会圆满落幕
- ERROR:Module not found: Error: Can‘t resolve ‘core-js/modules/es.promise.js‘ in ‘address‘
- 基于鸿蒙系统 + Hi3861 的wifi小车,可以通过电脑、手机控制
- 随缘php企业网站管理系统V2.0 shownews.php注入漏洞
- 【人脸识别实战二】服务器端设计与实现
- python 监控框架_httprunner+locusts+python接口测试框架
- jQuery--CSS样式操作及动画操作
- [个人心得]敏捷管理Agile中Epic, story 和task的用途和管理目标
- 【模式识别】最小风险贝叶斯决策