STM32F0驱动DS1220AD采集芯片

今天做一下ADS1220的驱动编写:

1.通信协议

1.1采用是SPI通信模式,因为我的单片机脚没有接spi功能就直接用模拟的方式来使用了;

管脚定义如下:

    //PB2 MOSI-DIN
    //PA7 SCK
   //PA6 CS

1.2 通讯命令

8.5.3.1 RESET (0000 011x)
将器件复位为默认值。发送 RESET 命令后应至少等待 (50µs + 32 · t (CLK) ) 方可继续发送其他任何命令。
8.5.3.2 START/SYNC (0000 100x)
在单次模式下, START/SYNC 命令用于启动单次转换,或(在转换的发送过程中)复位数字滤波器,随后重启新
一次转换。如果将器件设置为连续转换模式,为了启动连续转换,必须一次性发出 START/SYNC 命令。如果在连
续转换模式下发送 START/SYNC 命令,则会复位数字滤波器并重启连续转换。
8.5.3.3 POWERDOWN (0000 001x)
POWERDOWN 命令将器件置于掉电模式。该命令关断所有内部模拟组件、断开低侧开关并关断两个 IDAC ,但保
持所有寄存器值。如果在转换过程中发出 POWERDOWN 命令,转换将在 ADS1220 进入掉电模式前完成。发出
START/SYNC 命令后,所有模拟组件立即返回至上一状态。
8.5.3.4 RDATA (0001 xxxx)
RDATA 命令将最新转换结果载入输出移位寄存器。当 DOUT/DRDY DRDY 未受监测时,可使用该命令指示提
供新转换结果。如果在 RDATA 命令字节中间完成转换,读操作结束时 DRDY 引脚状态将指示载入了旧结果或新
结果。如果载入旧结果, DRDY 将保持低电平,指示未读出新结果。新转换结果将在 DRDY 处于高电平时载入。
8.5.3.5 RREG (0010 rrnn)
RREG 命令从器件的配置寄存器读取 nn 指定的字节数(待读取字节数 – 1 ),起始寄存器地址为 rr 。在 RREG
令字节后,如有 nn + 1 个字节随时钟移出,则该命令完成。例如,从配置寄存器 1 (rr = 01) 开始读取三个字节 (nn
= 10) 的命令为 0010 0110
8.5.3.6 WREG (0100 rrnn)
WREG 命令向器件的配置寄存器写入 nn 指定的字节数(待写入字节数 – 1 ),起始寄存器地址为 rr 。在 WREG
命令字节后,如有 nn + 1 个字节随时钟移入,则该命令完成。例如,从配置寄存器 0 (rr = 00) 开始写入两个字节
(nn = 01) 的命令为 0100 0001 。配置寄存器在最后一个 SCLK 下降沿更新。

1.3通讯时序图

我采用的是单次转换:
需要:发送RDATA>连续取三次数据>开启下次一转换

2.寄存器配置

配置寄存器0

配置寄存器1

配置寄存器2

配置寄存器03

3.使用说明

简单附上了一个datesheet的接线说明

4.驱动代码

4.1ds1220.h
#ifndef __SPI_H
#define __SPI_H
#include "stm32f0xx.h"
#include "bsp.h"






void ADS1220_Init(void);
unsigned long GetAD(unsigned char channel);
void ADS1220_GPIOInit(void);
 



#endif
4.2 ds1220.c
#include "spi.h"



#define MUX_0  0X00//0000:AINP = AIN0,AINN = AIN1(默认设置)
#define MUX_1  0X10//0001:AINP = AIN0,AINN = AIN2
#define MUX_2  0X20//0010:AINP = AIN0,AINN = AIN3
#define MUX_3  0X30//0011:AINP = AIN1,AINN = AIN2
#define MUX_4  0X40//0100:AINP = AIN1,AINN = AIN3
#define MUX_5  0X50//0101:AINP = AIN2,AINN = AIN3
#define MUX_6  0X60//0110:AINP = AIN1,AINN = AIN0
#define MUX_7  0X70//0111:AINP = AIN3,AINN = AIN2
#define MUX_8  0X80//1000:AINP = AIN0,AINN = AVSS
#define MUX_9  0X90//1001:AINP = AIN1,AINN = AVSS
#define MUX_10 0XA0//1010:AINP = AIN2,AINN = AVSS
#define MUX_11 0XB0//1011:AINP = AIN3,AINN = AVSS
#define MUX_12 0XC0//1100:(V(REFPx) – V(REFNx)) / 4 监视(旁路 PGA)
#define MUX_13 0XD0//1101:(AVDD – AVSS) / 4 监视(旁路 PGA)
#define MUX_14 0XE0//1110:AINP 和 AINN 短接至 (AVDD + AVSS) / 2
//1111:保留
 
/*------------增益配置---------------------------------- 
**这些位用于配置器件增益。 在不使用 PGA 的情况下,
**可使用增益 1、2 和 4。在这种情况下,通过开关电容结 构获得增益。
------------------------------------------------------*/
#define PGA_0  0X00//000:增益 = 1(默认设置)//FS=6.144V
#define PGA_1  0X02//001:增益 = 2//FS=4.096V
#define PGA_4  0X04//010:增益 = 4//FS=2.048V
#define PGA_8  0X06//011:增益 = 8//FS=1.024V
#define PGA_16 0X08//100:增益 = 16//FS=0.512V
#define PGA_32 0X0A//101:增益 = 32//FS=0.256V
#define PGA_64 0X0C//110:增益 = 64//FS=0.256V
#define PGA_12 0X0E//111:增益 = 128//FS=0.256V
 
/*-----------------禁用和旁路内部低噪声 PGA----------------------
**禁用 PGA 会降低整体功耗,并可将共模电压范围 (VCM) 扩展为 AVSS – 0.1V 至AVDD + 0.1V。 
**只能针对增益 1、2 和 4 禁用 PGA。 
无论 PGA_BYPASS 设置如何,都始终针对增益设置 8 至 128 启用 PGA。 
**0:PGA 已启用(默认设置) 
**1:PGA 已禁用和旁路
---------------------------------------------------------------------*/
#define PGA_BYPASS_Enable  0x00//PGA 已启用(默认设置) 
#define PGA_BYPASS_Disable 0x01//已禁用和旁路
 
/*----------------------数据速率----------------------------------
**这些位控制数据速率设置,取决于所选工作模式。
**表 18 列出了正常模式、占空比 模式和 Turbo 模式对应的位设置。
-----------------------------------------------------------------*/
#define DR_20SPS   0X00
#define DR_45SPS   0X20
#define DR_90SPS   0X40
#define DR_175SPS  0X60
#define DR_330SPS  0X80
#define DR_600SPS  0XA0
#define DR_1000SPS 0XC0
 
/*-----------------工作模式 ---------------------------------------
**这些位控制器件所处的工作模式。
00:正常模式(256kHz 调制器时钟,默认设置)
01:占空比模式(内部占空比 1:4)
10:Turbo 模式(512kHz 调制器时钟)
11:保留
------------------------------------------------------------------*/
#define MODE_0 0x00	//正常模式(256kHz 调制器时钟,默认设置)
#define MODE_1 0x08	//占空比模式(内部占空比 1:4)
#define MODE_2 0x10	//Turbo 模式(512kHz 调制器时钟)
 
/*------------------转换模式----------------------------------------
此位用于为器件设置转换模式。 
0:单次模式(默认设置)
1:连续转换模式
-------------------------------------------------------------------*/
#define ConverMode_0 0x00//单次模式(默认设置)
#define ConverMode_1 0x04//连续转换模式
 
/*--------------------温度传感器模式------------------------------
此位用于启用内部温度传感器以及将器件置于温度传感器模式下。 
启用温度传感器模式后,配置寄存器 0 的设置不会产生任何影响,
器件会使用内部 基准进行测量。 
0:禁用温度传感器(默认设置) 
1:启用温度传感器
--------------------------------------------------------------------*/
#define TS_Disable 0x00//禁用温度传感器(默认设置)
#define TS_Enable  0x02//启用温度传感器
 
/*---------------------烧毁电流源-----------------------------------
此位用于控制 10μA 烧毁电流源。 
烧毁电流源可用于检测传感器故障(例如,传感器断路和短路)。 
0:电流源关断(默认设置) 
1:电流源接通
-------------------------------------------------------------------*/
#define BCS_Disable 0x00//电流源关断(默认设置) 
#define BCS_Enable  0x01//电流源接通
 
/*--------------------基准电压选择---------------------------------
这些位用于选择转换所使用的基准电压源。
00:选择 2.048V 内部基准电压(默认设置)
01:使用专用 REFP0 和 REFN0 输入选择的外部基准电压
10:使用 AIN0/REFP1 和 AIN3/REFN1 输入选择的外部基准电压
11:用作基准的模拟电源 (AVDD – AVSS)
--------------------------------------------------------------------*/
#define VREF_0 0X00//选择 2.048V 内部基准电压(默认设置)
#define VREF_1 0X40//使用专用 REFP0 和 REFN0 输入选择的外部基准电压
#define VREF_2 0X80//使用 AIN0/REFP1 和 AIN3/REFN1 输入选择的外部基准电压
#define VREF_3 0XC0//用作基准的模拟电源 (AVDD – AVSS)
 
/*----------------------FIR 滤波器配置------------------------------
这些位用于为内部 FIR 滤波器配置滤波器系数。 
在正常模式下,这些位仅与 20SPS 设置结合使用;
在占空比模式下,这些位仅与
5SPS 设置结合使用。对于所有其他数据速率,这些位均设置为 00。
00:无 50Hz 或 60Hz 抑制(默认设置)
01:同时抑制 50Hz 和 60Hz
10:只抑制 50Hz
11:只抑制 60Hz
------------------------------------------------------------------*/
#define FIR_Mode0  0x00//无 50Hz 或 60Hz 抑制(默认设置)
#define FIR_Mode1  0x10//同时抑制 50Hz 和 60Hz
#define FIR_Mode2  0x20//只抑制 50Hz
#define FIR_Mode3  0x30//只抑制 60Hz
 
/*----------------------低侧电源开关配置 --------------------------
此位用于配置 AIN3/REFN1 和 AVSS 之间连接的低侧开关的行为。 
0:开关始终处于断开状态(默认设置) 
1:开关会在发送 START/SYNC 命令时自动闭合,并在发出 POWERDOWN 命令 时自动断开。
------------------------------------------------------------------*/
#define PSW_ON  0X00//开关始终处于断开状态(默认设置) 
#define PSW_OFF 0X08//开关会在发送 START/SYNC 命令时自动闭合,并在发出 POWERDOWN 命令 时自动断开。
 
/*---------------------IDAC 电流设置-----------------------------
这些位用于为 IDAC1 和 IDAC2 激励电流源设置电流。
----------------------------------------------------------------*/
#define IDAC_0 0X00  //000:关断(默认设置)
#define IDAC_1 0X00  //001:10μA
#define IDAC_2 0X02  //010:50μA
#define IDAC_3 0X03  //011:100μA
#define IDAC_4 0X04  //100:250μA
#define IDAC_5 0X05  //101:500μA
#define IDAC_6 0X06  //110:1000μA
#define IDAC_7 0X07  //111:1500μA
 
/*------------------------IDAC1 路由配置-------------------------
这些位用于选择 IDAC1 将路由到的通道。
111:保留
----------------------------------------------------------------*/
#define IDAC1_0 0X00  //000:IDAC1 已禁用(默认设置)
#define IDAC1_1 0X20  //001:IDAC1 已连接至 AIN0/REFP1
#define IDAC1_2 0X40  //010:IDAC1 已连接至 AIN1
#define IDAC1_3 0X60  //011:IDAC1 已连接至 AIN2
#define IDAC1_4 0X80  //100:IDAC1 已连接至 AIN3/REFN1
#define IDAC1_5 0XA0  //101:IDAC1 已连接至 REFP0
#define IDAC1_6 0XC0  //110:IDAC1 已连接至 REFN0
 
/*------------------------IDAC2 路由配置-------------------------
这些位用于选择 IDAC2 将路由到的通道。
111:保留
----------------------------------------------------------------*/
#define IDAC2_0 0X00  //000:IDAC2 已禁用(默认设置)
#define IDAC2_1 0X04  //001:IDAC2 已连接至 AIN0/REFP1
#define IDAC2_2 0X08  //010:IDAC2 已连接至 AIN1
#define IDAC2_3 0X0c  //011:IDAC2 已连接至 AIN2
#define IDAC2_4 0X10  //100:IDAC2 已连接至 AIN3/REFN1
#define IDAC2_5 0X14  //101:IDAC2 已连接至 REFP0
#define IDAC2_6 0X18  //110:IDAC2 已连接至 REFN0
 
/*-----------------------DRDY 模式 -----------------------------
该位用于控制新数据就绪时 DOUT/DRDY 引脚的行为。 
---------------------------------------------------------------*/
#define DRDY_Mode0 0x00  //0:仅专用 DRDY 引脚用于指示数据何时就绪(默认设置)
#define DRDY_Mode1 0x02  //1:同时通过 DOUT/DRDY 和 DRDY 指示数据就绪。
 

unsigned char PolarFlag;

unsigned char Init_Config[4],channel0[8],channel1[8],channel2[8],channel3[8];


//#define ADS1220_RESET      0X03

#define ADS1220_RESET      0X06

#define ADS1220_START      0X08
#define ADS1220_POWERDOWN  0X02
#define ADS1220_RDATA      0X10
#define ADS1220_RREG       0X20
#define ADS1220_WREG       0X40
 



#define DIN_H GPIO_SetBits(GPIOB,GPIO_Pin_2)      //PB2 MOSI-DIN
#define DIN_L GPIO_ResetBits(GPIOB,GPIO_Pin_2)    //PB2 MOSI-DIN
 
#define SCK_H GPIO_SetBits(GPIOA,GPIO_Pin_7)      //PA7 SCK
#define SCK_L GPIO_ResetBits(GPIOA,GPIO_Pin_7)    //PA7 SCK
 
#define CS_H  GPIO_SetBits(GPIOA,GPIO_Pin_6)      //PA6 CS
#define CS_L  GPIO_ResetBits(GPIOA,GPIO_Pin_6)    //PA6 CS





void ADS1220_GPIOInit(void)
{

  		GPIO_InitTypeDef	GPIO_InitStructure;
	
		RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);     									//CS直接拉低,默认使能
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;			     								
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   						
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		GPIO_ResetBits(GPIOA,GPIO_Pin_6);
	
	
		RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);     									//SCK 时钟线,先上拉 输出模式
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;			     								
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   						
//		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
//	  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	  
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	  
		GPIO_SetBits(GPIOA,GPIO_Pin_7);
	
	
	
	  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);     									//DIN  单片机发送 ADS1220 接收
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;			     								
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;   						
//		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOB, &GPIO_InitStructure);
		
		GPIO_SetBits(GPIOB,GPIO_Pin_2);
	  
	  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);     									//DOUT  芯片发送数据,单片机接收,PB0,PB1 上拉输入,  PB0-DRDY  PB1-DOUT
		GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;			     								
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;   						
		GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOB, &GPIO_InitStructure);
		


}


/***************************************************************************
函数名称:WriteOneByte(unsigned char 命令)
 
用途:写入一个字节到ADS1220
*************************************************************************/
void WriteOneByte(unsigned char command)
{
    unsigned char i;
    for(i = 0; i < 8;i++)
    {
			if(command&0x80)
			DIN_H;//ADS1220_DIN  = 1;
			else
			DIN_L;//ADS1220_DIN  = 0;/
			command <<= 1;
			Delay_5us();
			Delay_5us();
			SCK_H;//ADS1220_SCK = 1;
			Delay_5us();
			Delay_5us();
			SCK_L;//ADS1220_SCK = 0;	
			Delay_5us();
			Delay_5us();
    }
}


/***************************************************************************
*函数名称:ReadOneByte()
 
*用途:从ADS1220读取一个字节
*************************************************************************/
unsigned char ReadOneByte(void)
{
    unsigned char result,i;
	
    SCK_L;//SCLK_L;
    for(i = 0;i<8; i++)
    {
        SCK_H;
        result <<= 0x01;
        if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1))
          result |= 0X01;
		
        SCK_L;
				Delay_5us();
			  Delay_5us();
    }
	
    return result;
}
 
 
/***************************************************************************
*函数名称:ReadData()
 
*用途:从ADS1220读取数据
 
 
*************************************************************************/
unsigned long ReadData(void)
{
    unsigned long adval;
	  unsigned  char a,b,c;
	
    CS_L;
    WriteOneByte(ADS1220_RDATA);
    a = ReadOneByte();
		b = ReadOneByte();
		c = ReadOneByte();
	  adval = a;
	  adval = (adval<<8) | b;
	  adval = (adval<<8) | c;
    CS_H;		
    return adval;
}
 
/***************************************************************************
*函数名称:ADReset()
 
*用途:复位ADS1220
 
 
*************************************************************************/
void ADReset(void)
{
	CS_L;
  WriteOneByte(ADS1220_RESET);
  CS_H;
}
 
/***************************************************************************
函数名称:ADS1220_Init()
 
*用途:ADS120初始化
*************************************************************************/
void ADS1220_Init(void)
{
	CS_H;
	SCK_H;
	DIN_H;
	
	ADReset();
}
 
/***************************************************************************
*函数名称:关闭电源()
 
*************************************************************************/
void ADPowerDown(void)
{
    CS_L;
    WriteOneByte(ADS1220_POWERDOWN);
    CS_H;
}
 
/***************************************************************************
*函数名称:ADStartConversion()
 
*用途:开始转换
 
*参数:
*************************************************************************/
void ADStartConversion(void)
{
    CS_L;
    WriteOneByte(ADS1220_START);
    CS_H;
}
 
/***************************************************************************
*函数名称:ReadRegister()
 
*用途:从寄存器中读取数据
 
*参数:数据
*************************************************************************/
void ReadRegister(void)
{
  unsigned char i;
  unsigned long Data;
  CS_L;
  WriteOneByte(ADS1220_RREG|0x03);     //从寄存器00开始连续读4个字节
	for (i=0; i< 4; i++)
	{
		 Data += ReadOneByte();
	}  
	CS_H;
	return;
}
 
/***************************************************************************
*函数名:WriteRegister(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData)
 
*用途:向寄存器写入数据
 
*步骤:写地址2。写入数据
 
* Params NumRegs-----寄存器的数字
*************************************************************************/
void WriteRegister(unsigned char StartAddress, unsigned char NumRegs, unsigned char * pData)
{
    unsigned char i;
    CS_L;
    
    WriteOneByte(ADS1220_WREG | (((StartAddress<<2) & 0x0c) |((NumRegs-1)&0x03)));
 
    for (i=0; i< NumRegs; i++)
    {
      WriteOneByte(*pData);
      pData++;
    }
    CS_H;
    return;
}
 
/***************************************************************************
函数名称:CofigAD(unsigned char channel)
 
*用途:设置采样通道
 
*参数:
 
*
*************************************************************************/
void CofigAD(unsigned char channel)
{
   switch(channel)
   {
    case 0: Init_Config[0] = MUX_8 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN0,AINN = AVSS ,PGA = 1,禁用PGA
            break;
    case 1: Init_Config[0] = MUX_9 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN1,AINN = AVSS ,PGA = 1,禁用PGA
            break;
    case 2: Init_Config[0] = MUX_10 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN2,AINN = AVSS,PGA = 1,禁用PGA
            break;
    case 3: Init_Config[0] = MUX_11 | PGA_0 | PGA_BYPASS_Disable;//单端模式,选择通道AINP = AIN3,AINN = AVSS,PGA = 1,禁用PGA
            break;
	  case 4: Init_Config[0] = MUX_0 | PGA_0 | PGA_BYPASS_Disable;//差分模式,选择通道AINP = AIN0,AINN = AIN1(默认设置),PGA = 1,禁用PGA
            break;
    }
 
		Init_Config[1] = 0XC0;
//    Init_Config[2] = 0X00;
     Init_Config[2] = 0X40;
    Init_Config[3] = 0X00;
    WriteRegister(0x00,0x04,Init_Config);
    ReadRegister();
}
 
 
 
/***************************************************************************
*函数名:GetAD(unsigned char channel)
 
*目的:得到结果
*************************************************************************/
unsigned long GetAD(unsigned char channel)
{
    unsigned long Result;
	
    CofigAD(channel);
    ADStartConversion();
    while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0));//while(ADS1220_DRDY);
    Result = ReadData();
    ADPowerDown();
	
	if(Result & 0x800000)
	{
		PolarFlag = 1;
		Result =  ~Result;
		Result =Result&0xffffff;
		Result = Result+1;
	}
	else PolarFlag =0;
	
    return Result;
}
 
 
 





 

4.3 main
#include "spi.h"
#include "usart.h"
#include "stm32f0xx.h"

int main()
{
    init_usart(9600);
	ADS1220_GPIOInit();    // ADS1220 Pin 脚初始化
    while(1)
{
     //--------------测试单极性-------------------------		
		tempA = GetAD(2);//配置为单极性输入模式,通道0输入
		printf("ADC采样数值%d \r\n",tempA);
	    dianya = (float)tempA*3.300/8388608; 
		printf("电压%10f v\r\n",dianya);//显示电压V

}
}

直接打印出引脚电压信号; 

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值