STM8S定时器TIM4定时1kHz输出

10 篇文章 1 订阅

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);
   }
  
 }

频率输出:
在这里插入图片描述
这里建议计数器计数次数不要太少,中断服务程序里程序不宜太多,否则会造成中断服务程序未执行完,又来一个中断,造成程序执行不正确。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值