da-an
June 3, 2025, 12:48pm
1
#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(); // 启用所有中断
}
强调文本
xfpd
June 3, 2025, 2:22pm
3
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(); // 启用所有中断
}
da-an:
人帮下我 Someone help me
我们理解,但请不要用相同的请求"碰撞"您的主题。
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 .
da-an
June 3, 2025, 3:00pm
4
#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(); // 启用所有中断
}
这我显示新用户不能上传附件
xfpd
June 3, 2025, 3:06pm
5
da-an:
新用户 new user
在 10 分钟内阅读/滚动 10 个主题中的 10 个帖子将允许发布。
Read/scroll 10 posts in 10 topics over 10 minutes will allow posting.
xfpd
June 3, 2025, 3:14pm
6
此 "VOLTAGE" 具有 "GLOBAL SCOPE"
da-an:
float voltage;
此 "VOLTAGE" 具有 "LOCAL SCOPE"
通过从 LOCAL SCOPE 中删除 "FLOAT" 初始化来使用 GLOBAL SCOPE。
Use the GLOBAL SCOPE by removing the "FLOAT" initialization from the LOCAL SCOPE.
此 "VOLTAGE" 具有 "LOCAL SCOPE"
da-an
June 3, 2025, 3:22pm
7
xfpd
June 3, 2025, 4:01pm
9
当结果为零 (0) 时,请对具有乘法或除法的方程持怀疑态度。
When the result is zero (0), be suspicious of equations with multiplication or division.
xfpd
June 4, 2025, 12:38pm
11
请出示您修改后的代码。
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.
Discover comprehensive tutorials on how to use Cirkit Designer, detailed documentation for electronic components, and step-by-step guides for project design. Ideal for students, hobbyists, and developers looking to create and innovate in circuit...
da-an
June 6, 2025, 11:07am
12
他连这个AD值好像也是0也没有数据,我真的有点搞不明白这个AD7705