三线噪声传感器连接ad7705读取的值一直是0v为什么

#include <Arduino.h>
#include <arduino-timer.h>

extern volatile bool timerFlag;  // 定时器标志
extern volatile bool newDataAvailable; // 新数据标志
extern float latestVoltage;       // 最新电压值


float Fb;
unsigned long Time = 0; 
float voltage;



// ====== 硬件配置 ======
#define TM7705_CS  10      // 片选引脚 (PORTB2)
#define TM7705_CLK 13      // 时钟引脚 (PORTB5)
#define TM7705_DIN 11      // 数据输入 (PORTB3)
#define TM7705_DOUT 12     // 数据输出 (PORTB4)
 
// ====== 寄存器定义 ======
#define REG_COMM   0x00    // 通信寄存器
#define REG_SETUP  0x10    // 设置寄存器
#define REG_CLOCK  0x20    // 时钟寄存器
#define REG_DATA   0x30    // 数据寄存器
 
// ====== 通道选择 ======
#define CH1_AIN1_P_AIN1_N 0x00  // 通道1
 
// ====== 全局变量 ======
const float vref = 2.5;          // 参考电压(根据实际模块调整)
volatile bool timerFlag = false;  // 定时器标志
volatile bool newDataAvailable = false; // 新数据标志
float latestVoltage = 0.0;       // 最新电压值
 
// ====== 优化的软件SPI传输 ======
byte TM7705_SPI_Transfer(byte data) {
  byte received = 0;
  for (int i = 7; i >= 0; i--) {
    // CLK下降沿
    PORTB &= ~(1 << PORTB5);              // CLK LOW
    delayMicroseconds(1);
    if (data & (1 << i)) PORTB |= (1 << PORTB3);  // DIN HIGH
    else PORTB &= ~(1 << PORTB3);         // DIN LOW
    // asm("nop"); asm("nop");              // 短暂延时
    delayMicroseconds(1);
    
    // CLK上升沿读取数据
    PORTB |= (1 << PORTB5);               // CLK HIGH
    delayMicroseconds(1);
    if (PINB & (1 << PORTB4)) received |= (1 << i); // 读取DOUT
    // asm("nop"); asm("nop");
  }
  return received;
}
 
// ====== TM7705初始化 ======
void TM7705_Init() {
  // 配置引脚方向
  DDRB |= (1 << DDB2) | (1 << DDB5); // CS, CLK为输出 (PORTD)
  DDRB |= (1 << DDB4);               // DIN为输出 (PORTB)
  DDRB &= ~(1 << DDB3);              // DOUT为输入 (PORTB)
  
  // 初始状态
  PORTB |= (1 << PORTB2);  // CS HIGH
  PORTB |= (1 << PORTB5);  // CLK HIGH
 
  // 硬件复位
  PORTB &= ~(1 << PORTB2); // CS LOW
  for (int i = 0; i < 10; i++) TM7705_SPI_Transfer(0xFF);
  PORTB |= (1 << PORTB2);  // CS HIGH
  delay(10);
 
  // 配置寄存器(50Hz输出率,增益=1)
  TM7705_WriteReg(REG_CLOCK, 0x0C);  // 50Hz
  TM7705_WriteReg(REG_SETUP, 0x45);  // 自校准,单极性
  Serial.println("Waiting for calibration...");
  uint32_t startTime = millis();
  while (digitalRead(TM7705_DOUT) == HIGH) {
    if (millis() - startTime > 1000) {
      Serial.println("Calibration timeout!");
      break;
    }
    delay(1);
  }
  Serial.println("Calibration done.");
}
 
// ====== 写寄存器 ======
void TM7705_WriteReg(byte regAddr, byte data) {
  PORTB &= ~(1 << PORTB2); // CS LOW
  TM7705_SPI_Transfer(regAddr);
  TM7705_SPI_Transfer(data);
  PORTB |= (1 << PORTB2);  // CS HIGH
}

// ====== 非阻塞式读取ADC ======
bool TM7705_ReadADC_NonBlocking(byte channel, int16_t *result) {
  static uint32_t lastReadTime = 0;
  static byte state = 0;
  
  switch (state) {
    case 0: // 启动转换
      TM7705_WriteReg(REG_COMM, channel);
      lastReadTime = millis();
      state = 1;
      break;
      
    case 1: // 等待转换完成
      if (digitalRead(TM7705_DOUT) == LOW) {
        PORTB &= ~(1 << PORTB2); // CS LOW
        TM7705_SPI_Transfer(REG_DATA | 0x08);
        *result = TM7705_SPI_Transfer(0x00) << 8;
        *result |= TM7705_SPI_Transfer(0x00);
        PORTB |= (1 << PORTB2);  // CS HIGH
        state = 0;
        return true;
      }
      // 超时检测(防止卡死)
      else if (millis() - lastReadTime > 100) {
        state = 0;
      }
      break;
  }
  return false;
}

// ====== 精确电压计算 ======
float ReadPreciseVoltage() {
  const uint8_t numSamples = 5;  // 采样次数
  int32_t sum = 0;
  int16_t adcValue;
  
  for (int i = 0; i < numSamples; i++) {
    while (!TM7705_ReadADC_NonBlocking(CH1_AIN1_P_AIN1_N, &adcValue)) {
      // 可在此处执行其他任务
    }
    sum += adcValue;
  }
  
  // 转换为电压(单极性模式)
  float voltage = ((sum / (float)numSamples) / 32768.0) * vref;
  return voltage;

}

void setup() 
{  
  
  Serial.begin(9600);
  TM7705_Init();
  initTimer1();
  delay(300);
  
}

void loop() 
{
  if (timerFlag) {
    timerFlag = false;  // 清除标志
    
    // 读取电压值
    voltage = ReadPreciseVoltage();
    Fb = voltage * 40;
    newDataAvailable = true;
  }
  
  if (newDataAvailable) {
    Serial.print("Voltage: ");
    Serial.print(voltage, 4);
    Serial.println(" V");
    newDataAvailable = false;
  }
  
}

// ====== 定时器1中断服务程序 ======
ISR(TIMER1_COMPA_vect) {
  timerFlag = true;  // 设置定时器标志
}

// ====== 初始化定时器1 ======
void initTimer1() {
  noInterrupts();           // 禁用所有中断
  TCCR1A = 0;               // 清零TCCR1A寄存器
  TCCR1B = 0;               // 清零TCCR1B寄存器
  TCNT1  = 0;               // 计数器初始化为0
  
  // 设置比较匹配寄存器为100ms
  // 16MHz时钟,预分频1024,计数到1562 = (16,000,000/(1024*10))-1
  OCR1A = 12499;     //100ms,1562   200ms,12499   500ms,31249
  TCCR1B |= (1 << WGM12);   // CTC模式
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024预分频
  TIMSK1 |= (1 << OCIE1A);  // 启用定时器比较中断
  interrupts();             // 启用所有中断
}

强调文本

卡了很久希望有人帮下我

Topic: 三线噪声传感器连接ad7705读取的值一直是0v为什么
The three-wire noise sensor connected to the AD7705 reads the value of 0V all the time

请格式化您的代码并将其放在 "code" 块中。
Please, format your code and place it in a "code" block.

#include <Arduino.h>
#include <arduino-timer.h>
extern volatile bool timerFlag; // 定时器标志
extern volatile bool newDataAvailable; // 新数据标志
extern float latestVoltage; // 最新电压值
float Fb;
unsigned long Time = 0;
float voltage;

// ====== 硬件配置 ======
#define TM7705_CS 10 // 片选引脚 (PORTB2)
#define TM7705_CLK 13 // 时钟引脚 (PORTB5)
#define TM7705_DIN 11 // 数据输入 (PORTB3)
#define TM7705_DOUT 12 // 数据输出 (PORTB4)

// ====== 寄存器定义 ======
#define REG_COMM 0x00 // 通信寄存器
#define REG_SETUP 0x10 // 设置寄存器
#define REG_CLOCK 0x20 // 时钟寄存器
#define REG_DATA 0x30 // 数据寄存器

// ====== 通道选择 ======
#define CH1_AIN1_P_AIN1_N 0x00 // 通道1

// ====== 全局变量 ======
const float vref = 2.5; // 参考电压(根据实际模块调整)
volatile bool timerFlag = false; // 定时器标志
volatile bool newDataAvailable = false; // 新数据标志
float latestVoltage = 0.0; // 最新电压值

// ====== 优化的软件SPI传输 ======
byte TM7705_SPI_Transfer(byte data) {
  byte received = 0;
  for (int i = 7; i >= 0; i--) {
    // CLK下降沿
    PORTB &= ~(1 << PORTB5); // CLK LOW
    delayMicroseconds(1);
    if (data & (1 << i)) PORTB |= (1 << PORTB3); // DIN HIGH
    else PORTB &= ~(1 << PORTB3); // DIN LOW
    // asm("nop"); asm("nop"); // 短暂延时 (short delay)
    delayMicroseconds(1);
    // CLK上升沿读取数据
    PORTB |= (1 << PORTB5);               // CLK HIGH
    delayMicroseconds(1);
    if (PINB & (1 << PORTB4)) received |= (1 << i); // 读取 DOUT (read DOUT)
    // asm("nop"); asm("nop");
  }
  return received;
}

// ====== TM7705初始化 ======
void TM7705_Init() {
  
  // 配置引脚方向
  DDRB |= (1 << DDB2) | (1 << DDB5); // CS, CLK为输出 (PORTD)
  DDRB |= (1 << DDB4); // DIN为输出 (PORTB)
  DDRB &= ~(1 << DDB3); // DOUT为输入 (PORTB)
  
  // 初始状态
  PORTB |= (1 << PORTB2); // CS HIGH
  PORTB |= (1 << PORTB5); // CLK HIGH
  
  // 硬件复位
  PORTB &= ~(1 << PORTB2); // CS LOW
  for (int i = 0; i < 10; i++) TM7705_SPI_Transfer(0xFF);
  PORTB |= (1 << PORTB2); // CS HIGH
  delay(10);

  // 配置寄存器(50Hz输出率,增益=1)
  TM7705_WriteReg(REG_CLOCK, 0x0C); // 50Hz
  TM7705_WriteReg(REG_SETUP, 0x45); // 自校准,单极性
  Serial.println("Waiting for calibration...");
  uint32_t startTime = millis();
  while (digitalRead(TM7705_DOUT) == HIGH) {
    if (millis() - startTime > 1000) {
      Serial.println("Calibration timeout!");
      break;
    }
    delay(1);
  }
  Serial.println("Calibration done.");
}

// ====== 写寄存器 ======
void TM7705_WriteReg(byte regAddr, byte data) {
  PORTB &= ~(1 << PORTB2); // CS LOW
  TM7705_SPI_Transfer(regAddr);
  TM7705_SPI_Transfer(data);
  PORTB |= (1 << PORTB2); // CS HIGH
}

// ====== 非阻塞式读取ADC ======
bool TM7705_ReadADC_NonBlocking(byte channel, int16_t *result) {
  static uint32_t lastReadTime = 0;
  static byte state = 0;
  switch (state) {
    case 0: // 启动转换
      TM7705_WriteReg(REG_COMM, channel);
      lastReadTime = millis();
      state = 1;
      break;
    case 1: // 等待转换完成
      if (digitalRead(TM7705_DOUT) == LOW) {
        PORTB &= ~(1 << PORTB2); // CS LOW
        TM7705_SPI_Transfer(REG_DATA | 0x08);
        *result = TM7705_SPI_Transfer(0x00) << 8;
        *result |= TM7705_SPI_Transfer(0x00);
        PORTB |= (1 << PORTB2);  // CS HIGH
        state = 0;
        return true;
      }
      // 超时检测(防止卡死)
      else if (millis() - lastReadTime > 100) {
        state = 0;
      }
      break;
  }
  return false;
}

// ====== 精确电压计算 ======
float ReadPreciseVoltage() {
  const uint8_t numSamples = 5; // 采样次数
  int32_t sum = 0;
  int16_t adcValue;
  for (int i = 0; i < numSamples; i++) {
    while (!TM7705_ReadADC_NonBlocking(CH1_AIN1_P_AIN1_N, &adcValue)) {
      // 可在此处执行其他任务
    }
    sum += adcValue;
  }
  // 转换为电压(单极性模式)
  float voltage = ((sum / (float)numSamples) / 32768.0) * vref;
  return voltage;
}

void setup()
{
  // display_init();
  Serial.begin(9600);
  TM7705_Init();
  initTimer1();
  delay(300);
  // Mode_3();
}

void loop()
{
  if (timerFlag) {
    timerFlag = false; // 清除标志
    // 读取电压值
    voltage = ReadPreciseVoltage();
    Fb = voltage * 40;
    newDataAvailable = true;
  }
  if (newDataAvailable) {
    Serial.print("Voltage: ");
    Serial.print(voltage, 4);
    Serial.println(" V");
    newDataAvailable = false;
  }
  // modeSelection();
}

// ====== 定时器1中断服务程序 ======
ISR(TIMER1_COMPA_vect) {
  timerFlag = true; // 设置定时器标志
}

// ====== 初始化定时器1 ======
void initTimer1() {
  noInterrupts(); // 禁用所有中断
  TCCR1A = 0; // 清零TCCR1A寄存器
  TCCR1B = 0; // 清零TCCR1B寄存器
  TCNT1 = 0; // 计数器初始化为0
  // 设置比较匹配寄存器为100ms
  // 16MHz时钟,预分频1024,计数到1562 = (16,000,000/(1024*10))-1
  OCR1A = 12499; //100ms,1562 200ms,12499 500ms,31249
  TCCR1B |= (1 << WGM12); // CTC模式
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024预分频
  TIMSK1 |= (1 << OCIE1A); // 启用定时器比较中断
  interrupts(); // 启用所有中断
}

我们理解,但请不要用相同的请求"碰撞"您的主题。
We understand, but please, do not "bump" your topic with the same request.

Topic: 三线噪声传感器连接ad7705读取的值一直是0v为什么
Topic: The three-wire noise sensor connected to the AD7705 reads the value of 0V all the time

请提供完整的接线图,包括电源。 如果您的项目足够小,请提供一张清晰的照片。
Please, provide a complete wiring diagram, including power supply. If your project is small enough, please, provide a clear photograph.

提供器件数据表的链接 (AD7705)
Please, provide a link to the device.

#include <Arduino.h>
#include <arduino-timer.h>

extern volatile bool timerFlag;  // 定时器标志
extern volatile bool newDataAvailable; // 新数据标志
extern float latestVoltage;       // 最新电压值


float Fb;
unsigned long Time = 0; 
float voltage;



// ====== 硬件配置 ======
#define TM7705_CS  10      // 片选引脚 (PORTB2)
#define TM7705_CLK 13      // 时钟引脚 (PORTB5)
#define TM7705_DIN 11      // 数据输入 (PORTB3)
#define TM7705_DOUT 12     // 数据输出 (PORTB4)
 
// ====== 寄存器定义 ======
#define REG_COMM   0x00    // 通信寄存器
#define REG_SETUP  0x10    // 设置寄存器
#define REG_CLOCK  0x20    // 时钟寄存器
#define REG_DATA   0x30    // 数据寄存器
 
// ====== 通道选择 ======
#define CH1_AIN1_P_AIN1_N 0x00  // 通道1
 
// ====== 全局变量 ======
const float vref = 2.5;          // 参考电压(根据实际模块调整)
volatile bool timerFlag = false;  // 定时器标志
volatile bool newDataAvailable = false; // 新数据标志
float latestVoltage = 0.0;       // 最新电压值
 
// ====== 优化的软件SPI传输 ======
byte TM7705_SPI_Transfer(byte data) {
  byte received = 0;
  for (int i = 7; i >= 0; i--) {
    // CLK下降沿
    PORTB &= ~(1 << PORTB5);              // CLK LOW
    delayMicroseconds(1);
    if (data & (1 << i)) PORTB |= (1 << PORTB3);  // DIN HIGH
    else PORTB &= ~(1 << PORTB3);         // DIN LOW
    // asm("nop"); asm("nop");              // 短暂延时
    delayMicroseconds(1);
    
    // CLK上升沿读取数据
    PORTB |= (1 << PORTB5);               // CLK HIGH
    delayMicroseconds(1);
    if (PINB & (1 << PORTB4)) received |= (1 << i); // 读取DOUT
    // asm("nop"); asm("nop");
  }
  return received;
}
 
// ====== TM7705初始化 ======
void TM7705_Init() {
  // 配置引脚方向
  DDRB |= (1 << DDB2) | (1 << DDB5); // CS, CLK为输出 (PORTD)
  DDRB |= (1 << DDB4);               // DIN为输出 (PORTB)
  DDRB &= ~(1 << DDB3);              // DOUT为输入 (PORTB)
  
  // 初始状态
  PORTB |= (1 << PORTB2);  // CS HIGH
  PORTB |= (1 << PORTB5);  // CLK HIGH
 
  // 硬件复位
  PORTB &= ~(1 << PORTB2); // CS LOW
  for (int i = 0; i < 10; i++) TM7705_SPI_Transfer(0xFF);
  PORTB |= (1 << PORTB2);  // CS HIGH
  delay(10);
 
  // 配置寄存器(50Hz输出率,增益=1)
  TM7705_WriteReg(REG_CLOCK, 0x0C);  // 50Hz
  TM7705_WriteReg(REG_SETUP, 0x45);  // 自校准,单极性
  Serial.println("Waiting for calibration...");
  uint32_t startTime = millis();
  while (digitalRead(TM7705_DOUT) == HIGH) {
    if (millis() - startTime > 1000) {
      Serial.println("Calibration timeout!");
      break;
    }
    delay(1);
  }
  Serial.println("Calibration done.");
}
 
// ====== 写寄存器 ======
void TM7705_WriteReg(byte regAddr, byte data) {
  PORTB &= ~(1 << PORTB2); // CS LOW
  TM7705_SPI_Transfer(regAddr);
  TM7705_SPI_Transfer(data);
  PORTB |= (1 << PORTB2);  // CS HIGH
}

// ====== 非阻塞式读取ADC ======
bool TM7705_ReadADC_NonBlocking(byte channel, int16_t *result) {
  static uint32_t lastReadTime = 0;
  static byte state = 0;
  
  switch (state) {
    case 0: // 启动转换
      TM7705_WriteReg(REG_COMM, channel);
      lastReadTime = millis();
      state = 1;
      break;
      
    case 1: // 等待转换完成
      if (digitalRead(TM7705_DOUT) == LOW) {
        PORTB &= ~(1 << PORTB2); // CS LOW
        TM7705_SPI_Transfer(REG_DATA | 0x08);
        *result = TM7705_SPI_Transfer(0x00) << 8;
        *result |= TM7705_SPI_Transfer(0x00);
        PORTB |= (1 << PORTB2);  // CS HIGH
        state = 0;
        return true;
      }
      // 超时检测(防止卡死)
      else if (millis() - lastReadTime > 100) {
        state = 0;
      }
      break;
  }
  return false;
}

// ====== 精确电压计算 ======
float ReadPreciseVoltage() {
  const uint8_t numSamples = 5;  // 采样次数
  int32_t sum = 0;
  int16_t adcValue;
  
  for (int i = 0; i < numSamples; i++) {
    while (!TM7705_ReadADC_NonBlocking(CH1_AIN1_P_AIN1_N, &adcValue)) {
      // 可在此处执行其他任务
    }
    sum += adcValue;
  }
  
  // 转换为电压(单极性模式)
  float voltage = ((sum / (float)numSamples) / 32768.0) * vref;
  return voltage;

}

void setup() 
{  
  
  Serial.begin(9600);
  TM7705_Init();
  initTimer1();
  delay(300);
  
}

void loop() 
{
  if (timerFlag) {
    timerFlag = false;  // 清除标志
    
    // 读取电压值
    voltage = ReadPreciseVoltage();
    Fb = voltage * 40;
    newDataAvailable = true;
  }
  
  if (newDataAvailable) {
    Serial.print("Voltage: ");
    Serial.print(voltage, 4);
    Serial.println(" V");
    newDataAvailable = false;
  }
  
}

// ====== 定时器1中断服务程序 ======
ISR(TIMER1_COMPA_vect) {
  timerFlag = true;  // 设置定时器标志
}

// ====== 初始化定时器1 ======
void initTimer1() {
  noInterrupts();           // 禁用所有中断
  TCCR1A = 0;               // 清零TCCR1A寄存器
  TCCR1B = 0;               // 清零TCCR1B寄存器
  TCNT1  = 0;               // 计数器初始化为0
  
  // 设置比较匹配寄存器为100ms
  // 16MHz时钟,预分频1024,计数到1562 = (16,000,000/(1024*10))-1
  OCR1A = 12499;     //100ms,1562   200ms,12499   500ms,31249
  TCCR1B |= (1 << WGM12);   // CTC模式
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024预分频
  TIMSK1 |= (1 << OCIE1A);  // 启用定时器比较中断
  interrupts();             // 启用所有中断
}

这我显示新用户不能上传附件

在 10 分钟内阅读/滚动 10 个主题中的 10 个帖子将允许发布。
Read/scroll 10 posts in 10 topics over 10 minutes will allow posting.

此 "VOLTAGE" 具有 "GLOBAL SCOPE"

此 "VOLTAGE" 具有 "LOCAL SCOPE"

通过从 LOCAL SCOPE 中删除 "FLOAT" 初始化来使用 GLOBAL SCOPE。
Use the GLOBAL SCOPE by removing the "FLOAT" initialization from the LOCAL SCOPE.

此 "VOLTAGE" 具有 "LOCAL SCOPE"

TM7705_中文数据手册.pdf (1.3 MB)

好的哥我明天去试试行不行

当结果为零 (0) 时,请对具有乘法或除法的方程持怀疑态度。

When the result is zero (0), be suspicious of equations with multiplication or division.

哥还是不行,还一直是0V

请出示您修改后的代码。
Please, show your revised code.

这个方程式中每个变量的值是多少?
What are the values of each variable in this equation?

没有上拉电阻器的未定义引脚可能会浮动(范围从 VDD 到 GND)。 此英文 Web 站点中的代码在作期间将 RESET 保持在高电平。

An undefined pin without a pull-up resistor can float (range from VDD to GND). The code from this English language web site holds RESET at HIGH during operation.

他连这个AD值好像也是0也没有数据,我真的有点搞不明白这个AD7705