# create a frequency, use CC1 as overflow

Question asked by Spell on Feb 16, 2012
Latest reply on Feb 17, 2012 by Spell
Hello, I want to create flanks with an Timer4 interrupt. I works if i use the interrupts from
external flanks. Now I want to create the flanks with an internal frequency. Its a little
complicated to describe all so I only describe the  problem.

Timer 4 CC3 and CC4 are used to create the outputsignal-flanks with an interrupt. For a
new flank I have to load a new value in the CC3 or CC4. But if i have a frequency wich is
less than 2^16/72MHz  => 918µs... I need a counter for the overflows. The counter is set
to with the number of overflows and counts down with ever CC1-flag.
Every time if I load the interrupt CCs i also load the CC1 with the same value. Now I can
check with the CC1 flag if the timer pass the 918µs after the last flank. But if the
new CC1 is to close the old CC1 one CC1-flag is left. I tryed to correct this by checking
the distance beween old CC1 and new CC1 and if the distance is to low (less than
25000) I add 2^15 to the value of CC1. Oncurrent I decrease the overflowcounter
because now it has to run on time more. Now it seems that the overflow is one to less if
the distance is more than 19000. So I get 1 Flag to much. If the distance is more than
5000 the outputsignal is correct. Is there a better way to do this or what is the bug in the
program?

//new frequency
if(Test_lock == RESET)        //if new flag is ready
{
n_Tim4_exte_CC1 = (n_Frequency >> 16) + 1//timerextension CC1

//if CC1 is set with + 2^15
if(test_CC1 == 1)
{
n_Tim4_exte_CC1--;
test_CC1 = 0;
TIM_ClearFlag(TIM4, TIM_FLAG_CC1);
}
Test_lock = SET;              //lock this function
}
//32 bit extension
if(TIM_GetFlagStatus(TIM4, TIM_FLAG_CC1) == SET   &&     //if timer pass CC1
n_Tim4_exte_CC1 > 0   )          //if not all overflow completed
{
n_Tim4_exte_CC1 --;
TIM_ClearFlag(TIM4, TIM_FLAG_CC1);
}

//free for next outputflank
if(n_Tim4_exte_CC1 == 0                      &&  //extension is 0
Flag_pos_Flank_dumped== SET         &&   //last flanks finshed
Flag_neg_Flank_dumped== SET        )

{
Flag_High_Flank = SET;                //function to set the new interrupts can be used 1 time
n_Timer4_output_start_pos = (n_Timer4_Impulsestart + n_Frequency); //new outputflank value
Test_lock = RESET;                //enable first if-function again

//if the new CC1 is to close the the old CC1
if((n_Timer4_output_start_pos > n_Timer4_Impulsestart                             &&
(n_Timer4_output_start_pos - n_Timer4_Impulsestart) < 25000)                 ||
(n_Timer4_output_start_pos < n_Timer4_Impulsestart                                 &&
(65535 - n_Timer4_Impulsestart + n_Timer4_output_start_pos) < 25000))
{
TIM_SetCompare1(TIM4, (n_Timer4_output_start_pos + 32767));  //set CC1 opposite
test_CC1 = 1;
TIM_ClearFlag(TIM4, TIM_FLAG_CC1);
}
else
{
TIM_SetCompare1(TIM4, n_Timer4_output_start_pos);  //set CC1 at the same value like the new flank
}
}

I hope someon can help me.. thank you.