Работа с двумя аналоговыми датчиками, ATmega16
Я хочу работать с двумя аналоговыми датчиками, подключенными к ATmega16. Первый - это датчик температуры (LM35), подключенный к PA0. Светодиод должен гореть, когда температура становится высокой. Второй - это фоторезистор, и он подключен к PA1. Я хочу включить светодиод при слабом освещении. Я искал решение по всему Интернету, но не смог найти ничего похожего на мою ситуацию. Все они говорят только об одном - вы не можете считывать показания двух аналоговых датчиков одновременно.
У меня есть этот код, который работает только для одного датчика:
#define F_CPU 1600000UL
#include <avr/io.h>
void ADC_Init() {
DDRA = 0x0;
ADCSRA = 0x87;
ADMUX = 0x40;
}
uint16_t ADC_Read(uint8_t channel) {
ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC)) ;
return ADC;
}
int main(void) {
ADC_Init();
DDRB = 0xFF;
while (1) {
uint8_t value;
value = ADC_Read(0);
if (value > 70) {
PORTB |= (1<<0);
} else {
PORTB &= ~(1<<0);
}
}
}
Можете ли вы как-то помочь мне изменить этот код, дать мне совет, как я могу это сделать, или какой-нибудь пример?
@cerouno, 👍0
Обсуждение1 ответ
Я только что просмотрел спецификацию ATmega16, так что, возможно, отнеситесь к этому ответу с недоверием.
Технически верно, что вы не можете считывать два канала АЦП одновременно, потому что существует только один АЦП, и вы должны мультиплексировать различные входы канала на этот один АЦП. Скорее всего, вы можете изменить источник АЦП во время выполнения, чтобы переключаться между различными каналами.
Взгляните на описание регистра ADMUX в техническом описании
Прямо сейчас вы устанавливаете мультиплексирование один раз во время выполнения функции init(), а затем никогда не меняете его. В вашем новом коде вам нужно будет изменить значение в регистре во время выполнения (в дополнение к любой другой требуемой конфигурации / обслуживанию), что должно произойти в вашем основном цикле ()
Описание высокого уровня:
int main()
{
system_init();
while (1)
{
set ADMUX to read from PA0
read ADC
set ADMUX to read from PA1
read ADC
do stuff
}
}
Я понимаю, что вы имеете в виду, но если я сделаю это в основном цикле, он не будет работать бесконечно, и канал будет изменен только один раз. Как я могу постоянно переключаться между этими двумя датчиками?, @cerouno
@cerouno Если вы поместите приведенный выше код в свой цикл while (1), он будет выполняться бесконечно. Я отредактирую псевдокод выше, чтобы показать это., @mooshoomatt
Если вы внимательно прочитаете техническое описание, то обнаружите тот факт, что вы должны выбросить первое чтение после операции переключения входа., @gbg
- Максимальная длина матрицы для инвертирования матрицы на atmega32
- В чем разница/связь между Arduino и AVR?
- Как преобразовать скетч примера Arduino в полный проект C++?
- Не удается записать загрузчик через Arduino Nano clone ISP в atmega328p
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Как создать задержки на языке ассемблера AVR
- Программирование микроконтроллера Attiny85 без arduino
- AVR (Arduino Uno) Serial.print и Serial.println печатают только 1 или 2 символа
Что происходит, когда вы меняете ADC_Read(0) на ADC_Read(1)?, @devnull
@devnull это работает только для одного датчика одновременно. Если я использую ADC_Read(1), это будет работать для второго датчика. Я попытался настроить его с помощью цикла переключения, в первом случае ADC_Read(0), во втором ADC_Read(1), но это не сработает., @cerouno
Хорошо. Поскольку MCU не может выполнять * любые * две вещи программно одновременно, вы можете считывать данные из канала 0 в одну переменную, считывать данные из канала 1 в другую переменную, а затем решать, что делать со светодиодами в соответствии с двумя значениями. Вы также можете отредактировать свой вопрос, чтобы показать этот второй код, который вы упомянули, поскольку ваш тест показывает, что аппаратная часть / АЦП уже работает для двух датчиков., @devnull
Я переформатировал код для удобства чтения и, делая это, взял на себя смелость добавить закрывающую фигурную скобку, которая отсутствовала в
ADC_Init()
., @Edgar BonetЯ голосую за закрытие этого вопроса, потому что пользователя не было здесь больше года, поэтому шансы на то, что этот вопрос будет принят, очень малы., @VE7JRO