今天做一下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
}
}
直接打印出引脚电压信号;