1.AD7799介绍

AD7799结构图如下所示:

其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示:

注意:

如果REG_CONFIG的REF_DET开启的话,那么输入AD值电压低于0.5V时,则差分输入ad值就无法检测了,如下图所示:

2.AD7799差分信号的输入模式

如下图所示,差分输入电压有3种模式:

注意:

单端输入电压(AIN-接地,只有正电压)则支持任意范围,比如In-Amp模式下,单端输入如果为10mv的话,也能检测到.

2.1 Unbuffered Mode非缓冲模式

该模式可测的AD值可以在 -30mV ~ (AVDD+30mv)范围之间,如果开了双极型模式(双极型模式通过将REG_CONFIG的U/B位设0实现),则也可以测-(AVDD+30mv)~30mV之间AD值.

也就是说假如我们要测的AD值位于-100mV~100mV之间,则用这个模式.

该模式优缺点:可测范围最大,但是精度误差不是很高

2.2 Buffered Mode缓冲模式

缓冲的作用就是减少测的AD误差,并且功耗相应地会增高点,该模式主要是测100mV~( AVDD-100mV)之间.

该模式优缺点:可测范围比Unbuffered小一点,并且精度误差高一点

2.3 In-Amp 高增益模式

需要将REG_CONFIG的Gain调到4及以上才是该模式,否则的话,就会根据REG_CONFIG的BUF位来自动判断是Buffered Mode还是Unbuffered Mode.

并且AD值必须位于300mv~(AVDD+1100mv)之间,否则的话该模式是无法检测AD值的,之前笔者就是测差分输入的正负20mV,却一直没有反应,后来才发现是处于这个模式的原因.

该模式优缺点:可测范围可以通过设置Gain来设置测试范围,比如VREF为3V,Gain=4,则可测量程为正负600mv.

注意:

当使用Buffered Mode或者In-Amp模式时,需要将REG_CONFIG的BO位开启,介绍如下图所示:

3.代码效果

串口截图如下:

通过电压发生器不停修改AD值时,可以看到万用表和串口打印的数据相差不大:

PS:由于GIF录制的像素位数太低,所以不清晰

4.代码实现

支持硬件SPI1或者GPIO模拟方式

代码通过宏AD7799_INTERFACE_MODE判断,能够支持硬件SPI1或者GPIO模拟方式,如下图所示:

通过宏定义VREF参考电压,以及GAIN增益值

如下图所示,只需修改下面宏,就可以实现转换电压数据自动转换:

实现通道1和通道2来回切换

串口发送select 1,表示选择通道1:

发送select 2,则表示选择通道2.

4.1初始化过程

     /*ad7799初始化*/AD7799_gpio_init();while(!AD7799_Init()){LED0 = !LED0;delay_ms(50);}      LED0 = 1;AD7799_Calibrate();                           //通道校准AD7799_SetGain(AD7799_CHIP_GAIN);               AD7799_SetBurnoutCurren(0);                  //关闭BOAD7799_SetBufMode(0);                        //由于我们要测的电压低于100mV,所以设置为Unbuffered ModeAD7799_SetChannel(ChannelBuf[0]);            //通道设置.AD7799_SetMode(AD7799_MODE_CONT,5);          //默认双极性   频率为5AD7799_SetReference(0);                      //关闭参考检测,因为我们的 AD7799_RefmV 参考电压低于0.5V

4.2 上面的函数如下所示:

void AD7799_gpio_init(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = AD_CS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(AD_CS_GPIO, &GPIO_InitStructure);                              //CS片选#if ( AD7799_INTERFACE_MODE == AD7799_INTERFACE_SPI1 )//spi1 modeSPI1_Init();SPI1_SetSpeed(SPI_BaudRatePrescaler_2);
#else//gpio模拟spi modeGPIO_InitStructure.GPIO_Pin = AD_DI_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(AD_DI_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = AD_SCK_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(AD_SCK_GPIO, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = AD_DO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;      GPIO_Init(AD_DO_GPIO, &GPIO_InitStructure);spi_AD7799_init();
#endif  AD7799_Reset();
}
void AD7799_SetGain(unsigned long gain)
{unsigned long command;command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);command &= ~AD7799_CONF_GAIN(0xFF);command |= AD7799_CONF_GAIN(gain);AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);
}void AD7799_SetBurnoutCurren(u8 enable)//设置BO
{unsigned long command;command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);command &= ~0X2000;if(enable)command |= 0X2000;AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);}void AD7799_SetBufMode(u8 enable)           //设置buf
{unsigned long command;command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);command &= ~0X10;
    if(enable)command |= 0X10;AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);
}void AD7799_SetChannel(unsigned long channel)
{unsigned long command;command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);command &= ~AD7799_CONF_CHAN(0xFF);command |= AD7799_CONF_CHAN(channel);AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);
}void AD7799_SetMode(unsigned long mode,u8  rate)
{unsigned long command;command = AD7799_GetRegisterValue(AD7799_REG_MODE,2);command &= ~AD7799_MODE_SEL(0xFF);command |= AD7799_MODE_SEL(mode);command &= 0XFFF0;command |= rate;                   //设置频率
AD7799_SetRegisterValue(AD7799_REG_MODE,command,2);
}
void AD7799_SetReference(unsigned char state)
{unsigned long command = 0;command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);command &= ~AD7799_CONF_REFDET(1);command |= AD7799_CONF_REFDET(state);AD7799_SetRegisterValue(AD7799_REG_CONF,  command, 2);}void AD7799_SetRegisterValue(unsigned char regAddress,unsigned long regValue,unsigned char size)
{unsigned char data[5] = {0x03, 0x00, 0x00, 0x00, 0x00};   data[0] = AD7799_COMM_WRITE |  AD7799_COMM_ADDR(regAddress);if(size == 1){data[1] = (unsigned char)regValue;}if(size == 2){data[2] = (unsigned char)((regValue & 0x0000FF) >> 0);data[1] = (unsigned char)((regValue & 0x00FF00) >> 8);}if(size == 3){data[3] = (unsigned char)((regValue & 0x0000FF) >> 0);data[2] = (unsigned char)((regValue & 0x00FF00) >> 8);data[1] = (unsigned char)((regValue & 0xFF0000) >> 16);}AD7799_CS_LOW;     SPI_Write(data,(1 + size));AD7799_CS_HIGH;
}unsigned long AD7799_GetRegisterValue(unsigned char regAddress, unsigned char size)
{unsigned char data[5] = {0x00, 0x00, 0x00, 0x00, 0x00};unsigned long receivedData = 0x00;    data[0] = AD7799_COMM_READ |  AD7799_COMM_ADDR(regAddress);AD7799_CS_LOW; SPI_Write(data,1);SPI_Read(data,size);AD7799_CS_HIGH;if(size == 1){receivedData += (data[0] << 0);}if(size == 2){receivedData += (data[0] << 8);receivedData += (data[1] << 0);}if(size == 3){receivedData += (data[0] << 16);receivedData += (data[1] << 8);receivedData += (data[2] << 0);}return receivedData;
}

4.3 获取通道电压代码如下所示:

      while(1){if(Serial_Post_ChannelValue!=0XFF)              //0:不选择   1~2:更改通道{CurrentChannelValue = Serial_Post_ChannelValue;Serial_Post_ChannelValue =0XFF;if(CurrentChannelValue && CurrentChannelValue<=2)        //1~2{AD7799_SetChannel(ChannelBuf[CurrentChannelValue-1]);//通道设置.          0~1delay_ms(10);AD7799_GetRegisterValue(AD7799_REG_DATA,3);//清空之前的AD}else if(CurrentChannelValue == 0){printf("%s value0 0 0 \r\n",Board_Name);}}if(CurrentChannelValue)                  //选择了通道?{for(i=0;i<2;i++)                 //获取每个通道数据if(CurrentChannelValue == (i+1)){while( !AD7799_Ready())                //1~2{delay_ms(5);}ADValues[i]=  analyzeAD7799_Data(AD7799_GetRegisterValue(AD7799_REG_DATA,3));}elseADValues[i] = 0.0000;    printf("%s 当前通道为:%d %.3fmV %.3fmV \r\n",Board_Name,CurrentChannelValue,ADValues[0],ADValues[1]);}      LED0 =!LED0;delay_ms(100);}

具体下载地址:https://download.csdn.net/download/qq_37997682/11240699

转载于:https://www.cnblogs.com/lifexy/p/11019237.html

STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI相关推荐

  1. 《STM32从零开始学习历程》——CAN通讯代码详解

    <STM32从零开始学习历程>@EnzoReventon CAN通讯代码详解 相关链接: <STM32从零开始学习历程>--CAN通讯协议物理层 CAN-bus规范 V2.0版 ...

  2. STM32循迹避障小车制作代码详解(简单实现版)

    感谢几年来大家的支持,看到大家对工程的呼声很高,所以来把工程上传了,大家自行下载即可哈,谢谢大家支持 这个代码是进阶版的,就是可以跑的很快的,和上面博客的主要区别就是这个代码的避障机制并不是做在主ma ...

  3. 【STM32】窗口看门狗 WWDG 实验代码详解

    文章目录 main.c wwdg.c wwdg.h main.c #include "led.h" #include "delay.h" #include &q ...

  4. 204B实战应用-LMK04821代码详解(二)

    204B实战应用-LMK04821代码详解(二) 一. SPI协议 通过阅读LMK04821数据手册,我们可以从中知道,可以通过SPI协议对LMK04821进行寄存器的配置工作,进而实现我们设计所需要 ...

  5. FPGA项目开发:204B实战应用-LMK04821代码详解(二)

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注FPGA技术江湖,在"闯荡江湖"."行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢. ...

  6. 【初篇】DHT11连接STM32、One wire单总线原理、GPIO代码详解

    目录 一.DHT11单总线原理 二.代码详解 三.代码 代码见文章末尾 一.DHT11单总线原理 DHT11温湿度传感器只需要一根线即可和MCU进行数据交换,无数据传输时,单线应为高电平状态,具体流程 ...

  7. 【genius_platform软件平台开发】第五十八讲:Linux系统之V4L2视频驱动-VIDIOC_REQBUFS向驱动申请帧缓冲代码详解

    VIDIOC_REQBUFS向驱动申请帧缓冲代码详解 1. 概述 2. 应用层 3. 内核驱动 3.1 vb2_ioctl_reqbufs函数 3.2 vb2_core_reqbufs函数 3.3 _ ...

  8. 基于RK3399ESP8285自动售货柜项目—MP08开发板端代码详解

    基于RK3399&ESP8285自动售货柜项目-②MP08开发板端代码详解 本系列文章将详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法,从硬件连接到网络通信再到软件实现,本 ...

  9. Linux驱动开发必看详解神秘内核(完全转载)

    Linux驱动开发必看详解神秘内核 完全转载-链接:http://blog.chinaunix.net/uid-21356596-id-1827434.html IT168 技术文档]在开始步入Lin ...

最新文章

  1. 如何防御潜在的破坏性DDoS攻击—Vecloud微云
  2. 深度学习核心技术精讲100篇(十一)-Google利器超强特征提取网络(Transformer)
  3. 科大星云诗社动态20201203
  4. DEKR 解构式人体关键点回归(二):标签分配(Label Assignment)
  5. 兼容性测试之VMware
  6. 知乎首次举办上星晚会 定档除夕前夜
  7. Mybatis配置信息浅析 MyBatis简介(二)
  8. 【three.js详解之一】入门篇
  9. linux下keepalived+nginx的负载均衡搭建
  10. wpf DoEvents
  11. Python实现截图AI文字识字小工具
  12. b类 蚂蚁金服_蚂蚁金服开放平台 - 文档中心
  13. 等保2.0详解(附3级检查表)
  14. 从IP138上获取数据,查询多个IP的归宿地
  15. 实现内网(局域网)控制所有电脑一键关机并且系统还原的方案
  16. 计算机词汇店名,有创意的店名大全
  17. Vivado® ML 版,让设计更智能化
  18. 小米嵌入式软件工程师笔试题目解析
  19. Restful API注解之@PathVariable和@JsonView详解
  20. solr分组查询、统计功能详解

热门文章

  1. 用python连接xmapp数据库
  2. 【小家java】java9新特性(简述十大新特性) 褒贬不一
  3. 安装黑群晖找不到局域网电脑_星际蜗牛安装黑群晖drive套件实现多台电脑文件实时同步...
  4. 毕业设计-基于SpringBoot就业管理系统
  5. Fiddler抓包工具基本操作-抓包APP篇
  6. IntelliJ IDEA中文插件
  7. OpenCV视频剪切
  8. 工业相机介绍及其与普通相机的区别
  9. 如何从电脑彻底清除mysql_如何彻底删除MYSQL
  10. Luogu P4707 重返现世