Отговори на тема  [ 72 мнения ]  Отиди на страница Предишна  1, 2, 3, 4, 5  Следваща
Zilog - Z8 Encore! F083A Series - Timer & Button 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30684
Местоположение: София
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Злото изглежда добро само сравнено с по-голямо зло :D Нищо против while като цяло, но много често се използва по най-ужасния начин. И бялата акула е много красиво животно, само да не се срещате очи в очи.


Чет Юли 12, 2018 9:27 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Славчооо, Славчооо.... добре, че не пишеш Смарт контракти на Solidity, че докато чакаш потребителя да натисне бутоня....
(там се плаща на инструкция, за тези които не са запознати)

Ще въвеждам значи правило и за while:

В ембедед се използват:

Цитат:
:idea: Стейт машини :idea:
а не "while"


Да, дори и за бутони.... то всъщност, както каза Тони преди, от там тръгва цялото неработене......

Или иначе казано, в най-простия си вариант един:

Цитат:
switch - case


Пет Юли 13, 2018 1:25 am
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
relsys написа:
Славчооо, Славчооо.... добре, че не пишеш Смарт контракти на Solidity, че докато чакаш потребителя да натисне бутоня....
(там се плаща на инструкция, за тези които не са запознати)

Ще въвеждам значи правило и за while:

В ембедед се използват:

Цитат:
:idea: Стейт машини :idea:
а не "while"


Да, дори и за бутони.... то всъщност, както каза Тони преди, от там тръгва цялото неработене......

Или иначе казано, в най-простия си вариант един:

Цитат:
switch - case

Написъл съм го кода в първата страница на темата както смятам, че е най-добре. :)

_________________
https://github.com/slav4ocom/


Пет Юли 13, 2018 1:45 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Съб Ное 22, 2014 7:23 pm
Мнения: 48
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Здравейте на всички и благодаря за отговорите !

Направих го така в крайна сметка, само Delay_Counter_5s++ оставих в интеръпта, поне така беше казал relsys, че било правилно, после бяха казани още 6368 начина, но няма значение де ( : Както беше споменато, 10 човека - 150 версии.

Осцилоскоп нямам, но имам лог. анализатор и получих следното:

При Delay 500ms- 4.998 - 4.974 - 4.856 - 4.958 - 4.926 - 4.928
При Delay 10ms - 5.078 - 5.11 - 4.932 - 4.987 - 4.922 - 4.945
Без Delay - 4.93 - 5.115 - 5.098 - 5.039 - 4.968 - 4.98

Не съм сигурен, защо се получава така, може би заради осцилатора:

Това е default-ния:

Internal precision RC oscillator

• 119 kHz or 20 MHz
• ± 4% accuracy when trimmed
• No external components required
• Unlock and write Oscillator Control Register (OSCCTL) to enable and select oscillator at either 20 MHz or 119 kHz

Относно кода и прословутото нулиране на брояча след натискане на бутона, чак сега го осъзнах, че така е правилно, защото брояча е постоянно циклещ (continuous) и той си натрупва произволна стойност и т.н. и оттам идваха различните времена. Предполагам, че ако си го направя (one-shot mode) таймера и си го пускам и спирам аз, няма да имам грижи.

Код:

int main(void)
{
   PortConfig();
   InterruptConfig();
   TimerConfig();

   while(1)
   {
      //if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
      {/* Да */
         //Delay(DELAY_CONSTANT_10_MSEC); /* Изчакване 10ms */
         
         if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         {/* Да */
            Delay_Counter_5s = 0; /* Нулираме брояча */
            
            PAOUT |= 1 << 1; /* Включи сетодиода */
         }   
      }
      
      if(25 == Delay_Counter_5s)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
            
         Delay_Counter_5s = 0; /* Нулираме брояча */
      }
   }
}

void interrupt Timer0_ISR(void) _At TIMER0
{   
   Delay_Counter_5s++;
}



Пет Юли 13, 2018 12:46 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Ами да, но освен брояча, трябва да нулираш и таймера, защото и той е натрупал някаква стойност.

_________________
https://github.com/slav4ocom/


Пет Юли 13, 2018 2:12 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Съб Ное 22, 2014 7:23 pm
Мнения: 48
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Предполагам, трябва и при четенето на бутона и при брояча да го нулирам таймера, имам в предвид и в двата if-a:

Код:

while(1)
   {
      if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
      {/* Да */
         Delay(DELAY_CONSTANT_500_MSEC); /* Изчакване 500ms */
         
          if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         {/* Да */
            Delay_Counter_5s = 0; /* Нулираме брояча */
            
            T0H = 0x00; /*Нулираме таймера */
            T0L = 0x00; /*Нулираме таймера */
            
            PAOUT |= 1 << 1; /* Включи сетодиода */
         }   
      }
      
      if(25 == Delay_Counter_5s)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
            
         Delay_Counter_5s = 0; /* Нулираме брояча */
         
         T0H = 0x00; /*Нулираме таймера */
         T0L = 0x00; /*Нулираме таймера */
      }
   }





При 500ms - 5.016 - 5.016 - 5.016 - 5.016 - 5.016

При 10ms - 5.074 - 5.073 - 5.112 - 5.073 - 5.074

Без Delay - 5.093 - 5.127 - 5.09 - 5.179 - 5.111

Явно при 500ms е най-добре, нз защо, а малкото отклонение идва от осцилатора.


Пет Юли 13, 2018 3:04 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Нещата тамън взеха да си идват на мястото и пак кривнаха....

Това с нулирането на таймера не е добра идея. Единствено ще поправи джитера който имаш. Ще работи за конкретния частен случай.
Но какво ще правим ако се появи още един бунон... Ще пуснем още един таймер ли??
А и на всичкото отгоре имаш делей от 10 мс, в който висиш....

Та така:

Сега направи таймера да генерира прекъсване на 1 мс.
Промени променливата на 32 битова, хубаво ще е и да я преименуваш... на time_ms примерно...
Промени съответно и константата от 25 на 5000 и ще продължим нататък.


Пет Юли 13, 2018 4:46 pm
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Ами така, е но пък се хаби процентно много процесорно време, идеята на тези таймери с прекъсвания е да броят без процесор, и като са готови да сигнализират. Всяко едно влизане в прекъсване е известен брой инструкции. То и на 1ms пак ще има някакъв jitter . Въпрос на компромиси.
Код:

boolean chronometer_on = FALSE;

while(1)
   {
    if(!chronometer_on) // ако не си стартирал все още хронометъра:
      if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
      {/* Да */
         //Delay(DELAY_CONSTANT_500_MSEC); /* Изчакване 500ms */ това го изкоментирваш (махаш)
         chronometer_on = TRUE; // сигнал за пуснат хронометър
          //if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         //{/* Да */
            Delay_Counter_5s = 0; /* Нулираме брояча */
           
            T0H = 0x00; /*Нулираме таймера */
            T0L = 0x00; /*Нулираме таймера */
           
            PAOUT |= 1 << 1; /* Включи сетодиода */
         //}   
      }
     
      if(25 == Delay_Counter_5s)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
         chronometer_on = FALSE; // семафор за спрян хронометър
           
         //Delay_Counter_5s = 0; /* Нулираме брояча */ // това
         //T0H = 0x00; /*Нулираме таймера */ // това
         //T0L = 0x00; /*Нулираме таймера */ // и това са излишни
      }
   }


      


със chronometer_on указваш, дали хронометъра е запуснат. Ако си го запуснал един път, второ натискане на бутона нищо не прави. При това отпада нуждата от debounce на бутона. Няма и заключващото delay() което хаби процесорно време.

_________________
https://github.com/slav4ocom/


Пет Юли 13, 2018 5:25 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Съб Ное 22, 2014 7:23 pm
Мнения: 48
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Еее, Славчо, това е умно измислено с тоя boolean, аз разбира се сам нямаше да се сетя никога :D

Само искам да интерпретирам тези 2 кода, дали ги разбирам правилно:

Таймера стартира и почва да си цъка интеръпти и да се увеличава Delay_Counter_5s++. While започва да се изпълнява, прочитаме бутона, нулираме брояча и таймера, тъй като са натрупали някакви стойности и светваме диода. Стават 5 секунди, изключваме диода, нулираме отново брояча и таймера, тъй като таймера си цъка и е вероятно отново да са натрупали някакви стойности.

Код:

while(1)
   {
      if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
      {/* Да */
         Delay(DELAY_CONSTANT_500_MSEC); /* Изчакване 500ms */
         
         if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         {/* Да */
            Delay_Counter_5s = 0; /* Нулираме брояча */
            
            T0H = 0x00; /*Нулираме таймера */
            T0L = 0x00; /*Нулираме таймера */
            
            PAOUT |= 1 << 1; /* Включи сетодиода */
         }   
      }
      
      if(25 == Delay_Counter_5s)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
            
         Delay_Counter_5s = 0; /* Нулираме брояча */
         
         T0H = 0x00; /*Нулираме таймера */
         T0L = 0x00; /*Нулираме таймера */
      }
   }
}

void interrupt Timer0_ISR(void) _At TIMER0
{   
   Delay_Counter_5s++;
}





Тук ми е малко странно как така, стартираме таймера, а после проверяваме в while-a, ако не е стартиран, да четем бутона, след това казваме, че е стартиран с timer_on = TRUE, нулираме отново брояча и таймера, тъй като са натрупали отново произволни стойности, светваме диода. Минават 5 секунди, изключваме диода и спираме таймера. Обяснението ми тук, че не нулираме отново брояча и таймера, е защото тук директно спираме таймера с timer_on = FALSE, докато горе се налага да нулираме стойностите, защото той продължава да цикли. Има ли нещо вярно в това ?!

Код:

int main(void)
{
   PortConfig();
   InterruptConfig();
   TimerConfig(); -------------> Тук стартираме таймера, а пък отдолу проверяваме ако не е стартиран ?!

   while(1)
   {
      if(!timer_on) /* Ако не сме стартирали таймера... */
      {
         if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         {/* Да */
            timer_on = TRUE; /* Сигнал за пуснат таймер */
            
            Delay_Counter_5s = 0; /* Нулираме брояча */
            
            T0H = 0x00; /*Нулираме таймера */
            T0L = 0x00; /*Нулираме таймера */
            
            PAOUT |= 1 << 1; /* Включи светодиода */
         }   
      }
      
      if(25 == Delay_Counter_5s)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
            
         timer_on = FALSE; /* Знак за спрян таймер */
      }
   }
}



Благодаря и се извинявам за хилядите въпроси!


Пет Юли 13, 2018 6:56 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Абе , вие сте се ошашавили.
Delay се ползва само по изключение, като ресетваш нещо си и нямаш друга по-важна работа.
Питащият да се опита ,да изхвърли "delay" от мислите си.

ПС. Имам предвид "delay" не само като закъснение, но и като дума в речника.
На практика - при натискане на бутон няма закъснения, има валидиране на натискане/отпускане. Реакцията на машината е достатъчно бърза- коректно валидиране на натискане и реакция стават преди човекът да прекрати натискането.


Пет Юли 13, 2018 7:00 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Таймера не го спирай, просто спри брояча:
Код:
void interrupt Timer0_ISR(void) _At TIMER0
{   
    if(chronometer_on) // ако хронометъра е пуснат
              Delay_Counter_5s++; // инкрементираме брояча. След като изброи до 25 ще спре да брои.
}





Metyyy написа:
Тук ми е малко странно как така, стартираме таймера, а после проверяваме в while-a, ако не е стартиран, да четем бутона, след това казваме, че е стартиран с timer_on = TRUE, нулираме отново брояча и таймера, тъй като са натрупали отново произволни стойности, светваме диода. Минават 5 секунди, изключваме диода и спираме таймера. Обяснението ми тук, че не нулираме отново брояча и таймера, е защото тук директно спираме таймера с timer_on = FALSE, докато горе се налага да нулираме стойностите, защото той продължава да цикли. Има ли нещо вярно в това ?!

Когато си пуснал хронометъра, бутона вече няма да прави нищо в програмата, докато не изтече времето.

_________________
https://github.com/slav4ocom/


Пет Юли 13, 2018 7:10 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
slav4o.com написа:
Таймера не го спирай, просто спри брояча:
Код:
void interrupt Timer0_ISR(void) _At TIMER0
{   
    if(chronometer_on) // ако хронометъра е пуснат
              Delay_Counter_5s++; // инкрементираме брояча. След като изброи до 25 ще спре да брои.
}





Metyyy написа:
Тук ми е малко странно как така, стартираме таймера, а после проверяваме в while-a, ако не е стартиран, да четем бутона, след това казваме, че е стартиран с timer_on = TRUE, нулираме отново брояча и таймера, тъй като са натрупали отново произволни стойности, светваме диода. Минават 5 секунди, изключваме диода и спираме таймера. Обяснението ми тук, че не нулираме отново брояча и таймера, е защото тук директно спираме таймера с timer_on = FALSE, докато горе се налага да нулираме стойностите, защото той продължава да цикли. Има ли нещо вярно в това ?!

Когато си пуснал хронометъра, бутона вече няма да прави нищо в програмата, докато не изтече времето.


Абе не учи човека на грешни практики!!!

Как ще миксираш работата на бутон, хронометър и променливата за реално време, че и пипане по регистри....
И тая всичката боза само за един бутон и един светодиод... ами ако трябва да е нещо истинско?

Бутон, хронометър и още каквито и да са неща нямат нищо общо по между си.
Всички те трябва да могат да работят независимо едно от друго. А вече логиката на устройството ще определи кога - какво се случва.

А аз се чудя, що 2018 година не ми работят чистачките на колата... и защо понякога не работи нищо освен Back бутона..... е как да работят.... :rolleyes:

@Metyyy:

В предния пост съм ти посочил вярната посока.


Пет Юли 13, 2018 11:43 pm
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
relsys написа:
Абе не учи човека на грешни практики!!!

Добре при положение, че моят и твоят пример работят (между другото този който ти посочваш също съм използвал лично), не е ли по-добре напиши му на човека този начин има тези и тези предимства, има тези и тези недостатъци, онзи има онези и онези. Не съм казал да не пробва твоя вариант, нека пробва всички да види кое как що.

relsys написа:
А аз се чудя, що 2018 година не ми работят чистачките на колата... и защо понякога не работи нищо освен Back бутона..... е как да работят.... :rolleyes:

каква е колата ? :roll:

_________________
https://github.com/slav4ocom/


Съб Юли 14, 2018 12:25 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
Ми да пробва и хероин, да види как е....

Иначе естествено, че и аз съм писал глупости, които сега като ги погледна и ме е срам. Ама не съм учил никой на тях.

Колата е Nissan Pulsar.


Съб Юли 14, 2018 12:45 am
Профил ICQ WWW
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Съб Ное 22, 2014 7:23 pm
Мнения: 48
Мнение Re: Zilog - Z8 Encore! F083A Series - Timer & Button
It's done, relsys!

Код:

#include <ez8.h> /* Този хедър позволява да достъпваме вътрешните регистри като всички останали, чрез имената им. */
#include "stdtypes.h"

static uint32 Time_ms = 0;

#define BUTTON_PRESSED  (0)
#define BUTTON_RELEASED (1)

extern void PortConfig(void);
extern void InterruptConfig(void);
extern void TimerConfig(void);
extern boolean ReadButton(void);

int main(void)
{
   PortConfig();
   InterruptConfig();
   TimerConfig();

   while(1)
   {
      if(BUTTON_PRESSED == ReadButton()) /* Бутонът натиснат ли е ? */
         {/* Да */
            PAOUT |= 1 << 1; /* Включи светодиода */
         }   
      }
      
      if(5000 == Time_ms)
      {
         PAOUT &= ~(1 << 1); /* Изключи светодиода */
      }
   }
}

void interrupt Timer0_ISR(void) _At TIMER0
{
   Time_ms++; /* Увеличавай брояча */
}

void PortConfig(void)
{
   PADD &= ~(1 << 1); /* За да конфигурираме извод PA1 като изход, трябва да нулираме бит 1 на регистър PADD */
   
   PBDD |= 1 << 0; /* Kонфигурираме извод PB0 като вход */
}

void InterruptConfig(void)
{
   IRQCTL |= 1 << 7; /* Прекъсванията се разрешават с глобалния бит IRQE в регистър IRQCTL. Бит IRQE
   се установява в 1 */
   
   IRQ0ENL |= 1 << 5; /* Достатъчно е да установим единия от двата или и двата бита. Младши бит 5 e за
   разрешаване на прекъсване от Таймер0. Всеки източник на прекъсване има локален механизъм за разрешаване. Този
   механизъм също се използва за задаване и на софтуерен приоритет на прекъсванията. Тъй като имаме само един
   източник на прекъсване в програмата, е без значение какво ниво на приоритет ще изберем. */
   
   IRQ0ENH |= 1 << 5; /* Достатъчно е да установим единия от двата или и двата бита. Младши бит 5 e за
   разрешаване на прекъсване от Таймер0. Всеки източник на прекъсване има локален механизъм за разрешаване. Този
   механизъм също се използва за задаване и на софтуерен приоритет на прекъсванията. Тъй като имаме само един
   източник на прекъсване в програмата, е без значение какво ниво на приоритет ще изберем. */
}

void TimerConfig(void)
{
   T0H = 0x00; /* Записваме старшата част на числото -> Регистрите съдържат първоначалната стойност от която брои таймера */
   T0L = 0x00; /* Записваме младшата част на числото -> Регистрите съдържат първоначалната стойност от която брои таймера */
   
   T0RH = 0x4E; /* Записваме старшата част -> Регистрите съдържат макс. 16-бит броячна стойност до която брои таймера и тя е 65535 */
   T0RL = 0x20; /* Записваме младшата част -> Регистрите съдържат макс. 16-бит броячна стойност до която брои таймера и тя е 65535 */
   
   /* Системна честота - 20MHz => За да генерираме сигнал с честота 1000Hz (период 1ms) => 1ms * 20MHz / 1  = 20 000 */
   
   T0CTL0 = 0x00; /* Непрекъснат режим */
   T0CTL1 = 0x81; /* Коефициент на деление 1 и стартиране на таймера */
}

boolean ReadButton(void)
{
   return (PBIN & (1 << 0)) ? BUTTON_RELEASED : BUTTON_PRESSED;
}



А от тук нататък ?


Съб Юли 14, 2018 9:54 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 72 мнения ]  Отиди на страница Предишна  1, 2, 3, 4, 5  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 5 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни