ads1243

1721
  • admin
    ///-----------------------------------------------------------------------------
    /// ADS1243 驱动 - Arduino Nano
    /// 硬件配置: CS 接地, PDWN 接 VDD
    ///-----------------------------------------------------------------------------
    #include <SPI.h>
    
    // ==================== 引脚定义 ====================
    // CS 已接地,不需要定义
    // PDWN 已接 VDD,不需要定义
    const int PIN_DRDY  = 9;      // 数据就绪
    const int PIN_LED   = 13;     // 板载 LED
    
    // ==================== SPI 设置 ====================
    SPISettings spiSettings(250000, MSBFIRST, SPI_MODE1);
    
    // ==================== 寄存器地址 ====================
    enum ADS1243_REG {
        SETUP_REG = 0x00,
        MUX_REG   = 0x01,
        ACR_REG   = 0x02,
        ODAC_REG  = 0x03,
        DIO_REG   = 0x04,
        DIR_REG   = 0x05,
        IOCON_REG = 0x06,
        OCR0_REG  = 0x07,
        OCR1_REG  = 0x08,
        OCR2_REG  = 0x09,
        FSR0_REG  = 0x0A,
        FSR1_REG  = 0x0B,
        FSR2_REG  = 0x0C,
        DOR2_REG  = 0x0D,
        DOR1_REG  = 0x0E,
        DOR0_REG  = 0x0F
    };
    
    // ==================== 命令 ====================
    enum ADS1243_CMD {
        RDATA_CMD     = 0x01,
        RDATAC_CMD    = 0x03,
        STOPC_CMD     = 0x0F,
        RREG_CMD      = 0x10,
        WREG_CMD      = 0x50,
        SELFCAL_CMD   = 0xF0,
        SELFOCAL_CMD  = 0xF1,
        SELFGCAL_CMD  = 0xF2,
        SYSOCAL_CMD   = 0xF3,
        SYSGCAL_CMD   = 0xF4,
        WAKEUP_CMD    = 0xFB,
        DSYNC_CMD     = 0xFC,
        SLEEP_CMD     = 0xFD,
        RESET_CMD     = 0xFE
    };
    
    // ==================== 寄存器位定义 ====================
    #define SETUP_BOCS    0x08
    #define SETUP_GAIN_1   0x00
    #define SETUP_GAIN_2   0x01
    #define SETUP_GAIN_4   0x02
    #define SETUP_GAIN_8   0x03
    #define SETUP_GAIN_16  0x04
    #define SETUP_GAIN_32  0x05
    #define SETUP_GAIN_64  0x06
    #define SETUP_GAIN_128 0x07
    
    #define ACR_U_BIPOLAR  0x40
    #define ACR_SPEED      0x20
    #define ACR_BUFEN      0x10
    #define ACR_RANGE      0x04
    #define ACR_DR_15HZ    0x00
    #define ACR_DR_7_5HZ   0x01
    #define ACR_DR_3_75HZ  0x02
    
    // ==================== 全局变量 ====================
    int32_t adcValue;
    
    // ==================== SPI 事务宏(CS 已接地,无需控制) ====================
    #define SPI_START() do { \
        SPI.beginTransaction(spiSettings); \
    } while(0)
    
    #define SPI_END() do { \
        SPI.endTransaction(); \
    } while(0)
    
    // ==================== 核心函数 ====================
    
    /**
     * @brief 等待 DRDY 变为低电平(数据就绪)
     * @param timeout_ms 超时时间(毫秒)
     * @return true=就绪, false=超时
     */
    static bool waitDrdy(unsigned long timeout_ms = 1000) {
        unsigned long start = millis();
        while (digitalRead(PIN_DRDY) == HIGH) {
            if (millis() - start > timeout_ms) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * @brief 发送单字节命令
     */
    static void sendCmd(uint8_t cmd) {
        if (!waitDrdy()) return;
        SPI_START();
        SPI.transfer(cmd);
        SPI_END();
        // 校准命令需要额外等待
        if (cmd == SELFCAL_CMD || cmd == SELFOCAL_CMD || 
            cmd == SELFGCAL_CMD || cmd == SYSOCAL_CMD || 
            cmd == SYSGCAL_CMD) {
            delay(200);
        }
    }
    
    /**
     * @brief 写寄存器
     */
    static void writeReg(uint8_t reg, uint8_t value) {
        if (!waitDrdy()) return;
        SPI_START();
        SPI.transfer(WREG_CMD | reg);
        SPI.transfer(0x00);        // 写入 1 个寄存器
        SPI.transfer(value);
        SPI_END();
    }
    
    /**
     * @brief 读寄存器
     */
    static uint8_t readReg(uint8_t reg) {
        if (!waitDrdy()) return 0xFF;
        SPI_START();
        SPI.transfer(RREG_CMD | reg);
        SPI.transfer(0x00);        // 读取 1 个寄存器
        uint8_t value = SPI.transfer(0xFF);
        SPI_END();
        return value;
    }
    
    /**
     * @brief 读取 ADC 转换数据(24位有符号)
     */
    static int32_t readData(void) {
        if (!waitDrdy()) return 0;
        
        SPI_START();
        SPI.transfer(RDATA_CMD);
        delayMicroseconds(50);     // 等待数据准备 (t6)
        
        uint32_t raw = 0;
        raw |= (uint32_t)SPI.transfer(0xFF) << 16;
        raw |= (uint32_t)SPI.transfer(0xFF) << 8;
        raw |= (uint32_t)SPI.transfer(0xFF);
        SPI_END();
        
        return (int32_t)(raw << 8) >> 8;
    }
    
    /**
     * @brief 读取完整的校准寄存器值(24位)
     */
    static uint32_t readCalReg(uint8_t reg_high) {
        uint32_t value = 0;
        value |= (uint32_t)readReg(reg_high) << 16;
        value |= (uint32_t)readReg(reg_high + 1) << 8;
        value |= (uint32_t)readReg(reg_high + 2);
        return value;
    }
    
    /**
     * @brief 设置通道和增益
     * @param pos_channel 正输入端 0~7 (AIN0~AIN7)
     * @param neg_channel 负输入端 0~7 (AIN0~AIN7)
     * @param gain        0~7 (1,2,4,8,16,32,64,128)
     */
    static void setChannel(uint8_t pos_channel, uint8_t neg_channel, uint8_t gain) {
        if (pos_channel > 7 || neg_channel > 7) return;
        writeReg(MUX_REG, (pos_channel << 4) | neg_channel);
        writeReg(SETUP_REG, gain & 0x07);
    }
    
    /**
     * @brief 执行自校准(偏移+增益)
     */
    static void selfCalibrate(void) {
        uint8_t setup = readReg(SETUP_REG);
        uint8_t current_gain = setup & 0x07;
        
        // 增益校准:PGA 必须为 1
        if (current_gain != SETUP_GAIN_1) {
            writeReg(SETUP_REG, SETUP_GAIN_1);
            delay(10);
        }
        sendCmd(SELFGCAL_CMD);
        
        // 恢复增益并做偏移校准
        if (current_gain != SETUP_GAIN_1) {
            writeReg(SETUP_REG, current_gain);
            delay(10);
        }
        sendCmd(SELFOCAL_CMD);
    }
    
    /**
     * @brief 打印所有寄存器(调试用)
     */
    static void printRegisters(void) {
        Serial.println("--- ADC Registers ---");
        Serial.print("SETUP: 0x"); Serial.println(readReg(SETUP_REG), HEX);
        Serial.print("MUX:   0x"); Serial.println(readReg(MUX_REG), HEX);
        Serial.print("ACR:   0x"); Serial.println(readReg(ACR_REG), HEX);
        Serial.print("ODAC:  0x"); Serial.println(readReg(ODAC_REG), HEX);
        Serial.print("DIO:   0x"); Serial.println(readReg(DIO_REG), HEX);
        Serial.print("DIR:   0x"); Serial.println(readReg(DIR_REG), HEX);
        Serial.print("IOCON: 0x"); Serial.println(readReg(IOCON_REG), HEX);
        
        uint32_t ocr = readCalReg(OCR2_REG);
        uint32_t fsr = readCalReg(FSR2_REG);
        Serial.print("OCR:   0x"); Serial.println(ocr, HEX);
        Serial.print("FSR:   0x"); Serial.println(fsr, HEX);
        Serial.println("----------------------");
    }
    
    // ==================== 初始化 ====================
    void setup() {
        pinMode(PIN_DRDY, INPUT);
        pinMode(PIN_LED, OUTPUT);
        
        // PDWN 已接 VDD,不需要控制
        // CS 已接地,不需要控制
        
        SPI.begin();
        
        Serial.begin(115200);
        while (!Serial) { delay(10); }
        
        Serial.println("ADS1243 Initializing...");
        Serial.println("CS = GND, PDWN = VDD");
        
        // 1. 复位芯片
        sendCmd(RESET_CMD);
        delay(10);
        
        // 2. 配置: AIN0(+) AIN1(-), 增益 1
        setChannel(0, 1, SETUP_GAIN_1);
        
        // 3. 配置 ACR: 双极性 + 缓冲器 + 15SPS
        writeReg(ACR_REG, ACR_U_BIPOLAR | ACR_BUFEN | ACR_DR_15HZ);
        
        // 4. 自校准
        Serial.println("Self-calibrating...");
        selfCalibrate();
        
        // 5. 打印寄存器
        printRegisters();
        
        Serial.println("Ready!");
    }
    
    // ==================== 主循环 ====================
    void loop() {
        adcValue = readData();
        
        Serial.print("ADC: ");
        Serial.println(adcValue);
        
        digitalWrite(PIN_LED, HIGH);
        delay(50);
        digitalWrite(PIN_LED, LOW);
        
        delay(500);
    }
  • admin
    #1
    // ============================================================
    // ADS1243 简洁驱动 - Arduino Nano
    // 硬件: CS 接地, PDWN 接 VDD
    // ============================================================
    
    #include <SPI.h>
    
    const int PIN_DRDY = 9;   // 数据就绪(低电平有效)
    const int PIN_LED  = 13;  // 板载 LED
    
    // SPI 设置: 250kHz, MSB先传, 模式1
    SPISettings spiSettings(250000, MSBFIRST, SPI_MODE1);
    
    // 命令
    #define RDATA  0x01
    #define RREG   0x10
    #define WREG   0x50
    #define RESET  0xFE
    
    // 寄存器
    #define SETUP  0x00
    #define MUX    0x01
    #define ACR    0x02
    
    // 增益
    #define GAIN_1   0x00
    #define GAIN_2   0x01
    #define GAIN_4   0x02
    #define GAIN_8   0x03
    #define GAIN_16  0x04
    #define GAIN_32  0x05
    #define GAIN_64  0x06
    #define GAIN_128 0x07
    
    // ============================================================
    // 等待 DRDY 变低(数据就绪)
    // ============================================================
    bool waitDrdy(unsigned long timeout_ms = 1000) {
        unsigned long t0 = millis();
        while (digitalRead(PIN_DRDY) == HIGH) {
            if (millis() - t0 > timeout_ms) return false;
        }
        return true;
    }
    
    // ============================================================
    // 写寄存器
    // ============================================================
    void writeReg(uint8_t reg, uint8_t val) {
        if (!waitDrdy()) return;
        SPI.beginTransaction(spiSettings);
        SPI.transfer(WREG | reg);   // 写命令 + 寄存器地址
        SPI.transfer(0x00);         // 写1个寄存器 (n-1)
        SPI.transfer(val);
        SPI.endTransaction();
    }
    
    // ============================================================
    // 读寄存器
    // ============================================================
    uint8_t readReg(uint8_t reg) {
        if (!waitDrdy()) return 0xFF;
        SPI.beginTransaction(spiSettings);
        SPI.transfer(RREG | reg);   // 读命令 + 寄存器地址
        SPI.transfer(0x00);         // 读1个寄存器 (n-1)
        uint8_t v = SPI.transfer(0xFF);
        SPI.endTransaction();
        return v;
    }
    
    // ============================================================
    // 读取 ADC 数据(24位有符号)
    // ============================================================
    int32_t readADC() {
        if (!waitDrdy()) return 0;
        
        SPI.beginTransaction(spiSettings);
        SPI.transfer(RDATA);
        delayMicroseconds(10);      // t6 等待
        
        uint32_t raw = 0;
        raw |= (uint32_t)SPI.transfer(0xFF) << 16;
        raw |= (uint32_t)SPI.transfer(0xFF) << 8;
        raw |= (uint32_t)SPI.transfer(0xFF);
        SPI.endTransaction();
        
        // 24位有符号扩展
        return (int32_t)(raw << 8) >> 8;
    }
    
    // ============================================================
    // 设置通道和增益
    // pos, neg: 0~7 对应 AIN0~AIN7
    // gain:     0~7 对应 1,2,4,8,16,32,64,128
    // ============================================================
    void setChannel(uint8_t pos, uint8_t neg, uint8_t gain) {
        writeReg(MUX, (pos << 4) | neg);
        writeReg(SETUP, gain & 0x07);
    }
    
    // ============================================================
    // 初始化
    // ============================================================
    void setup() {
        pinMode(PIN_DRDY, INPUT);
        pinMode(PIN_LED, OUTPUT);
        pinMode(10, OUTPUT);          // SS 必须设为输出,否则 SPI 可能进从机模式
        
        SPI.begin();
        Serial.begin(115200);
        
        // 复位
        SPI.beginTransaction(spiSettings);
        SPI.transfer(RESET);
        SPI.endTransaction();
        delay(10);
        
        // 配置: AIN0(+)/AIN1(-), 增益1
        setChannel(0, 1, GAIN_1);
        
        // 配置 ACR: 双极性 + 缓冲器 + 15SPS
        writeReg(ACR, 0x54);  // 0x54 = 双极性|缓冲器|15SPS
        
        Serial.println("ADS1243 Ready");
    }
    
    // ============================================================
    // 主循环
    // ============================================================
    void loop() {
        int32_t val = readADC();
        
        Serial.print("ADC: ");
        Serial.println(val);
        
        digitalWrite(PIN_LED, !digitalRead(PIN_LED));
        delay(100);   // 15SPS下约66ms一次转换,100ms读取不会丢太多
    }

发表回复

登录后回复