STM8S定時器TIM4定時1kHz輸出

1.將主時鐘切換到HSE;(外部晶振爲8MkHz)
2.將主時鐘時鐘頻率8分頻,即計數器時鐘週期爲1us;
3.設置定時器250us中斷一次;
4.在中斷程序裏判斷中斷次數是否到2次;
5.到2次翻轉引腳電平。(邏輯分析儀檢測頻率)
寄存器版:

unsigned char i=255;
PE_DDR_DDR5=1;//配置PD0爲輸出模式
PE_CR1_C15=1;//配置PD0爲推輓模式
PE_CR2_C25=0;//配置PD0輸出最大爲10Mhz

  if(CLK_CMSR==0xE1) {//如果HSI爲主時鐘源(復位值),切換到HSE
    CLK_SWCR_SWIEN=1;//時鐘切換中斷使能
    CLK_SWR=0xB4;//HSE爲主時鐘源
    asm("rim");//開啓全局中斷
  }

while(CLK_SWCR_SWBSY)//等待忙標誌復位
{
    i--;
    if(i==0) {
      CLK_SWCR_SWBSY=0;//如果時鐘切換沒有成功,清除標誌位SWBSY以復位當前的切換操作
      break;
    }    
}
  
  TIM4_CNTR=0; //初始化計數器值
  TIM4_ARR=0xFA; //自動重裝寄存器值250,250us
  TIM4_PSCR_PSC=0x03; //預分頻係數爲8,8M/8=1M->1us
  TIM4_EGR_UG=1; //手動產生一個更新事件,立即更新預分頻器
  TIM4_IER_UIE=1;//更新中斷使能
  TIM4_CR1_CEN=1;//使能計數器
  
  while(1);
}



#pragma vector=CLK_SWITCH_vector
	__interrupt void CLK_IRQHandler(void){
 	 CLK_SWCR_SWIF=0;//清除中斷標誌
 	  CLK_SWCR_SWEN=1;//使能時鐘切換的執行  
}

unsigned char t4=0;
#pragma vector=TIM4_OVR_UIF_vector
__interrupt void TIM4_IRQHandler(void){
  
 t4++;
  if(t4==2)
  {
    	PE_ODR_ODR5=!PE_ODR_ODR5;//取反
    	t4=0;   
 }
 TIM4_SR_UIF=0; 
}

庫函數版:

 CLK_DeInit();//重置時鐘相關寄存器到默認復位值
  GPIO_Init(GPIOE, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);

  enableInterrupts();//使能全局中斷

  ErrorStatus es;
  es = CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, ENABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
  //手動切換;新的時鐘源:HSE;啓動切換中斷;保持原時鐘源開啓
  if (es == SUCCESS)  //切換是否成功,SUCCESS or ERROR
  {
     TIM4_TimeBaseInit(TIM4_PRESCALER_8, 0xFA);//初始化時基單元,8分頻,自動重載寄存器值爲250
     TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);//使能TIM4更新中斷
    // TIM4_PrescalerConfig(TIM4_PRESCALER_8, TIM4_PSCRELOADMODE_UPDATE);
     TIM4_GenerateEvent(TIM4_EVENTSOURCE_UPDATE);//手動產生更新事件
     TIM4_Cmd(ENABLE);//啓動定時器
      
  }
  else{
    CLK_SYSCLKEmergencyClear();//清除時鐘切換標誌
  }


  /* Infinite loop */
  while (1)

中斷服務程序:

INTERRUPT_HANDLER(CLK_IRQHandler, 2)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
  
  ITStatus flags_tatus;
  flags_tatus = CLK_GetITStatus(CLK_IT_SWIF);//檢測時鐘切換中斷標誌
  if (flags_tatus == SET)  //如果時鐘切換中斷標誌SWIF是置位狀態,SET or RESET
  {
    CLK_ClearITPendingBit(CLK_IT_SWIF);//清除時鐘切換中斷標誌
 
    CLK_ClockSwitchCmd(ENABLE);//啓動時鐘切換功能 
  };
}


 unsigned char i=0;
 INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
 {
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
   i++;
   TIM4_ClearFlag(TIM4_FLAG_UPDATE);
   if(i==2){
     i=0;
     GPIO_WriteReverse(GPIOE, GPIO_PIN_5);
   }
  
 }

頻率輸出:
在這裏插入圖片描述
這裏建議計數器計數次數不要太少,中斷服務程序里程序不宜太多,否則會造成中斷服務程序未執行完,又來一箇中斷,造成程序執行不正確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章