公司有一个项目用到了AD7606,控制器用的STM32,使用的模式是并行16位模式,程序刷好之后发现读取的AD数据乱码,结果发现是因为AD7606的接地不对,当然这个问题是我师傅找出来的,查找的过程如下:
用示波器看了BUSY线,转换线等各种线的波形,目的是确定芯片是否正常工作。
师傅又测量了V1通道两端的波形,在没有给输入的情况下发现存在波形。
后面师傅又去看了下手册,发现V1通道需要接AGND,基准电压接地脚同样要接AGND,但是在电路中,V1与V8通道与基准电压接地脚的地线都分开了,通道接到了24V地,基准接到了3V3,所以导致读取的数据乱码。
原因就是地线分开了。
#include "delay.h" //.C文件
#include "ad7606.h"
#include "dac.h"
void AD7606_reset(void);
void AD7606_startConv(void);
u16 AD7606_readFirstData(void);
/************************************************
函数名称 : AD7606_config
功 能 : 初始化AD7606引脚
参 数 : 无
返 回 值 : 无
*************************************************/
void AD7606_config(void)
{
GPIO_InitTypeDef GPIO_initStructure;
RCC_APB2PeriphClockCmd(AD7606_PORT_RCC,ENABLE); //开启AD7606引脚时钟
GPIO_initStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //16位数据端输入
GPIO_initStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_initStructure.GPIO_Pin = AD7606_DATA_PORT;
GPIO_Init(AD7606_DATA_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_FRST_PORT; //FRST引脚配置,浮空输入
GPIO_Init(AD7606_FRST_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_BUSY_PORT; //BUSY引脚,浮空输入
GPIO_Init(AD7606_BUSY_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出方式
GPIO_initStructure.GPIO_Pin = AD7606_RANGE_PORT; //RANGE配置
GPIO_Init(AD7606_RANGE_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_OS0_PORT; //过采样引脚配置
GPIO_Init(AD7606_OS0_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_OS1_PORT;
GPIO_Init(AD7606_OS1_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_OS2_PORT;
GPIO_Init(AD7606_OS2_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_CONAB_PORT; //转换配置
GPIO_Init(AD7606_CONAB_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_RST_PORT; //复位
GPIO_Init(AD7606_RST_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_RD_PORT; //RD
GPIO_Init(AD7606_RD_GPIOx,&GPIO_initStructure);
GPIO_initStructure.GPIO_Pin = AD7606_CS_PORT; //CS
GPIO_Init(AD7606_CS_GPIOx,&GPIO_initStructure);
AD7606_RANGE_10V();
AD7606_CS_HIGH();
AD7606_RST_LOW();
AD7606_RD_HIGH();
AD7606_CONAB_HIGH();
AD7606_SampleRate(AD7606_SAMPLE_200K);
}
/**
@brief 设置AD7606采样频率
@param -sampleRate- AD7606_SAMPLE_200K: 采样频率200kHz \n
AD7606_SAMPLE_100K: 采样频率100kHz \n
AD7606_SAMPLE_50K: 采样频率50kHz \n
AD7606_SAMPLE_25K: 采样频率25kHz \n
AD7606_SAMPLE_12K5: 采样频率12.5kHz \n
AD7606_SAMPLE_6K25: 采样频率6.25kHz \n
AD7606_SAMPLE_3K125:采样频率3.125kHz \n
*/
void AD7606_SampleRate(u8 sampleRate)
{
switch(sampleRate)
{
case AD7606_SAMPLE_200K: //采样频率200kHz
AD7606_OS0_LOW();
AD7606_OS1_LOW();
AD7606_OS2_LOW();
break;
case AD7606_SAMPLE_100K: //采样频率100kHz
AD7606_OS0_HIGH();
AD7606_OS1_LOW();
AD7606_OS2_LOW();
break;
case AD7606_SAMPLE_50K: //采样频率50kHz
AD7606_OS0_LOW();
AD7606_OS1_HIGH();
AD7606_OS2_LOW();
break;
case AD7606_SAMPLE_25K: //采样频率25kHz
AD7606_OS0_HIGH();
AD7606_OS1_HIGH();
AD7606_OS2_LOW();
break;
case AD7606_SAMPLE_12K5: //采样频率12.5kHz
AD7606_OS0_LOW();
AD7606_OS1_LOW();
AD7606_OS2_HIGH();
break;
case AD7606_SAMPLE_6K25: //采样频率6.25kHz
AD7606_OS0_HIGH();
AD7606_OS1_LOW();
AD7606_OS2_HIGH();
break;
case AD7606_SAMPLE_3K125: //采样频率3.125kHz
AD7606_OS0_LOW();
AD7606_OS1_HIGH();
AD7606_OS2_HIGH();
break;
default:
AD7606_OS0_LOW(); //采样频率200kHz
AD7606_OS1_LOW();
AD7606_OS2_LOW();
break;
}
}
/**
@brief AD7606读取转换值
@param -data- 8个16位元素的数组,用来存储8通道转换值。参数为数组首地址。
@return 0: 转换成功 \n
其他值: 转换失败
@warning data数组的长度必须大于等于8
*/
u8 AD7606_readConversionValue(u16 *data)
{
u8 i;
u16 counter;
static uint8_t a=1;
GPIO_InitTypeDef GPIO_initStructure;
GPIO_initStructure.GPIO_Mode = GPIO_Mode_IPU; //AD7606数据输出端引脚配置,上拉输入模式
GPIO_initStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_initStructure.GPIO_Pin = AD7606_DATA_PORT;
GPIO_Init(AD7606_DATA_GPIOx,&GPIO_initStructure);
AD7606_CS_RD_HIGH(); //CS\RD引脚配置为高电平
if(a==1)
{
a=0;
AD7606_reset(); //复位信号
}
i = AD7606_BUSY_STATE(); //判断BUSY
AD7606_startConv(); //转换信号
counter = 0;
i = AD7606_BUSY_STATE(); //判断BUSY
while(i)
{
i = AD7606_BUSY_STATE(); //判断BUSY
//delay_us(0);
counter ++;
if(counter > 50000) //判断超时
return 1;
}
AD7606_CS_LOW(); //CS拉低
i = AD7606_FRST_STATE(); //判断FRST
AD7606_RD_HIGH(); //RD下降沿,V1通道开始转换
delay_us(1);
AD7606_RD_LOW();
delay_us(2);
counter = 0;
i = AD7606_FRST_STATE(); //判断FRST
while(!i)
{
//delay_us(1);
i = AD7606_FRST_STATE(); //判断FRST
counter ++;
if(counter > 50000) //判断超时
return 2;
}
data[0] = AD7606_READ_DATA(); //V1通道数据传入data中
AD7606_RD_HIGH(); //---------AD7606_RD_HIGH
for(i=1;i<=7;i++)
{
delay_us(2);
AD7606_RD_LOW(); //RD下降沿数据转换完
delay_us(2);
data[i] = AD7606_READ_DATA(); //读取数据
//data[i] = ((data[i] & 0xff) << 8) + (data[i] >> 8);
// data[i] = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_15) |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_14) << 1 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_13) << 2 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12) << 3 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) << 4 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_10) << 5 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_9) << 6 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_8) << 7 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7) << 8 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6) << 9 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_5) << 10 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_4) << 11 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_3) << 12 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2) << 13 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1) << 14 |
// GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_0) << 15;
delay_us(2);
AD7606_RD_HIGH(); //--------
}
AD7606_CS_HIGH();
AD7606_CONAB_HIGH(); //用于判定
return 0;
}
/************************************************
函数名称 : AD7606_reset
功 能 : 复位AD7606
参 数 : 无
返 回 值 : 无
*************************************************/
void AD7606_reset(void)
{
AD7606_RST_HIGH();
delay_us(1);
AD7606_RST_LOW();
delay_us(1);
}
/************************************************
函数名称 : AD7606_startConv
功 能 : 转换信号
参 数 : 无
返 回 值 : 无
*************************************************/
void AD7606_startConv(void)
{
AD7606_CONAB_HIGH();
delay_us (2);
AD7606_CONAB_LOW();
delay_us(2);
AD7606_CONAB_HIGH();
//delay_us(1);
}
#ifndef _AD7606_H_
#define _AD7606_H_
#include "stm32f10x.h"
#define AD7606_PORT_RCC RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB //时钟引脚
#define AD7606_DATA_GPIOx GPIOD //数据引脚
#define AD7606_DATA_PORT GPIO_Pin_All
#define AD7606_FRST_GPIOx GPIOB //FRST
#define AD7606_FRST_PORT GPIO_Pin_3
#define AD7606_BUSY_GPIOx GPIOB //BUSY
#define AD7606_BUSY_PORT GPIO_Pin_4
#define AD7606_RANGE_GPIOx GPIOB //RANGE
#define AD7606_RANGE_PORT GPIO_Pin_8
#define AD7606_OS0_GPIOx GPIOB //OS0
#define AD7606_OS0_PORT GPIO_Pin_2
#define AD7606_OS1_GPIOx GPIOB //OS1
#define AD7606_OS1_PORT GPIO_Pin_1
#define AD7606_OS2_GPIOx GPIOB //OS2
#define AD7606_OS2_PORT GPIO_Pin_0
#define AD7606_CONAB_GPIOx GPIOB //CONAB
#define AD7606_CONAB_PORT GPIO_Pin_9
#define AD7606_RST_GPIOx GPIOB //RST
#define AD7606_RST_PORT GPIO_Pin_7
#define AD7606_RD_GPIOx GPIOB //RD
#define AD7606_RD_PORT GPIO_Pin_6
#define AD7606_CS_GPIOx GPIOB //CS
#define AD7606_CS_PORT GPIO_Pin_5
#define AD7606_CS_HIGH() GPIO_SetBits(AD7606_CS_GPIOx,AD7606_CS_PORT) //CS高电平
#define AD7606_CS_LOW() GPIO_ResetBits(AD7606_CS_GPIOx,AD7606_CS_PORT) //CS低电平
#define AD7606_RST_HIGH() GPIO_SetBits(AD7606_RST_GPIOx,AD7606_RST_PORT) //RST高
#define AD7606_RST_LOW() GPIO_ResetBits(AD7606_RST_GPIOx,AD7606_RST_PORT) //RST低
#define AD7606_RD_HIGH() GPIO_SetBits(AD7606_RD_GPIOx,AD7606_RD_PORT)
#define AD7606_RD_LOW() GPIO_ResetBits(AD7606_RD_GPIOx,AD7606_RD_PORT)
#define AD7606_RANGE_10V() GPIO_SetBits(AD7606_RANGE_GPIOx,AD7606_RANGE_PORT) //范围正负10
#define AD7606_RANGE_5V() GPIO_ResetBits(AD7606_RANGE_GPIOx,AD7606_RANGE_PORT) //5V
/*******转换信号*****************************************/
#define AD7606_START_CONV() do{GPIO_SetBits(AD7606_CONAB_GPIOx,AD7606_CONAB_PORT);\
GPIO_ResetBits(AD7606_CONAB_GPIOx,AD7606_CONAB_PORT);\
delay_us(1);\
GPIO_SetBits(AD7606_CONAB_GPIOx,AD7606_CONAB_PORT);}while(0)
#define AD7606_OS0_HIGH() GPIO_SetBits(AD7606_OS0_GPIOx,AD7606_OS0_PORT) //过采样
#define AD7606_OS0_LOW() GPIO_ResetBits(AD7606_OS0_GPIOx,AD7606_OS0_PORT)
#define AD7606_OS1_HIGH() GPIO_SetBits(AD7606_OS1_GPIOx,AD7606_OS1_PORT)
#define AD7606_OS1_LOW() GPIO_ResetBits(AD7606_OS1_GPIOx,AD7606_OS1_PORT)
#define AD7606_OS2_HIGH() GPIO_SetBits(AD7606_OS2_GPIOx,AD7606_OS2_PORT)
#define AD7606_OS2_LOW() GPIO_ResetBits(AD7606_OS2_GPIOx,AD7606_OS2_PORT)
#define AD7606_CONAB_HIGH() GPIO_SetBits(AD7606_CONAB_GPIOx,AD7606_CONAB_PORT) //转换
#define AD7606_CONAB_LOW() GPIO_ResetBits(AD7606_CONAB_GPIOx,AD7606_CONAB_PORT)
#define AD7606_READ_DATA() GPIO_ReadInputData(AD7606_DATA_GPIOx)
#define AD7606_BUSY_STATE() GPIO_ReadInputDataBit(AD7606_BUSY_GPIOx,AD7606_BUSY_PORT)
#define AD7606_FRST_STATE() GPIO_ReadInputDataBit(AD7606_FRST_GPIOx,AD7606_FRST_PORT)
#define AD7606_CS_RD_LOW() AD7606_CS_LOW();AD7606_RD_LOW()
#define AD7606_CS_RD_HIGH() AD7606_CS_HIGH();AD7606_RD_HIGH()
#define AD7606_SAMPLE_200K 0 //过采样200K
#define AD7606_SAMPLE_100K 1 //过采样100K
#define AD7606_SAMPLE_50K 2 //过采样50K
#define AD7606_SAMPLE_25K 3 //过采样25K
#define AD7606_SAMPLE_12K5 4 //过采样12.5K
#define AD7606_SAMPLE_6K25 5 //过采样6.25K
#define AD7606_SAMPLE_3K125 6 //过采样3.125K
#define AD7606_VOLT_0V5 1638
#define AD7606_VOLT_3V3 10813
#define AD7606_VOLT_3V5 11469
void AD7606_config(void); //AD7606初始化
void AD7606_SampleRate(u8 sampleRate);
u8 AD7606_readConversionValue(u16 *data); //数据读取函数
#define AD7606_1LSB_VOLT 0.00030518 //最小精度
#endif