Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

ядове с вектор на прекъсване
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=16715
Страница 1 от 4

Автор:  lcr [ Пон Авг 12, 2019 5:21 pm ]
Заглавие:  ядове с вектор на прекъсване

Постановката е следната:

pic16f1827, компилатор XC8

RB0 е вход с прекъсване по отрицателен фронт.

Векторът на прекъсване:

Код:
void __interrupt() INTERRUPT_InterruptManager (void)
{
    // interrupt handler
   if(INTCONbits.IOCIE == 1 && INTCONbits.IOCIF == 1)
    {
    TMR1H=0;
    TMR1L=0;
   
   
   
    while(RB0==0)
    {
    T1CONbits.TMR1ON = 1;
   
    }
    T1CONbits.TMR1ON = 0;
    P=((TMR1H << 8) | TMR1L);
   
    if(P>60000)
    {
        P=0;
   
    TMR1H=0;
    TMR1L=0;
    }
   
   
    IOCBFbits.IOCBF0 = 0;
   
    while(RB0)
    {
       
      T1CONbits.TMR1ON = 1;
     
    }
     T1CONbits.TMR1ON = 0;
     T=((TMR1H << 8) | TMR1L);   
     
     if(T>60000)
     {
         T=0;
         TMR1H=0;
         TMR1L=0;
         
     }
     
   
    IOCBFbits.IOCBF0 = 0;
 
   }
}



Променливите P и T се формират коректно и се четат в основния цикъл.

Искам, когато спре импулсната поредица, да се вдигне LATB4.

За целта в основния цикъл съм написал:

Код:
  if(RB0)
           
        {
            i++;
        }
       
       
        else
           
        {
            i=0;
        }
       
       
        if(i>200)
       
        {
           
           
             LATB4=1;
             i=0;
        }
       


проблемът е, че понякога става а понякога - не. Не мога да разбера, защо.

Автор:  slav4o.com [ Пон Авг 12, 2019 5:33 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Ами LATBbits.LATB4
LATB4 е member of LATBbits
Код:

void _interrput() ISR (void)
{
   if(IOCBFbits.IOCBF0){
     PravishKakvotoPravish();
     IOCBFbits.IOCBF0;
   }

}

void main (void)
{

   INTCONbits.IOCIE = 1; // enable IOC interrupts
   //INTCONbits.IOCIF = 0; // clear IOC flag
   IOCBP = 0b00000000;  // disable positive edge detect on all pins
   IOCBN = 0b00000001; // enable negative edge detect only on RB0


   while(1)
   {
     // osnoven cikal
   }

}



Автор:  lcr [ Пон Авг 12, 2019 5:45 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Не е от това.

Пропуснах да поясня, че е конфигуриран само RB0, като IOC:

Код:
//interrupt on change for group IOCBF - flag
    IOCBFbits.IOCBF0 = 0;
    //interrupt on change for group IOCBN - negative
    IOCBNbits.IOCBN0 = 1;


по някаква причина променливата "i" не увеличава стойността си.

Автор:  slav4o.com [ Пон Авг 12, 2019 5:53 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Ами търсиш прекъсване по отрицателен фронт. Ако idle state ти е HIGH (RB) значи в предния фронт RB0 става LOW (!RB)
Пък ти правиш проверка дали е високо if(RB) , трябва да е if(!RB)
Обаче аз не разбирам защо е тази проверка. По скоро трябва когато имаш прекъсване от пина влизаш в ISR()
Там обработваш прекъсването и триеш флага.

Код:
if(INTCONbits.IOCIE == 1 && INTCONbits.IOCIF == 1)

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

Чрез IOCBNbits.IOCBN0 = 0; спираш едновременно генерирането на прекъсвания и на флагове от RB0.
Тоест ако влезеш в прекъсване от друго нещо, няма да има йок флагове ако си го спрял.
Достатъчно е да проверяваш в прекъсването дали идва от RB0
Код:
if(IOCBFbits.IOCBF0)
Това при положение, че изобщо имаш други прекъсвания

Автор:  lcr [ Пон Авг 12, 2019 6:28 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

С обработването след прекъсването нямам проблем. Имам проблем, когато фиксирам RB0 високо, т.е няма повече отрицателни фронтове - демек ISR повече не се изпълнява и следва "i" да расте в основния цикъл. Веднъж расте а друг път - не.

Автор:  slav4o.com [ Пон Авг 12, 2019 6:36 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Не можах да ти разбера точно идеята.
Как разбираш че i не се инкрементира. Като стане 201 се нулира и пак почва. Ако разбираш за инкрементирането по LATA4 , то мисля проблема е че не си го написал LATAbits.LATA4;
Друга възможна причина е i да е unsigned char - 0-255; и ако някъде другаде го инкрементираш да го превърташ и да не става над 200.

Автор:  lcr [ Пон Авг 12, 2019 8:44 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Ясно е че трябва да се нулира при 201, но няма инструкция, която да върне LATB4 в нула. Дефинирана е като unsigned int. Това с превъртането ми дойде на ум, дори пробвах да я направя long, но все тая.

Идеята ми е, като спрат импулсите да се вдигне нещо, примерно LATB4. В ISR нищо не мога да правя по въпроса, по понятни причини. Първото за което се сетих е това за достатъчно дълго държане на RB0 високо и така достигната стойност на "i".

Както и да е. За днес приключих, утре продължавам. :)

Благодаря ти за насоките!

Автор:  Stoimen [ Пон Авг 12, 2019 8:56 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Как се излиза от прекъсването след последния отрицателен импулс ?

Автор:  lcr [ Пон Авг 12, 2019 8:58 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Като се нулира флага IOCBFbits.IOCBF0 в края на ISR.

Автор:  Stoimen [ Пон Авг 12, 2019 9:02 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Нулирането на флага ще препятства следващо фалшиво влизане, но как се прескача това
Код:
while(RB0)
    {
       
      T1CONbits.TMR1ON = 1;
     
    }

Автор:  Stoimen [ Пон Авг 12, 2019 9:06 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Сетни едно краче като изход и го вдигай при влизане в прекъсването и съответно смъквай преди да излезеш. Така ще можеш да видиш какво става.

Автор:  lcr [ Пон Авг 12, 2019 9:14 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Ами ISR не е завършила. След като RB0 се е вдигнал, броячът отново се пуска и брои докато RB0 e високо.
Чак след това идва краят на ISR, флагът на прекъсването се нулира и се връщаме в main.

Идеята е да се измери продължителността на ниската част от периода (P) и високата (T).

Автор:  lcr [ Пон Авг 12, 2019 9:16 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Stoimen написа:
Сетни едно краче като изход и го вдигай при влизане в прекъсването и съответно смъквай преди да излезеш. Така ще можеш да видиш какво става.


Това го правих и прекъсването работи коректно. Нещата се мажат след връщането в основния цикъл.

Автор:  Stoimen [ Пон Авг 12, 2019 9:22 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Въпросът ми беше какво става след последния отрицателен импулс.
Идва си отрицателния фронт -> влизаме в прекъсването -> чакаме в while да "свърши" ниската част -> чакаме в while да "свърши" високата част -> излизаме от прекъсването.
Какво става ако "ниската" или "високата" част не свършват :)

Автор:  slav4o.com [ Пон Авг 12, 2019 9:23 pm ]
Заглавие:  Re: ядове с вектор на прекъсване

Напиши
Код:
if(i > 200){
  i = 0;
  LATAbits.LATA4 = !LATAbits.LATA4;
}

Не подавай никакви импулси на RB0 и виж с осцилоскоп дали има импулси на RA4

Страница 1 от 4 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/