/*
*********************************************************************************************************
*
* 模块名称 : ADS1256 驱动模块(8通道带PGA的24位ADC)
* 文件名称 : bsp_ads1256.c
* 版 本 : V1.0
* 说 明 : ADS1256模块和CPU之间采用SPI接口。本驱动程序支持硬件SPI接口和软件SPI接口。
* 通过宏切换。
*
* 修改记录 :
* 版本号 日期 作者 说明
* V1.0 2014-01-01 armfly 正式发布
*
* Copyright (C), 2013-2014, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#include "bsp.h"
#define SOFT_SPI /* 定义此行表示使用GPIO模拟SPI接口 */
//#define HARD_SPI /* 定义此行表示使用CPU的硬件SPI接口 */
/*
ADS1256模块可以直接插到STM32-V5开发板CN26排母(2*6P 2.54mm)接口上.
ADS1256模块 STM32-V5开发板
+5V <------ 5.0V 5V供电
GND ------- GND 地
DRDY ------> PH9 准备就绪
CS <------ PH10 SPI_CS
DIN <------ PH11 SPI_MOSI
DOUT ------> PA5 SPI_MISO
SCLK <------ PA4 SPI时钟
GND ------- GND 地
PDWN <------ PA0 掉电控制
RST <------ PC0 复位信号
NC 空脚
NC 空脚
*/
/*
ADS1256基本特性:
1、模拟部分供电5V;
2、SPI数字接口电平:3.3V
3、PGA设置范围: 1、2、4、8、16、32、64、
4、参考电压2.5V (推荐缺省的,外置的)
5、输入电压范围:PGA = 1 时, 可输入正负5V
6. 自动校准 (当设置了PGA,BUF使能、数据采样率时,会启动自校准)
7. 输入的缓冲器可设置启用和关闭(一般选启用)
外部晶振频率 = 7.68MHz,
时钟频率 tCLK = 1/7.68M = 0.13uS
输出数据周期 tDATA = 1 / 30K = 0.033mS (按30Ksps计算)
对SPI的时钟速度要求: (ads1256.pdf page 6)
最快 4个tCLK = 0.52uS
最慢 10个tDATA = 0.3mS (按 30Ksps 计算)
SCL高电平和低电平持续时间最小 200ns
RREG, WREG, RDATA 命令之后,需要延迟 4 * tCLK = 0.52uS;
RDATAC, RESET, SYNC 命令之后,需要延迟 24 * tCLK = 3.12uS;
实际测试,在3.3V上电后, 及时不做任何配置,ADS125的DRDY 口线即开始输出脉冲信号(2.6us高,33.4低,频率30KHz)
*/
/*
调试记录
(1) 设置寄存器时,SCK过快导致芯片不能每次都收到数据。原因: 发送的相邻的字节之间需要延迟一小段时间.
(2) 连续复位CPU时,偶尔出现芯片输出采样率异常。
*/
#if !defined(SOFT_SPI) && !defined(HARD_SPI)
#error "Please define SPI Interface mode : SOFT_SPI or HARD_SPI"
#endif
#ifdef SOFT_SPI /* 软件SPI */
/* 定义GPIO端口 */
#define RCC_SCK RCC_AHB1Periph_GPIOA
#define PORT_SCK GPIOA
#define PIN_SCK GPIO_Pin_4
#define RCC_DIN RCC_AHB1Periph_GPIOH
#define PORT_DIN GPIOH
#define PIN_DIN GPIO_Pin_11
#define RCC_CS RCC_AHB1Periph_GPIOH
#define PORT_CS GPIOH
#define PIN_CS GPIO_Pin_10
#define RCC_RESET RCC_AHB1Periph_GPIOC
#define PORT_RESET GPIOC
#define PIN_RESET GPIO_Pin_0
#define RCC_PWDN RCC_AHB1Periph_GPIOA
#define PORT_PWDN GPIOA
#define PIN_PWDN GPIO_Pin_0
#define RCC_DRDY RCC_AHB1Periph_GPIOH
#define PORT_DRDY GPIOH
#define PIN_DRDY GPIO_Pin_9
#define RCC_DOUT RCC_AHB1Periph_GPIOA
#define PORT_DOUT GPIOA
#define PIN_DOUT GPIO_Pin_5
/* 定义口线置0和置1的宏 */
#define PWDN_0() GPIO_ResetBits(PORT_PWDN, PIN_PWDN)
#define PWDN_1() GPIO_SetBits(PORT_PWDN, PIN_PWDN)
#define RESET_0() GPIO_ResetBits(PORT_RESET, PIN_RESET)
#define RESET_1() GPIO_SetBits(PORT_RESET, PIN_RESET)
#define CS_0() GPIO_ResetBits(PORT_CS, PIN_CS)
#define CS_1() GPIO_SetBits(PORT_CS, PIN_CS)
#define SCK_0() GPIO_ResetBits(PORT_SCK, PIN_SCK)
#define SCK_1() GPIO_SetBits(PORT_SCK, PIN_SCK)
#define DI_0() GPIO_ResetBits(PORT_DIN, PIN_DIN)
#define DI_1() GPIO_SetBits(PORT_DIN, PIN_DIN)
#define DO_IS_HIGH() (GPIO_ReadInputDataBit(PORT_DOUT, PIN_DOUT) == Bit_SET)
#define DRDY_IS_LOW() (GPIO_ReadInputDataBit(PORT_DRDY, PIN_DRDY) == Bit_RESET)
#endif
#ifdef HARD_SPI /* 硬件SPI */
;
#endif
/* 寄存器定义: Table 23. Register Map --- ADS1256数据手册第30页 */
enum
{
/* 寄存器地址, 后面是复位后缺省值 */
REG_STATUS = 0, // x1H
REG_MUX = 1, // 01H
REG_ADCON = 2, // 20H
REG_DRATE = 3, // F0H
REG_IO = 4, // E0H
REG_OFC0 = 5, // xxH
REG_OFC1 = 6, // xxH
REG_OFC2 = 7, // xxH
REG_FSC0 = 8, // xxH
REG_FSC1 = 9, // xxH
REG_FSC2 = 10, // xxH
};
/* 命令定义: TTable 24. Command Definitions --- ADS1256数据手册第34页 */
enum
{
CMD_WAKEUP = 0x00, // Completes SYNC and Exits Standby Mode 0000 0000 (00h)
CMD_RDATA = 0x01, // Read Data 0000 0001 (01h)
CMD_RDATAC = 0x03, // Read Data Continuously 0000 0011 (03h)
CMD_SDATAC = 0x0F, // Stop Read Data Continuously 0000 1111 (0Fh)
CMD_RREG = 0x10, // Read from REG rrr 0001 rrrr (1xh)
CMD_WREG = 0x50, // Write to REG rrr 0101 rrrr (5xh)
CMD_SELFCAL = 0xF0, // Offset and Gain Self-Calibration 1111 0000 (F0h)
CMD_SELFOCAL= 0xF1, // Offset Self-Calibration 1111 0001 (F1h)
CMD_SELFGCAL= 0xF2, // Gain Self-Calibration 1111 0010 (F2h)
CMD_SYSOCAL = 0xF3, // System Offset Calibration 1111 0011 (F3h)
CMD_SYSGCAL = 0xF4, // System Gain Calibration 1111 0100 (F4h)
CMD_SYNC = 0xFC, // Synchronize the A/D Conversion 1111 1100 (FCh)
CMD_STANDBY = 0xFD, // Begin Standby Mode 1111 1101 (FDh)
CMD_RESET = 0xFE, // Reset to Power-Up Values 1111 1110 (FEh)
};
static void ADS1256_Send8Bit(uint8_t _data);
static uint8_t ADS1256_Recive8Bit(void);
static void ADS1256_WaitDRDY(void);
static void ADS1256_ResetHard(void);
static void ADS1256_DelaySCLK(void);
static void ADS1256_DelayDATA(void);
static void ADS1256_WriteCmd(uint8_t _cmd);
static void ADS1256_WriteReg(uint8_t _RegID, uint8_t _RegValue);
static uint8_t ADS1256_ReadReg(uint8_t _RegID);
static int32_t ADS1256_ReadData(void);
static void ADS1256_SetChannal(uint8_t _ch);
//static void ADS1256_SetDiffChannal(uint8_t _ch);
ADS1256_VAR_T g_tADS1256;
static const uint8_t s_tabDataRate[ADS1256_DRATE_MAX] =
{
0xF0, /* 复位时缺省值 */
0xE0,
0xD0,
0xC0,
0xB0,
0xA1,
0x92,
0x82,
0x72,
0x63,
0x53,
0x43,
0x33,
0x20,
0x13,
0x03
};
/*
*********************************************************************************************************
* 函 数 名: bsp_InitADS1256
* 功能说明: 配置STM32的GPIO和SPI接口,用于连接 ADS1256
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitADS1256(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
#ifdef SOFT_SPI
RESET_1();
PWDN_1();
CS_1();
SCK_0(); /* SPI总线空闲时,钟线是低电平 */
DI_1();
/* 打开GPIO时钟 */
RCC_AHB1PeriphClockCmd(RCC_SCK | RCC_DIN | RCC_DOUT | RCC_CS | RCC_DRDY | RCC_RESET | RCC_PWDN, ENABLE);
/* 配置几个推完输出IO */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /* 设为输出口 */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 设为推挽模式 */
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /* 上下拉电阻不使能 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; /* IO口最大速度 */
GPIO_InitStructure.GPIO_Pin = PIN_SCK;
GPIO_Init(PORT_SCK, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_DIN;
GPIO_Init(PORT_DIN, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_CS;
GPIO_Init(PORT_CS, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_RESET;
GPIO_Init(PORT_RESET, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_PWDN;
GPIO_Init(PORT_PWDN, &GPIO_InitStructure);
/* 配置GPIO为浮动输入模式(实际上CPU复位后就是输入状态) */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; /* 设为输入口 */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 设为推挽模式 */
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /* 无需上下拉电阻 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* IO口最大速度 */
GPIO_InitStructure.GPIO_Pin = PIN_DOUT;
GPIO_Init(PORT_DOUT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin