Ich habe diesen Timer (TIM4) im PWM-Modus. Ich gebe einen PWM-Kanal aus und möchte etwas warten und dann die neuesten ADC-Samples aus einer DMA-Konvertierung abrufen.
TIM4 -> ARR ist 4096 TIM4 -> CCR1 ist dynamisch, aber es beginnt bei etwa 200
Ich möchte an der steigenden Flanke des TIM4-Impulses beginnen, die Hälfte der Impulse pünktlich abwarten und dann die neuesten und besten DMA-Samples abrufen ... Hier ist ein Ausschnitt dessen, was ich vorhabe:
Wo sich die Dinge zu lösen scheinen, ist die Linie: TIM5->ARR = TIM4->CCR1/2;
. Seltsam ist, dass, wenn ich dort eine Konstante einfüge, wie TIM5->ARR = 20;
, es gut funktioniert ... Es feuert nicht mitten im On-Puls von TIM4, aber es feuert bei 20 / FCLK, die Sie erwarten würden .
Ich habe DM00236305.pdf gelesen, aber ich konnte nicht verstehen, worüber sie mit Shadow-Registern sprachen, was meiner Meinung nach mein Problem ist. Ich habe auch versucht, dem zu folgen, was hier gesagt wurde, aber das war auch ziemlich vauge, und ich war mir nicht sicher, ob es zutraf, da er eher über Ausgangsvergleiche als über automatische Neuladeregister sprach.
Wie passe ich TIM5->ARR an, um die Hälfte von TIM4->CCR1 zu verfolgen?
void TIM5_IRQHandler(void)
{
/* USER CODE BEGIN TIM5_IRQn 0 */
HAL_GPIO_WritePin(GPIOA, TX_Pin, SET);
HAL_TIM_Base_Stop(&htim5);
while(!(DMA2->LISR & DMA_LISR_TCIF0));
motorDummy_FOC.curr_a_sense = ADCValue[0];
motorDummy_FOC.curr_b_sense = ADCValue[1];
update_PWM(&motorDummy_FOC);
HAL_GPIO_WritePin(GPIOA, TX_Pin, RESET);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim == &htim4){
HAL_GPIO_WritePin(GPIOA, RX_Pin, SET);
GPIOC->ODR = 0b0000000000000110;
//TIM4->CR1 &= ~(1<<0);
MX_TIM5_Init();
TIM5->ARR = (TIM4->CCR1/2);
HAL_TIM_Base_Start_IT(&htim5);
HAL_TIM_Base_Start(&htim5);
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim){
if (htim == &htim4){
GPIOC->ODR = 0b0000000000000100;
HAL_GPIO_WritePin(GPIOA, RX_Pin, RESET);
}
}
void update_PWM(motorFOC *c){
if(c->curr_b_sense < c->curr_b_commanded)
{c->i_feedback++;}
else if(c->curr_b_sense > c->curr_b_commanded)
{c->i_feedback--;}
TIM4->CCR1 = c->i_feedback;
}
Ich denke, der Fehler, den Sie machen, ist, dass Sie die Timer-Basisuhr in IRQHandler() stoppen und sie in PeriodElapsedCallback() aktualisieren möchten, was innerhalb von IRQHandler() ausgeführt wird.
Das, wonach Sie suchen, ist das Makro __HAL_TIM_SET_AUTORELOAD .
In *_hal_tim.h-Dateien sind einzelne Makros definiert, um die ARR-, CCR- usw. Werte zu aktualisieren. Das Einzige, was Sie tun müssen, ist, den CCR-Wert dynamisch zu erfassen und das Makro zu aktualisieren, Sie müssen den Timer nicht stoppen und starten..! Das gleiche Problem wird hier angesprochen .
Jeroen3
testname123