WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

внимательно читай спецификацию.
Ну, блииииин.. опять читать заставляете.. нет бы просто сказать, мол так вот и так. ))

Евстифеева-то я прочитал, но там об этом ни гу-гу. а вот читать на английском - для меня мука.. Плоховато язык знаю. Много времени уходит
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

FreshMan писал(а):но тогда надо будет коротать время в цикле, ожидая пока ADSC не станет равен нулю
а если мне надо запустить преобразование и идти дальше по своим делам, как тут быть ?
насколько я понимаю, без проверки ADIF тут не обойтись
а если подумать? ;) чем проверка установки ADIF принципиально отличается от проверки сброса ADSC? тем, что ADIF нужно дополнительно сбрасывать после проверки?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

В принципе, ARV правильно написал, что в нормальном использовании не бывает случаев, когда можно запустить следующее преобразование случайно. Либо это одиночный запуск с последующим сбросом флага или без такового, либо если запуск автоматически, то тогда можно просто считывать значение, не парясь, изменялось оно или нет. либо отслеживать его изменение. зависит от того, что нам надо. И в автоматическом запуске оно само запускается.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: WinAvr в вопросах и ответах

Сообщение FreshMan »

ARV писал(а):что ADIF нужно дополнительно сбрасывать после проверки?
если не разрешено прерывание то надо вручную сбрасывать оный флаг
но мне видится выгода в том, что не надо бездействовать в пустом цикле
или я не правильно понимаю сущнойсть вещей ?
Tell Me The Truth
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

А чего Вам ждать? Делайте свои дела и время от времени проверяйте ADSC. К тому же, ADSC в одиночном режиме запуска автоматически сбрасывается по окончанию преобразования (так же, как и устанавливается ADIF). так что, какая Вам разница, проверять ADIF на единицу или ADSC на ноль?
Реклама
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: WinAvr в вопросах и ответах

Сообщение FreshMan »

так то оно так......, но вот есть ньюанс
ADC я запускаю раз в секунду !
в фоновом режиме у меня вот такой код

Код: Выделить всё

int main(void)
{
	InitPeripheryATmega8A();

	while (1)
	{
		if(bit_is_set(ADCSRA,ADIF)) Conversion(ADC); // ADC - это 16 разрядная переменна, состоящая из ADCH и ADCL

	}
}
поэтому, если я буду проверять на ноль ADSC то ф-ция Conversion(); будет вызываться напрастно
оно то может и ничего....., это же всего-то камешек, что ему будет
но с другой стороны: зачем заганять лошадей ?
Tell Me The Truth
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

FreshMan писал(а):но мне видится выгода в том, что не надо бездействовать в пустом цикле
или я не правильно понимаю сущнойсть вещей ?
давайте попробуем издалека

Код: Выделить всё

int main(void){
   InitPeripheryATmega8A();
   while (1){
      if(bit_is_set(ADCSRA,ADIF)) Conversion(ADC); // ADC - это 16 разрядная переменна, состоящая из ADCH и ADCL
   }
}
вы считаете, что в этом коде в основном цикле делается нечто полезное? скажите, чем хуже вот такой вариант, в котором вообще не проверяется никаких флагов:

Код: Выделить всё

int main(void){
   InitPeripheryATmega8A();
   while (1){
     Conversion(ADC); // ADC - это 16 разрядная переменна, состоящая из ADCH и ADCL
     _delay_ms(1000); // пауза в 1 секунду
   }
}
сущность вещей в том, что если вы хотите нагрузить основной цикл чем-то полезным, то вам нужно использовать прерывания от АЦП для обработки полученного результата. опрос флага или ожидание в основном цикле - это вовсе не "полезная" загрузка. во всяком случае, в конкретно вашем примере кода.

кстати, нет никакой разницы между  if(bit_is_set(ADCSRA,ADIF)) Conversion(ADC); и  if(bit_is_clear(ADCSRA,ADSC)) Conversion(ADC);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

Разница небольшая есть. бит ADIF можно сбросить и при этом больше внутренности проверяющего кода запускаться не будут. а вот ADSC установить для этих же целей уже нельзя - запустится преобразование. поэтому нужно будет делать отдельный флаг, чтобы не юзать лишний раз внутрянку. А зачем этот огород, если есть ADIF? просто его надо перед запуском преобразования сбрасывать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

само собой, разница небольшая есть. в том числе ее можно поискать в ответе на вопрос "почему АЦП запускается именно 1 раз в секунду, а не 2 или не 200 раз?". может быть, ничего страшного в том, что АЦП будет постоянно измерять, нет?

в своей практике я ни разу не выходил за рамки двух вариантов: либо тупое ожидание конца преобразования while(ADSCRA & _BV(ADSC)); либо работа по прерываниям. и я просто не могу понять, зачем нужно придумывать другие варианты.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

Так сами же начали "сочинять" ))
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

это я начал сочинять?! по-моему, это СвежийЧел сочиняет, а я пытаюсь угомонить его неистовое творчество :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: WinAvr в вопросах и ответах

Сообщение FreshMan »

ARV писал(а):сущность вещей в том, что если вы хотите нагрузить основной цикл чем-то полезным, то вам нужно использовать прерывания от АЦП для обработки полученного результата.
а в обработчике прерываний выполнять преобразование ?

Код: Выделить всё

 unsigned char Num1=0, Num2=0, Num3=0, Num4=0;

	 while (_ADC >= 1000)
	 {
		 _ADC -= 1000;
		 Num1++;
	 }

	 while (_ADC >= 100)
	 {
		 _ADC -= 100;
		 Num2++;
	 }

	 while (_ADC >= 10)
	 {
		 _ADC -= 10;
		 Num3++;
	 }
	 Num4 = _ADC ;

	 Screen[2] =Num1;
	 Screen[3] =Num2;
	 Screen[4] =Num3;
	 Screen[5] =Num4;
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

FreshMan, прежде всего надо хорошо подумать, как распределяются ваши процессы в программе на фоновые и основные.

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

основные - это те процессы, к регулярности обращения к которым никаких особых требований не предъявляется. например, это могут быть какие-то вычисления, обработка вводимых ползьзователем данных, ввод-вывод на дисплей и т.п.

деление, конечно, условное - вряд ли кто сумеет вам запретить сделать в основном цикле динамическую индикацию, а диалог с пользователем вести по прерываниям :)))

судя по обрывкам информации, проскакивающей "между строк" ваших сообщений, я делаю такое предположение: у вас есть что-то типа Nixi-индикатора, причем с использованием динамической индикации и ШИМ-регулировки яркости индикаторов. вы теперь хотите что-то там измерить при помощи АЦП и вывести это на индикатор, но при этом так, чтобы не разрушить ранее сделанную индикацию. я угадал?

так вот, могу дать несколько советов, а пользоваться ими или нет - дело ваше. правда, боюсь, что к теме топика это будет иметь мало отношения - да простят меня модераторы!

1. выделите все, что касается индикации, в отдельный файл. общение с этим модулем ведите только через "интерфейсные" функции, и необходимый минимум переменных. отладив индикацию, больше в этот файл не заглядывайте - это почти гарантия, что вы не сломаете то, что уже работает.

2. определитесь с основными процессами в вашей системе. мне кажется (не настаиваю), то обработка АЦП, обработка нажатий кнопок, вычисления - все это основные (не фоновые) задачи. т.е. в общих чертах я бы сделал как-то так:

Код: Выделить всё

while(1){ // основной цикл
   key = get_key(); // опрос кнопок
   adc = get_adc(); // измерение АЦП
   switch(key){
      // тут обрабатываем нажатия кнопок
   }
   // если нужно, обрабатываем результат АЦП
   output_to_display(/* всякие выводимые значения */); // вывод на индикатор результатов работы
}
как видите, все исключительно последовательно и без всяких флагов и т.п.

3. если по каким-то причинам слишком частое измерение АЦП вам неприемлемо, то предлагаю рассмотреть такой вариант: по таймеру запускаете АЦП, при этом АЦП вызывет прерывание по окончанию измерения. в обработчике этого прерывания вы переписываете значение из регистров ADC в volatile переменную, значение которой тупо возвращаете функцией get_adc(); чем хорош такой вариант? да хотя бы тем, что основной цикл при этом вообще никак не меняется! единственное, о чем надо помнить, так это о том, что обращение к неоднобайтной переменной с результатом АЦП должно быть атомарным.

вот, как-то так...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

Смею немного поправить более опытного кота по поводу фоновых процессов. )
предположим, что есть основной цикл, который периодически повторяется (скажем, раз в 100 мс)
есть основные вычисления, которые должны выполнится в любом случае (допустим, их время выполнения варьируется в зависимости от условий от 10 до 80 мс, при этом время их выполнения не может быть больше времени основного цикла)
и есть фоновые процессы - это те, которые делаются в оставшемся промежутке от времени выполнения основных вычислений (в нашем случае, это 20-90 мс). Причем, если обработка фонового процесса не помещается в остаток времени, он может сохранить промежуточное значение и продолжить вычисления в следующем основном цикле. Т.е. фон - это задний план. То, что может подождать.

Так делается в промышленных контроллерах типа Siemens. И это правильно.

в таком случае, динамическая индикация - это основной процесс (как наиболее критичный, поскольку разные временные задержки там мало приемлемы), а вот обработка кнопок и все остальной части - это фон. :beer:
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

я придерживаюсь несколько иных формулировок.

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

Мой уютный бложик... заходите!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: WinAvr в вопросах и ответах

Сообщение FreshMan »

ARV писал(а):судя по обрывкам информации, проскакивающей "между строк" ваших сообщений, я делаю такое предположение: у вас есть что-то типа Nixi-индикатора, причем с использованием динамической индикации и ШИМ-регулировки яркости индикаторов. вы теперь хотите что-то там измерить при помощи АЦП и вывести это на индикатор, но при этом так, чтобы не разрушить ранее сделанную индикацию. я угадал?
почти :))
у меня есть часы на газоразрядных индикаторах ИН-4
в часах присутствуют разные визуальные эффекты при отображении времени: перелив, перебор, плавная смена ну и обычная смена цифр
при помощи ацп я хочу задавать предел яркости, в зависимости от времени суток
можна было-бы его включить и пущай он постоянно молотит....., но это я считаю не гуманным :))
хочу запускать измерения раз в 1 сек по таймеру
ARV писал(а):1. выделите все, что касается индикации, в отдельный файл. общение с этим модулем ведите только через "интерфейсные" функции, и необходимый минимум переменных. отладив индикацию, больше в этот файл не заглядывайте - это почти гарантия, что вы не сломаете то, что уже работает.
вот все что связанно с моей индикацией
https://dpaste.de/8qHt
думаете это можна вынести в отдельный файл ?
Tell Me The Truth
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

Кстати, еще интересен такой вопрос: если во время преобразования попытаться сбросить флаг ADSC (старт преобразования и его текущий статус, идет/не идет), то преобразование остановится? или же его можно остановить только выключением всего АЦП?
Судя по эмулятору студийному, бит ADSC сбросится, но преобразование закончено будет. Это скорее всего можно использовать для остановки преобразований в автоматическом режиме запуска.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: WinAvr в вопросах и ответах

Сообщение FreshMan »

можна ли таким образом, при инициализации, в eeprom записать значение ?

Код: Выделить всё

static uint16_t EEMEM twilight_threshold=1025;
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: WinAvr в вопросах и ответах

Сообщение ARV »

так можно заставить компилятор создать файл для прошивки EEPROM.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ИС-пытатель
Вымогатель припоя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Re: WinAvr в вопросах и ответах

Сообщение ИС-пытатель »

В CV AVR если Вы объявляете переменную с модификатором eeprom, то при последующем присвоении ей значения в EEPROM автоматически пишется ее значение. В студии такого нет. В принципе, можете просто сделать макрос и процедуру записи.
Ответить

Вернуться в «AVR»