AD7705电路与程序设计

详细资料参考ADI官方资料

ADI官网:http://www.analog.com/cn/

AD7705原理图和PCB可以参考ADI官方的Evaluation Board:http://www.analog.com/media/en/technical-documentation/evaluation-documentation/140293408AD7705_06.pdf

电路部分

    官方给出的电路原理图和PCB是通过并口与计算机通信的,因此需要把与并口通信相关的电路去掉,下图是经过修改后的原理图


实物图(做的很丑)


STM32程序

1、选用的是STM32F407ZET6的开发板

2、使用I/O模拟SPI通信

3、参考AD7705芯片手册对寄存器的介绍,将其大部分功能写入了 AD7705.H

4、已将部分功能写进类中,部分类成员函数为空函数,现有的函数能够完成寄存器写入和读取的操作。

5、下一步计划是将函数再进行封装,将AD7705的所有功能实现

SPI.cpp

#include "project.h"

// SCLK PC10
// CS       PC12
// RES     PD1
// DOUT PD3   receive
// DIN     PD5
// DRDY  PD7  receive

void GPIO_SPI_Init()
{
    GPIO_InitTypeDef  GPIO_InitStructure;
        
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);     //使能PD端口时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_5;//PD 1,5推挽输出  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOD 1 5
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12;//PC 10,12推挽输出
    GPIO_Init(GPIOC,&GPIO_InitStructure);//初始化GPIOG
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_7;//PD 3 7 输入
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
    GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIOD 3 7
    
    RES = 1;
    SCLK = 1;
    CS = 0;
}

AD_Resgister::AD_Resgister()
{
//Register
    Commu_Register=0;
    Setup_Register=0;
    Clock_Register=0;

//Data
    Data_Receive=0;
    
    CS=0;//chip select AD board
}

//Initialize
void AD_Resgister::AD_Init()
{
    Commu_Register=0;
    SPI_Write(Commu_Register | Reg_Setup);
    SPI_Write(Setup_Register);
    
    Commu_Register=0;
    SPI_Write(Commu_Register | Reg_Clock);
    SPI_Write(Clock_Register);
}

//Register
void AD_Resgister::Communication()//Read and write
{
    Commu_Register |= Read;
    SPI_Write(Commu_Register);
    SPI_Read(bits_8);
    Data_Receive=0;
}

void AD_Resgister::Setup(u8 reg_setup)//Only write
{
    Commu_Register &= 0x87;      //clear RS2 RS1 RS0 R/W
    Commu_Register |= Reg_Setup; //RS2 RS1 RS0
    Commu_Register |= Write;     //R/W
    
    Setup_Register = reg_setup;
    
    SPI_Write(Commu_Register);
    SPI_Write(Setup_Register);
}

void AD_Resgister::Clock(u8 reg_setup)//Only write
{
    Commu_Register &= 0x87;      //clear RS2 RS1 RS0 R/W
    Commu_Register |= Reg_Clock; //RS2 RS1 RS0
    Commu_Register |= Write;     //R/W
    
    Clock_Register = reg_setup;
    
    SPI_Write(Commu_Register);
    SPI_Write(Clock_Register);
}
    
void AD_Resgister::Data()//Only read
{
    Commu_Register &= 0x87;     //clear RS2 RS1 RS0 R/W
    Commu_Register |= Reg_Data; //RS2 RS1 RS0
    Commu_Register |= Read;     //R/W
    
    SPI_Write(Commu_Register);
    SPI_Read(bits_16);
}

//hardly use
void AD_Resgister::Test()//Only read
{}

void AD_Resgister::Offset()//Offset register
{}

void AD_Resgister::Gain()//Gain register
{}

//ad operation
void AD_Resgister::Reset_AD()//Reset AD7705
{
    RES = 0;
    delay_us(5);
    RES = 1;
    delay_us(500);
}

void AD_Resgister::Default_AD()
{
    u8 i=32;
    DIN = 1;
    for(;i>0;i--)
    {
        SCLK = 0;
        delay_us(1);
        SCLK = 1;
        delay_us(1);
    }
    delay_us(500);
}

//SPI operation
void AD_Resgister::SPI_Write(u8 ad_register)
{
    u8 i = 0;
    u8 temp = 0x01<<7;
    for(;i<8;i++)
    {    
        if((temp & ad_register) == 0)
            DIN = 0;
        else
            DIN = 1;
        temp = temp>>1;
        
        SCLK=0;
        delay_us(1);
        SCLK = 1;
        delay_us(1);
    }
}

void AD_Resgister::SPI_Read(u8 register_bits)
{
    u8 i = 0;
    Data_Receive = 0;
    for(;i<register_bits;i++)
    {
        SCLK = 0;
        delay_us(1);
        SCLK = 1;
        delay_us(1);
        if(DOUT == 0)
            Data_Receive = Data_Receive<<1;
        else
        {
            Data_Receive = Data_Receive<<1;
            Data_Receive += 0x01;
        }
    }
}

SPI.h

#ifndef _SPI_H
#define _SPI_H

extern "C"{
void GPIO_SPI_Init(void);//Init GPIO
}

#define u8 unsigned char
#define u32 unsigned int

class AD_Resgister
{
public:
//Register
    u8 Commu_Register;
    u8 Setup_Register;
    u8 Clock_Register;

//Data
    u32 Data_Receive;

//structure function
    AD_Resgister(void);

//Initialize
    void AD_Init(void);

//Register
    void Communication(void);//Read and write
    void Setup(u8 reg_setup);//Only write
    void Clock(u8 reg_clock);//Only write
    void Data(void);//Only read
    void Test(void);//Only read

//hardly use
    void Offset(void);//Offset register
    void Gain(void);//Gain register

//ad operation
    void Reset_AD(void);
    void Default_AD(void);

//SPI operation
    void SPI_Write(u8 ad_register);
    void SPI_Read(u8 register_bits);
};

#endif

AD7705.H   里面是和AD7705寄存器相关的宏定义

#ifndef _AD7705_H
#define _AD7705_H

//refer to datasheet page 16 to 37

//register bits
#define bits_8  8
#define bits_16 16
#define bits_24 24

//define GPIO
#define SCLK PCout(10)
#define CS     PCout(12)
#define RES  PDout(1)
#define DOUT PDin(3)
#define DIN  PDout(5)
#define DRDY PDin(7)

/******************Communication Register******************/

/*
 | 0/DRDY |   RS2  |   RS1  |   RS0  |   R/W  |  STBY  |   CH1  |   CH0  |
 |       7      |      6   |     5    |     4    |     3     |      2    |     1     |    0      |
*/


//register selection  RS2 RS1 RS0
#define Reg_Com    0x00<<4 //8bits register
#define Reg_Setup  0x01<<4 //8bits register
#define Reg_Clock  0x02<<4 //8bits register
#define Reg_Data   0x03<<4 //16bits register
#define Reg_Test   0x04<<4 //8bits register
#define Reg_OffSet 0x06<<4 //24bits register
#define Reg_Gain   0x07<<4 //24bitss register

//read or write  R/W
#define Read  1<<3
#define Write 0<<3

//standby or normal  STBY
#define Normal  0<<2
#define Standby 1<<2

//channel select CH1 CH0
#define CH1_difference 0x00
#define CH2_difference 0x01
#define CH1_AIN1_N     0x02
#define CH_AIN_N       0x03

/******************Setup Register******************/

/*
 |   MD1  |   MD0  |   G 2  |   G 1  |   G 0  |   B/U  |   BUF  |  FSYNC |
 |    7       |    6       |    5    |    4    |    3     |    2      |    1     |      0      |
*/

//Operating mode  MD1 MD0
#define Mode_Normal      0x00<<6
#define Self_Calinration 0x01<<6
#define Zero_Scale       0x02<<6
#define Full_Scale       0x03<<6

//gain select  G2 G1 G0
#define Gain_1   0x00<<3
#define Gain_2   0x01<<3
#define Gain_4   0x02<<3
#define Gain_8   0x03<<3
#define Gain_16  0x04<<3
#define Gain_32  0x05<<3
#define Gain_64  0x06<<3
#define Gain_128 0x07<<3

//Bipolar/Unipolar Operation B/U
#define Bipolar  0<<2
#define Unipolar 1<<2

//Filter Sync
#define Filter_On  0
#define Filter_OFF 1

/******************Clock Register******************/

/*
 |  ZERO  |  ZERO  |  ZERO  | CLKDIS | CLKDIV |   CLK  |   FS1  |   FS0  |
 |      7     |     6      |      5     |     4      |      3      |     2    |     1    |     0    |
*/

//clock devide   CLKDIV
#define CLKDIV_0 0<<3  //internal clock equal to crystal oscillator
#define CLKDIV_1 1<<3  //internal clock equal to half crystal oscillator

//XALT determined CLK register  CLK
#ifndef XALT_Lowspeed
    #define CLK 1<<2
#else
    #define CLK 0<<2
#endif

//output update rate (HZ) FS1 FS0
#if CLK==1<<2
    #define Rate_50  0x00
    #define Rate_60  0x01
    #define Rate_250 0x02
    #define Rate_500 0x03
#else
    #define Rate_20  0x00
    #define Rate_25  0x01
    #define Rate_100 0x02
    #define Rate_200 0x03
#endif

#endif

main.cpp

#include "project.h"

AD_Resgister AD_7705;
u32 AD_average = 0;
u8 Receive = 0; //TIM3 IRQ flag

int main()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//Set system exit priority group 2
    uart_init(115200);//Set serial bound 115200
    delay_init(168);
    LED_Init();
    GPIO_SPI_Init();
    
    LED0=1;
    LED1=0;
    
    //Reset AD7705
    AD_7705.Reset_AD();
    
    //AD Initialization
    AD_7705.AD_Init();
    
    //Communication register configure
    AD_7705.Commu_Register = CH1_difference;//channel 1 difference input
    AD_7705.Communication();
    
    //Setup register configure
    AD_7705.Setup( Mode_Normal | Gain_1 | Bipolar | Filter_On );
    
    //Clock register configure
    AD_7705.Clock( CLKDIV_1 | CLK | Rate_60 );
    
    //Wait AD7705 500us
    delay_us(500);
    
    //Read data
    AD_7705.Data();
    AD_average = AD_7705.Data_Receive;
    TIM3_Init();
    while(1)
    {
        if(Receive)
        {
            printf("AD  \n");
            printf("%d\n",AD_average);
            Receive = 0;
        }
    }
}

TIM3.c

#include "project.h"
extern AD_Resgister AD_7705;
extern u32 AD_average;
extern u8 Receive;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

extern "C"{
void TIM3_Init(void)
{
    /* -----------------------------------------------------------------------

    default SystemInit
    {
    APB1 clock Prescaler=4,APB1_Frequence=42M
    TIM2~TIM7、TIM12~TIM14 Frequence=2*APB1_Frequence=84M
    TIMx_CLK=84M

    APB2 clock Prescaler=2,APB2_Frequence=84M
    TIM1、TIM8~TIM11 Frequence=2*APB2_Frequence=168M
    TIMx_CLK=168M

    }
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles.

    In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1),
    since APB1 prescaler is different from 1.
    TIM3CLK = 2 * PCLK1
    PCLK1 = HCLK / 4
    => TIM3CLK = HCLK / 2 = SystemCoreClock /2

    To get TIM3 counter clock at 21 MHz, the prescaler is computed as follows:
    Prescaler = (TIM3CLK / TIM3 counter clock) - 1
    Prescaler = ((SystemCoreClock /2) /21 MHz) - 1

    To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows:
    ARR = (TIM3 counter clock / TIM3 output clock) - 1 = 665

    ----------------------------------------------------------------------- */
    //PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1;
    
    uint16_t TIM3_Counter_CLK = 1;//Set TIM3 CLK MHz
    uint16_t TIM3_Output_CLK = 60;//Set TIM3 clock Hz
    uint32_t TIM3_Period = ((TIM3_Counter_CLK * 1000000) / TIM3_Output_CLK) - 1;
    uint16_t PrescalerValue = (uint16_t)((SystemCoreClock / 2) / (TIM3_Counter_CLK * 1000000)) - 1;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //Enable TIM3 clock
    
  TIM_TimeBaseStructure.TIM_Period = TIM3_Period;     //Set period 0~65535
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;  //Clock division
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //Count up mode
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
    
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //Enable TIM3 interrupt
    TIM_Cmd(TIM3,ENABLE); //Enable TIM3
    
    NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
    {
            AD_7705.Data();
            AD_average = AD_7705.Data_Receive;
            Receive=1;
            LED0=~LED0;
            LED1=~LED1;
    }
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //clear interrupt flag
}
}

猜你喜欢

转载自blog.csdn.net/qq_33499752/article/details/80077931