реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Прерывания от компаратора, нужно два разных обработчика
prottoss
сообщение Jul 6 2007, 15:34
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SpyBot @ Jul 6 2007, 23:06) *
Странно, почему нет printf? wink.gif

ИМХО экономия возможна на lcd_gotoxy - считать адрес вручную.
ftoa зачем вобще тут нужно??? 07.gif какие здесь могут быть числа с плавающей точкой?
с printf тоже проблемы не уйдут, больно жручая до памяти, ибо входным параметром идет *char, а это значит, что компилятору для начала нада поместить строку во флэш, потом, при вызове printf, создать в памяти данных массив и в него загрузить строку, а потом уже, адрес массива отдать printf smile.gif

А зачем вообще плавающая точка? Что измеряем? Может лучше фиксированная подойдетьsmile.gif С ней проще...

Маненько не то сказал по поводу printf smile.gif . Вы же строки не выводите... Но все равно printf для Вашего варианта "плохая" функция


--------------------
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 6 2007, 16:04
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Меряем напряжение до 1000 В (меряем делитель АЦП) и частоту 50 +/- 5 Гц (1/TCNT0).

Цитата
Но все равно printf для Вашего варианта "плохая" функция

А какие есть варианты?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
SpyBot
сообщение Jul 6 2007, 16:10
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 285
Регистрация: 5-11-05
Пользователь №: 10 491



Цитата(prottoss @ Jul 6 2007, 19:34) *
с printf тоже проблемы не уйдут, больно жручая до памяти, ибо входным параметром идет *char, а это значит, что компилятору для начала нада поместить строку во флэш, потом, при вызове printf, создать в памяти данных массив и в него загрузить строку, а потом уже, адрес массива отдать printf smile.gif

А зачем вообще плавающая точка? Что измеряем? Может лучше фиксированная подойдетьsmile.gif С ней проще...

Маненько не то сказал по поводу printf smile.gif . Вы же строки не выводите... Но все равно printf для Вашего варианта "плохая" функция

Это был риторический вопрос, сорри smile.gif
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 6 2007, 16:15
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(smk @ Jul 7 2007, 00:04) *
Меряем напряжение до 1000 В (меряем делитель АЦП) и частоту 50 +/- 5 Гц (1/TCNT0).
А какие есть варианты?
Опа... И зачем здеся флоат???


--------------------
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 6 2007, 16:21
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
Опа... И зачем здеся флоат???


Критикуеш - предлагай!

Что раньше работало, то и писал...


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
AndryG
сообщение Jul 6 2007, 16:21
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 23-05-05
Из: UA
Пользователь №: 5 317



перечитал дважды, но не нашел Вашего ответа на
"отказаться от float"
Напряжение до 1000 измеряете, а какая "дельта"? С какой точностью?

На экран вы выводите, насколько я понял, в целых (d=1)
Частоту в сотых (в = 0.01)
Для чего тогда float?
Может сразу держать напряжение в вольтах, а частоту "в сотых герца"?
Типа F=5003 -- это 50.03Гц

Цитата
Обработчиков всего два. А статические переменные использую, но в "технологических" целях. Например, узнать прерывание первое или второе (запустить/остановить таймер).

А может тогда сразу смотреть на биты таймера? "Если не работает - запустить" ... или ... "если таймер стоит - прерывание первое/второе" ...
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 6 2007, 16:38
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(smk @ Jul 7 2007, 00:21) *
Критикуеш - предлагай!
Что раньше работало, то и писал...
Уже несколько раз говорилось про фиксированную запятую. ТО бишь все числа получаются целые, но разряды с 0 по N (младшие) отделены от разрядов N+1....M воображаемой точкой. smile.gif


--------------------
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 6 2007, 16:46
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
Уже несколько раз говорилось про фиксированную запятую


согласен. Как реализовать? printf "полегче", но не выход. Имеем теперь 1109 слов, а надо 1024.

Цитата
Напряжение до 1000 измеряете, а какая "дельта"? С какой точностью?


1 В, а проше говоря насколько АЦП позволит.

Цитата
На экран вы выводите, насколько я понял, в целых (d=1)
Частоту в сотых (в = 0.01)


Да, верно.

про флоат забыл, делать дальше что?


Цитата
Может сразу держать напряжение в вольтах, а частоту "в сотых герца"?
Типа F=5003 -- это 50.03Гц


Так и хочу.
U= 1000 V
F= 50.05 Hz


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 6 2007, 16:51
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(smk @ Jul 7 2007, 00:46) *
согласен. Как реализовать? printf "полегче", но не выход. Имеем теперь 1109 слов, а надо 1024.


Уже было на форуме про это...

Код
/*****************************************************************************
Преобразовывает переменную ULONG в неупакованное

десятичное и далее в строку
******************************************************************************/
void ulong2str(UINT32 val)
{
   UINT32 d = 1000000000;
   for(UCHAR i = 0; i < 10; i++) /* цикл по пяти знакам */
    {
       dbg_msg[i] = 0; /* формируем сумму искомого числа */
       while(val >= d) /* пока порядок не отрицательный */
        { val-= d; /* вычитаем из знака порядок */
         dbg_msg[i]++; /* и увеличиваем искомое число */
        }

        dbg_msg[i] += 0x30; /* преобразуем в ASCII символ */
        d /= 10; /* получаем следующий (младший) порядок */
    }
    dbg_msg[10] = 0;
}


Можно довести до любых мыслимых для АВР разрядов, сдесь 32, точку ставим, где хотим


--------------------
Go to the top of the page
 
+Quote Post
AndryG
сообщение Jul 6 2007, 17:11
Сообщение #25


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 23-05-05
Из: UA
Пользователь №: 5 317



Цитата
Имеем теперь 1109 слов, а надо 1024.

:-) Ну! сжать сишную прогу на пару десятков слов всегда можно ... теперь по каждой строке пробежаться, да мелочевку поправить. :-)

Плюс выше приведенный пост ... поздравляю Вас с решением задачки.

Ну а если не получится ужать - если можно, то код в студию ... ужмем коллективно :-)
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 6 2007, 17:26
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
Ну а если не получится ужать - если можно, то код в студию ... ужмем коллективно :-)


Заинтриговали. Даю. Бить ногами по голове можно, каску надел! Только бы помоголо.





вот
Прикрепленные файлы
Прикрепленный файл  pelt261.txt ( 7.29 килобайт ) Кол-во скачиваний: 92
 


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jul 6 2007, 18:05
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(AndryG @ Jul 7 2007, 01:11) *
:-) Ну! сжать сишную прогу на пару десятков слов всегда можно ... теперь по каждой строке пробежаться, да мелочевку поправить. :-)
Плюс выше приведенный пост ... поздравляю Вас с решением задачки.Ну а если не получится ужать - если можно, то код в студию ... ужмем коллективно :-)
Повторюсь - вместо того, чтобы сжимать до немыслимых пределов Сишную прогу, лучше заложить МК с бОльшими ресурсами - себе дешевле выйдеть smile.gif


--------------------
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 6 2007, 18:12
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
лучше заложить МК с бОльшими ресурсами


А вот бы сжать, подождать так пока Тини461 или Тини861 не выпустят, а потом наворачивать. Хороший контроллер Тиня эта. И ног под девайс в самый раз.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
AndryG
сообщение Jul 7 2007, 07:24
Сообщение #29


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 23-05-05
Из: UA
Пользователь №: 5 317



Ну раз всего проекта нет, то давай по кускам .... расскажу, что я надумал .. а Вы уж проверяйте - Вы проект пишете, а я только на код смотрю.
Повторюсь ... я не вникаю в алгоритм ... так-что смотрите внимательно.

Код
if (ACSR==0x4C)
  m++;
if (ACSR==0x4F)
{
if (a==0)
    {
    TCCR0 = 0x02; //start timer, делитель на 8, 1 тик = 1 мкС
    a=1;//признак включенного таймера
    }
else
    {    
    TCCR0 = 0x00; //stop timer
    a=0;//признак выключенного таймера
    b=1;//признак завершения измерения периода
    };

};

Судя по коду ACSR принимает только два значения ... значит можно проверять только один бит байта, который принимает разные значения. if (ACSR & 0x01){}else{} вместо двух if. Выигрыш в проверки одного бита вместо двух сравнений чисел.
Изм. периода. Идея ... насколько понял ...
нач. условие: таймер выключен, счетчик сброшен, b==0.
первое прерывание - запускаем таймер
второе прерывание - останавливаем таймер и поднимаем флаг b
Вопрос: "для чего вы в А дублируете состояние таймера? Проверяйте if(TCCR0 & 0x02 )"
Второй вопрос: "зачем вам знать, включен он или нет" ... может вместо "если включен, то выключить, иначе включить" .. просто написать "изменить состояние" => TCCR0 ^ 0x02; ... если правильно поставить нач. условия, то всё отработает красиво.
Код
interrupt [ANA_COMP] void ana_comp_isr(void)
{
//а если ACSR=0x4C то считаем к-во прерываний
//Если ACSR=0x4F то считаем период,  
if (ACSR & 0x01) // (ACSR==0x4F)
  {
    TCCR0 = TCCR0 ^ 0x02; // переключили таймер
    if (!(TCCR0 & 0x02))  //если таймер выключен - значит подсчет закончен
      b=1;//признак завершения измерения периода
  }
  else // (ACSR==0x4C)
    m++;
}

ЗАПОМНИЛИ .... в осн. цикле нужно инициализировать B, TCCR0, ACSR, TCNT0

Код
// *** БЛОК ПРОВЕРКИ ПОСТОЯННОЕ-ПЕРЕМЕННОЕ ***
    // Interrupt on Output Toggle (прерываемся при любом изменении состояния компаратора)
      ACSR=0x4C;
      // Global enable interrupts
      #asm("sei")
      delay_ms(45);  //время проведения измерения
      #asm("cli")    //выключаем прерывания чтоб не отвлекать АЛУ
      if (m>=3)      //если зарегистрировано 3 и больше перепадов за 45 мс, то считаем что
                     //меряем переменку
        {
        ACDC=1;      //устанавливаем признак переменки
        m=0;         //обнуляем счетчик
        }
      else
        {
        ACDC=0;      //устанавливаем признак постоянки
        m=0;         //обнуляем счетчик
        };

Тут всё просто.
Код

// *** БЛОК ПРОВЕРКИ ПОСТОЯННОЕ-ПЕРЕМЕННОЕ ***
  ACSR=0x4C; //(прерываемся при любом изменении состояния компаратора)
  m = 0;         //это дело обнулим одо его подсчета .. кстати .. зачем ДВА раза это писать.
  #asm("sei")
  delay_ms(45);  //время проведения измерения
  #asm("cli")    //выключаем прерывания чтоб не отвлекать АЛУ
  ACDC = 0;    // такой вариант вместо if-else дает выигрыш в слово :)
  if (m>4)
    ACDC = 1;



дальше ...

___
P.S.
Цитата
Повторюсь - вместо того, чтобы сжимать до немыслимых пределов Сишную прогу, лучше заложить МК с бОльшими ресурсами - себе дешевле выйдеть

А как же ТВОРЧЕСТВО ?! :-)

Код
// *** БЛОК ИЗМЕРЕНИЯ ПЕРИОДА ***
  ACSR=0x4F;
  b = 0;
  TCNT0 = 0;
  #asm("sei")  
  while (!b);  //точно не помню, но CVAVR при ( ==0) умудряется ставить сравнение с константой
  #asm("cli")
  F=1/TCNT0*1000000; //вычисляем значение частоты ВОТ ЗДЕСЬ БОЛЬШАЯ ПОТЕРЯ!!! но это уже нужно алгоритм крутить. а не код оптимизировать
  ACSR.7=0;


По блоку измерения напруги ... опишите словами .. зачем два измерения ... Вы так интересно закрутили флагами и переменными, не хочу въежать ... и потом ... зачем Вам здесь вообще прерывание?
Всё равно Вы сидите delay_ms(50) -- ждете, пока отработают прерывания
Можно в главном цикле просто мониторить флаг окончания преобразования ... какой выигрыш: нет процедуры прерывания, нет delay_ms(50)
И еще ... в CVAVR по умолчанию сохраняет все регистры при переходе на прерывание ... уже не помню, посмотрите в справке. помойму он сохраняет регистры, которые и так не использует никогда - это тоже слов 20 даст размера.
ну и с индикацией тоже не ясно, что используется и т.д. .. посему посоветовать ничего не могу.

Пробуйте - поведаете насколько получилось сжать и сколько еще нужно :-)
____
P.S.
Вариант с измерением напряжения без прерывания ADC
Код
  ADMUX=ADC_VREF_TYPE;
  ADCSR=0xCE;//включить АЦП, начать преобразование

  while (пока не закончилось преобразование - флаг не помню)

  adc_data =ADCW;

ADCSR.6=1; //запустить преобразование

  while (пока не закончилось преобразование - флаг не помню)

  U=ADCW;  

  while (пока не закончилось преобразование - флаг не помню)

if (adc_data > U)
  U = adc_data;

if (ACDC==1)
    U = U/1.414; //!!!!!!!!!!!!!!!!!!!!!  U -> целое!!! И что мы получим?

// прерывание ADС, c, adc_data_max убрать за ненадобностью.


______
P.P.S

U => точно надо с знаком INT ... может UNSIGNED CHAR подойдет?

Проверьте типы переменных ... если не нужен знак - перейдите на беззнаковые переменные
Go to the top of the page
 
+Quote Post
smk
сообщение Jul 7 2007, 07:29
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата
По блоку измерения напруги ... опишите словами .. зачем два измерения ... Вы так интересно закрутили флагами и переменными, не хочу въежать ... и потом ... зачем Вам здесь вообще прерывание?


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

Цитата
Можно в главном цикле просто мониторить флаг окончания преобразования ... какой выигрыш: нет процедуры прерывания, нет delay_ms(50)


Да. можно просто провести 195 преобразований, выбрав из них максимальный результат. Это даст экономию?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 22:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01517 секунд с 7
ELECTRONIX ©2004-2016