PWM_ON: timer0_set_pwm_on_counter(uint16_t pwm_on)

6 posts / 0 new
Last post
alex
Offline
Last seen: 4 years 4 weeks ago
Joined: 2014-08-20 03:39
PWM_ON: timer0_set_pwm_on_counter(uint16_t pwm_on)

timer0 init:
//Enables TIMER0,TIMER2 clock
set_tmr_enable(CLK_PER_REG_TMR_ENABLED);

//Sets TIMER0,TIMER2 clock division factor to 8
set_tmr_div(CLK_PER_REG_TMR_DIV_8);

// initilalize PWM with the desired settings
timer0_init(TIM0_CLK_FAST, PWM_MODE_ONE, TIM0_CLK_NO_DIV);

// set pwm Timer0 On, Timer0 'high' and Timer0 'low' reload values
timer0_set(500, TIMER0_M_VALUE, TIMER0_PERIOD_VALUE-TIMER0_M_VALUE);

Per my test, the PWM_ON value in timer0_pwm_on_counter() has a limiation, i.e.
- when I set PWM_ON value to 50, the tested interrupt cycle is around 0.5ms;
- when I set PWM_ON value to 500, the tested interrupt cycle is kept at around 0.5ms;
- when I set PWM_ON value to 1000, the tested interrupt cycle is still kept at aound 0.5ms;
- when I set PWM_ON value to 2000, the tested interrupt cycle increased to around 1ms;
- when I set PWM_ON value to 4000, the tested interrupt cycle increased to around to 2ms

so, the least timer0 interrupt time cycle could only be set is 0.5ms? we'd like to have a 0.005ms~0.01ms timer0 interrupt time cycle, is there any way to get it ?

alex
Offline
Last seen: 4 years 4 weeks ago
Joined: 2014-08-20 03:39
OK...I can get around 0.065ms

OK...I can get around 0.065ms timer0 interrupt cycle by init set_tmr_div(CLK_PER_REG_TMR_DIV_1); but is there any way for a shorter ?
Thank you.

alex
Offline
Last seen: 4 years 4 weeks ago
Joined: 2014-08-20 03:39
Hi JE,

Hi JE,
Could you kindly help look into my issue? thank you!

Alex.

TR_Dialog
Offline
Last seen: 7 months 3 weeks ago
Staff
Joined: 2014-06-30 23:52
Hi Alex:

Hi Alex:

 

set_tmr_div(CLK_PER_REG_TMR_DIV_8);

The above clock set the timer0 clock at 16 MHz/8 = 2MHz.

source for timer0_set is :

void timer0_set(uint16_t pwm_on, uint16_t pwm_high, uint16_t pwm_low)
{
    SetWord16(TIMER0_ON_REG, pwm_on);   
    SetWord16(TIMER0_RELOAD_M_REG, pwm_high);
    SetWord16(TIMER0_RELOAD_N_REG, pwm_low);
}

TIMER0_ON_REG sets the duration for which  a tone (as defined by TIMER0_RELOAD_M_REG and TIMER0_RELOAD_N_REG) are played before an interrupt occurs.

When (TIMER0_RELOAD_M_REG == TIMER0_RELOAD_N_REG) you get 50 % duty cycle.

Another important thing about interrupt is the following: When ON counter reaches zero, interrupt does not occur right away. If the ON-counter reaches zero it will remain zero until the T0 counter also reaches zero while decrementing the value loaded from the TIMER0_RELOAD_N_REG. Then only the interrupt occurs. T0 counter is alternately loaded with values from TIMER0_RELOAD_M_REG and TIMER0_RELOAD_N_REG.

I donot know what specific values you are loading onto TIMER0_RELOAD_M_REG and TIMER0_RELOAD_N_REG.

I can give you an example: the following will create an interrupt every one ms while playing a 1000 Hz tone

#define CONV(x) (2000000/(2*x))

timer0_set(2000, CONV(1000), CONV(1000));

Thanks,

TR_DIALOG

 

 

 

 

alex
Offline
Last seen: 4 years 4 weeks ago
Joined: 2014-08-20 03:39
Thank you TR, so the

Thank you TR, so the interrupt cycle decided both by ON-counter and/or(alternately) M/N counter. I'll try other tests...

TR_Dialog
Offline
Last seen: 7 months 3 weeks ago
Staff
Joined: 2014-06-30 23:52
I have updated the example

I have updated the example given earlier.