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?.
解決済! 解決策の投稿を見る。
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
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
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.