Регистр АЦП всегда возвращается высоким
Независимо от напряжения в точке A0, программное обеспечение всегда возвращает высокое значение (1023).
volatile unsigned char* ADmux = (unsigned char*) 0x7C;
volatile unsigned char* ADCSRa = (unsigned char*) 0x7A;
volatile unsigned char* ADCSRb = (unsigned char*) 0x7B;
volatile unsigned char* ADCh = (unsigned char*) 0x79;
volatile unsigned char* ADCl = (unsigned char*) 0x78;
int Voltage;
void adc_init()
{
*ADmux = 0x00; // установка всего регистра в 0, в частности установка Refs1 и refs0 в 0, что означает, что опорное напряжение равно AREF
*ADCSRa = 0b10000111; // Устанавливает самый значимый бит равным 1, что является битом включения АЦП, а 3 наименее значимых бита являются прескаляром, который равен 128
}
unsigned int adc_read( unsigned char adc_channel)
{
*ADmux = *ADmux | 0b00000000;// установите биты mux равными 0, чтобы проверить A0 независимо от того, что такое adc_channel
*ADCSRa = *ADCSRa | 0b01000000; // установите высокий бит ADSC для начала преобразования
while(*ADCSRa & 0b01000000);//подождите, пока ADSC не опустится, указанное преобразование будет завершено
return ADC; //возвращаемые биты в регистрах ацп
}
void setup() {
// поместите свой установочный код здесь, чтобы запустить один раз:
Serial.begin(9600);
adc_init(); // инициализирует ацп
}
void loop() {
// поместите свой основной код здесь, чтобы запускать его повторно:
Voltage = adc_read(0b00000); // вызовы adc_read
Serial.print(Voltage); // печатает показания напряжения
Serial.write("\n");
}
А вот схема схемы:
Я прочесал главу 26 документа atmega2560 и описания каждого регистра, но я в растерянности. Почему содержимое регистров ацп всегда заполняется цифрами 1 независимо от напряжения на а0?
@ClockwerkSC, 👍2
Обсуждение2 ответа
Лучший ответ:
Во-первых, позвольте мне дать несколько советов по стилю программирования.
Нет смысла определять собственные переменные для доступа к
аппаратным регистрам: avr-libc делает это за вас, вам просто нужно
#include <avr/io.h>
. На самом деле, вам не нужно #включать что-либо:
Arduino IDE автоматически #включает Arduino.h , который, в свою очередь
#включает avr/io.h.
Далее, тот же avr-libc также определяет макросы для битовых имен, поэтому вам не нужно явно записывать двоичные числа в свой собственный код (который подвержен ошибкам). И пара полезных макросов, которые вы можете использовать, чтобы сделать код немного более читабельным. Например:
void adc_init()
{
ADMUX = _BV(REFS0); // Ссылка на АЦП = AVCC
ADCSRA = _BV(ADEN) // включить АЦП
| _BV(ADPS2) // установить прескалер на 128
| _BV(ADPS1) // то же самое
| _BV(ADPS0); // то же самое
}
unsigned int adc_read(unsigned char adc_channel)
{
ADMUX = _BV(REFS0) | (adc_channel & 7); // выбрать канал
ADCSRA |= _BV(ADSC); // начало преобразования
// Преобразование завершается, когда ADSC становится низким.
loop_until_bit_is_clear(ADCSRA, ADSC);
return ADC; // возврат регистра данных ацп
}
А теперь давайте ответим на ваш вопрос. Когда вы устанавливаете значения REFS0
и
REFS1
равными 0, опорное напряжение указывается как “AREF, внутреннее В
REF выключен ”. Подразумевается, что вы должны принести свой
собственный эталон напряжения и подключить его к контакту AREF. В противном случае AREF
остается как плавающий вход. Это проиллюстрировано на схеме
АЦП. Вот соответствующая часть:
Как вы видите здесь, REFS0
используется для подключения AREF к одной из других
возможных ссылок: либо AVCC, либо внутренней запрещенной зоне. Если REFS0
равен
нулю, то транзистор, изображенный выше, выключен, а AREF остается плавающим.
Каковы значения сопротивления для R1 и LDR1? Их соотношение будет определять напряжение при А0. Если соотношение их сопротивлений слишком велико (например, 100:1), то любой свет, измеренный LDR1, приведет лишь к небольшому изменению измеряемого напряжения. Если разница достаточно велика, то напряжение также может казаться постоянно низким или высоким. Если у вас есть мультиметр, проверка напряжения этой цепи делителя может помочь определить, что происходит.
https://learn.sparkfun.com/tutorials/voltage-dividers/all
- DHT11 аналоговый или цифровой?
- Как считывать аналоговое значение на ESP32-CAM с включенным считывателем SD-карт?
- Ardunio Mega/ATmega2560: использование порта F или K как для аналоговых входов, так и для цифровых выходов.
- Arduino измерительный высоковольтный электрический забор
- analogRead() не считывает более 500 Гц
- Шум в Analog Read Serial от инструментального усилителя (ina122p)
- Как на самом деле Arduino измеряет напряжение?
- ESP32 чтение аналоговый 2,4 ГГц
что вы читаете, если удаляете R1?, @jsotola
@jsotola он все еще читает 1023, @ClockwerkSC
Какую IDE вы используете, если таковая имеется? Убедитесь, что MUX5, at ADCSRB: 3 установлен в 0, а также ADTS2:0 at ADCSRB 2:0, чтобы включить режим свободного хода., @towe
Я заставил программу работать, установив refs0 в 1. Таким образом, это означает, что опорное напряжение переключилось с AREF на AVCC. Кто-нибудь знает, почему это небольшое изменение заставляет его работать? Разве AREF не 5V по умолчанию?, @ClockwerkSC
@towe Я использую стандартную Arduino IDE., @ClockwerkSC