AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
27.12.2023, 19:31
|
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Использование нескольких каналов АЦП и вывод на дисплей
Приветствую всех!
Товарищи Прошу помощи. Продолжаю свой путь в изучение мк avr
Столкнулся с АЦП. Азы как включить нужную лапку и сам АЦП понял.
Понимаю что возможно только последовательное чтение, так как мультиплексор один.
Камень atmega 128
Но есть острая необходимость юзать от 2 до 7 каналов.
Покажите пожалуйста на примере моего кода, как организовать последовательное чтение. Я примерно понимаю что можно какую то переменную взять и за счет инкрементации этой переменой и ее передачи в значение admux как то переключать каналы, но не понимаю как написать. Может в таймере нулевом или в векторе прерываний ацп по завершению преобразования?
Мой код под спойлером:
Нажмите, чтобы открыть спойлер
PHP код:
|
#define F_CPU 8000000UL
#include ‹avr/io.h›
#include ‹avr/io.h›
#include ‹util/delay.h›
#include ‹avr/interrupt.h›
#include ‹util/atomic.h›
#include ‹stdlib.h›
#include "n5110.h"
//-------------------------------------------------------------------------------------------------------------------------
void displey_start(void) // Активирую Порт B на выход, для того что бы активировать дисплей
{
DDRB = 0xff;
PORTB = 0x00;
Lcd_init();
Lcd_clear();
Lcd_update();
LcdContrast(62);
}
//-------------------------------------------------------------------------------------------------------------------------
void adc_start(void) // запуск ацп от внешнего ИОН 5v
{
ADCSRA |=(1‹‹ADEN); // Запускаю работу АЦП
//ADCSRA |=(1‹‹ADFR); // Разрешаю работу АЦП в измерения free running(непрерывные измерения)
ADCSRA |=(1‹‹ADPS2) | (1‹‹ADPS1) | (1‹‹ADPS1); // Устанавливаю частоту дискретезации 125кгц с помощью делителя на 128
ADMUX |=(1‹‹REFS0); // Использую внешний источник опорного напряжения 5v
ADMUX |= (1‹‹MUX1) | (1‹‹MUX0); // Настраиваю 3 порт АЦП на работу
}
//-------------------------------------------------------------------------------------------------------------------------
int readADC()
{
//ADCSRA |=(1‹‹ADFR); // Разрешаю работу АЦП в измерения free running(непрерывные измерения)
ADCSRA |=(1‹‹ADSC); // Запускаю преобразование АЦП
while((ADCSRA&(1‹‹ADSC))); // Жду окончания преобразования
return ADC;
}
int main(void)
{
adc_start();
displey_start();
sei();
while (1)
{
Lcd_clear();
//char buff[5];
//itoa(readADC(), buff, 10);
//Lcd_print(0, 1, FONT_2X, (unsigned char*)buff);
//Lcd_printf(0,0,FONT_1X,(((float)readADC()*5)/1023)*4,2);
//Lcd_printf(2,2,FONT_1X,(((float)readADC(1)*5)/1023)*4,2);
Lcd_printf(0,0,FONT_1X,((((float)readADC()*5)/1023-0.5)*100),1);
Lcd_update();
}
}
|
Последний раз редактировалось Devil Byte; 27.12.2023 в 21:12.
|
|
|
|
27.12.2023, 19:46
|
|
Прописка
Регистрация: 27.01.2015
Сообщений: 259
Сказал спасибо: 50
Сказали Спасибо 28 раз(а) в 27 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Devil Byte
|
Но есть острая необходимость юзать от 2 до 7 каналов.
Покажите пожалуйста на примере моего кода, как организовать параллельное чтение.
|
Параллельное чтение чего? Там один АЦП, а "каналы" всего лишь ключ-мультиплексор попеременно подключающий вход ADC к разным ногам МК. Нечего там параллелить, измерение и чтение результата можно только последовательно для каждого из каналов прозводить.
|
|
|
|
27.12.2023, 20:00
|
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Alcest
|
Параллельное чтение чего?
|
Опечатался, в первом предложении я написал последовательное чтение.
К чему вы повторяйте про ацп и мультиплексор? я написал тоже самое.
И так же написал о последовательном чтение каналов
|
|
|
|
27.12.2023, 20:23
|
|
Прописка
Регистрация: 27.01.2015
Сообщений: 259
Сказал спасибо: 50
Сказали Спасибо 28 раз(а) в 27 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Обычный цикл for, счетчик циклов будет номером канала. Он же может быть номером элемента в массиве в который будете записывать измеренные значения напряжения.
|
|
|
|
27.12.2023, 20:29
|
|
Прописка
Регистрация: 27.01.2015
Сообщений: 259
Сказал спасибо: 50
Сказали Спасибо 28 раз(а) в 27 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Devil Byte
|
Опечатался, в первом предложении я написал последовательное чтение.
|
Откуда мне знать, в каком конкретно предложении вы опечатались?
|
|
|
|
27.12.2023, 21:00
|
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Alcest
|
Обычный цикл for
|
А счетчик за счет чего перебрать? за счет таймера счетчика или прерывания по завершению преобразования ADC?
|
|
|
|
27.12.2023, 21:56
|
|
Прописка
Регистрация: 27.01.2015
Сообщений: 259
Сказал спасибо: 50
Сказали Спасибо 28 раз(а) в 27 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Просто ждать в конце каждой итерации цикла прерывания от АЦП, пока процесс измерения не завершится. Или флаг проверять (я уж не знаю, как там в AVR устроено). А счетчик цикла сам будет увеличиваться в каждой итерации на единицу или другое какой значение. Правда, тормоза будут дикие. Пока крутится цикл for с обращениями к АЦП внутри него, ничего другого делать микроконтроллер не сможет.
|
|
|
|
27.12.2023, 22:25
|
|
Прописка
Регистрация: 27.01.2015
Сообщений: 259
Сказал спасибо: 50
Сказали Спасибо 28 раз(а) в 27 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Хотя, ничто не мешает сделать так как вы и сами предполагали - увеличивать на единицу некую переменную по прерыванию от АЦП, и ее значение подставлять в номер канала. Оформить код в функцию, к которой обращаться по тем же прерываниям. В функции увеличивать переменную, подставлять ее в номер канала. И там же записывать значения в массив. До тех пор, пока нужное количество каналов не будет проверено. Это проверкой условия if. После чего сбросить номер канала в 0 для следующей последовательности измерений. Тут же (после крайнего измерения) можно выключить АЦП после последнего измерения, чтобы прерывания не вызывали функцию когда это не нужно. Все повторится при следующем включении АЦП.
|
|
|
|
30.12.2023, 11:05
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
PHP код:
|
unsigned int adc[7];
unsigned int read_adc(unsigned char channel)
{
ADMUX = channel | (1‹‹REFS1) | (1‹‹REFS0) | (0‹‹ADLAR);
delay_us(10);
ADCSRA |= (1‹‹ADSC);
while((ADCSRA & (1‹‹ADIF)) == 0);
ADCSRA |= (1‹‹ADIF);
return ADCW;
}
...
for(i = 0; i ‹ 7; i++) adc[i] = read_adc[i];
|
Это без прерываний.
Вам с какой частотой нужно опрашивать каналы?
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
30.12.2023, 11:40
|
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Godzilla82
|
Это без прерываний.
Вам с какой частотой нужно опрашивать каналы?
|
Я примерно понял то что вы написали но я представлял примерно так
PHP код:
|
uint16_t readAdc(uint8_t channel) { uint8_t LowBitValue; ADMUX = (1‹‹REFS0) | channel; ADCSRA |= (1‹‹ADSC); while((ADCSRA &(1‹‹ADIF))==0); ADCSRA |= (1‹‹ADIF); LowBitValue = ADCL; return((ADCH‹‹8) | LowBitValue); }
|
Только потом в чати где я вывожу на дисплей результат нужно в readAdc(сюда записать channel). Или что нужно вписать? я хочу отображать на дисплее несколько каналов сразу например:
PHP код:
|
//Lcd_printf(0,0,FONT_1X,(((float)readADC(1)*5)/1023)*4,2); //Lcd_printf(2,2,FONT_1X,(((float)readADC(2)*5)/1023)*4,2);
|
Как это реализовать?
Еще я не совсем понял где должен цикл for крутиться? в каком нибудь счетчике таймере?
А на счет считывания, ну чем быстрее тем лучше, я помню что там ограничения по частоте есть, близко к максимально меня устроит
Последний раз редактировалось Devil Byte; 30.12.2023 в 12:28.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Видео уроки
|
dosikus |
Микроконтроллеры, АЦП, память и т.д |
61 |
23.01.2012 21:06 |
Помогите с ЦАП AD7708/AD7718 или их аналогами
|
ST_Senya |
Микроконтроллеры, АЦП, память и т.д |
9 |
30.11.2009 19:03 |
Помогите с проэктом: 1 АЦП 8бит + 16 комутируемых каналов
|
vahamov |
Микроконтроллеры, АЦП, память и т.д |
54 |
13.07.2009 11:10 |
зачем PIC-ам много каналов АЦП?
|
stri |
Микроконтроллеры, АЦП, память и т.д |
3 |
01.11.2007 12:32 |
PIC16F877A
|
pawelk |
Микроконтроллеры, АЦП, память и т.д |
17 |
28.05.2005 23:54 |
Часовой пояс GMT +4, время: 13:07.
|
|