Delay in ms function

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
1,506件の閲覧回数
Skaptor
Contributor I

Hello,

 

I´m developing a delay function that works in milliseconds.

 

this is my code so far:

 

void delayms(unsigned int time)
{
  result1 = max_value / 1000;
 
  final_result = result1 * time;
 
  d_enabled = FALSE;
 
  if(!d_enabled)
  {   
    dmsec     = 0;
    TPM2MOD   = final_result;
    TPM2SC    = 0x0F;
    TPM2C0SC  = 0x54;                
    TPM2C1SC  = 0x10;
    d_enabled = TRUE;
  }
 
  while(!delay_done);
}

 

Here´s the TPM_ISR

 

interrupt VectorNumber_Vtpm2ch0 void timer2_CH0(void)
{

  // Clear CH0F flag
  TPM2C0SC &=0x7F;
 
    dmsec++;
   
    if(dmsec == final_result)
    {
      TPM2MOD  = 0;
      TPM2SC   = 0x00;
      TPM2C0SC = 0x00;                
      TPM2C1SC = 0x00;
      delay_done  = TRUE;
    }
 
              
  //Clear the 16-bit timer1 counter
  //TPM1CNTH = 0x00;
 
}

 

My timer counts at 1 second with a MOD equal to 0xFF ot 65535 so basically assigns the MOD value to a fixed one depending on the function call.

 

My problem is, with that while it seems the timer ISR is not working, so I´m looking for a way to loop inside the function until the timer returns a flag?.

ラベル(1)
0 件の賞賛
返信
1 解決策
1,060件の閲覧回数
bigmac
Specialist III

Hello,

 

I cannot understand your reasoning for changing the modulo value from free-running mode, or for the use of a TPM prescale setting of 128.  Both would seem quite unnecessary.  Additionally, you seem to have a channel setting to toggle on output compare.  You actually require software compare mode for this application.

 

Basically you require that a channel interrupt occurs every millisecond, by using software output compare mode for the TPM channel.  When each interrupt occurs, I prefer to decrement the 'dmsec' counter, so that when timeout is reached the counter value will be zero, and further counting is inhibited.  No other timeout flags would be necessary.

 

#define INCRVAL  4000           // Value for 1ms increment    // assuming 4MHz bus, prescale 1// Global variable:volatile word dmsec;/*************************************************************************/// Initialisation for TPM2 modulevoid TPM2_init( void){   TPM2MOD  = 0;                // Free-running mode   TPM2SC   = 0x08;             // Bus clock source, prescale 1   TPM2C0SC = 0x00;  // Channel 0 initially disabled}/*************************************************************************/// Set delay timeout period (multiples of 1ms)void setdelay_ms( word time){   __asm sei;                   // Disable interrupts   TPM2C0V = TPM2CNT + INCRVAL; // First compare value   dmsec = time;   TPM2C0SC = 0x50;             // Software compare mode, interrupt enabled   TPM2C0SC_CH0F = 0;           // Ensure flag is clear   __asm cli;                   // Enable interrupts}/*************************************************************************/// Wait for delay timeout periodvoid waitdelay_ms( word time){   setdelay_ms( time);   while (dmsec)           // Wait for timeout      __RESET_WATCHDOG();}/*************************************************************************/// ISR for TPM2 channel 0interrupt void ISR_TPM2C0( void){   TPM2C0SC_CH0F = 0;           // Clear flag      TPM2C0V += INCRVAL;          // Next compare value   if (dmsec) {      dmsec--;      if (dmsec == 0)         TPM2C0SC = 0x00;       // Disable further TPM2C0 interrupts   }}

    

Regards,

Mac

 

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
1,061件の閲覧回数
bigmac
Specialist III

Hello,

 

I cannot understand your reasoning for changing the modulo value from free-running mode, or for the use of a TPM prescale setting of 128.  Both would seem quite unnecessary.  Additionally, you seem to have a channel setting to toggle on output compare.  You actually require software compare mode for this application.

 

Basically you require that a channel interrupt occurs every millisecond, by using software output compare mode for the TPM channel.  When each interrupt occurs, I prefer to decrement the 'dmsec' counter, so that when timeout is reached the counter value will be zero, and further counting is inhibited.  No other timeout flags would be necessary.

 

#define INCRVAL  4000           // Value for 1ms increment    // assuming 4MHz bus, prescale 1// Global variable:volatile word dmsec;/*************************************************************************/// Initialisation for TPM2 modulevoid TPM2_init( void){   TPM2MOD  = 0;                // Free-running mode   TPM2SC   = 0x08;             // Bus clock source, prescale 1   TPM2C0SC = 0x00;  // Channel 0 initially disabled}/*************************************************************************/// Set delay timeout period (multiples of 1ms)void setdelay_ms( word time){   __asm sei;                   // Disable interrupts   TPM2C0V = TPM2CNT + INCRVAL; // First compare value   dmsec = time;   TPM2C0SC = 0x50;             // Software compare mode, interrupt enabled   TPM2C0SC_CH0F = 0;           // Ensure flag is clear   __asm cli;                   // Enable interrupts}/*************************************************************************/// Wait for delay timeout periodvoid waitdelay_ms( word time){   setdelay_ms( time);   while (dmsec)           // Wait for timeout      __RESET_WATCHDOG();}/*************************************************************************/// ISR for TPM2 channel 0interrupt void ISR_TPM2C0( void){   TPM2C0SC_CH0F = 0;           // Clear flag      TPM2C0V += INCRVAL;          // Next compare value   if (dmsec) {      dmsec--;      if (dmsec == 0)         TPM2C0SC = 0x00;       // Disable further TPM2C0 interrupts   }}

    

Regards,

Mac

 

0 件の賞賛
返信
1,060件の閲覧回数
Skaptor
Contributor I

Thank you very much, the only thing I had to do was, the incrval was 4000 so it was giving me a 336ms pulse, so I just multiplied, divided and changed the INCRVAL to a fixed value. Now it gives me the correct amount of ms.

 

Regards.

0 件の賞賛
返信