вопрос по АЦП

exolon
Offline
Зарегистрирован: 20.05.2015

ребята подскажите, знаю я тут всем надоел

uint16_t A5_Read()
{
  uint16_t An;
  ADMUX=B01000101;//конфигурируем вывод А5 с внутренним 1,1в
  ADCSRA = B10010111;//конфигурируем ацр
  ADCSRA |= (1<<ADSC);
while (ADCSRA & (1 << ADSC)) {An = ADCH;} //ждем окончания преобразования
  An = (An<<8) + ADCL; //сдвигаем в лево старшие 2 бита, читаем и прибавляем младшие 8 бит
  return An;
}

uint16_t A1_Read()
{
  uint16_t Ap;
  ADMUX=B01000001;//конфигурируем вывод А1 с внутренним 1,1в
  ADCSRA = B10010111;//конфигурируем ацр
  ADCSRA |= (1<<ADSC);
while (ADCSRA & (1 << ADSC)) {Ap = ADCH;} //ждем окончания преобразования
  Ap = (Ap<<8) + ADCL; //сдвигаем в лево старшие 2 бита, читаем и прибавляем младшие 8 бит
  return Ap;
}

это кусок кода который я хочу доработать, дело в том что когда читаю с отдельно A5_Read или отдельно A1_Read стабильно получаю значение с АЦП порта 5 или 1 а вот стоит зачитать A5_Read и A1_Read выводит порой такую белеберду, от этого вопрос чо я упустил  

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

три раза Аве (в православии - Богородица Дева радуйся), черыте раза Падре (в православии - Отче наш),  и 100 раз- даташит на контроллер, то самое важное!

АЦП в контроллере - ОДИН, млин!!! Первое измерение - всегда говно. Или нужно его ОЧЕНЬ ПРАВИЛЬНО ДЕЛАТЬ. После переключения мультиплексора первое измерение - выкинуть и пользовать второе и т.д.

exolon
Offline
Зарегистрирован: 20.05.2015

никто не спорит что ацп у контроллера один, вопрос был не в этом

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

exolon, во-первых код нужно вставлять как положено.  Во-вторых нужно приводить код полностью. В-третьих Вы даёте конфигурацию регистров в неудобном формате (reg=Bxxxxxxxx) , вынуждая проверяющего открывать даташит. Нужно  расписывать каждый бит, как в срочке ADCSRA |= (1<<ADSC); В строчке ADMUX у вас явное несоответствие комментария написанному.  В строчке ADCSRA непонятно зачем возводится 4й  флаговый бит. Это говорит о том, то обработчик применяется без понимая его работы.В-пятых где регистр ADCSRB?? Даже если он равен нулю, нужно его явно обнулить. Это порочная практика не обнулять регистры используемой перефирии. ну и последнее - в строке while у вас ГЛАВНАЯ ошибка. Надеюсь разберетесь самостоятельно что это за ошибка.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Дима прав, в ADMUX у Вас написано реф - питание, а в комментарии, что 1.1В.

И я, возможно  эмоционально, но написал именно причину - после переключения мультиплексора Вам следует сделать не одно измерение, а несколько (хотя бы два), отбросив результат первого.

Ну и само измерение, тут да, забавно, Дима Вам точно указал.

И мне кажется, что это общее место - все что ли одну и туже ошибку копируют?

Есть в AVR-GCC обращение сразу к сдвоенному регистру, к Хай и Лоу одновременно, просто ADC, без дурацких сдвигов.. Компилятор все правильно делает сам.