STM32之AD5410驱动

AD5410是一款ADI的DAC,驱动如下:

/******************************************************************************
* 文 件  名 称:BspAD5410.c
* 文件功能概述:实现AD5410的接口
* 文 件  作 者:
* 版        本:V1.0.0.0
* 修 订  记 录:2017-6-30创建
******************************************************************************/

/***************************相关配置*******************************************
              该驱动对应于AD5410的菊花链模式
******************************************************************************/

#include "BspAD5410.h"

#define AD5410xDelayUs(x) DelayUs(x) 
#define USE_DAISY_CHAIN 1

/*
 * 数据类型-AD5410端口信息
 */
typedef struct AD5410CtrlStruc
{
  E_SPIx     AD5410xSPIx;
  S_GpioCtrl AD5410xLATCH;
}S_AD5410Ctrl;

/*
 * 用于记录AD5410的端口信息
 */
static S_AD5410Ctrl stAD5410Ctrl[E_AD5410_Max] = 
{
  /* AD5410_1 */
  {
    E_SPI_2,
    {RCC_AHB1Periph_GPIOG,GPIOG,GPIO_Pin_6}    //LATCH
  },
  /* AD5410_2 */
  {
    E_SPI_2,
    {RCC_AHB1Periph_GPIOG,GPIOG,GPIO_Pin_6}    //LATCH
  }
};

/*
 * 拉高5410的LATCH端口
 */
static __inline void AD5410_LATCH_HIGH(E_AD5410 eAD5410)
{
  GPIOxWriteBit(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOx, stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxPinx , 1);
}
/*
 * 拉低5410的LATCH端口
 */
static __inline void AD5410_LATCH_LOW(E_AD5410 eAD5410)
{
  GPIOxWriteBit(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOx, stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxPinx , 0);
}

/*
 *SPI总线上挂接的设备类型不一样,每次使用前均需对总线进行初始化
 */
static void AD5410InitSPIModule(E_AD5410 eAD5410)
{
	SPI_InitTypeDef SPIxInitStruct;  
    
  /* Initialize the SPI_Direction member */
  SPIxInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  /* initialize the SPI_Mode member */
  SPIxInitStruct.SPI_Mode = SPI_Mode_Master;
  /* initialize the SPI_DataSize member */
  SPIxInitStruct.SPI_DataSize = SPI_DataSize_8b;
  /* Initialize the SPI_CPOL member */
  SPIxInitStruct.SPI_CPOL = SPI_CPOL_Low;
  /* Initialize the SPI_CPHA member */
  SPIxInitStruct.SPI_CPHA = SPI_CPHA_1Edge;
  /* Initialize the SPI_NSS member */
  SPIxInitStruct.SPI_NSS = SPI_NSS_Soft;    
  /* Initialize the SPI_FirstBit member */
  SPIxInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
  /* Initialize the SPI_CRCPolynomial member */
  SPIxInitStruct.SPI_CRCPolynomial = 7;
	
	SPIxUpdateModule(stAD5410Ctrl[eAD5410].AD5410xSPIx,&SPIxInitStruct);
}

/*******************************************************************************
 * 函 数 名:static sint8 AD5410xEnableOperate(void)
 * 参    数:
 * 返    回:0
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:在LATCH信号线产生一个下降沿
 * 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 AD5410xEnableOperate(E_AD5410 eAD5410)
{
  
  //拉高LATCH
  AD5410_LATCH_HIGH(eAD5410);

  AD5410xDelayUs(10);
  
  //拉低LATCH
  AD5410_LATCH_LOW(eAD5410);
  
  return 0;
}

/*******************************************************************************
 * 函 数 名:static sint8 AD5410xDisableOperate(void)
 * 参    数:void
 * 返    回:0
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:在LATCH信号线产生一个上升沿,该信号线的上升沿会锁存数据
 * 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 AD5410xDisableOperate(E_AD5410 eAD5410)
{
  
  //拉低LATCH
  AD5410_LATCH_LOW(eAD5410);
  
  AD5410xDelayUs(10);
  
  //拉高LATCH
  AD5410_LATCH_HIGH(eAD5410);
  
  return 0;
}

/*******************************************************************************
 * 函 数 名:static sint8 AD5410xWriteReg(E_AD5410 eAD5410, uint8 RegAddr, uint16 value)
 * 参    数:E_AD5410 eAD5410 : E_AD5410_1或E_AD5410_2
            uint8 RegAddr      : 寄存器地址字节
             uint16 value      :数据
 * 返    回:0
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410写寄存器
 * 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 AD5410xWriteReg(E_AD5410 eAD5410, uint8 RegAddr, uint16 value)
{
  
#if USE_DAISY_CHAIN
  uint8 SendData[3*E_AD5410_Max]={0};

  memset(SendData,0,sizeof(SendData));
  
  AD5410xEnableOperate(eAD5410);
  
  SendData[(E_AD5410_Max-1-eAD5410)*3 + 0] = RegAddr;
  SendData[(E_AD5410_Max-1-eAD5410)*3 + 1] = value>>8;
  SendData[(E_AD5410_Max-1-eAD5410)*3 + 2] = value&0xff;
  
  SPIxWriteBytes(stAD5410Ctrl[eAD5410].AD5410xSPIx, SendData, 3*E_AD5410_Max);
   
  AD5410xDisableOperate(eAD5410);
#else
  uint8 SendData[3]={0x00, 0x00, 0x00};

  AD5410xEnableOperate(eAD5410);
   
  SendData[0] = RegAddr;
  SendData[1] = value>>8;
  SendData[2] = value&0xff;
  
  SPIxWriteBytes(stAD5410Ctrl[eAD5410].AD5410xSPIx, SendData, 3);  
  
  AD5410xDisableOperate(eAD5410);
#endif
     
  return 0;
}

/*******************************************************************************
 * 函 数 名:static sint8 AD5410xReadReg(E_AD5410 eAD5410,uint8 RegAddr, uint16 *value)
 * 参    数:E_AD5410 eAD5410 : E_AD5410_1或E_AD5410_2
            uint8 RegAddr  :寄存器地址
            uint16 *value  :数据指针
 * 返    回:0
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410读寄存器操作,只进行读取操作,读取命令的发送部分额外处理
 * 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 AD5410xReadReg(E_AD5410 eAD5410,uint8 RegAddr, uint16 *value)
{
	uint8 SendData[3*E_AD5410_Max]={0};
  uint8 RecvData[3*E_AD5410_Max]={0};
  uint8 i = 0;
	
	/*先配置为回读模式*/
  AD5410xEnableOperate(eAD5410);
  
	AD5410xWriteReg(eAD5410,ADDR_FUNC_READBACK,RegAddr);
	
	AD5410xDisableOperate(eAD5410);
	
	AD5410xDelayUs(10);
	
	AD5410xEnableOperate(eAD5410);
	
#if USE_DAISY_CHAIN
  
  memset(SendData, 0, sizeof(SendData));
  memset(RecvData, 0, sizeof(RecvData));
  
  for(i=0;i<E_AD5410_Max*3;i++)
  {
    SPIxWriteReadByte(stAD5410Ctrl[eAD5410].AD5410xSPIx, &SendData[i], &RecvData[i]);
  }
  
  {
    uint16 Temp[2]={0,0};
    
    Temp[0] = RecvData[(E_AD5410_Max-1-eAD5410)*3 + 1];
    Temp[1] = RecvData[(E_AD5410_Max-1-eAD5410)*3 + 2];
    
    *value = (Temp[0]<<8) | Temp[1];
  }
  
#else
  /*发送空指令字,使得数据从SDO上输出*/
	SPIxWriteReadByte(stAD5410Ctrl[eAD5410].AD5410xSPIx, &SendData[0], &RecvData[0]);
	SPIxWriteReadByte(stAD5410Ctrl[eAD5410].AD5410xSPIx, &SendData[1], &RecvData[1]);
	SPIxWriteReadByte(stAD5410Ctrl[eAD5410].AD5410xSPIx, &SendData[2], &RecvData[2]);  
  
  *value = (RecvData[1]<<8) | RecvData[2];
#endif
  
	AD5410xDisableOperate(eAD5410);
	
 
  
  return 0;
}

/*******************************************************************************
 * 函 数 名:static sint8 AD5410xSoftReset(E_AD5410 eAD5410)
 * 参    数:E_AD5410 eAD5410 : E_AD5410_1或E_AD5410_2
 * 返    回:0
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410软件复位         
 * 修改记录:2017-6-30创建
*******************************************************************************/
static sint8 AD5410xSoftReset(E_AD5410 eAD5410)
{
  uint8 SendValidData[3]={0x56, 0x00, 0x00};
  uint8 SendInvalidData[3]={0x00, 0x00, 0x00};
	
	AD5410xEnableOperate(eAD5410);
	
#if USE_DAISY_CHAIN
  {
    sint8 i = 0;
    for(i=E_AD5410_Max-1;i>=0;i--)
    {
      if(eAD5410 == ((E_AD5410)i))
      {
        SPIxWriteBytes(stAD5410Ctrl[eAD5410].AD5410xSPIx, SendValidData, 3);
      }
      else
      {
        /*发送空指令字,跳过后一级5410的数据*/
		   SPIxWriteBytes(stAD5410Ctrl[eAD5410].AD5410xSPIx, SendInvalidData, 3);  
      }
    }
  }
#else
  SPIxWriteBytes(stAD5410Ctrl[eAD5410].AD5410xSPIx, SendValidData, 3);
#endif

  
	AD5410xDisableOperate(eAD5410);
  
  return 0;
}

/*******************************************************************************
 * 函 数 名:sint8 AD5410xInit(E_AD5410 eAD5410)
 * 参    数:E_AD5410 eAD5410:详见E_AD5410
 * 返    回: 0  : 正常返回 
             -1 :SPI初始化失败        -2 :AD5410复位失败
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410初始化      
 * 修改记录:2017-6-30创建
*******************************************************************************/
sint8 AD5410xInit(E_AD5410 eAD5410)
{
  sint8 ret = 0;
  
  if(eAD5410 < E_AD5410_Max)
  {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
#if USE_DAISY_CHAIN
    /******** 菊花链模式,公用一个LATCH引脚 ********/
    
    /* 配置LATCH引脚 */
    RCC_AHB1PeriphClockCmd(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxSource, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxPinx;
    GPIO_Init(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOx, &GPIO_InitStructure);  
    
    AD5410_LATCH_LOW(eAD5410);	
    
    AD5410InitSPIModule(eAD5410);//SPI总线上挂接的设备类型不一样,每次使用前均需对总线进行初始化
    
    for(eAD5410=E_AD5410_1;eAD5410<E_AD5410_Max;eAD5410++)
    {
      AD5410xSoftReset(eAD5410);
    }
    
    for(eAD5410=E_AD5410_1;eAD5410<E_AD5410_Max;eAD5410++)
    {  
      /******************配置AD5410为0-20mA范围,使能菊花链模式,使能输出,选择外部15K电阻************************************/
	    AD5410xWriteReg(eAD5410, ADDR_FUNC_CTRL_REG, CTRL_0_20_RANG | CTRL_DCEN_ENABLE | CTRL_OUTEN_ENABLE | CTRL_REXT_ENABLE);  
    }
#else    
    /*配置LATCH引脚*/
    RCC_AHB1PeriphClockCmd(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxSource, ENABLE);
    
    /*配置LATCH引脚*/
    GPIO_InitStructure.GPIO_Pin = stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOxPinx;
    GPIO_Init(stAD5410Ctrl[eAD5410].AD5410xLATCH.GPIOx, &GPIO_InitStructure);  
    
    AD5410_LATCH_LOW(eAD5410);		
    
	  AD5410InitSPIModule(eAD5410);//SPI总线上挂接的设备类型不一样,每次使用前均需对总线进行初始化
    
    AD5410xSoftReset(eAD5410);
    
    /******************配置AD5410为0-20mA范围,使能菊花链模式,使能输出,选择外部15K电阻************************************/
	  AD5410xWriteReg(eAD5410, ADDR_FUNC_CTRL_REG, CTRL_0_20_RANG | CTRL_DCEN_ENABLE | CTRL_OUTEN_ENABLE | CTRL_REXT_ENABLE);
#endif
  }
  else
  {
    ret = -1;
  }

  return ret;
}

/*******************************************************************************
 * 函 数 名:sint8 AD5410xWriteDataReg(E_AD5410 eAD5410, uint16 data)
 * 参    数:E_AD5410 eAD5410 : E_AD5410_1或E_AD5410_2
             uint16 data       :数据
 * 返    回: 0  : 正常返回 
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410写数据寄存器操作   
 * 修改记录:2017-6-30创建
*******************************************************************************/
sint8 AD5410xWriteDataReg(E_AD5410 eAD5410, uint16 data)
{
  uint16 SendData = 0x0000;
	
	AD5410InitSPIModule(eAD5410);//SPI总线上挂接的设备类型不一样,每次使用前均需对总线进行初始化
	
  SendData = (data<<4)&0xFFF0 ;  
	    
  AD5410xWriteReg(eAD5410, ADDR_FUNC_DATA_REG, SendData);
   
  return 0;
}

/*******************************************************************************
 * 函 数 名:sint8 AD5410xRead(E_AD5410 eAD5410, E_AD5410_REG_ADDR RegAddr, uint16 *data)
 * 参    数:E_AD5410 eAD5410         : E_AD5410_1或E_AD5410_2
             E_AD5410_REG_ADDR RegAddr : 寄存器地址
             uint16 *data              :数据
 * 返    回: 0  : 正常返回 
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:AD5410读数据寄存器操作   
 * 修改记录:2017-6-30创建
*******************************************************************************/
sint8 AD5410xReadDataReg(E_AD5410 eAD5410, uint16 *data)
{
  uint16 RecvData = 0x0000;  
  
	AD5410InitSPIModule(eAD5410);//SPI总线上挂接的设备类型不一样,每次使用前均需对总线进行初始化
	
  AD5410xReadReg(eAD5410,ADDR_FUNC_DATA_REG,&RecvData);
  
  RecvData = ((RecvData>>4)&0x0FFF);
  
  *data = RecvData;
    
  return 0;
}

/*******************************************************************************
 * 函 数 名:uint16 AD5410xValueToCurrent(float value, float MaxValue)
 * 参    数:float value     :上层要输出的数据
            float MaxValue :上层传入的最大值
 * 返    回: 0  : 正常返回 
 * 创 建 人:
 * 创建时间:2017-6-30
 * 详    述:根据传入最大值,计算量化得到符合AD5410范围的数据
 * 修改记录:2017-6-30创建
*******************************************************************************/
uint16 AD5410xValueToCurrent(float value, float MaxValue)
{
  if(value >= MaxValue)
  {
    value = MaxValue;
  }
  else
  {}
    
  return (uint16)roundf((float)(value * AD5410_RATIO / MaxValue));
}

#if 1
void AD5410xTestSPI(void)
{
	uint8   SendData=0x55;
	uint16   RecvData[9]={0x00,0x00,0x00};
		
	AD5410InitSPIModule(E_AD5410_1);
	
	AD5410xWriteDataReg(E_AD5410_1,SendData);
	AD5410xWriteDataReg(E_AD5410_2,SendData);
	
	AD5410xReadDataReg(E_AD5410_1,RecvData);
	AD5410xReadDataReg(E_AD5410_2,&RecvData[1]);
	

	return;
}
#endif

头文件:

/******************************************************************************
* 文 件  名 称:BspAD5410.h
* 文件功能概述:实现AD5410驱动接口声明
* 文 件  作 者:
* 版        本:V1.0.0.0
* 修 订  记 录:2017-6-30创建
******************************************************************************/

#ifndef __BSP_AD5410_H__
#define __BSP_AD5410_H__


/*----------------------------------------------*
 * 包含头文件                                   *
 *----------------------------------------------*/
#include "..\BspInterface.h"
/*----------------------------------------------*
 * 宏定义                                       *
 *----------------------------------------------*/
/************************************************************************************************
*AD5410的数据是按照24位宽组织的
*DB23~DB16 :地址字节
*DB15~DB0  :数据字
************************************************************************************************/
 
/*****************************地址字节功能定义***************************************************/
#define ADDR_FUNC_NOP          0x00
#define ADDR_FUNC_DATA_REG     0x01
#define ADDR_FUNC_CTRL_REG     0x55
#define ADDR_FUNC_RST_REG      0x56
                               
#define ADDR_FUNC_READBACK     0x02
/*****************************地址字节功能定义结束***************************************************/

/*****************************回读数据时的读取地址定义  占用DB1~DB0***************************************************/
#define READBACK_REG_MASK      0x03

#define READBACK_STATUS_REG    0x00
#define READBACK_DATA_REG      0x01
#define READBACK_CTRL_REG      0x02
/*****************************回读数据时的读取地址定义结束***************************************************/

#define NOP_OPERATION          0x000000      //空操作

/*****************************控制寄存器定义***************************************************/
#define CTRL_RANG_MASK         0x07          //输出范围掩码
#define CTRL_4_20_RANG         0x05          //4-20mA输出范围
#define CTRL_0_20_RANG         0x06          //0-20mA输出范围
#define CTRL_0_24_RANG         0x07          //0-24mA输出范围

#define CTRL_DCEN_ENABLE        (1 << 3)      //菊花链使能

#define CTRL_SREN_ENABLE        (1 << 4)      //数字压摆率使能

#define CTRL_OUTEN_ENABLE       (1 << 11)     //使能输出

#define CTRL_REXT_ENABLE        (1 << 12)     //外部电阻选择
/*****************************控制寄存器定义结束***************************************************/

#define RST_REG_ENABLE          (1 << 0)       //软件复位

#define AD5410_RATIO (0xFFF)

/*----------------------------------------------*
 * 常量定义                                     *
 *----------------------------------------------*/
typedef enum
{
  E_AD5410_REG_ADDR_STATUS,
  E_AD5410_REG_ADDR_DATA,
  E_AD5410_REG_ADDR_CTRL
}E_AD5410_REG_ADDR; 
 
typedef enum
{
  E_AD5410_1 = 0x00,
  E_AD5410_2,
  
  E_AD5410_Max,
  
  E_AD5410_Invalid
}E_AD5410;
/*----------------------------------------------*
 * 外部变量说明                                 *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 全局变量                                     *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 模块级变量                                   *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 外部函数原型说明                             *
 *----------------------------------------------*/

/*----------------------------------------------*
 * 内部函数原型说明                             *
 *----------------------------------------------*/
sint8 AD5410xInit(E_AD5410 eAD5410);

sint8 AD5410xWrite(E_AD5410 E_AD5410, uint8 reg, uint16 data);

sint8 AD5410xWriteCtrlReg(E_AD5410 E_AD5410, uint16 data);

sint8 AD5410xWriteDataReg(E_AD5410 E_AD5410, uint16 data);

sint8 AD5410xRead(E_AD5410 E_AD5410, E_AD5410_REG_ADDR RegAddr, uint16 *data);

sint8 AD5410xReadDataReg(E_AD5410 E_AD5410, uint16 *data);

uint16 AD5410xValueToCurrent(float value, float MaxValue);

#endif

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值