Например TDA7294

Форум РадиоКот :: Просмотр темы - Нестабильность из-за задержек
Форум РадиоКот
https://radiokot.ru/forum/

Нестабильность из-за задержек
https://radiokot.ru/forum/viewtopic.php?f=57&t=176597
Страница 6 из 8

Автор:  Самсусамыч [ Ср апр 21, 2021 09:03:36 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Самсусамыч, ну и кто в твоем хексе увидит твой алгоритм?

Я пишу программы не для демонстрации своего алгоритма. Так как не являюсь виртуозом в данном направлении (даже в ближайшем приближении). Это пусть профессионалы демонстрируют меж собой свои умения. Для меня главное, чтобы программа корректно работала в железе как ранее задумано. А как это написано не столь важно. Да и исходники написанные в АВ мало кому помогут понять что в алгоритме реализовано. Или Вы забыли, что я пишу исключительно на АВ (Algorithm Builder) и другими языками программирования не владею? Ранее Вы с лёгкостью дизассемблировали мой код, а что случилось в этот раз? Стало лениво? При Ваших знаниях и умениях, Вам-то он зачем? Ткнуть меня носом, где я делаю что-то не так глядя с Вашей колокольни? Так я Вам сразу скажу, я много чего делаю не так… главное алгоритм работает в железе как тому требуется. И только этот факт мне приносит удовольствие. :)

Что касается макета… кому интересно, тот соберёт в железе или в протеусе… а кому не интересно, то о чём тогда разговор… :dont_know:

Ну а для АВ_шников то вот исходник крайней версии прошивки. Только тапками не закидывайте... :)))
Вложение:
Butt_OUT.zip

Автор:  Demiurg [ Ср апр 21, 2021 09:35:01 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

NStorm, выше уже писал. Когда то и я учился на подобных обсуждениях. И также же как ТС, задам вопрос, мэтры подтягиваются и началось. Так тема живёт своей жизнью. На данный момент ничего плохого не происходит. Скажете, создадим новую тему. Есть но, новый топик будет не жизнеспособен. Потому что нужны конкретные примеры. В данной теме он есть. Есть ТЗ от ТС, и уже есть примеры.

Автор:  Starichok51 [ Ср апр 21, 2021 10:50:07 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Самсусамыч писал(а):
Ранее Вы с лёгкостью дизассемблировали мой код, а что случилось в этот раз?
тогда мне было интересно, а в этот раз вообще нет интереса.
и в тот раз я установил АБ, а не занимался дизассемблированием.

Автор:  Самсусамыч [ Ср апр 21, 2021 11:18:37 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Странный Вы человек… раз не интересно, зачем тогда Вам исходник? Вопрос риторический (если что). :)

Автор:  NStorm [ Ср апр 21, 2021 11:31:39 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Чтобы прочитать исходик "компилятор" в общем-то не нужен...

Автор:  Самсусамыч [ Ср апр 21, 2021 11:46:38 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Возможно… я таких тонкостей не знаю.

Автор:  Starichok51 [ Ср апр 21, 2021 19:13:13 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Самсусамыч писал(а):
раз не интересно, зачем тогда Вам исходник?
я говорил за других, кому тут интересно.

Автор:  Sergbern [ Чт апр 22, 2021 02:14:08 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Ivanoff-iv, аплодирую стоя! Даже не спрашиваю , как до этого дошёл. Сколько смотрел роликов и от камрада libral1973 , и в книгах Лебедева и Белова -- близко похожего не было, чтобы хоть как-то оттолкнуться или провести аналогию. Так что , " кирпичик для лего " получен и будет заложен.
P.S. Во истину, сколько людей -- столько и мнений, и каждый прав, и мнение каждого имеет место быть.
ВСЕМ СПАСИБО! Берегите себя и всех близких.

Автор:  Ivanoff-iv [ Чт апр 22, 2021 06:10:30 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Рад, что кому-то мой метод понравился, а, т.к. возможно теперь его применять буду не я один, то должен выложить не только преимущества, но и обнаруженные нюансы метода:
1) используемые в потоках переменные (все, которые должны пережить паузу (а точнее перезапуск) потока) должны быть глобальными или статик.
2) кодевижен не очень хорошо разделяет области видимости переменных - имена переменных в разных потоках не должны быть одинаковыми (это не косяк метода, это косяк кодевижена).
3) внутри цикла for паузу поставить не получилось (пока не знаю почему), но for можно заменить на while, там всё работает.
4) не выйдет поставить задержку внутри функции, вызываемой из потока.
Объявить поток в потоке, или в вызываемой из потока функции теоретически можно, но работать оно будет непредсказуемо. (т.к. чтобы правильно работали задержки в потоке поток должен вызываться регулярно, а поток внутри потока уже не будет вызываться регулярно)
5) семафоров и прочего тут нет, взаимодействие между потоками осуществляется через общие переменные.
в т.ч. и приостановка потока - делается цикл с задержкой, условие цикла меняется извне потока.
6) метод проверен в кодевижене и в алгоритм билдере, в других средах не проверялся... как проверю отпишусь.

Автор:  Demiurg [ Чт апр 22, 2021 15:47:37 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Посмотрел ваши примеры, обсуждение. ТС по ТЗ так и не отписался. Как быть в той ситуации, когда нажаты несколько кнопок. Предлагаю ТС-у все таки расколоться и пояснить как должны работать все кнопки на его устройстве.
А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.

Автор:  Самсусамыч [ Чт апр 22, 2021 17:19:31 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.

А если нажать, то что будет? :)

У меня два варианта на любой вкус… в первом можно нажимать любое количество кнопок в группе и они будут отрабатывать. Во втором варианте можно тоже нажимать любое количество кнопок в группе, но отработает только первая нажатая в группе, остальные в группе будут игнорироваться.

Автор:  Dimon456 [ Чт апр 22, 2021 18:25:37 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Demiurg писал(а):
А пока предлагаю усложнить задачу. Несколько кнопок нажимать нельзя.
А я все нажму, это не соревнование, есть ТЗ, делайте, или не делайте.

Ivanoff-iv, глянул я ваш код, это гораздо проще, чем у Demiurg, собирается вот в такое
Спойлер
Код:
StartPotok(key_trigg);
{
   static unsigned int  key_trigg_EscapeIteration=1;
    static unsigned char key_trigg_StepOfPotok=0;                               
           
      if (key_trigg_EscapeIteration)
       {
        (key_trigg_EscapeIteration)--;             
             if ((key_trigg_EscapeIteration)==0)
            {                             
                  switch (key_trigg_StepOfPotok)
              {
               case 0: (key_trigg_EscapeIteration)=0
                     if(!PINC.2)                  //проверка
                     {
                        //задержка 10 ms (номера могут быть не по порядку, главное, чтоб не повторялись и были от 1 до 255)
                        key_trigg_StepOfPotok=3; key_trigg_EscapeIteration=(10)+1;             
                        goto key_trigg_End;
               case(3): (key_trigg_EscapeIteration)=0
                        if(!PINC.2)              //повторная проверка
                        {
                           PINC.0=1;            // переключение d9 (записью 1 в регистр PIN производится переключение 1->0 0->1 порта)
                           do  {
                                 key_trigg_StepOfPotok=1; key_trigg_EscapeIteration=(0)+1;             
                                 goto key_trigg_End;
               case(1): (key_trigg_EscapeIteration)=0
                              }while (!PINC.2);//ждём отпускания
                        };
                     }
               default:
                              key_trigg_EscapeIteration=(tim)+1;
                              key_trigg_StepOfPotok=0;
                              
                     key_trigg_End:
            };
         };
      };
}

StartPotok(largeoperation);
{
   static unsigned int  largeoperation_EscapeIteration=1;
    static unsigned char largeoperation_StepOfPotok=0;                               
           
      if (largeoperation_EscapeIteration)
       {
        (largeoperation_EscapeIteration)--;             
             if ((largeoperation_EscapeIteration)==0)
            {                             
                  switch (largeoperation_StepOfPotok)
              {
               case 0: (largeoperation_EscapeIteration)=0
                     PORTC.4=1;                    //мигаем желтым светодиодом D13
                     _delay_ms(300);                //вот он - зависон (не знаю, какими вычислениями занять, поэтому просто делай)
                     PORTC.4=0;
                     largeoperation_StepOfPotok=1; largeoperation_EscapeIteration=(300)+1;             
                            goto largeoperation_End;
               case(1): (largeoperation_EscapeIteration)=0
               
               default:
                     largeoperation_EscapeIteration=(tim)+1;
                     largeoperation_StepOfPotok=0;
                     largeoperation_End: asm("nop");
              };
           };
      };
}
а благодаря #asm("sei") в прерывании - разрешены вложенные прерывания, у вас на блокировке входа основано, иначе бы стек адресами возврата бы переполнился.

Автор:  Ivanoff-iv [ Чт апр 22, 2021 18:44:29 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Да, всё так.
раньше для выхода из потока была команда brake; но если пауза стояла в цикле, то брейк выходил из цикла, а не из потока... пришлось добавить метку.

Добавлено after 2 minutes 44 seconds:
Dimon456, а чем ты дефайны развернул? и в какой ИДЕ?

Автор:  Dimon456 [ Чт апр 22, 2021 20:07:42 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Ivanoff-iv писал(а):
а чем ты дефайны развернул?
Ручками в блокноте Notepad++.

Автор:  Sergbern [ Чт апр 22, 2021 22:06:03 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Demiurg, в моём проекте несколько нажатых кнопок не рассматривалось за ненужностью. Генератор ЗЧ, одна группа из 4-ёх кнопок -- выбор диапазона, другая -- делитель, коммутация -- реле Panasonic TX212 , разумеется, с ключами. Группы между собой независимы, одновременное нажатие в разных группах ничего особенного не даст, только штатное включение в каждой группе. А в пределах одной группы -- так сверх-одновременно не получится, с опозданием хоть на микросекунду последняя кнопка и сработает. По сути -- кнопка-защёлка, без антидребезга . 9-ая кнопка -- режим МЕАНДР. Моргунчик для большей наглядности, знать бы , что так архи-сложно -- можно было и не делать

Автор:  Demiurg [ Пт апр 23, 2021 03:11:53 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Уточнение. Генератор ЗЧ отдельно, схема на мк отдельно или все на мк?

Автор:  Ivanoff-iv [ Пт апр 23, 2021 05:58:26 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Sergbern, можно реализовать отработку множественного нажатия кнопок по разному:
1) "по старшинству" - кнопка с большим приоритетом отменяет действие кнопок с меньшим (так у тебя сделано)
2) "первая" - отрабатывается только первая нажатая кнопка,(легко сделать, организовав 2 потока (по потоку на каждую группу кнопок) и по маленькому циклу внутри потока - для каждой кнопки. В зависимости от условия цикла остальные кнопки могут блокироваться либо до отпускания этой кнопки (1 группа) или до отпускания всех кнопок группы (2я группа))
Спойлер
Код:
/////////   1-я   группа кнопок
StartPotok(Group1);
while (!PIND.0) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0; Delay_t(Group1,1,0);};
while (!PIND.1) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0; Delay_t(Group1,2,0);};
while (!PIND.2) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0; Delay_t(Group1,3,0);};
while (!PIND.3) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0; Delay_t(Group1,4,0);};
EndPotok(Group1);
/////////   2-ая   группа кнопок
StartPotok(Group2);
if (!PIND.4) {PORTB.4=1; PORTB.5=0; PORTB.6=0; PORTB.7=0;};
if (!PIND.5) {PORTB.5=1; PORTB.6=0; PORTB.7=0; PORTB.4=0;};
if (!PIND.6) {PORTB.6=1; PORTB.4=0; PORTB.5=0; PORTB.7=0;};
if (!PIND.7) {PORTB.7=1; PORTB.4=0; PORTB.5=0; PORTB.6=0;};
while ((~PIND)&0b11110000){Delay_t(Group2,1,0);};
EndPotok(Group2);
3) "последняя" - тут нужно добавить переменную состояния кнопок на прошлом витке, находить изменения состояния кнопок и по ним зажигать светодиоды.
Спойлер
Код:
char Key=~PIND; //сразу инвертировал чтоб 1 соответствовала нажатой кнопке
static char OldKey=0;
if ((1<<0)&(Key)&(~OldKey)) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0;};
if ((1<<1)&(Key)&(~OldKey)) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0;};
if ((1<<2)&(Key)&(~OldKey)) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0;};
if ((1<<3)&(Key)&(~OldKey)) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0;};
OldKey=Key;//запомнили уже нажатые кнопки

можно нахождение разницы "вынести за скобки"
Код:
char Key=~PIND; //сразу инвертировал чтоб 1 соответствовала нажатой кнопке
static char OldKey=0;
char NewKey=Key&~OldKey;
if ((1<<0)&(NewKey)) {PORTB.0=1; PORTB.1=0; PORTB.2=0; PORTB.3=0;};
if ((1<<1)&(NewKey)) {PORTB.1=1; PORTB.0=0; PORTB.2=0; PORTB.3=0;};
if ((1<<2)&(NewKey)) {PORTB.2=1; PORTB.0=0; PORTB.1=0; PORTB.3=0;};
if ((1<<3)&(NewKey)) {PORTB.3=1; PORTB.0=0; PORTB.1=0; PORTB.2=0;};
OldKey=Key;//запомнили уже нажатые кнопки

присоединяюсь к вопросу о генераторе: нужно ли его в этот мк добавить?

Автор:  Dimon456 [ Пт апр 23, 2021 07:17:01 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Ivanoff-iv писал(а):
присоединяюсь к вопросу о генераторе: нужно ли его в этот мк добавить?
Да, да, с шагом 1Гц и без джиттера.

Автор:  Demiurg [ Пт апр 23, 2021 07:32:16 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

У ТС три группы кнопок. Все независимые. Диапазон. Уровень сигнала. Меандр.
Получается, что у первых двух групп в рамках группы одновременное нажатие кнопок недопустимо. А одновременное нажатие трех групп допустимо. А это меняет всю картину... Я недаром просил ТЗ с самого начала.

Автор:  Ivanoff-iv [ Пт апр 23, 2021 07:34:00 ]
Заголовок сообщения:  Re: Нестабильность из-за задержек

Да, да, с шагом 1Гц и без джиттера.
Генератор... держи :)) :
Спойлер
Код:
include <tiny13a.h>
#define K_speed 30
#define MIN 1
#define MAX 40000
#define Butt  (~PINB&(1<<0))
#define Out() (PINB=(1<<4))            //переключение ножки
       unsigned int  Frq=10;           //текущая частота
eeprom unsigned int  E_Frq;            //запомненная частота
       unsigned int  Tim=1000;         //период
       unsigned char Ost=0xff;         //остаток

void Calc(void)                        //вычисляем период и довесок
{
unsigned long int  tTim=12000000/Frq;  //вычисляем период
unsigned char tOst=tTim;               //последний байт (до256)
tOst>>=1;                              //делим на 2
tOst|=0x80;                            //прибавим 128 (вычисляем довесок)
//у нас 2 довеска - сумма их как-раз и получится 1 полный оборот и остаток (но их пришлось делить на 2 т.к. трудно обработать 2 близко стоящих прерывания)
tTim>>=8;                              //делим период на 256
#asm("cli")
Tim=tTim;                              //выводим в буфера
Ost=tOst;
#asm("sei")
};

// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
static unsigned int  countS=0;         //счетчик периодов таймера для работы
static unsigned char ReductK=0;        //счетчик периодов таймера для опроса кнопки (делитель)
static unsigned char K_tim=0;          //время нажатия кнопки
static unsigned char K_count=0;        //количество нажатий кнопки

PORTB.5=1;                             //машем лапкой, обозначающей работу АЛУ (загрузка ЦП)
if (countS) {countS--;}
else
  {
  countS=Tim;                          //взводим таймер обратно
  Out();                               //работаем работу
  };
  OCR0A=(countS<2)? Ost:0xff;          //выбираем скорость таймера
//if (SPL>0x9C)                        //проверял срыв стека...
  {                                    //обрабатываем нажатие кнопки
  #asm("sei")                          //это для того, чтобы основная работа продолжалась
  ReductK++;                           //переменная сбрасывается по переполнению
  if (ReductK==0)
    {                       
    if (K_tim)
      {
      K_tim++;
      if (K_tim>K_speed)
        { 
        if Butt
          {
          K_tim=K_speed;
          if (K_count==2) Frq=(Frq>MIN)?  Frq-1:MIN;  //кнопка удерживается - убавляем скорость
          if (K_count==4) Frq=(Frq<MAX)?  Frq+1:MAX;  //нажата 1 раз и удерживается - добавляем скорость
          if (K_count>=6) if (E_Frq!=Frq) E_Frq=Frq;  //нажата 3 раза (или более) - обновляем сохраненную скорость
          Calc();                                     //возможно скорость изменилась - пересчитаем периоды
          }
        else{K_tim=0;};                               //если кнопка уже отпущена - сбросим и остановим таймер
        }
      else
        {
        if Butt {if ((K_count&1)==1) K_count++;}     //приращаем счет при каждом нажатии и отпускании кнопки
        else    {if ((K_count&1)==0) K_count++;};
        }; 
      }
    else{if Butt K_tim++; K_count=1;};  //если кнопка нажата впервые - запускаем её таймер и устанавливаем счет
    };
  };
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 2
#pragma optsize-
CLKPR=0x80;
CLKPR=0x01;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
PORTB=0x7F;
DDRB=0x30;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 2400,000 kHz
// Mode: CTC top=OCR0A
TCCR0A=0x02;
TCCR0B=0x01;
TCNT0=0x00;
OCR0A=0xFF;
OCR0B=0x00;

// External Interrupt(s) Off
// sleepmode = sleep
GIMSK=0x00;
MCUCR=0x20;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x04;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

if (E_Frq==0xffff) E_Frq=10;
Frq=E_Frq;
//Frq=10000;
Calc();

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      PORTB.5=0;
      //#asm("sleep")
      }
}


Вложения:
motalka13.zip [95.43 KiB]
Скачиваний: 103

Страница 6 из 8 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/