使用STM32-SPI1控制AD7705 Sigma-Delta ADC芯片

STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)

  • 原理图
  • 手册说明
  • 功能方框图
  • 引脚功能
  • 片内寄存器
  • 通信寄存器(RS2、RS1、RS0=0、0、0)
  • 设置寄存器
  • 时钟寄存器
  • 数据寄存器(RS2、RS1、RS0=0、1、1)
  • 测试寄存器(RS2、RS1、RS0=1、0、0);上电/复位状态:00Hex
  • 零标度校准寄存器(RS2、RS1、RS0=1、1、0);上电/复位状态:1F4000Hex
  • 满标度校准寄存器(RS2、RS1、RS0=1、1、1);上电/复位状态:5761ABHex
  • 校准过程
  • 代码部分
  • 原理图


    该芯片需要晶振(Y2)和参考电源电压(U3)

    手册说明

    AD7705与国产TM7705型号差不多,也就是可以参考国产的手册。

    AD7705利用 Σ-Δ 转换技术实现了 16 位无丢失代码性能。选定的输入信号被送到一个基于模拟调制器的增益可编程专用前端。片内数字滤波器处理调制器的输出信号。通过片内控制寄存器可调节滤波器的截止点和输出更新速率,从而对数字滤波器的第一个陷波进行编程。

    TM7705 是双通道全差分模拟输入,带有一个差分基准输入。当电源电压为 5V、基准电压为 2.5V 时,该器件都可将输入信号范围从 0~+20mV 到 0~+2.5V 的信号进行处理。还可处理±20mV~±2.5V 的双极性输入信号,对于 TM7705 是以 AIN(-)输入端为参考点。

    功能方框图

    引脚功能

    片内寄存器

    通信寄存器(RS2、RS1、RS0=0、0、0)



    设置寄存器


    时钟寄存器



    数据寄存器(RS2、RS1、RS0=0、1、1)

    测试寄存器(RS2、RS1、RS0=1、0、0);上电/复位状态:00Hex

    零标度校准寄存器(RS2、RS1、RS0=1、1、0);上电/复位状态:1F4000Hex

    满标度校准寄存器(RS2、RS1、RS0=1、1、1);上电/复位状态:5761ABHex

    校准过程


    代码部分

    以STM32F103和标准库作为底板
    main.c

    #include "led.h"
    #include "delay.h"
    #include "key.h"
    #include "sys.h"
    #include "usart.h"
    
    #include "bsp_spi.h"
    
    
    
    #define CS_ADC_LOW()    GPIO_ResetBits(GPIOA,GPIO_Pin_4)   
    #define CS_ADC_HIGH()   GPIO_SetBits(GPIOA,GPIO_Pin_4)
    /************************************************
     ALIENTEK精英STM32开发板实验4
     串口 实验   
     技术支持:www.openedv.com
     淘宝店铺:http://eboard.taobao.com 
     关注微信公众平台微信号:"正点原子",免费获取STM32资料。
     广州市星翼电子科技有限公司  
     作者:正点原子 @ALIENTEK
    ************************************************/
    
     u8 num1[6];
     float l_ncm1;
     u8 num2[6];
     float l_ncm2;
    
    
    //写数据
    void AD7705_WriteByte(u8 Dst_Addr)   
    {   
            CS_ADC_LOW();//使能器件  
            delay_us(20);
            Spi1_readwritebyte(Dst_Addr);
            delay_us(100);
            CS_ADC_HIGH();//使能器件  
    }
    /********AD7705初始化函数***********/
    
    void Init_AD7705(u8 chnanel)
    {
        u8 i;
        for(i=0;i<150;i++)/* 多于连续32个 DIN=1 使串口复位 */
        {
            AD7705_WriteByte(0xff);//持续DIN高电平写操作,恢复AD7705接口
        }  
            delay_ms(1);
        switch(chnanel)
        {
          case 1:
                 AD7705_WriteByte(0x20); /* 写时钟寄存器选中ch1*/
                 AD7705_WriteByte(0x0C); /* 4.9152MHz时钟,250Hz数据更新速率 */
                 AD7705_WriteByte(0x10); /*选择设置寄存器,使用chnanel 1*/
                 AD7705_WriteByte(0x47); //写设置寄存器 ,设置成双极性、无缓冲、增益为2、滤波器工作、自校准
          break;
    			/*有更改,时钟寄存器设为0x0a,4.9152MHz时钟,500Hz数据更新速率,*/
          case 2:
                 AD7705_WriteByte(0x21); /* 写时钟寄存器选中ch2 */
                 AD7705_WriteByte(0x0f); /* 4.9152MHz时钟,500Hz数据更新速率 */
                 AD7705_WriteByte(0x11); /*选择设置寄存器,使用chnane 2*/
                 AD7705_WriteByte(0x46); //写设置寄存器,设置成双极性、无缓冲、增益为2、滤波器工作、自校准
           break;
           default:       
                    break;
            }
    }
    
    /* 读AD7705转换数据 输入通道channel */
    u16 GetData7705_CH1(void)
    {
    	u16 temp1 = 0;
    	u16 DataL = 0;
    	u16 DataH = 0;
    	Init_AD7705(1);                        //初始化通道1
    	delay_ms(1);
    	AD7705_WriteByte(0x39);   //选中CH1数据寄存器读  
    	while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2==0)){}//待数据准备好AdDrdy=0  
    	CS_ADC_LOW(); //使能器件  
    	delay_us(20);
    	DataH = Spi1_readwritebyte(0xff);
    	DataL = Spi1_readwritebyte(0xff);
    	delay_us(100);
    	CS_ADC_HIGH();   //取消片选        
    	DataH = DataH << 8;
    	temp1  =  DataH | DataL;
    
    	return temp1;
    }
    
    
    /* 读AD7705转换数据 输入通道channel */
    u16 GetData7705_CH2(void)
    {
    	u16 temp2 = 0;
    	u16 DataL = 0;
    	u16 DataH = 0;
    	Init_AD7705(2);                //初始化通道2
    	delay_ms(1);
    	AD7705_WriteByte(0x38);   //选中CH2数据寄存器读  
    	while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2==0));  //待数据准备好AdDrdy=0  
    	CS_ADC_LOW(); //使能器件  
    	delay_us(20);
    	DataH = Spi1_readwritebyte(0xff);
    	DataL = Spi1_readwritebyte(0xff);
    	delay_us(100);
    	CS_ADC_HIGH();   //取消片选        
    	DataH = DataH << 8;
    	temp2  =  DataH | DataL;
    
    	return temp2;
    }
    //数据处理
    
    
    void ADC_7705(void)
    {        
    	
    			u16 RCH1_16bit,RCH2_16bit;              
    			RCH1_16bit = GetData7705_CH1();								
    			l_ncm1  = (float)(RCH1_16bit*(2.5/65535)); //算出通道1电压
    			RCH2_16bit = GetData7705_CH2();
    			l_ncm2  = (float)(RCH2_16bit*(2.5/65535)); //算出通道2电压
    
    //			 num1[0]    = l_ncm1/10000+'0';
    //			 num1[2]    = (l_ncm1%10000)/1000+'0';
    //			 num1[3]    = (l_ncm1%1000)/100+'0';
    //			 num1[4]    = (l_ncm1%100)/10+'0';
    //			 num1[5]    = l_ncm1%10+'0';
    
    //			num2[0]    = l_ncm2/10000+'0';
    //			num2[2]    = (l_ncm2%10000)/1000+'0';
    //			num2[3]    = (l_ncm2%1000)/100+'0';
    //			num2[4]    = (l_ncm2%100)/10+'0';
    //			num2[5]    = l_ncm2%10+'0';
    
    			printf("buff1:%f\n",l_ncm1);
    			printf("buff2:%f\n",l_ncm2);
    		 if(l_ncm2>8500|l_ncm2<8200)
    		 {
    
    			 delay_ms(10);
    			 l_ncm2=0;
    				 
    		 }
    		 else
    		 {
    
    		 }
    		 
    }
    
    
     int main(void)
     {		
    
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
     	LED_Init();			     //LED端口初始化
    	KEY_Init();          //初始化与按键连接的硬件接口
    	 
      Spi1_init();				 //SPI 初始化
    	 GPIO_SetBits(GPIOA,GPIO_Pin_0);
    	 Init_AD7705(1);
    	 delay_ms(250);
    	 Init_AD7705(2);
     	while(1)
    	{
    //		Spi1_readwritebyte(0xAA);
    //		printf("buff1:%X\n",GetData7705_CH1());
    //		delay_ms(100);
    //		printf("buff2:%X\n",GetData7705_CH2());
    
    		
    		ADC_7705();		
    		
    		
    		delay_ms(250);
    		
    	}	 
    	
    	
    	
     }
    
    
    

    bsp_spi.c

    #include "bsp_spi.h"
    
     /**
      * 函数功能: SPI 读写一个字节
      * 输入参数: 要写入的字节
      * 返 回 值: 读取到的字节
      * 说    明:无
      */
    void Spi1_init(void)
    {
     	GPIO_InitTypeDef GPIO_InitStructure;
      SPI_InitTypeDef  SPI_InitStructure;
    	
    	/* 使能GPIO和SPI时钟 */
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA, ENABLE );//PORTB时钟使能 
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_SPI1,  ENABLE );//SPI2时钟使能 	
    
      /* 配置SPI功能引脚:SCK 时钟引脚 */	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  			 //复用推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
    	
    	 /* 配置SPI功能引脚:MISO 主机输出从机输入引脚 */	
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
      /* 配置SPI功能引脚:MOSI 主机输入从机输出引脚 */	
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    
      /* SPI外设配置 --NSS 引脚由软件控制以及 MSB 先行模式*/
      SPI_Cmd(SPI1, DISABLE); //失能能SPI外设
      SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
      SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
      SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
      SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;                //选择了串行时钟的稳态:时钟悬空高
      SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //数据捕获于第二个时钟
      SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
      SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
      SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
      SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
      SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
    	
      /* 配置SPI功能引脚:CS 串行Flash片选引脚 */	
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	/* 配置SPI所用的引脚:默认高电平 */	
    	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
    	
    	SPI_Cmd(SPI1, ENABLE); //使能SPI外设
    
    /* RES */	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //复用推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
    /* CS */	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  			 //复用推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
    /* DRDY */	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  			 //复用推挽输出 
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);         				 //初始化GPIO
    	
    		GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_4|GPIO_Pin_2);
    }
    
    
     /**
      * 函数功能: SPI 速度设置函数
      * 输入参数: 
    							SPI_BaudRatePrescaler_2   2分频 
    							SPI_BaudRatePrescaler_8   8分频 
    							SPI_BaudRatePrescaler_16  16分频  
    							SPI_BaudRatePrescaler_256 256分频 
    
      * 返 回 值: 无
      * 说    明:
      */ 
    void Spi1_SetSpeed(u8 Spi_baudrateprescaler)
    {
      assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
    	SPI1->CR1&=0XFFC7;
    	SPI1->CR1|=Spi_baudrateprescaler;	//设置SPI1速度 
    	SPI_Cmd(SPI1,ENABLE); 
    } 
    
    
     /**
      * 函数功能: SPI 读写一个字节
      * 输入参数: 要写入的字节
      * 返 回 值: 读取到的字节
      * 说    明:无
      */
    u8 Spi1_readwritebyte(u8 Txdata)
    {		
    	u8 retry=0;				 	
    	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
    		{
    		retry++;
    		if(retry>200)return 0;
    		}			  
    	SPI_I2S_SendData(SPI1, Txdata); //通过外设SPIx发送一个数据
    	retry=0;
    
    	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
    		{
    		retry++;
    		if(retry>200)return 0;
    		}
    	return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据					    
    }
    
    
    

    bsp_spi.h

    #ifndef __BSP_SPI_H__
    #define __BSP_SPI_H__
    
    /* 包含头文件 ----------------------------------------------------------------*/
    #include <stm32f10x.h>
    #include "sys.h"
    /* 类型定义 ------------------------------------------------------------------*/
    
    /* 宏定义 --------------------------------------------------------------------*/
    
    /* 
    
    SPI引脚分布
    
    SPI1			挂载时钟 APB1
    SCK				PA5
    MISO			PA6
    MOSI			PA7
    CS				PA4
    
    SPI2			挂载时钟 APB2
    SCK				PB13
    MISO			PB14
    MOSI			PB15
    CS				PB12
    
    */
    
    
    
    /* SPI配置*/
    #define SPIx                        SPI1
    #define SPI_CLK                     RCC_APB2Periph_SPI1
    
    #define SPI_SCK_CLK                 RCC_APB2Periph_GPIOA   
    #define SPI_SCK_PORT                GPIOA   
    #define SPI_SCK_PIN                 GPIO_Pin_5
    
    #define SPI_MISO_CLK                RCC_APB2Periph_GPIOA    
    #define SPI_MISO_PORT               GPIOA
    #define SPI_MISO_PIN                GPIO_Pin_6
    
    #define SPI_MOSI_CLK                RCC_APB2Periph_GPIOA    
    #define SPI_MOSI_PORT               GPIOA 
    #define SPI_MOSI_PIN                GPIO_Pin_7
    
    #define SPI_CS_CLK                  RCC_APB2Periph_GPIOA    
    #define SPI_CS_PORT                 GPIOA
    #define SPI_CS_PIN                  GPIO_Pin_4
    
    #define SPI_CS_ENABLE()             GPIO_ResetBits(SPI_CS_PORT, SPI_CS_PIN)
    #define SPI_CS_DISABLE()            GPIO_SetBits(SPI_CS_PORT, SPI_CS_PIN)
    
    
    #define CS_LOW	GPIO_WriteBit(SPI_CS_PORT, SPI_CS_PIN, Bit_RESET)
    #define CS_HIGH	GPIO_WriteBit(SPI_CS_PORT, SPI_CS_PIN, Bit_SET)
    
    
    /* 扩展变量 ------------------------------------------------------------------*/
    /* 函数声明 ------------------------------------------------------------------*/
    
    
    void Spi1_SetSpeed(u8 SPI_BaudRatePrescaler); 		//SPI 速度设置函数
    void Spi1_init(void);															//SPI 初始化
    u8 Spi1_readwritebyte(u8 TxData);									//SPI 数据写入或读取
    
    
    
    #endif
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用STM32-SPI1控制AD7705 Sigma-Delta ADC芯片

    发表评论