AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
30.12.2023, 12:33
|
#11
|
Гражданин KAZUS.RU
Регистрация: 10.06.2010
Сообщений: 598
Сказал спасибо: 222
Сказали Спасибо 234 раз(а) в 154 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Devil Byte
|
близко к максимально меня устроит
|
Можете на это не рассчитывать.
Максимальная частота возможна только на одном канале в режиме непрерывного измерения.
Как уже Вам показали в коде, при переключении каналов нужно выдержать задержку для перезаряда емкости, иначе Вы погоду на Марсе измерять будите.
Мало того АЦП измеряет мгновенные значения и для получения стабильных показаний данные, как минимум, надо пропустить через ЦФ(цифровой фильтр) хотя бы в виде скользящего среднего, или скользящей медианы.
А уже потом преобразовывать в попугаи напряжения и выводить на ЛСД
|
|
|
|
30.12.2023, 12:44
|
#12
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от DmitriyVDN
|
Можете на это не рассчитывать.
|
Ну во первых я не говорил максимальная частота, близко к этому, если это возможно.
На аднный момент я только изучаю МК. А вы пытайтесь рассказать мне про нелинейные зависимости, фильтры и диаграммы. Я усредню значения программно если мне это потребуется. Сейчас я просто хочу научится использовать несколько каналов, и не претендую на точность как у флюка или роде и шварц. Спасибо за совет
Последний раз редактировалось Devil Byte; 30.12.2023 в 12:48.
|
|
|
|
30.12.2023, 14:33
|
#13
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Максимальная частота - это 10-15 кГц. Ну пусть 8.
У вас 8 каналов - это уже 1 кГц.
Вы что-нибудь увидите на дисплее, если будете обновлять 1000 раз в сек?
Да и сам дисплей не даст обновлять с такой частотой.
Какой дисплей кстати?
8 значений - это много. Даже в HEX - это 4 символа на канал - надо уже 32 символа. Но это нечитаемо. Если писать U1=12.55V, то это уже 10 символов на канал.
|
|
|
|
30.12.2023, 15:05
|
#14
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Godzilla82
|
Максимальная частота - это 10-15 кГц. Ну пусть 8.
|
Вот немного подправил код. Но только так и не разобрался куда втыкать цикл для перебора каналов. И еще не понимаю ацп сейчас же она работает в 10 битном режиме?
Дисплей нокиа 5510, подключал к ЛБП на макетке, на одном канале быстро обновляется. Понимаю что преключение каналов замелит это, но думаю будет все равно приемлемо. На дисплей вывожу с помощью его же функции, а сам расчет явно преобразую в дабл
Нажмите, чтобы открыть спойлер
PHP код:
|
#define F_CPU 8000000UL
#include ‹avr/io.h›
#include ‹util/delay.h›
#include ‹avr/interrupt.h›
#include ‹util/atomic.h›
#include ‹stdbool.h›
#include ‹stdint.h›
#include ‹inttypes.h›
#include ‹stdlib.h›
#include "n5110.h"
//-------------------------------------------------------------------------------------------------------------------------
void displey_start(void) // Активирую Порт B на выход, для того что бы активировать дисплей
{
DDRB &= ~((1‹‹PINB1) | (1‹‹PINB2) | (1‹‹PINB3) | (1‹‹PINB4) | (1‹‹PINB5));
PORTB = 0x00;
Lcd_init();
Lcd_clear();
Lcd_update();
LcdContrast(62);
}
//-------------------------------------------------------------------------------------------------------------------------
void adc_start(void) // запуск ацп от внешнего ИОН 5v
{
ADCSRA |=(1‹‹ADFR); // Разрешаю работу АЦП в измерения free running(непрерывные измерения)
ADCSRA |=(1‹‹ADEN); // Запускаю работу АЦП
ADCSRA |=(1‹‹ADPS2) | (1‹‹ADPS1) | (1‹‹ADPS1); // Устанавливаю частоту дискретезации 125кгц с помощью делителя на 128
}
//-------------------------------------------------------------------------------------------------------------------------
int readAdc(int channel)
{
int LowBitValue;
channel=channel & 0x61;
ADMUX = (1‹‹REFS0) | channel;
ADCSRA |= (1‹‹ADSC);
while((ADCSRA &(1‹‹ADIF))==0);
//while (ADCSRA & (1 ‹‹ ADSC));
ADCSRA |= (1‹‹ADIF);
LowBitValue = ADCL;
return((ADCH‹‹8) | LowBitValue);
//return ADC;
}
int main(void)
{
adc_start();
displey_start();
sei();
while (1)
{
Lcd_clear();
Lcd_printf(2,2,FONT_1X,(((double)readAdc(1)*5)/1023)*4,2);
Lcd_update();
}
}
|
|
|
|
|
30.12.2023, 15:14
|
#15
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
PHP код:
|
while (1) { Lcd_clear(); for(i = 0; i ‹ 8; i++) Lcd_printf(2,2+i*10,FONT_1X,(float)(readAdc(i)*20)/1023,2); Lcd_update(); }
|
Не нужно никакое непрерывное преобразование. Одиночные измерения. Пример функции я приводил.
Последний раз редактировалось Godzilla82; 30.12.2023 в 15:21.
|
|
|
|
30.12.2023, 16:20
|
#16
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Godzilla82
|
функции я приводил.
|
сделал как вы написали в последнем сообщении, получил какой то мусор, наверное что то не так делаю.
сделал почти как в первом вашем примере
Нажмите, чтобы открыть спойлер
PHP код:
|
int readAdc(int channel)
{
int LowBitValue;
ADMUX = (1‹‹REFS0) | channel;
ADCSRA |= (1‹‹ADSC);
while((ADCSRA &(1‹‹ADIF))==0);
//while (ADCSRA & (1 ‹‹ ADSC));
ADCSRA |= (1‹‹ADIF);
LowBitValue = ADCL;
return((ADCH‹‹8) | LowBitValue);
}
int main(void)
{
adc_start();
displey_start();
sei();
while (1)
{
Lcd_clear();
Lcd_printf(0,0,FONT_1X,(((double)readAdc(0)*5)/1023)*4,2); //Вывод с нулевого канала
Lcd_printf(0,1,FONT_1X,(((double)readAdc(1)*5)/1023)*4,2); // вывод с первого канала
Lcd_printf(0,2,FONT_1X,(((double)readAdc(2)*5)/1023)*4,2); // вывод со второго канала
Lcd_update();
}
}
|
В протеусе выводит конечно с указанных каналов, но понимаю что в железе не будет... по прежнему не понимаю куда воткнуть фор и связать его с переменной channel ((((((
|
|
|
|
30.12.2023, 18:02
|
#17
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Devil Byte
|
по прежнему не понимаю куда воткнуть фор и связать его с переменной channel ((((((
|
Так я же вам написал готовый код с циклом for.
Ещё раз - не надо запускать непрерывные преобразования в adc_start.
Чтобы не мелькало добавьте delay_ms(500) после lcd_update.
P.S. Зачем вы умножаете на 4 перед выводом на экран?
P.P.S. Зачем тут double? Тут и целочисленной арифметики за глаза.
Последний раз редактировалось Godzilla82; 30.12.2023 в 18:06.
|
|
|
|
30.12.2023, 19:34
|
#18
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Godzilla82
|
Так я же вам написал готовый код с циклом for.
Ещё раз - не надо запускать непрерывные преобразования в adc_start.
Чтобы не мелькало добавьте delay_ms(500) после lcd_update.
P.S. Зачем вы умножаете на 4 перед выводом на экран?
P.P.S. Зачем тут double? Тут и целочисленной арифметики за глаза.
|
Простите, я же говорю не заработал ваш пример, не знаю что я не так с ним делаю.
Да я и не запускаю непрерывные преобразования. Дисплей и так не мелькает в протеусе, задержку буду добавлять когда домой вернусь к железу.
Умножаю на 4 потому что использую делитель напряжения перед входом.
На счет переменных потом буду играться с оптимальными, мне важно запустить все семь каналов/
Сделал как под спойлером, работает только первых 3 канала
Нажмите, чтобы открыть спойлер
PHP код:
|
void adc_start(void) // запуск ацп от внешнего ИОН 5v
{
ADCSRA |=(1‹‹ADEN); // Запускаю работу АЦП
ADCSRA |=(1‹‹ADPS2) | (1‹‹ADPS1) | (1‹‹ADPS1); // Устанавливаю частоту дискретезации 125кгц с помощью делителя на 128
ADMUX |= (1‹‹REFS0); // Внешний ИОН
}
//-------------------------------------------------------------------------------------------------------------------------
int readAdc(unsigned int channel)
{
unsigned char set_ch = ADMUX;
set_ch &= ~((1‹‹MUX4) | (1‹‹MUX3) | (1‹‹MUX2) | (1‹‹MUX1) | (1‹‹MUX0));
switch(channel)
{
case 1: set_ch |= (1‹‹MUX0); break;
case 2: set_ch |= (1‹‹MUX1); break;
case 3: set_ch |= (1‹‹MUX2); break;
case 4: set_ch |= (1‹‹MUX3); break;
//case 5: set_ch |= (1‹‹MUX4); break;
//case 6: set_ch |= (1‹‹MUX5); break;
//default:break;
}
ADMUX=set_ch;
_delay_us(50);
//int LowBitValue;
ADCSRA |= (1‹‹ADSC);
//while((ADCSRA &(1‹‹ADIF))==0);
//ADCSRA |= (1‹‹ADIF);
while ((ADCSRA & (1 ‹‹ ADSC)));
//LowBitValue = ADCL;
//return((ADCH‹‹8) | LowBitValue);
//return ADC;
}
int main(void)
{
adc_start();
displey_start();
sei();
while (1)
{
Lcd_clear();
Lcd_printf(0,0,FONT_1X,(((double)readAdc(0)*5)/1023)*4,3); //Вывод с нулевого канала
Lcd_printf(0,1,FONT_1X,(((double)readAdc(1)*5)/1023)*4,3); // вывод с первого канала
Lcd_printf(0,2,FONT_1X,(((double)readAdc(2)*5)/1023)*4,3); // вывод со второго канала
Lcd_printf(0,3,FONT_1X,(((double)readAdc(3)*5)/1023)*4,3); // вывод со второго канала
Lcd_update();
_delay_ms(150);
}
}
|
|
|
|
|
30.12.2023, 22:33
|
#19
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
PHP код:
|
unsigned int read_adc(unsigned char channel) { ADMUX = channel; delay_us(10); ADCSRA |= (1‹‹ADSC); while((ADCSRA & (1‹‹ADIF)) == 0); ADCSRA |= (1‹‹ADIF); return ADCW; }
void adc_init(void) { ADMUX = 0; ADCSRA = (1‹‹ADEN) | (1‹‹ADPS2) | (1‹‹ADPS1); }
void main(void) { unsigned char i; adc_init(); lcd_init(20); while(1) { lcd_gotoxy(0,0); for(i = 0; i ‹ 8; i++) printf("%5.1f",(float)read_adc(i) * 5.0 / 1024.0 ); } }
|
АЦП настроен на внешний ИОН, подключённый к AREF.
Последний раз редактировалось Godzilla82; 31.12.2023 в 10:57.
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
31.12.2023, 07:37
|
#20
|
Временная регистрация
Регистрация: 07.03.2019
Сообщений: 87
Сказал спасибо: 11
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Использование нескольких каналов АЦП и вывод на дисплей
Сообщение от Godzilla82
|
for(i*=*0;*i*‹*8;*i++)*printf("%5.1f",(float)read_ adc(i)***5.0*/*1024.0*);
|
Я немного по другому сделал но вроде работает. в любом случае в железе буду проверять когда прилечу.
Подскажите для чего вот эта запись? SFIOR = (0‹‹ACME); ? он же и так в нуле?
И еще такой вопрос, как понять, какой возвращает результат АЦП? если просто написать return, без чтения младшего и старшего бита.
Последний раз редактировалось Devil Byte; 31.12.2023 в 07:56.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
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, время: 23:29.
|
|