123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include "ADS1256.h"
- #include "cmsis_os.h"
- #include "printf.h"
- /**
- ******************************************************************************
- * @file ADS1256.c
- ******************************************************************************
- * @attention
- * ADS1256模块
- * +5V <------ 5.0V 5V供电
- * GND ------- GND 地
- * DRDY ------> PA11 准备就绪 低准备好 高未准备好
- * CS <------ PB12 SPI_CS 低有效,操作完拉高
- * DIN <------ PB15 SPI_MOSI
- * DOUT ------> PB14 SPI_MISO
- * SCLK <------ PB13 SPI时钟
- * GND ------- GND 地
- * PDWN <------ VDD 掉电控制 常高
- * RST <------ PA8 复位信号 常高,拉低再拉高生效复位
- *
- * 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)
- ******************************************************************************
- */
- extern SPI_HandleTypeDef ADS1256_SPI_HANDLE;
- void ADS1256_SendCommand(uint8_t cmd) { // 发送单字节命令给ADS
- ADS1256_CS_LOW();
- for (volatile uint8_t i = 0; i < 5; i++) {} // ≈300~500ns 延迟
- HAL_SPI_Transmit(&ADS1256_SPI_HANDLE, &cmd, 1, SPI_TIMEOUT);
- for (volatile uint8_t i = 0; i < 5; i++) {} // ≈300~500ns 延迟
- ADS1256_CS_HIGH();
- }
- void ADS1256_WriteRegister(uint8_t reg, uint8_t value) {
- uint8_t tx[3] = {
- ADS1256_CMD_WREG | (reg & 0x0F),
- 0x00, // 写1个寄存器
- value
- };
- ADS1256_CS_LOW();
- for (volatile uint8_t i = 0; i < 5; i++) {}
- HAL_SPI_Transmit(&ADS1256_SPI_HANDLE, tx, 3, SPI_TIMEOUT);
- for (volatile uint8_t i = 0; i < 5; i++) {}
- ADS1256_CS_HIGH();
- }
- uint8_t ADS1256_ReadRegister(uint8_t reg) {
- uint8_t tx[2] = { ADS1256_CMD_RREG | (reg & 0x0F), 0x00 };
- uint8_t rx = 0;
- ADS1256_CS_LOW();
- for (volatile uint8_t i = 0; i < 5; i++) {}
- HAL_SPI_Transmit(&ADS1256_SPI_HANDLE, tx, 2, SPI_TIMEOUT);
- for (volatile uint8_t i = 0; i < 5; i++) {} // ≈读取前延迟
- HAL_SPI_Receive(&ADS1256_SPI_HANDLE, &rx, 1, SPI_TIMEOUT);
- for (volatile uint8_t i = 0; i < 5; i++) {}
- ADS1256_CS_HIGH();
- return rx;
- }
- void ADS1256_Reset(void) { // 复位
- ADS1256_RST_LOW();
- osDelay(1);
- ADS1256_RST_HIGH();
- osDelay(5);
- ADS1256_SendCommand(ADS1256_CMD_RESET); // 软件复位
- osDelay(5);
- }
- void ADS1256_SetChannel(uint8_t mux) { // 设置输入通道(MUX 寄存器值)
- ADS1256_WriteRegister(ADS1256_REG_MUX, mux);
- ADS1256_SendCommand(ADS1256_CMD_SYNC);
- ADS1256_SendCommand(ADS1256_CMD_WAKEUP);
- }
- void ADS1256_SetGain(ADS1256_Gain_t gain) { // 设置增益
- uint8_t adcon = ADS1256_ReadRegister(ADS1256_REG_ADCON);
- adcon &= 0xF8;
- adcon |= (gain & 0x07);
- ADS1256_WriteRegister(ADS1256_REG_ADCON, adcon);
- }
- void ADS1256_SetDataRate(ADS1256_DataRate_t dr) { // 设置采样率
- ADS1256_WriteRegister(ADS1256_REG_DRATE, (uint8_t)dr);
- }
- void ADS1256_StartConversion(void) { // 启动一次转换
- ADS1256_SendCommand(ADS1256_CMD_SYNC);
- ADS1256_SendCommand(ADS1256_CMD_WAKEUP);
- ADS1256_SendCommand(ADS1256_CMD_RDATA);
- }
- uint8_t ADS1256_ReadID(void) { // 读取芯片 ID(高 4 位) ID高4位应该是0x03
- ADS1256_SendCommand(ADS1256_CMD_SYNC);
- osDelay(1); // 延迟 ≥6us,这里用1ms最保险,兼容RTOS调度延迟
- ADS1256_SendCommand(ADS1256_CMD_WAKEUP);
- for (volatile uint8_t i = 0; i < 5; i++) {} // 补一点 CS 往后延
- uint8_t status = ADS1256_ReadRegister(ADS1256_REG_STATUS);
- return (status >> 4) & 0x0F;
- }
- bool ADS1256_ReadData(int32_t* out) { // 读取数据(需判断 DRDY 是否为低)
- uint8_t rx[3];
- if (HAL_GPIO_ReadPin(ADS1256_DRDY_GPIO_PORT, ADS1256_DRDY_PIN) != GPIO_PIN_RESET) {
- ADS_PRINTF("[ADS1256] DRDY pin not low, skipping read.\r\n");
- return false;
- }
- ADS1256_CS_LOW();
- HAL_SPI_Receive(&ADS1256_SPI_HANDLE, rx, 3, SPI_TIMEOUT);
- ADS1256_CS_HIGH();
- *out = ((int32_t)rx[0] << 16) | ((int32_t)rx[1] << 8) | rx[2];
- if (*out & 0x800000) *out |= 0xFF000000; // Sign extend if negative
- return true;
- }
- float ADS1256_ConvertToVoltage(int32_t raw, float vref, int gain) {
- return ((float)raw / 8388608.0f) * (vref / gain); // V = (raw / 2的23次方 —— 8388608)* (vref / gain) 单位V ,2的22次方= 4194304
- }
- void ADS1256_SetClockSource(uint8_t useInternal) // CLK = 0:使用外部晶振 1:使用内部晶振
- {
- if (useInternal > 1) return;
- uint8_t status = ADS1256_ReadRegister(ADS1256_REG_STATUS);
- if (useInternal)
- status |= (1 << 2); // CLK = 1:使用内部晶振
- else
- status &= ~(1 << 2); // CLK = 0:使用外部晶振
- ADS1256_WriteRegister(ADS1256_REG_STATUS, status);
- }
- bool ADS1256_IsUsingExternalClock(void)
- {
- uint8_t status = ADS1256_ReadRegister(ADS1256_REG_STATUS);
- return (status & (1 << 3)) != 0; // CLKSTAT
- }
- void ADS1256_Init(void) { // 初始化 ADS1256
- // ADS1256_Reset();
- // osDelay(50);
- // 默认外部晶振,连续采样模式
- HAL_GPIO_WritePin(GPIOB, ADS_SYNC_PDWN_Pin, GPIO_PIN_SET);
- HAL_GPIO_WritePin(GPIOB, ADS_SYNC_PDWN_Pin, GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB, ADS_SYNC_PDWN_Pin, GPIO_PIN_SET);
-
- ADS1256_SetClockSource(0); // 0使用外部晶振 1内部晶振
- ADS1256_WriteRegister(ADS1256_REG_STATUS, 0x06); // 0000 0 110 自动校准开启(ACAL = 1), 输入缓冲器关闭(BUFEN = 0)
- ADS1256_WriteRegister(ADS1256_REG_ADCON, 0x20); // 时钟输出禁用(CLKOUT = 00), 增益为1倍(输入是几mV,增益增大至8)
- ADS1256_SetDataRate(ADS1256_DR_1000SPS); // ADS1256_DR_1000SPS
- ADS1256_SetChannel(ADS1256_MUX_AIN0_AINCOM); // AIN1 - AINCOM
- ADS1256_SendCommand(ADS1256_CMD_SELFCAL);// 启动自动增益和偏移校准 必须最后执行该指令
- ADS1256_SendCommand(ADS1256_CMD_RDATAC); // 连续采样
- }
|