[uquote="Jman",url="/forum/viewtopic.php?p=3159507#p3159507"]И мне можно прерывание выбросить.[/uquote]
можно, конечно, прерывание выбросить. Но оно для того и реализовано в контроллере, чтобы не чесать правой рукой левое ухо.
У вас было все изначально правильно, за исключением неправильного инкремента ADMUX. так что городить городушки с заменой прерывания ADC прерыванием таймера, это даже не чесать левое ухо правой рукой, это сродни удалению гланд через анальный проход.
Я одно не пойму. Как щелкать каналами и работать с прерыванием по окончанию измерения канала ясно. А вот как это делать через определенные интервалы времени...
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
[uquote="Jman",url="/forum/viewtopic.php?p=3159565#p3159565"]Я одно не пойму. Как щелкать каналами и работать с прерыванием по окончанию измерения канала ясно. А вот как это делать через определенные интервалы времени...[/uquote]
а вот я не пойму, зачем это делать? В контроллере есть специальное прерывание, которое вызывается по окончанию преобразования. зачем же лепить горбатого к стенке?
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
[uquote="Jman",url="/forum/viewtopic.php?p=3159573#p3159573"]Нужен опрос каждого канала по 200 микросекунд.[/uquote]
тогда сделайте прерывание по таймеру и перенесите строку:
из прерывания по окончанию преобразования в прерывание по таймеру. Но тут есть нюансы. Если преобразование длится более, чем 200 мкс, то, разумеется, у вас будут проблемы. Посему, сначала разрешаете только одно прерывание по окончанию преобразования, добавляете туда две строчки и осциллографом замеряете, сколько длится преобразование.
ISR( TIMER0_OVF_vect )
{
// 100 us oveflow
// Reinitialize Timer 0 value
TCNT0=0x9C;
ADCSRA|=(1<<ADSC); //ADCSRA|=0x40
}
ISR (ADC_vect)
{
//static byte input_index=0;
// Read the AD conversion result
adc_data[input_index]=ADCW;
// Select next ADC input
if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))
input_index=0;
ADMUX=(FIRST_ADC_INPUT % 3)| (ADC_VREF_TYPE+input_index);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
//ADCSRA|=(1<<ADSC);
}
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
ISR( TIMER0_OVF_vect )
{
// 100 us oveflow
// Reinitialize Timer 0 value
TCNT0=0x9C;
ADCSRA|=(1<<ADSC); //ADCSRA|=0x40
}
ISR (ADC_vect)
{
//static byte input_index=0;
// Read the AD conversion result
adc_data[input_index]=ADCW;
// Select next ADC input
if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT))
input_index=0;
ADMUX=(FIRST_ADC_INPUT % 3)| (ADC_VREF_TYPE+input_index);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
//ADCSRA|=(1<<ADSC);
}
[/uquote]
ADCW, это что за зверь?
а вообще, код какой-то непонятный. Я даже и не понял, что он делает
Судя по ДШ в ADCW пишутся оба регистра ADCL и ADCH. А код CV AVR генерирует
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
[uquote="Jman",url="/forum/viewtopic.php?p=3159597#p3159597"]Судя по ДШ в ADCW пишутся оба регистра ADCL и ADCH. А код CV AVR генерирует[/uquote]
судя по даташиту регистр называется ADC. Но в CV чего только не может быть
[uquote="Jman",url="/forum/viewtopic.php?p=3159597#p3159597"]А код CV AVR генерирует[/uquote]
тогда понятно. Этот уж нагенерирует за пять минут столько, что тысячу мудрецов за год не смогут разобрать
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
Ivanoff-iv писал(а):некоторое снижение случайной ошибки, вот например возьмём 10бит шим (младший разряд шумящий) сложим 2 замера и получим 11бит сигнал, младший шумящий - отсекаем его (/2) и получаем обратно 10бит сигнал, но уже стабильней.
об этом и говорю...)) три выборки АЦП - просто стабильней... но это не убирает шум полностью. Нужно или делать МНОГО выборок (оцифровать входной сигнал), или использовать другой алгоритм, например я часто исмпользую гистерезис, который полностью убирает шум АЦП...
чёто вы замудрили.. куча прерываний... Можно просто делать выборки АЦП через 200 мкс в цикле... Например типа так:
mesto_1: // начало
ADMUX=0b01100001; // где 1 - номер канала..
ADCSRA|=0b01000000; // где 1 - старт преобразования...
delay_us(200); // ждём 200 мкс...
a=ADCW; // записали данные из АЦП в переменную "a" (тип int).
goto mesto_1; // конец. Перейти вначало.
... и т.д. Короче крутимся в цикле без прерываний))
Последний раз редактировалось roman.com Чт авг 10, 2017 13:22:39, всего редактировалось 1 раз.
... и т.д. Короче крутимся в цикле без прерываний))
Так не интересно. Такой вариант заработал сразу же. Тем более его генерирует Code Vision =)
[color=#4080FF]- Бежит этот подлец-электрон, а вокруг его масса (аж 10 в 23й) штук ионов кремния и 10 в 15й ионов примеси и он, подлец, взаимодействует![/color]
)) не интересно им... Это хорошо если МК кроме оцифровки входного сигнала ничего бельше не делает... А если МК выполняет сложные операции с высокой точностью... В этом случае МК вообще не может отвлекаться на прерывания...
я не люблю прерывания.. с ними постоянно головняк..
[uquote="roman.com",url="/forum/viewtopic.php?p=3159659#p3159659"]три выборки АЦП - просто стабильней... но это не убирает шум полностью. Нужно или делать МНОГО выборок (оцифровать входной сигнал),[/uquote]
много выборок ему нельзя делать, он ограничен 200 микросекундами
[uquote="roman.com",url="/forum/viewtopic.php?p=3159659#p3159659"]или использовать другой алгоритм, например я часто исмпользую гистерезис, который полностью убирает шум АЦП...[/uquote]
что за гистерезис?
Добавлено after 4 minutes 4 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=3159667#p3159667"])) не интересно им... Это хорошо если МК кроме оцифровки входного сигнала ничего бельше не делает... А если МК выполняет сложные операции с высокой точностью... В этом случае МК вообще не может отвлекаться на прерывания...[/uquote]
ну да, конечно, на прерывания отвлекаться нельзя, а вот задержки на 200 мкс делать можно. Вам самим-то не смешно?
Если ваш контроллер выполняет много разных задач, то при помощи прерывания обрабатываются самые важные. Для того прерывания и придуманы
[uquote="roman.com",url="/forum/viewtopic.php?p=3159667#p3159667"]я не люблю прерывания.. с ними постоянно головняк..[/uquote]
то, что не любите, это чувствуется, а головняк не от прерываний, а от неумения их правильно использовать
a=ADCW/2;
if (a>ub+1) {u=a/2; ub=a;};
if (a<ub-1) {u=a/2; ub=a;};
Тут, на выходе 10 разрядного АЦП получаем 8 разрядов данных (или 9 разрядов). Понятно, что разрешающая способность АЦП меньше, но зато последний разряд не шумит)) т.к. урень шума на входе АЦП меньше шага квантования АЦП...
ozonn писал(а):при помощи прерывания обрабатываются самые важные. Для того прерывания и придуманы
я об этом и говрю..)) у меня самые важные - это аварийное отключение систем ))
ozonn писал(а):на прерывания отвлекаться нельзя, а вот задержки на 200 мкс делать можно.
задержка - это просто пример, если МК больше ничем не занят, то множно и делей delay_us(200);...
но чаще у меня по другому:
mesto_1: // начало
ADMUX=0b01100001; // где 1 - номер канала..
ADCSRA|=0b01000000; // где 1 - старт преобразования...
delay_us(200); // ждём 200 мкс... Пока идет преобразование АЦП, МК выполняет полезную работу, без отрыва на прерывание. ))
a=ADCW; // по окончании выполнения полезной работы, записали данные из АЦП в переменную "a" (тип int).
goto mesto_1; // конец. Перейти вначало.
[uquote="roman.com",url="/forum/viewtopic.php?p=3159681#p3159681"]гистерезис обычный... например вот так:
a=ADCW/2;
if (a>ub+1) {u=a/2; ub=a;};
if (a<ub-1) {u=a/2; ub=a;};[/uquote]
честно говоря не понял. сначала делим результат измерения на 2, потом, независимо от того, больше ли это частное чем предыдущее частное плюс один или оно меньше, чем предыдущее частное минус один, выполняем одно и то же действие, а именно, еще раз делим результат на два. Т.е. получаем результат в четыре раза меньше измеренного. В чем тут фокус?
Добавлено after 2 minutes 35 seconds:
[uquote="roman.com",url="/forum/viewtopic.php?p=3159681#p3159681"]Пока идет преобразование АЦП, МК выполняет полезную работу, без отрыва на прерывание. ))[/uquote]
да, именно так и организавна программа с использованием прерывания. Пока идет преобразование, контроллер выполняет другую задачу, а как только преобразование завершилось, приступает к его обработке. И чем вам это не нравится?
roman.com писал(а):Тут, на выходе 10 разрядного АЦП получаем 8 разрядов данных (или 9 разрядов). Понятно, что разрешающая способность АЦП меньше, но зато последний разряд не шумит))
чтобы получать 8 разрядов с нешумящими (хотя это самообман) разрядами, специально придуман режим "выравнивания влево" (бит ADLAR) - включите его и пользуйтесь ADCH в качестве результата - к чему какие-то загадочные вычисления, гистерезисы и т.п.?
но повторяю еще раз: это самообман. кто вам мешает в 10-битном результате всегда тупо давить младший бит в 0? и не будет он шуметь...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...