এসটিএম 32: টাইমার বিঘ্ন তত্ক্ষণাত্ কাজ করে


10

এটি STM32F429 এ আমার প্রকল্পে টাইমার জন্য কোড:

//timer initialization
 void timerInit()
 {
  uwPrescalerValue2 = (uint32_t) ((SystemCoreClock / 2) / 100000) - 1;
  RS485Timer.Instance = TIM5;
  RS485Timer.Init.Period = 67400000; // high value to notice interrupt even without debugging
  RS485Timer.Init.Prescaler = 400000;
  RS485Timer.Init.ClockDivision = 0;
  RS485Timer.Init.CounterMode = TIM_COUNTERMODE_UP;
  HAL_TIM_Base_Init(&RS485Timer);
 }

 void timerReset()
 {
 HAL_TIM_Base_Stop_IT(&RS485Timer);
 HAL_TIM_Base_DeInit(&RS485Timer);
 HAL_TIM_Base_Init(&RS485Timer);
 HAL_TIM_Base_Start_IT(&RS485Timer);
 printf("%d timer reset\n", countereset);
 countereset++;
 } 

 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
 {
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* TIMx Peripheral clock enable */
  __TIM5_CLK_ENABLE();

  /*##-2- Configure the NVIC for TIMx #########################################*/
  /* Set the TIMx priority */
  HAL_NVIC_SetPriority(TIM5_IRQn, 7, 1);

  /* Enable the TIMx global Interrupt */
  HAL_NVIC_EnableIRQ(TIM5_IRQn);
 }

 void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
 {
  __TIM5_FORCE_RESET();
  __TIM5_RELEASE_RESET();

  HAL_NVIC_DisableIRQ(TIM5_IRQn);
 }

 void TIM5_IRQHandler(void)
 {
  if (__HAL_TIM_GET_FLAG(&RS485Timer, TIM_FLAG_UPDATE) != RESET)      //In case other interrupts are also running
  {
   if (__HAL_TIM_GET_ITSTATUS(&RS485Timer, TIM_IT_UPDATE) != RESET)
   {
    __HAL_TIM_CLEAR_FLAG(&RS485Timer, TIM_FLAG_UPDATE);
    HAL_TIM_IRQHandler(&RS485Timer);
    printf("timer interrupt\n");
   }
  }
 }

এবং timerReset()আমার প্রোগ্রামের মাঝখানে ফাংশন চলার পরে , বিরতি কয়েক সেকেন্ড পরে নয়, প্রায় অবিলম্বে শুরু হয়। হার্ডওয়্যার সমস্যা আছে কিনা তা পরীক্ষা করার জন্য আমি আরও কয়েকজন টাইমার চেষ্টা করেছি, তবে না, তা নয়।


আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি আপনার টাইমারসেট () ফাংশনে টাইমার বিঘ্নিত পতাকাটি স্পষ্টভাবে সাফ করুন।
brhans

1
ডিআইনিট এবং ইনিশ __HAL_TIM_CLEAR_FLAG (& RS485 টাইমার, TIM_FLAG_UPDATE) এর মধ্যে যোগ করার পরে; এবং __HAL_TIM_CLEAR_FLAG (& RS485 টাইমার, TIM_IT_UPDATE); নতুন কিছু হচ্ছে না।
m0drzew

উত্তর:


9

আমি এটি একটি STM32F105 নিয়ে ছুটে এসেছি। আপনি যা ব্যবহার করছেন তার চেয়ে STM32F1xx স্ট্যান্ডার্ড পেরিফেরাল লাইব্রেরি ফাংশনগুলি কিছুটা আলাদা তবে ধারণাটি একই হওয়া উচিত।

TIM_TimeBaseInit()ফাংশন ইস্যু করার কারণে TIM_SR_UIF পতাকাটি সেট হয়ে যায়। আমি কেন পিছনে ফিরে যাননি। একবার এই বিটটি সেট হয়ে গেলে, ইন্টারপটটি সক্ষম হওয়ার সাথে সাথেই এটি ট্রিগার হয়ে যায়।

এটি ঠিক করার জন্য, ফোন করার পরে TIM_TimeBaseInit(), আমি সঙ্গে সঙ্গে কল করেছি TIM_ClearITPendingBit()। তারপরে আমি বাধাটি সক্ষম করব TIM_ITConfig()। এটি সমস্যার সমাধান করেছে।

আমার সম্পূর্ণ সূচনা রুটিনটি এরকম দেখাচ্ছে:

// Enable the peripheral clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

// Configure the timebase
TIM_TimeBaseInitStructure.TIM_Prescaler = 1;
TIM_TimeBaseInitStructure.TIM_Period = 35999;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);

// That last function caused the UIF flag to get set. Clear it.
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);

// Configure so that the interrupt flag is only set upon overflow
TIM_UpdateRequestConfig(TIM5, TIM_UpdateSource_Regular);

// Enable the TIM5 Update Interrupt type
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);

2
এইচএল লাইব্রেরিগুলি ব্যবহার করে STM32L151 তে একই সমস্যা। কার্যতালিকা (যেমন টিআইএম 6 এর জন্য):__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);

3
নতুন এইচএল ড্রাইভারের একটি মন্তব্যে ব্যাখ্যা করা হয়েছে কেন: পিএসসির মানটি আরম্ভের সময় আপডেট করতে বাধ্য করার জন্য এটি করা হয় কারণ এটি কোনও আপডেট ইভেন্টের পরে কেবলমাত্র এসআর-> পিএসসিতে লোড হয়।
গ্যালাক্সি

সুন্দর, @ গ্যালাক্সি, তথ্যের জন্য ধন্যবাদ।
বিটসম্যাক

1

যেহেতু আমারও একই সমস্যা ছিল এবং আমার উত্তরও পাওয়া যায়নি, তাই আমি অন্যদের সাহায্য করার আশায় আমার অভিজ্ঞতা ভাগ করে নিচ্ছি।

আমি বিশ্বাস করি যে আপনার ক্ষেত্রে, টাইমার শুরু করার আগে ইউআরএস (আপডেট অনুরোধ উত্স) নির্ধারণ করাও সমস্যার সমাধান করে।

আমার ক্ষেত্রে, আমি নিম্ন-স্তরের ড্রাইভারগুলি ব্যবহার করছি, সুতরাং উদাহরণ কোডটি হ'ল:

//Enables APB1 TIM16 peripheral clock
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM16);

//Sets update event source to counter overflows only
LL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER);

//Configures the TIM16 time base
LL_TIM_InitTypeDef TIM_InitStruct;
TIM_InitStruct.Prescaler = 7999;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 2999;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = 0;
LL_TIM_Init(TIM16, &TIM_InitStruct);

//Enables update interrupt
LL_TIM_EnableIT_UPDATE(TIM16);

//Enables timer counter
LL_TIM_EnableCounter(TIM16);

//Enables Interrupt
NVIC_EnableIRQ(TIM16_IRQn);

সমস্যাটি হ'ল আমি সময় বেসটি কনফিগার করার জন্য LL_TIM_SetPrescaler(TIM16, 7999)এবং LL_TIM_SetAutoReload(TIM16, 2999)ফাংশনগুলি ব্যবহার করছিলাম এবং আমি আবিষ্কার করেছি যে এই ফাংশনগুলি ব্যবহার করার সময় মানগুলি আপডেট করা হচ্ছিল না, তাই মানগুলি ব্যবহার করে আপডেট করার জন্য আমাকে একটি ইভেন্ট তৈরি করতে হয়েছিল LL_TIM_GenerateEvent_UPDATE(TIM16)

তারপরে আপনি হয় LL_TIM_ClearFlag_UPDATE(TIM16)বাধা সক্ষম করার আগে ইভেন্টের পতাকা সাফ করতে পারেন , বা LL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)ইভেন্টটি তৈরির আগে ব্যবহার করতে পারেন ।


1

ওয়ান পালস মোডে আমারও একই সমস্যা ছিল এবং আমি এইচএল লাইব্রেরির সমাধান পেয়েছি। আমি যখন "টিআইএম 2_আইআরকিউ হ্যান্ডলার" ফাংশনে টাইমার পতাকাগুলি নিয়ন্ত্রণ করি তখন আমি দেখেছিলাম "ক্যাপচার তুলনা পতাকা 1" সেট করা আছে। সুতরাং আমি "ক্যাপচার তুলনা পতাকা 1" সাফ করে দিয়েছি। তবে এবার দেখলাম "ক্যাপচার তুলনা পতাকা 2" সেট করা আছে। সুতরাং আমি ফলোয়িং কোডগুলি ব্যবহার করে আমার "টিআইএম 2_আইআরকিউ হ্যান্ডলার" ফাংশনে সমস্ত তুলনামূলক পতাকাগুলি (1 থেকে 4 পর্যন্ত) সাফ করেছি।

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */

  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */
  if(__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC1) != RESET)
  {
      timer2Proccess();
      __HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_CC1 );
      __HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_CC2 );
      __HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_CC3 );
      __HAL_TIM_CLEAR_FLAG(&htim2,TIM_FLAG_CC4 );
  }
  /* USER CODE END TIM2_IRQn 1 */
}

0

TIM_TimeBaseInit () এবং STM32F0xx নিয়ে একই সমস্যা। এই ফাংশনের শেষ স্ট্রিং:

  TIMx->EGR = TIM_PSCReloadMode_Immediate;

এটি ইভেন্ট জেনারেশন রেজিস্টারে আপডেট ইভেন্ট সেট করে। এজন্য আমি আইআরকিউ হ্যান্ডলারের কাছে পরীক্ষা করেছি:

void TIM1_IRQHandler() {
if(TIM_GetFlagStatus(TIM1, TIM_FLAG_Update) == SET) {
    TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
    if((TIM1 -> CR1 & TIM_CR1_CEN) == 0) return; //Timer is not working
    //Interrupt code
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.