|
AD7747是一款高分辨率、Σ-Δ型电容数字转换器(CDC)。要测量的电容可直接连接到器件输入端。该架构还具有高分辨率(24-bit无失码、最高19.5-bit有效分辨率)、高线性度(±0.01%)和高精度(±10 fF工厂校准)等固有特性。AD7747的电容输入范围是±8 pF(可变),而且可接受最大17 pF共模电容(不可变),后者可以通过一个可编程片内数字电容转换器(CAPDAC)来平衡。
代码使用MSP430FR5969测试,软件I2C,方便移植
因为官方只提供了AD7746测试代码,寄存器有些不同,引用了它的头文件并做修改
实际使用时遇到一个问题,我使用的软件模拟I2C在读取数据时写头SLV_ID,写SUB_ADDR后执行发停止位,然后重新发送SLV_ID读取当前地址的寄存器值,这是一个错误的写法,在以往的I2C传感器测试中没有出现过问题,原因应该是其它器件在收到停止位时并不会将寄存器重新指向零,而AD7747不同,如果发送停止位,寄存器会指针会移到0,再次执行读取时实际上是从零开始读取,后来将中间的停止位去掉后解决。
另外一个需要注意的是,为了保证数据的准确性,在启动连续转换模式时
一定要从数据输出寄存器的起始地址连续读取3个字节
如果分3次读取CAP_H,CAP_M,CAP_L这三个寄存器,可能会导致读取到的3个数据没有同步更新
比如刚读取了第一次转换的24位数据的高8位CAP_H后,如果间隔过长或者正好第二次数据转换完成后更新了输出寄存器
这时再读取CAP_M和CAP_L则对应了第2组24位数据的低16位
测试数据
- /*******************************************************************************
- * Copyright (C), 2017, littleshrimp(虾扯蛋)
- * FileName: main.c
- * Author: littleshrimp
- * Version : 1.0
- * Date: 2017-09-24 21:46
- * Description:
- * Function List: //
- * 1. -------
- * History:
- * <author> <time> <version > <desc>
- * littleshrimp 2017-09-24 21:46 build this moudle
- ******************************************************************************/
- /*
- MSP430FR5969
- -----------------
- | P2.0/UCA0TXD|----> PC
- | |
- | |
- | P2.1/UCA0RXD|<---- PC
- | |
- SCL --o--|P3.5 |
- | |
- SDA --o--|P3.6 |
- */
- /*******************************************************************************
- * * INCLUDES
- * */
- #include "msp430.h"
- #include <stdio.h>
- #include <math.h>
- #include <stdint.h>
- #include "uart.h"
- #include "soft_i2c.h"
- #include "timer.h"
- /*******************************************************************************
- * * MACROS
- * */
- /*******************************************************************************
- * * CONSTANTS
- * */
- /* AD7746 Slave Address */
- #define AD7746_ADDRESS 0x48
- /* AD7746 Slave Address */
- #define AD7746_RESET_CMD 0xBF
- /* AD7746 Register Definition */
- #define AD7746_REG_STATUS 0
- #define AD7746_REG_CAP_DATA_HIGH 1
- #define AD7746_REG_CAP_DATA_MID 2
- #define AD7746_REG_CAP_DATA_LOW 3
- #define AD7746_REG_VT_DATA_HIGH 4
- #define AD7746_REG_VT_DATA_MID 5
- #define AD7746_REG_VT_DATA_LOW 6
- #define AD7746_REG_CAP_SETUP 7
- #define AD7746_REG_VT_SETUP 8
- #define AD7746_REG_EXC_SETUP 9
- #define AD7746_REG_CFG 10
- #define AD7746_REG_CAPDACA 11
- #define AD7746_REG_CAPDACB 12
- #define AD7746_REG_CAP_OFFH 13
- #define AD7746_REG_CAP_OFFL 14
- #define AD7746_REG_CAP_GAINH 15
- #define AD7746_REG_CAP_GAINL 16
- #define AD7746_REG_VOLT_GAINH 17
- #define AD7746_REG_VOLT_GAINL 18
- /* AD7746_REG_STATUS bits */
- #define AD7746_STATUS_RDY (1 << 2)
- #define AD7746_STATUS_RDYVT (1 << 1)
- #define AD7746_STATUS_RDYCAP (1 << 0)
- /* AD7746_REG_CAP_SETUP bits */
- #define AD7746_CAPSETUP_CAPEN (1 << 7)
- #define AD7746_CAPSETUP_CAPDIFF (1 << 5)
- /* AD7746_REG_VT_SETUP bits */
- #define AD7746_VTSETUP_VTEN (1 << 7)
- #define AD7746_VTSETUP_VTMD_INT_TEMP (0 << 5)
- #define AD7746_VTSETUP_VTMD_EXT_TEMP (1 << 5)
- #define AD7746_VTSETUP_VTMD_VDD_MON (2 << 5)
- #define AD7746_VTSETUP_VTMD_EXT_VIN (3 << 5)
- #define AD7746_VTSETUP_EXTREF (1 << 4)
- #define AD7746_VTSETUP_VTSHORT (1 << 1)
- #define AD7746_VTSETUP_VTCHOP (1 << 0)
- /* AD7746_REG_EXC_SETUP bits */
- #define AD7746_EXCSETUP_EXCDAC (1 << 3)
- #define AD7746_EXCSETUP_EXCEN (1 << 2)
- #define AD7746_EXCSETUP_EXCLVL_VDD_8 (0 << 0)
- #define AD7746_EXCSETUP_EXCLVL_VDD_4 (1 << 0)
- #define AD7746_EXCSETUP_EXCLVL_VDD_3_8 (2 << 0)
- #define AD7746_EXCSETUP_EXCLVL_VDD_2 (3 << 0)
- /* AD7746_REG_CFG bits */
- #define AD7746_CONF_VTFS(x) (((x) & 0x3) << 6)
- #define AD7746_CONF_CAPFS(x) (((x) & 0x7) << 3)
- #define AD7746_CONF_MODE_IDLE (0 << 0)
- #define AD7746_CONF_MODE_CONT_CONV (1 << 0)
- #define AD7746_CONF_MODE_SINGLE_CONV (2 << 0)
- #define AD7746_CONF_MODE_PWRDN (3 << 0)
- #define AD7746_CONF_MODE_OFFS_CAL (5 << 0)
- #define AD7746_CONF_MODE_GAIN_CAL (6 << 0)
- /* AD7746_REG_CAPDACx bits */
- #define AD7746_CAPDAC_DACEN (1 << 7)
- #define AD7746_CAPDAC_DACP(x) ((x) & 0x7F)
- /*******************************************************************************
- * * TYPEDEFS
- * */
- /*******************************************************************************
- * * GLOBAL VARIABLES
- * */
- /*******************************************************************************
- * * EXTERNAL VARIABLES
- * */
- /*******************************************************************************
- * * EXTERNAL FUNCTIONS
- * */
- /*******************************************************************************
- * * LOCAL VARIABLES
- * */
-
- uint8_t txBuf[40];
- uint8_t rxBuf[40];
- float cap,vt;
- /*******************************************************************************
- * * PROFILE CALLBACKS
- * */
- /*******************************************************************************
- * * LOCAL FUNCTIONS
- * */
- void dco_init(void);
- /*******************************************************************************
- * * PUBLIC FUNCTIONS
- * */
- void delay(int32_t d)
- {
- while(d--)
- {
- __delay_cycles(1000);
- }
- }
- void AD7746_Reset(void)
- {
- uint8_t cmd = 0;
-
- cmd = AD7746_RESET_CMD;
- i2c_write_n_byte(AD7746_ADDRESS << 1,cmd,txBuf,0);
- }
- void AD7747_Init(void)
- {
- AD7746_Reset();
- delay_ms(6000);
- //AD7746_REG_VT_SETUP
- txBuf[0] = AD7746_CAPSETUP_CAPEN | AD7746_CAPSETUP_CAPDIFF;
- //AD7746_REG_VT_SETUP
- txBuf[1] = AD7746_VTSETUP_VTEN | AD7746_VTSETUP_VTMD_INT_TEMP| AD7746_VTSETUP_VTCHOP;
- //AD7746_REG_EXC_SETUP
- txBuf[2] = AD7746_EXCSETUP_EXCDAC | AD7746_EXCSETUP_EXCEN | AD7746_EXCSETUP_EXCLVL_VDD_3_8 ;
- //AD7746_REG_CFG
- txBuf[3] = AD7746_CONF_MODE_CONT_CONV;
- //AD7746_REG_CAPDACA
- txBuf[4] = AD7746_CAPDAC_DACEN | AD7746_CAPDAC_DACP(0x00);
- //AD7746_REG_CAPDACB
- txBuf[5] = AD7746_CAPDAC_DACEN | AD7746_CAPDAC_DACP(0x00);
- //
- i2c_write_n_byte(AD7746_ADDRESS << 1,AD7746_REG_CAP_SETUP, txBuf,6);
- }
- float AD7747_GetVT(void)
- {
- uint32_t temp;
- rxBuf[0] = AD7746_STATUS_RDYVT;
- while(!(rxBuf[0] & AD7746_STATUS_RDYVT))
- {
- i2c_read_n_byte(AD7746_ADDRESS << 1,AD7746_REG_STATUS,rxBuf,1);
- }
- i2c_read_n_byte(AD7746_ADDRESS << 1,AD7746_REG_VT_DATA_HIGH,rxBuf,3);
- temp = ((uint32_t)rxBuf[0] << 16) + ((uint32_t)rxBuf[1] << 8) + rxBuf[0];
- return (float)temp / 2048.00 - 4096.00;
- }
- float AD7747_GetCAP(void)
- {
- int32_t capData = AD7746_STATUS_RDYCAP;
-
- rxBuf[0] = 0;
- while(!(rxBuf[0] & AD7746_STATUS_RDYCAP))
- {
- i2c_read_n_byte(AD7746_ADDRESS << 1,AD7746_REG_STATUS,rxBuf,1);
- }
- i2c_read_n_byte(AD7746_ADDRESS << 1,AD7746_REG_CAP_DATA_HIGH,rxBuf,3);
- capData = ((uint32_t)rxBuf[0] << 16) + ((uint32_t)rxBuf[1] << 8) + rxBuf[0];
- capData -= 8388607;
- return (float)capData / 8388607.00 * 8.192;
- }
- int main( void )
- {
- char outBuf[64];//base64缓存
- WDTCTL = WDTPW + WDTHOLD;//停止看门狗
- PM5CTL0 &= ~LOCKLPM5;//这个是一定要加的,不然GPIO不能使用
- dco_init();
- i2c_init();//初始化I2C
- AD7747_Init();
- uart_init();
- while(1)
- {
- vt = AD7747_GetVT();
- cap = AD7747_GetCAP();
- sprintf(outBuf,"%.6f\t%.2f",cap,vt);
- uart_tx_string(outBuf);//输出到PC
- uart_tx_string("\r\n");//换行
- delay(1000);
- }
- }
- void dco_init(void)
- {
- // Configure one FRAM waitstate as required by the device datasheet for MCLK
- // operation beyond 8MHz _before_ configuring the clock system.
- FRCTL0 = FRCTLPW | NWAITS_1;
- // Clock System Setup
- CSCTL0_H = CSKEY >> 8; // Unlock CS registers
- CSCTL1 = DCORSEL | DCOFSEL_4; // Set DCO to 16MHz
- CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set SMCLK = MCLK = DCO,
- // ACLK = VLOCLK
- CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers
- CSCTL0_H = 0; // Lock CS registers
- }
复制代码
1.msp430fr5969 soft i2c AD7747.rar
(18.03 KB, 下载次数: 171)
|
|