Отговори на тема  [ 41 мнения ]  Отиди на страница 1, 2, 3  Следваща
Проблем с таймер 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Проблем с таймер
Здравейте, ползвам микроконтролер 8051f021 и имам следния проблем. Използвам 2 таймера, за да генерирам честата и импулс. Таймерът на импулса е през 1мс и е с приоритет. Проблемът е че на изхода не получавам увеличаване през 1мс както е зададено, а получавам сигнал с разлика от 200-800us от искания. Например аз искам 8мс, а на изхода имам 7,8us. А към края на при искани 30мс получавам 29мс.

void timer1_ISR(void) interrupt 3 //Timer to generate output signal
{
TH1 = 0xFA; //1ms
TL1 = 0xCB;

FRQ1 = FRQ1 - 1;
if(FRQ1 == 0)
{
Valve_on = 1; // valve OFF
FRQ1=FRQ;
CNTIMP1=CNTIMP;
CNTIMP1++;
LED = 0;
}

CNTIMP1 = CNTIMP1 - 1;
if(CNTIMP1 == 0)
{

CNTIMP1=CNTIMP;

Valve_on = 0; // valve ON
LED = 1;
}

}


Вто Сеп 08, 2015 3:18 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 12, 2004 3:38 pm
Мнения: 9103
Местоположение: Chicago, IL
Мнение Re: Проблем с таймер
Много добре си ги получаваш - дължи се на софтуерния ти PWM. Можеш малко да го оптимизираш, но никога няма да е точно колкото искаш. Ако искаш точна честота ползвай хардуерен PWM.


Вто Сеп 08, 2015 3:42 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Re: Проблем с таймер
Нямам възможност да го ползвам. Има ли друг начин?


Вто Сеп 08, 2015 4:20 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
Тези 200-300 микросекунди ...
-или има друго прекъсване с по-голям приоритет, което твърде често съвпада с прекъсването по таймера
-или някъде забраняваш прекъсванията и нещо чакаш.
На каква честота работи процесора?


Вто Сеп 08, 2015 4:52 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
Всъщност, покажи цялата програма.


Вто Сеп 08, 2015 4:58 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Re: Проблем с таймер
Имам два таймера, този таймер е на 1мс и е с най- висок приоритет. Другият таймер е на 5мс - той ми следи за бутони и други функции. Процесорът е на 16MHz/12


Вто Сеп 08, 2015 4:58 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Re: Проблем с таймер
Код:
#include "c8051F020.h"
#include <intrins.h>
//#include "delay.h"

unsigned char bdata BUT1FL = 0x100;
sbit BUT1FL_0 = BUT1FL^0;
sbit BUT1FL_1 = BUT1FL^1;
sbit BUT1FL_2 = BUT1FL^2;
sbit BUT1FL_3 = BUT1FL^3;
sbit BUT1FL_4 = BUT1FL^4;
sbit BUT1FL_5 = BUT1FL^5;
sbit BUT1FL_6 = BUT1FL^6;
sbit BUT1FL_7 = BUT1FL^7;

unsigned char bdata BUT2FL = 0x101;
sbit BUT2FL_0 = BUT2FL^0;
sbit BUT2FL_1 = BUT2FL^1;
sbit BUT2FL_2 = BUT2FL^2;
sbit BUT2FL_3 = BUT2FL^3;
sbit BUT2FL_4 = BUT2FL^4;
sbit BUT2FL_5 = BUT2FL^5;
sbit BUT2FL_6 = BUT2FL^6;
sbit BUT2FL_7 = BUT2FL^7;

unsigned char bdata FFP = 0x102;
sbit FFP_0 = FFP^0;
sbit FFP_1 = FFP^1;
sbit FFP_2 = FFP^2;
sbit FFP_3 = FFP^3;
sbit FFP_4 = FFP^4;
sbit FFP_5 = FFP^5;
sbit FFP_6 = FFP^6;
sbit FFP_7 = FFP^7;


unsigned char bdata FSS = 0x103;
sbit FSS_0 = FSS^0;
sbit FSS_1 = FSS^1;
sbit FSS_2 = FSS^2;
sbit FSS_3 = FSS^3;
sbit FSS_4 = FSS^4;
sbit FSS_5 = FSS^5;
sbit FSS_6 = FSS^6;
sbit FSS_7 = FSS^7;
unsigned char bdata  CNTFSSB4 = 0x104;
unsigned char bdata  CNTB2 = 0x105;
unsigned char bdata  CNTB1 = 0x106;
unsigned char bdata  CNTFFPB3 = 0x107;
void but_plus(); // Button up
void butplus ();
void but_minus(); // Button down
void butminus ();
void but_FP();      // Button frquency/pulse selector
void but_Start_Stop();
void Start_Stop();
void Master_button();

sbit FP =  P1^5; // Frequency/Pulse width selector
sbit Start =  P1^6; // Start/stop button for signal
sbit Plus =  P2^3; // Plus
sbit Minus =  P2^4; // Minus
sbit Valve_on = P0^5;//output for valve

sbit LED = P1^7; // Pulse indicator


unsigned char c;
unsigned int   CNTIMP;
unsigned int   CNTIMP1;
unsigned int   CNTFRQ;

unsigned int FRQ1;
unsigned int FRQ;

#define  LCD_DATA P3
sbit LCD_RS   =   P0^2;
sbit LCD_EN   =   P0^4;

unsigned char  data_ind[3];
char init_value;
#define lcd_delay 400

void delay(unsigned int j)
{
                unsigned int i=0;
                for(i=0;i<j;i++);
}
/*=======================================

            LCD INITIALIZAIOTN

=======================================*/


void LCD_STROBE (void);

void lcd_write(unsigned char c)
{
delay(lcd_delay);
   LCD_DATA = ( ( c >> 4 ) & 0x0F );
   LCD_STROBE();
   LCD_DATA = ( c & 0x0F );
   LCD_STROBE();
}

/*
*    Clear and home the LCD
*/

void lcd_clear(void)
{
   LCD_RS = 0;
   lcd_write(0x1);
delay(lcd_delay);
}

/* write a string of chars to the LCD */

void lcd_puts(const char * s)
{
   LCD_RS = 1;   // write characters
   while(*s)
      lcd_write(*s++);
}

/* write one character to the LCD */
/*
void lcd_putch(char c)
{
   LCD_RS = 1;   // write characters
   lcd_write( c );
}
*/

/*
* Go to the specified position
*/

void lcd_goto(unsigned char pos)
{
   LCD_RS = 0;
   lcd_write(0x80+pos);
}
   
/* initialise the LCD - put into 4 bit mode */

void lcd_init()
{
   

   init_value = 0x3;

   LCD_RS = 0;
   LCD_EN = 0;
   

delay(lcd_delay);

//Delay after starting the LCD
   LCD_DATA    = 0x30;
   LCD_STROBE();

delay(lcd_delay);

   LCD_DATA    = 0x30;//3
   LCD_STROBE();
delay(lcd_delay);
   
   LCD_DATA    = 0x30;//3
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA    = 0x20;//3
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA    = 0x02;//2
   LCD_STROBE();
delay(lcd_delay);
   
   LCD_DATA    = 0x08;//2
   LCD_STROBE();
   LCD_DATA    = 0x08;//8
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA    = 0x00;//0
   LCD_STROBE();
   LCD_DATA    = 0x08;//8
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA    = 0x00;//0
   LCD_STROBE();
   LCD_DATA    = 0x0f;//0x0f
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA   =0x00;
   LCD_STROBE();
   LCD_DATA   =0x06;
   LCD_STROBE();
delay(lcd_delay);

   LCD_DATA   =0x00;
   LCD_STROBE();
   LCD_DATA   =0x0c;//0c
   LCD_STROBE();
delay(lcd_delay);



   
LCD_RS = 1;
}


void LCD_STROBE(void)
{
   LCD_EN = 1;
delay(lcd_delay);
   LCD_EN= 0;
}


/*=======================================

         END LCD INITIALIZAIOTN

========================================*/
void itoa(int number)
{
data_ind[2] = '\0';
data_ind[1] = (number%10);
data_ind[0] = ((number%100) - data_ind[1])/10;

data_ind[1] = data_ind[1] + '0';
data_ind[0] = data_ind[0] + '0';

}

void LCD_show()
{
   itoa(CNTFRQ); // Write in array value of FRQ or IMP and displey it to the LCD
   lcd_goto(0x00);
   lcd_puts("FRQ");

   lcd_goto(0x05);
   lcd_puts(data_ind);

   lcd_goto(0x09);
   lcd_puts("Hz");

   itoa(CNTIMP);
   lcd_goto(0x40);
   lcd_puts("PWM");

   lcd_goto(0x45);
   lcd_puts(data_ind);
   
   lcd_goto(0x49);
   lcd_puts("ms");
}


void Start_Stop(void)
{
   if (Start==0)
      {
      TR1=1; //Enable
         }
         else
            {
         
               TR1=0; // Disable
                        
            }

}

void FP_Selector(void)
{

   if (FP==0)
      {
   
                  // Start only Timer0
         lcd_goto(0x4d);
         lcd_puts(" ");
         lcd_goto(0x4e);
         lcd_puts(" ");
         lcd_goto(0x0d);
         lcd_puts("<<");


      }
      
         else
         {
         lcd_goto(0x0d);
         lcd_puts(" ");
         lcd_goto(0x0e);
         lcd_puts(" ");
         lcd_goto(0x4d);
         lcd_puts("<<");

            }

}




void Timer_Init()
{
    TMOD      = 0x11; // Timer0/Timer1 16 bit 11
   IP        = 0x08; // Timer 1 priority high
   OSCICN    = 0x07;
    WDTCN     = 0xDE;
    WDTCN     = 0xAD;
   IE        = 0x8A; // timer0/1 interrupt

}

void Port_init()
{

   P0MDOUT   = 0x3C;
    P1MDOUT   = 0x06;
    P2MDOUT   = 0x18;
    P3MDOUT   = 0x0F;
    XBR2      = 0x40;

}


void main(void)
{
   TR0=0;
//   TR1=0;
//TL1  = 0x65;   //Lower Byte
//TH1  = 0xFD;   //Upper Byte
//   TH1 = 0xFA;       //1ms
//   TL1 = 0xCB;
//   TH0 = 0xE5;//5ms
//   TL0 = 0xF5;
   Port_init();
   Timer_Init();
   lcd_init();
   TR0=1;
   Valve_on = 1;
   CNTFRQ = 1; // Starting value to frequency
   CNTIMP   =1; //Starting value tO  impuls

   while(1);

}


void timer1_ISR(void) interrupt 3 //Timer to generate output signal
{

   TH1 = 0xFA;       //1ms
   TL1 = 0xCB;


   FRQ1 = FRQ1 - 1;
   if(FRQ1 == 0)
   {
         Valve_on = 1; // valve OFF
       FRQ1=FRQ;
       CNTIMP1=CNTIMP;
       CNTIMP1++;
   
   }
      
   CNTIMP1 = CNTIMP1 - 1;
   if(CNTIMP1 == 0)
   {
   
       CNTIMP1=CNTIMP;
       
       Valve_on = 0; // valve ON

   }
   
}
void timer0_ISR (void) interrupt 1
{
TH0 = 0xE5;//5ms
TL0 = 0xF5;

      
   Master_button();
   LCD_show();//
  //Start_Stop();//
   FP_Selector();//
   but_plus();//
   but_minus();//
   but_Start_Stop();//


}
void Master_button()
{

   if(Plus==0)
      {
      BUT1FL_7=1;
      }
      else
      {   
      BUT1FL=0;
      }
     
      if(Minus==0)
      {
      BUT2FL_7=1;
      }
      else
      {   
      BUT2FL=0;
      }

   if(Start==0)
      {
      FSS_7=1;
      }
      else
      {   
      FSS=0;
      }



}


void broiach_FRQ()
{
   FRQ =  1000/CNTFRQ;// counter for frequency depending on timer1
   FRQ1 = FRQ; // working


}

void butplus () // count up
{   

   if (FP==0)
   {   
   if(CNTFRQ==30)
   {;}
      else
      {
         CNTFRQ = CNTFRQ+1;
          broiach_FRQ();


      }
      }
               else //PWM
            {
                  if(CNTIMP==30)
                  {;}
                  else
                  {
                  CNTIMP = CNTIMP+1;
                  
                  }      
            }
}         


void butminus () // count down
{
    
     if (FP==0)
   {
      if(CNTFRQ==1)
      {;}
      else
      {
         CNTFRQ = CNTFRQ-1;
         broiach_FRQ();

      }
      }
               else //PWM
            {      
                     if(CNTIMP==1)
                  {;}
                  else
                  {
                     CNTIMP = CNTIMP-1;

                  }
                  
                  

            }

}     

/*====================================

            BUTTON FLAG
            
======================================*/

void but_Start_Stop () // BUTTON FREQ OR PWM
{
if(FSS_7==1)
{
    if(FSS_5==0)      //if result is 1 - the button is ready
    {
       if(FSS_0==0)   //starting 30ms delay
       {
        FSS_0=1;
        CNTFSSB4=2;
       }
      else
      {
         if (FSS_2==1)
         {
            FSS_5=1;   
      //   Start = ~Start;
            Start_Stop();
         }
            else
            {
            CNTFSSB4--; 
               if(CNTFSSB4==0)
               {
               FSS_2=1;
               }
             }
            }
      }
      }
    else
    {
       Start_Stop();
    }
}

void but_plus ()
{
if(BUT1FL_7==1)
{
    if(BUT1FL_5==0)      //if result is 1 - the button is ready
    {
       if(BUT1FL_0==0)   //starting 30ms delay
       {
        BUT1FL_0=1;
        CNTB1=1;
      }
      else
      {
         if (BUT1FL_2==1)
         {
            BUT1FL_5=1;   
            butplus();
         }
            else
            {
            CNTB1--; 
               if(CNTB1==0)
               {
               BUT1FL_2=1;
               }
}}}}}

void but_minus ()
{
if(BUT2FL_7==1)
{
    if(BUT2FL_5==0)      //if result is 1 - the button is ready
    {
       if(BUT2FL_0==0)   //starting 30ms delay
       {
        BUT2FL_0=1;
        CNTB2=1;
       }

       else
      {
            if (BUT2FL_2==1)
         {
            BUT2FL_5=1;   
            butminus();
         }
            else
            {
            CNTB2--; 
               if(CNTB2==0)
               {
               BUT2FL_2=1;
               }
}}}}}


Вто Сеп 08, 2015 4:59 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
В ISR таймер 0 имаш твърде много неща.
Виж си таймер 1 ISR, няма никакви извиквания на други функции.
Където и да ти е проблемът - първо и задължително - първо се опразва таймер 0 ISR.
Не може главната програма нищо да не прави
while(1);

Кой знае как ти се омазват регистри и памет.

Т0 се презарежда от ISR, там се вдига някакъв флаг "Ехо, минаха 5 милискунди" и излиза, нищо друго.
Главната програма следи този флаг.
Като го види вдигнат - нулира флага и изпълнява всичко това което си вкарал в Т0.

Отделно обработката ти на бутоните е лоша. Потърси из темите "debounce", оттам може да ти набъбне Т0 ISR, но малко.

Според даташийта:
Цитат:
Therefore, the fastest possible response time is 5 system clock cycles:
1 clock cycle to detect the interrupt and 4 clock cycles to complete the LCALL to the ISR. If an interrupt is pending
when a RETI is executed, a single instruction is executed before an LCALL is made to service the pending interrupt.
Therefore, the maximum response time for an interrupt (when no other interrupt is currently being serviced or the
new interrupt is of greater priority) occurs when the CPU is performing an RETI instruction followed by a DIV as the
next instruction. In this case, the response time is 18 system clock cycles:


Това означава, че смяната на порт в T1ISR ще сработва с "житер" между 5 и 18 такта,
което на 16МХц не би трябвало да е важно.
Периодът на импулсите обаче може да се регулира доста добре , трябва малко да се
пипне презареждането на Т1 в прекъсването. Но това е твърде далечно .


Вто Сеп 08, 2015 5:38 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: Проблем с таймер
Освен всичко написано от колегите, какво означава че мне можеш да изпозлваш хардуерния PWM, точно тоя не го знам колко има, но повето от тия имат поне 4 PWM-а, не може и 4-те да са ти заети.
Също така не знам с какво компилираш, но в кейла имаше пак някаква особенност при обслужване на прекъсванията, трябва да погледна но имам спомен че за някои проекти съм изпозлвал мой код за обслужване на прекъсването. Но като цяло с тоя процесор не би следвлао да имаш никакви грижи дори и за софтуерно реализиран PWM.


Вто Сеп 08, 2015 6:03 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 12, 2004 3:38 pm
Мнения: 9103
Местоположение: Chicago, IL
Мнение Re: Проблем с таймер
bobi13 написа:
Нямам възможност да го ползвам. Има ли друг начин?

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


Вто Сеп 08, 2015 6:16 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Re: Проблем с таймер
Тъй като ползвам само вътрешния осцилатор, немога да го накарам да работи на толкова ниска честота
променям честотата от 1-30Хц
импулса - 1мс-30мс


Вто Сеп 08, 2015 6:23 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
Bobi13,
Обработката ти на бутоните е твърде разхвърляна и сложна, трудно е да се ориентирам.
Но предполагам ,че имаш проблеми и с бутоните.
Бих те посъветвал да оставиш Т1 за момента ,
направи си бутоните и дисплея, Т0 - минималистично.
Т1 както си го замислил- може би е добре, може и да не е - не съм наясно какво точно правиш. Остави го за края, наистина не е нещо особено - проблемите ти не идват оттам.


Вто Сеп 08, 2015 6:24 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Авг 07, 2013 1:11 am
Мнения: 41
Мнение Re: Проблем с таймер
Целта на Т0 е да следя бутоните през 5мс и ако има натиснат да направи проверка чрез флагове, дали наистина е натиснат и ако е да го обработи след 15мс (това е за бутони плюс и минус). Другия бутон е за старт/стоп на сигнала който изпращам към изхода.
Функцията мастер бутон, следи дали са вдигнати флаговете за натиснат бутон


Вто Сеп 08, 2015 6:31 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
Да, но съм си сипал ракийка, и това усложнява още нещата.
И да не бях с ракийка, пак не бих се зачел - някои неща не си струват времето, без да се обиждаш.
Ако LCDto се управлява коректно, изнеси му функциите - да не си гумбим времето с тях и
почвай другите неща. Пишеш - постваш. Все някой ще коментира. След 2 дена можеш да пробваш.


Вто Сеп 08, 2015 6:41 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 07, 2012 11:22 pm
Мнения: 3084
Мнение Re: Проблем с таймер
На всяка функция напиши коментар на български - какво трябва да прави.


Вто Сеп 08, 2015 6:42 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 41 мнения ]  Отиди на страница 1, 2, 3  Следваща

Кой е на линия

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


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

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