#include "ADS1256tb.h" #include "main.h" #include "cmsis_os.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) * (AVSS + 0.05V) ~ (AVDD – 1.5V) 如果AVSS = 0V,AVDD = 5.0V,则最大输入电压 = 5.0 - 1.5 = 3.5V,所以输入范围为0.05-3.5V * 可尝试关闭输入缓冲器, ****************************************************************************** */ static SPI_HandleTypeDef *ads_spi; static void ADS_Delay_us(uint16_t us) { uint32_t delay = us * (SystemCoreClock / 1000000 / 5); while (delay--) __NOP(); } static void ADS1256_SendCmd(uint8_t cmd) { ADS1256_CS_LOW(); HAL_SPI_Transmit(ads_spi, &cmd, 1, 10); ADS_Delay_us(5); ADS1256_CS_HIGH(); ADS_Delay_us(2); } static void ADS1256_WriteReg(uint8_t reg, uint8_t val) { uint8_t buf[3] = { CMD_WREG | (reg & 0x0F), 0x00, val }; ADS1256_CS_LOW(); HAL_SPI_Transmit(ads_spi, buf, 3, 10); ADS_Delay_us(5); ADS1256_CS_HIGH(); } //static uint8_t ADS1256_ReadReg(uint8_t reg) //{ // uint8_t cmd[2] = { CMD_RREG | (reg & 0x0F), 0x00 }; // uint8_t val; // ADS1256_CS_LOW(); // HAL_SPI_Transmit(ads_spi, cmd, 2, 10); // ADS_Delay_us(2); // HAL_SPI_Receive(ads_spi, &val, 1, 10); // ADS1256_CS_HIGH(); // return val; //} void ADS1256_Init(SPI_HandleTypeDef *hspi) { ads_spi = hspi; ADS1256_CS_HIGH(); osDelay(5); ADS1256_SendCmd(CMD_RESET); osDelay(5); ADS1256_SendCmd(CMD_SDATAC); // Stop continuous mode ADS1256_WriteReg(REG_STATUS, 0x06); // Auto-cal, MSB first 开启缓冲器 // 启用缓冲器的好处是输入阻抗更高、稳定性更强,但代价是 可输入范围缩窄(不能接近 AVDD) // ADS1256_WriteReg(REG_STATUS, 0x02); // 关闭输入缓冲器 ,缺少了滤波 输出偏差变大 ADS1256_WriteReg(REG_ADCON, 0x00 | GAIN_1); ADS1256_WriteReg(REG_DRATE, DRATE_1000SPS); // 数据率 ADS1256_SendCmd(CMD_SELFCAL); // Self-calibrate osDelay(10); } void ADS1256_SetChannel(uint8_t mux_pos) { while (ADS1256_DRDY_Read() == GPIO_PIN_SET); ADS1256_WriteReg(REG_MUX, mux_pos | MUX_AINCOM); // ADS1256_WriteReg(REG_MUX, mux_pos); ADS1256_SendCmd(CMD_SYNC); ADS1256_SendCmd(CMD_WAKEUP); } int32_t ADS1256_ReadChannel(uint8_t channel) { ADS1256_SetChannel(channel << 4); // AINx = channel while (ADS1256_DRDY_Read() == GPIO_PIN_SET); // 等待DRDY拉低 ADS1256_CS_LOW(); uint8_t cmd = CMD_RDATA; HAL_SPI_Transmit(ads_spi, &cmd, 1, 10); ADS_Delay_us(10); ADS_Delay_us(10); uint8_t buf[3]; HAL_SPI_Receive(ads_spi, buf, 3, 10); ADS1256_CS_HIGH(); int32_t raw = (buf[0] << 16) | (buf[1] << 8) | buf[2]; if (raw & 0x800000) raw |= 0xFF000000; // 符号扩展 return raw; } int32_t ADS1256_Readdata(void) { while (ADS1256_DRDY_Read() == GPIO_PIN_SET); // 等待DRDY拉低 ADS1256_CS_LOW(); uint8_t cmd = CMD_RDATA; HAL_SPI_Transmit(ads_spi, &cmd, 1, 10); ADS_Delay_us(10); ADS_Delay_us(10); uint8_t buf[3]; HAL_SPI_Receive(ads_spi, buf, 3, 10); ADS1256_CS_HIGH(); int32_t raw = (buf[0] << 16) | (buf[1] << 8) | buf[2]; if (raw & 0x800000) raw |= 0xFF000000; // 符号扩展 return raw; } float ADS1256_ConvertToVoltage(int32_t adc_val, float vref, uint8_t gain) { // return ((float)adc_val / 0x7FFFFF) * vref / gain *2; return ((float)adc_val / 0x400000) * vref / gain; }