Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
27.02.2011, 14:11
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Сообщение от 7Fantomas7
|
Но когда я попытался уменьшить частоту работы АЦП т.е. увеличил коэфициент деления то начался дурдом в канале ADC7 и чем больше коэфициент деления тем больше дурдом при коэфициенте деления 64 или 128 каналы меняются как бы местами, соответственно частота включения АЦП тоже корректируется соответствующим образом. И соответственно я ничего не в состоянии понять. В запредельном режиме работает, в нормальном режиме не работает.
|
Уже была подобная тема https://kazus.ru/forums/showthread.php?t=34233 Или косяк в коде, или глюк среды программирования. После смены канала делайте одно "холостое" измерение. А вообще с АЦП всегда работают на прерываниях - запускают проц в Noise reduction и ждут окончания преобразования. Тогда холостые измерения не нужны при правильном коде. Ловите свои косяки и делайте частоту измерения пониже. 15...30 кГц
|
|
|
|
27.02.2011, 14:23
|
|
Почётный гражданин KAZUS.RU
Регистрация: 23.09.2008
Адрес: Козьмодемьянск. Это на Волге.
Сообщений: 2,400
Сказал спасибо: 5,548
Сказали Спасибо 1,049 раз(а) в 605 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Скорей всего что-то не то с усреднителем. Попробуйте привести код. При достаточно большой частоте повторений измерений имеет смысл увеличить буфер усреднителя.
ИМХО.
|
|
|
|
27.02.2011, 17:02
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Цитата:
|
Попробуйте привести код
|
Конкретно сейчас код выглядит примерно так
Есть в main цикл в котором крутимся (цикл порезаный обработка событий нажатия кнопок удалена)
Код:
|
while (start==1 && rejim==0){ //если старт разрешен и режим установлен как источник тока
ADC_I(); //замерили величину тока
PWM_control_I(); //подкоректировали величину тока если необходимо
ADC_U(); //померили напряжение
indi(); //отобразили на индикаторе текущие значения измерения
} |
Есть функции ADC_I и ADC_U
например ADC_I выглядит так
Код:
|
void ADC_I (void){ //делаем АЦП ADC6
static unsigned int calculator_bufer_I[15];//буфер фильтра тока среднее арифметическое
volatile unsigned char I_ADC; //переменная результат измерения I
if (flag_ADC_I==1){ //Если разрешено АЦП (частота разрешений 133,333 кГц)
ADCH=0b00000000;
ADMUX=0b00100110;
//ADCSRA=0b11000001;//делитель 2
ADCSRA=0b11000011;//делитель 8
delay_us(8);
I_ADC=ADCH;
calculator_bufer_I[14]=calculator_bufer_I[13];
calculator_bufer_I[13]=calculator_bufer_I[12];
calculator_bufer_I[12]=calculator_bufer_I[11];
calculator_bufer_I[11]=calculator_bufer_I[10];
calculator_bufer_I[10]=calculator_bufer_I[9];
calculator_bufer_I[9]=calculator_bufer_I[8];
calculator_bufer_I[8]=calculator_bufer_I[7];
calculator_bufer_I[7]=calculator_bufer_I[6];
calculator_bufer_I[6]=calculator_bufer_I[5];
calculator_bufer_I[5]=calculator_bufer_I[4];
calculator_bufer_I[4]=calculator_bufer_I[3];
calculator_bufer_I[3]=calculator_bufer_I[2];
calculator_bufer_I[2]=calculator_bufer_I[1];
calculator_bufer_I[1]=calculator_bufer_I[0];
calculator_bufer_I[0]=I_ADC;
izmerenoe_I=(calculator_bufer_I[0]+calculator_bufer_I[1]+calculator_bufer_I[2]+calculator_bufer_I[3]
+calculator_bufer_I[4]+calculator_bufer_I[5]+calculator_bufer_I[6]+calculator_bufer_I[7]
+calculator_bufer_I[8]+calculator_bufer_I[9]+calculator_bufer_I[10]+calculator_bufer_I[10]
+calculator_bufer_I[11]+calculator_bufer_I[12]+calculator_bufer_I[13]+calculator_bufer_I[14])/15;
//sprintf (&sym_out1[0],"%s","izmerenoe_I");
indy_I=izmerenoe_I; //переменной которую будем передавать в индикацию присваиваем то что намерили (Ток)
flag_ADC_I=0; //сбросили флаг разрешения АЦП
}
} |
Функция ADC_U выглядит так же не вижу смысла приводить.
Цитата:
|
При достаточно большой частоте повторений измерений имеет смысл увеличить буфер усреднителя.
|
Буфера 15 байт куда уж больше, хотелось бы 4 байтами обойтись.
niXto
За ссылку спасибо у меня именно CVAVR 2.05
Цитата:
|
Или косяк в коде, или глюк среды программирования.
|
Так сам понимаю, только косяк найти не могу и в чем глюк не могу определить.
Цитата:
|
После смены канала делайте одно "холостое" измерение.
|
А как же я это сделаю у меня два канала работают 1-2-1-2 и т.д. в круговую. Но попробую.
Цитата:
|
Ловите свои косяки и делайте частоту измерения пониже. 15...30 кГц
|
Так ловлю ж. Нет мне конечно очень нравится что с дуру АЦП работает на такой большой частоте вот только еще бы стабильности добавить чтоб буфер байта 4 был вообще красота была бы. Только здается мне что так не правильно. А может быть причиной то что на остальных 6 пинах висит динамичка, а именно переключаются разряды. Хотя в то время когда происходит АЦП пины находятся в статическом состоянии и разряды не переключаются.
|
|
|
|
27.02.2011, 17:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Сообщение от niXto
|
А вообще с АЦП всегда работают на прерываниях - запускают проц в Noise reduction и ждут окончания преобразования. Тогда холостые измерения не нужны при правильном коде.
|
Переведу, на всякий случай, на русский язык. В этом режиме (ADC Noise Reduction) запускается измерение АЦП и останавливаются многие системы ядра (МК переводится в Idle режим), при этом помех от других систем не будет. Но и работать больше ничего не будет до ближайшего прерывания. ШИМ в том числе. Вот и думайте - оно Вам надо?
Для попробовать, можно поглумиться. Чтобы проверить точность измерения в тепличном режиме.
|
|
|
|
27.02.2011, 19:44
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Сообщение от omercury
|
Чтобы проверить точность измерения в тепличном режиме.
|
C работающим ШИМом термин "точность" к АВР-овскому АЦП неприменим
ИМХО
|
|
|
|
27.02.2011, 19:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Цитата:
|
при этом помех от других систем не будет. Но и работать больше ничего не будет до ближайшего прерывания. ШИМ в том числе. Вот и думайте - оно Вам надо?
|
Не надо. ШИМ должен работать все время. Более того я знаю что люди умудряются не только мерять но и управлять шириной каждого импульса Mega 16й . Я таким экстремалом не решился заниматься и делаю все по среднему т.е. сделал из процесора мудреный резистор. Вы это знаете. Конечно сейчас попробую переделать флаг запуска следующего АЦП по четкому завершению предидущего.
|
|
|
|
27.02.2011, 20:05
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Сообщение от niXto
|
C работающим ШИМом термин "точность" к АВР-овскому АЦП неприменим
ИМХО
|
Знаю
Сообщение от omercury
|
Дело в том, что в кристалле модуль АЦП находится рядом с модулями таймеров. Вот они-то и дают наводку на АЦП. Для исключения влияния таймеров - их рекомендуют отключать на время измерения. Получается замкнутый круг - хочется точности работы по таймингам - надо использовать таймеры, но не будет точности измерений. И наоборот... Такая вот петрушка.
|
Сообщение от 7Fantomas7
|
люди умудряются не только мерять но и управлять шириной каждого импульса Mega 16й
|
Это несложно. По флагу Compare Match грузить новое значение для компаратора. Для 8-битного таймера - это 256 его тактов(если не СТС режим), для 16-битного много больше.
Сообщение от 7Fantomas7
|
Конечно сейчас попробую переделать флаг запуска следующего АЦП по четкому завершению предидущего.
|
Можно это сделать в прерывании ADC Complete. Алгоритм - сохранить SREG, установить флаг, восстановить SREG. Или - сохранить SREG, считать ADCL+ADCH, установить флаг, запустить АЦП с настройками другого канала, восстановить SREG.
П.С. SREG Си сам сохранит, а вот чтоб флаг точно сработал, надо задать ему свойство volatile.
Последний раз редактировалось omercury; 27.02.2011 в 20:30.
|
|
|
|
27.02.2011, 22:56
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Частота запуска однократного АЦП
omercury,
Цитата:
|
Можно это сделать в прерывании ADC Complete. Алгоритм
|
Об этом поговорим судя по всему чуть позже. Я кажись въехал по крайней мере в шпротеусе нашел ошибку. Ваши доводы абсолютно верны как и всех остальных кто предлагает делать в прерываниях. Но как говорится легкие пути нам не ведомы.
Есть код.
Код:
|
void ADC_I (void){ //делаем АЦП ADC6
static unsigned int calculator_bufer_I[15];//буфер фильтра тока среднее арифметическое
volatile unsigned char I_ADC; //переменная результат измерения I
if (flag_ADC_I==1){ //Если разрешено АЦП (частота разрешений 133,333 кГц)
ADCH=0b00000000;
ADMUX=0b00100110;
ADCSRA=0b11000011;//делитель 8
delay_us(8);
I_ADC=ADCH; |
Я допустил существенную ошибку запуская функцию АЦП по флагу с нужной выдержкой времени if (flag_ADC_I==1)пока не важно с какой частотой это происходит. Но судя по всему так делать нельзя.
Дело втом что этот участок не верен
Код:
|
ADMUX=0b00100110;
ADCSRA=0b11000011;//делитель 8
delay_us(8);
I_ADC=ADCH; |
Выдержка времени мала. Я просмотрел поведение бита ADSC в регистре ADCSRA и при такой выдержке этот бит не успевает обнулится когда ваполняется I_ADC=ADCH;. Другими словами я в переменную пишу значение которого нет, преобразование не закончено и в переменную пишутся нули что и не удивительно ведь я обнулил ADCH=0b00000000;.
Я поставил задержку delay_us(14), этой задержки достаточно и в шпротеусе отчетливо видно как ADSC сбрасывается в 0. Но блин зараза в ADCH все равно нули. Соответственно я не погу просмотреть что реально происходит в процесоре, поэтому приходится опираться на то что еть. Но один канал то работает, второй я не исследовал и паралельную работу не исследовал.
Отсюда рисуется ряд вопросов.
Во время задержки delay преобразование происходит или нет, если нет то почему сбрасывается ADSC? Если преобразование происходит во время delay то почему не видно изменения в ADCH ?
Отсюда рисуется для меня в принципе идеальный алгоритм:
Запустили АЦП- АЦПируем до до завершения преобразования-произошло прерывание в котором обрабатываем результаты (а ШИМ не трогаем)-пошли дальше. Как организовать красный участок. А если не двигаться никуда во время преобразования то и прерывание не нужно. Вобщем как то так.
Последний раз редактировалось 7Fantomas7; 27.02.2011 в 22:59.
|
|
|
|
27.02.2011, 23:27
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Сообщение от 7Fantomas7
|
Как организовать красный участок.
|
Ждать результата преобразования по задержке нехорошо. Можно, но некрасиво.
Бит ADSC - это бит запуска преобразования АЦП.
Флаг ADIF устанавливается по окончании преобразования независимо от того, включено прерывание или нет. Вот его и надо анализировать. На Си будет такая конструкция:
Код:
|
while (ADCSRA & ADIF)=0
{
};
I_ADC=ADCH; |
или так
Код:
|
while ~(ADCSRA & ADIF)
{
};
I_ADC=ADCH; |
(примерно так, точнее пока не могу - Си не знаю. Читать могу, а писать нет. Иностранный язык ![Рот до ушей](images/smilies/icon_doushei.gif) . Т.е. ожидаем, пока флаг не установлен). Дальше считываем ADCH.
Сообщение от 7Fantomas7
|
почему сбрасывается ADSC?
|
ADSC сбрасывается сам через 25 тактов АЦП независимо от результата преобразования. Так устроено...
Последний раз редактировалось omercury; 27.02.2011 в 23:37.
|
|
|
|
28.02.2011, 00:22
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Частота запуска однократного АЦП
Цитата:
|
Ждать результата преобразования по задержке нехорошо. Можно, но некрасиво.
|
Да я согласен что не красиво.
Цитата:
|
Бит ADSC - это бит запуска преобразования АЦП.
Флаг ADIF устанавливается по окончании преобразования независимо от того, включено прерывание или нет. Вот его и надо анализировать.
|
А вот тут постойте, чет не так. Евстифеев считает по другому. Я честно говоря опираюсь на его.
Цитата:
|
Длительность цикла преобразования составляет 13 тактов для несиметричного входа...., выборка и запоминание входного сигнала осуществляется в течение первых 1,5 тактов. Через 13 тактов преобразование завершается, бит ADSC аппаратно сбрасывается в 0.результат преобразования сохраняется в регистре данных АЦП
|
Заметьте через 13 тактов должно завершится преобразование и бит ADSC брасывается по окончании преобразования
Цитата:
|
ADSC сбрасывается сам через 25 тактов АЦП независимо от результата преобразования.
|
Не совсем вяжется утверждение.
Но да суть не в том. Допустим я сделаю прерывание по окончании АЦП и запущу обработчик. ШИМ остановится. Вы же знаете что для меня это не допустимо, Вы ж знаете куда это.. Я и так прерывания по таймеру 0 собираюсь запретить и сделать тактирование от шима, а то на выходе шима пачки импульсов Вы кодато предлагали тактировать от шима, снимаю шляпу были правы. Какой выход с АЦП?
P.S. прошу прощения с симуляцией все нормально ADCH отображается нормально, это я натормозил.
Последний раз редактировалось 7Fantomas7; 28.02.2011 в 00:59.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:17.
|
|