Почему не работает?
- Войдите на сайт для отправки комментариев
Вс, 31/03/2019 - 16:37
int read_voltage() { ADCSRA = (1 << ADEN); delay(10); ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (1 << MUX0); delay(10); ADCSRA |= (1 << ADSC); while (bit_is_set(ADCSRA, ADSC)); uint8_t low = ADCL; uint8_t high = ADCH; long result = (high << 8) | low; Serial.println(result); return result; }
Приветствую, вот функция для определения напряжения на пине ADC3 относительно напряжения питания. К сожалению ф-я выдает только 1023, в то время как стандаратная ф-я analogread(А3) выдает корректное значение. В чем загвоздка? Микроконтроллер atmega328
Даже не спрашиваю, чем Вас не устраивает analgRead (догадываюсь).
А так, Вы не задали делитель частоты (биты ADPS2-0 регистра ADSRA). Когда там нули, он уж больно крутой.
Для частоты 16М нужно взвести в 1 все три бита. А вообще, для максимальной точности измерения делитель определяется так:
Ну, и по коду.
1) ВСЕ записи типа (0 << N) - лишние, только засоряют текст.
2) если фунция у Вас возвращает int, нафига Вы объявили переменную result как long?
3) Отрадно, что Вы слышали про порядок чтения 16-битных регистров, но не надо мудрствовать лукаво. Строки №№ 8-10 спокойно заменяются на
Больше ничего не нужно.
1) Это на любителя. Часто для наглядности. На мой взгляд засоряют скобки.
Ниже наглядно показывает что есть что. И позволяет оперативно изменять при необходимости, с минимумом телодвижений.
ADMUX = 0<<REFS1 | 1<<REFS0 | 0<<MUX3 | 0<<MUX2 | 1<<MUX1 | 1<<MUX0;
не понимаю как так, но уже далеко не первый раз замечаю, что после перезагрузки программмы/компьютера тот или иной скетч начинает работть, хотя до этого никак..тут так и вышло...
насчет прескаллера, я думал, что он необходим только для большей точности. А так данные теперпь получаются при наличии этой строки "ADCSRA = (bit(ADPS2) | bit(ADPS1));" и без нее
1)это как раз таки для наглядности, можно и в 3-х соснах заблудиться)
2) Да, нужно привести к 1 типу
3) Нет, все куда прозаичнее, конкретно эту часть я взял из чужого скетча, но ваше написание, безусловно проще
С перскэйлером осторожнее. То, что я привёл - это рекомендация производителя контроллера для обеспечения нормальной 10 бит точности.
насчет прескаллера, я думал, что он необходим только для большей точности.
Если точность не нужна, а нужна скорость, ADPS можно высталять на минимальный коеффициент. Актуально для регулирующих систем с обратной связью, где важно относительное значение.
Большое спасибо за разъяснения, завтра поиграюсь с этим делителем