Отговори на тема  [ 140 мнения ]  Отиди на страница Предишна  1 ... 6, 7, 8, 9, 10  Следваща
новобранец 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение 
zle написа:
Мерси Тони. Прекъсване от таймера или порт Б предполагам, а стейт машина какво ще рече :)


Ето ти стейт машина, която обработва бутон:

Код:
switch (STATE)
  {
    case IDLE:
      {
        if(!Input(PIN_A2))
          {
            filter_time = 0;
            STATE = FILTER;
          }
        break;
      }
    case FILTER:
      {
        if (filter_time >= DEBOUNCE_TIME)
          if(!Input(PIN_A2))
            {
              STATE = BUTTON_PRESSED;
            }
          else
            {
              STATE = IDLE;
            }
      }
    case BUTTON_PRESSED:
      {
        //here do something
        STATE = WAIT_RELEASE;
      }
    case WAIT_RELEASE:
      {
        if(Input(PIN_A2))
          STATE = IDLE;
      }
  }


Както виждаш има променлива filter_time, която се инкрементира в прекъсване, което ти дава някакво еталонно време, примерно 1 ms. Целта е програмата да не забие някъде и да чака 10 или 100 ms, а през това време да изпълнява нещо друго. Като ти пък трябва да осигуриш извикаването в главния или по-главен цикъл достатъчно често.


Чет Юли 29, 2010 3:59 pm
Профил ICQ WWW
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Мар 11, 2010 12:24 am
Мнения: 92
Мнение 
мерси много сядам да почета малко, че прекъсванията не са ми много ясни и не само те де :) пък ще видим :)


Чет Юли 29, 2010 4:51 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 2:45 am
Мнения: 263
Мнение 
В switch конструкцията по принцип има и default поле. За прегледност (и не само) е хубаво да се слага и то.


Чет Юли 29, 2010 4:58 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Яну 24, 2006 6:34 pm
Мнения: 1753
Местоположение: Варна
Мнение 
Това е на asm ,работи си . Има бит който "помни" ,че еднократно е натиснат бутона...
;-----------
Tst_Buton: Jb Buton , N_Buton ; Ако не е натиснат бутона-скок
Jb Proti_Buton , End_Buton ; Ako е вдигнат фл. противоповторност-скок
;-
Setb Proti_Buton ; Вдига флаг "противоповторност"

Cpl Bit_Led ;Сменя кой Led да свети
;-----
Jmp End_Buton ; Скок

;--------------------
N_Buton: Clr Proti_But ; Снема противоповторност
End_Buton:

_________________
За пари сичко праим,даже и работим...


Чет Юли 29, 2010 11:40 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение 
Тва може а е на всичко, но не и на асемблер и в този вид не прави нищо, ако използваш някой странен асемблер, или микрочип с въвели някакви макроси може и да стане, но едва ли това написано като асм код в ССS ще направи нещо :)


Пет Юли 30, 2010 9:29 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение 
.... и въобще разумен човек не би трябвало и да си помисля на днешно време на пише на асемблер...


Пет Юли 30, 2010 9:49 am
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
Ами те майкрочип трябва да следват линията "юзера май ше иска да натиска бутон", както правят майкрософт.


Пет Юли 30, 2010 11:17 am
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Мар 11, 2010 12:24 am
Мнения: 92
Мнение 
Ем ще натискам бутони пък евентуално ако се науча да натискам бутони може и нещо смислено да направя.


Пет Юли 30, 2010 11:26 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Юни 01, 2008 9:54 pm
Мнения: 1503
Местоположение: Пловдив
Мнение 
relsys написа:
.... и въобще разумен човек не би трябвало и да си помисля на днешно време на пише на асемблер...

абе недей така, разумият юзър ако го закърши с 1К памет ще пише на асемблер, не ами ще свети! примерно за някой келяв софт проц дето е на нивото на пик12 или дърта 16-ка или нещо такова какво мислиш, че се прави? не е излишно човек да го може това, хич даже :wink: а че повечето процове в днешно време са си половин ПЦ и там освен високо ниво другото е загуба на време, е друга тема.


Пет Юли 30, 2010 3:04 pm
Профил WWW
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Мар 11, 2010 12:24 am
Мнения: 92
Мнение 
Някой може ли да ми разясни малко какво се случва в горния код, които е дал relsys там със switch(STATE) в смисъл ясно ми е как бачка switch обаче в случая немога да разбера как процесора разбира дали е IDLE или FILTER и тн. switch(STATE) проверява, кой case е и изпълнява съответните инструкции след това. Не ми е ясно как да ги дефинирам тея IDLE,BUTTON_PRESSED ...


Пет Юли 30, 2010 3:30 pm
Профил
Ранг: Ориентиран
Ранг: Ориентиран

Регистриран на: Вто Фев 06, 2007 2:45 am
Мнения: 263
Мнение 
Малък едит:
Стейтовете, за които става дума описват фазите, през които преминава натискането и отпускането на бутона. Ето един вариант на това, което ти каза и relsys, само че минаваш без прекъсвания. Идеята е да викаш OneButtonDebounceTask() циклично (виж по-долу на колко време). Ако не е ясно как да направиш циклично извикване, ще питаш пак :) Цикличното извикване ти позволява да ползваш променлива-таймер за дебаунс времето, вместо да окупираш хардуерен таймер само за тази цел.
Както виждаш, стейтовете се сменят сами, в зависимост от това дали имаш натиснат бутон, за колко време е натиснат и т.н. Твоята работа я свършваш в съответния стейт (по избор).

Код:
#define TASK_PERIOD_MS   10   // На колко милисекунди ще извикваш OneButtonDebounceTask().
#define DEBOUNCE_TIME_MS        50   // Дебаунс време, милисекунди. Добре е да е кратно на TASK_PERIOD_MS
#define pBUTTON                          pA2 // тук си дефинираш пина, на който си вързал бутона. "0" -> натиснат

// Декларации на използваните типове
// Стейтовете:
typedef enum {
    IDLE,                 // бутона е отпуснат
    DEBOUNCING,   // бутона е натиснат и тече дебаунс
    DEBOUNCED,    // бутона е натиснат, дебаунс времето е изтекло, състоянието на бутона е потвърдено
    CANCELLED,     // бутона е отпуснат преди да е изтекло дебаунс времето
    RELEASING       // чакаме бутона да се отпусне
} TStates;

// Локални променливи
static TStates     еState = IDLE;

// Декларации на използваните функции
void OneButtonDebounceTask(void);
TStates GetDebounceState(void);

// Дефиниции на използваните функции
void OneButtonDebounceTask(void)
{
    static UInt16      debounceTimer;   // Брои надолу. Като стане 0, значи времето е изтекло

    switch (еState)
    {
    case IDLE:
        {
            if (0 == pBUTTON)
            {
                // Зареждаме таймера
                debounceTimer = (DEBOUNCE_TIME_MS / TASK_PERIOD_MS);
                еState = DEBOUNCING;
            }
            break;
        }

    case DEBOUNCING:
        {
            // Натиснат ли е все още бутона?
            if (0 == pBUTTON)
            {
                // Да. Дебаунс времето изтекло ли е?
                if (0 == debounceTimer)
                {
                    // Да, сменяме стейта
                    еState = DEBOUNCED;
                }
                else
                {
                    // Не, цъкаме таймера
                    debounceTimer--;
                }
            }
            else
            {
                // Бутона е отпуснат по време на дебаунс
                eState = CANCELLED;
            }
           
            break;
        }

    case DEBOUNCED:
        {
            // Тук можеш да свършиш каквото трябва при натискане на бутона
            eState = RELEASING;

            break;
        }

    case CANCELLED:
        {
            // Тук можеш да свършиш нещо в случай, че бутона се отпусне преждевременно.
            // Удобно е, ако искаш да имаш различно поведение при кратко натискане и при
            // задържане за повече време (2-3 секунди).

            eState = RELEASING;

            break;
        }

    case RELEASING:
        {
            // Бутона отпуснат ли е?
            if (0 != pBUTTON)
            {
                // Да, сменяме стейта
                еState = IDLE;
            }
            else
            {
                // Не, оставаме в същия стейт
            }

            break;
        }

    default:
        {
            // Тук можеш да влезеш само при някакво омазване на RAM-a, затова сетваш познат стейт.
            eState = IDLE;
            break;
        }
    }
}

// С тази функция можеш да гледаш стейта от други модули
TStates GetDebounceState(void)
{
    return еState;
}


(В C-то uppercase се ползва само за константи.)


Последна промяна tolstolob на Пет Юли 30, 2010 10:43 pm, променена общо 3 пъти



Пет Юли 30, 2010 4:03 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Мар 11, 2010 12:24 am
Мнения: 92
Мнение 
мерси :)


Пет Юли 30, 2010 4:14 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Яну 24, 2006 6:34 pm
Мнения: 1753
Местоположение: Варна
Мнение 
ToHu написа:
Тва може а е на всичко, но не и на асемблер и в този вид не прави нищо, ако използваш някой странен асемблер, или микрочип с въвели някакви макроси може и да стане, но едва ли това написано като асм код в ССS ще направи нещо :)

Т'ва си е на 8051 , за PIC не ми се рови как става :) . Пък ,че работи писах ве4е. Човека иска кат натисне едно копче да се сменят 2 Led-a. Програмката която съм показал прави това. При всяко натискане на бутона инвертира един бит, от него да си цъка диодите .

_________________
За пари сичко праим,даже и работим...


Пет Юли 30, 2010 9:38 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Чет Мар 11, 2010 12:24 am
Мнения: 92
Мнение 
Нещо с тея cese немога да се оправа(за сега)и пробвах с таймер0 да генерирам тея закъснения от по 16ms ама отново не превкючва при всяко натискане.

void main()
{
int A=0x01;
set_tris_a(0xff);
set_tris_c(0x00);
output_c(0x00);
set_timer0(0);
setup_timer_0(RTCC_DIV_256|RTCC_INTERNAL);
while(true)
{
if(T0IF)
T0IF=0;
if(!input(PIN_A3))
A=!A;

if(input(PIN_A3))
if(T0IF)
{
T0IF=0;
if(A==0)
output_c(0x01);
else
output_C(0x02);
}
}
}


Нед Авг 01, 2010 7:30 pm
Профил
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Чет Мар 19, 2009 8:33 pm
Мнения: 804
Мнение 
И аз като начинаещ не се справям добре , но пробвай това , поне на протеус работи .

Код:
#include <16f690.h>
#include <stdio.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //Data EEPROM Code Protected
#FUSES NOPROTECT //Code protected from reads
#FUSES NOMCLR //Master Clear pin enabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //Reset when brownout detected
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_A5,rcv=PIN_A4,bits=8 )


int1 LedStatus;



// Поява на прекъсване на някой от входовете A0_A5

#INT_RA 
void Switching_PortA() {


disable_interrupts(INT_RA  );
clear_interrupt(INT_RA );
       


  If ( input(PIN_A3)==0)
      { 
         
         
        LedStatus=!LedStatus;
     
      }
   

  enable_interrupts(INT_RA  );

}//  End  ***************************





void main()
{
int1 PreviewLedStatus  ; // последно състояние на диодите

set_tris_c(0x00);
set_tris_a(0xff);

      enable_interrupts(INT_RA );// turn on interrupts
      enable_interrupts(GLOBAL);
     
       ext_int_edge(H_TO_L);

LedStatus=1;
PreviewLedStatus=0;

while(true)
{
   if (PreviewLedStatus != LedStatus)
       
      if( LedStatus==0)
           { output_c(0x01) ;
             PreviewLedStatus = LedStatus;   
           }
         
       else
          { output_c(0x02) ;
           PreviewLedStatus = LedStatus;   
          }
       
           

}


Нед Авг 01, 2010 8:53 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 140 мнения ]  Отиди на страница Предишна  1 ... 6, 7, 8, 9, 10  Следваща

Кой е на линия

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


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

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