PY32F003F18之定时器中断

news2024/11/30 2:27:00

PY32F003F18定时器有TIM1,TIM3,TIM14,TIM16和TIM17。其中TIM1为高级定时器,其它为通用定时器。见下表:

一、PY32F003F18定时器的工作模式:

1、边沿对齐模式

计数器工作在"边沿对齐模式"
设置"TIMx控制寄存器1(TIMx_CR1)"的DIR和"TIMx控制寄存器1(TIMx_CR1)"的CMS[1:0]
CMS[1:0]=00,配置TIMx为边沿对齐模式,当DIR=0时,计数器向上计数;当DIR=1时,计数器向下计数;

计数器使用"内部时钟源":
如果从模式控制器被禁止,则CEN、DIR(TIMx_CR1 寄存器)和UG 位(TIMx_EGR 寄存器)是事实上的控制位,并且只能被软件修改。只要CEN 位被写成1,预分频器的时钟就由内部时钟CK_INT 提供。

2、中央对齐模式1

3、中央对齐模式2

4、中央对齐模式3
中央对齐模式,计数器从0开始计数到自动加载的值(TIMx_ARR 寄存器),会产生一个计数器溢出事件;然后向下计数,
当计数器计数到1时,也会产生一个计数器下溢事件;然后再从0开始重新计数,这样循环往复开始计数。所以计数器中断时间不变。
计数器工作在"中央对齐模式"
设置"TIMx控制寄存器1(TIMx_CR1)"的CMS[1:0]
1)、CMS[1:0]=01,配置TIMx为中央对齐模式1,计数器交替地向上和向下计数;若配置为输出通道的,则在计数器向下计数时,"OCx的输出比较中断标志位"被置1;
2)、CMS[1:0]=10,配置TIMx为中央对齐模式2,计数器交替地向上和向下计数;若配置为输出通道的,则在计数器向上计数时,"OCx的输出比较中断标志位"被置1;
3)、CMS[1:0]=11,配置TIMx为中央对齐模式3,计数器交替地向上和向下计数;若配置为输出通道的,则在计数器向上/向下计数时,"OCx的输出比较中断标志位"被置1;

计数器使用"内部时钟源"
如果从模式控制器被禁止,则CEN、DIR(TIMx_CR1 寄存器)和UG 位(TIMx_EGR 寄存器)是事实上
的控制位,并且只能被软件修改。只要CEN 位被写成1,预分频器的时钟就由内部时钟CK_INT 提供。

二、计数器使用内部时钟源的时序图

 三、测试程序

#include "TIM1_COUNTERMODE_UP.h"
#include "LED.h"
#include "MyTimer.h"

/*
计数器工作在"边沿对齐模式"
//将"TIMx控制寄存器1(TIMx_CR1)"的DIR=0
//将"TIMx控制寄存器1(TIMx_CR1)"的CMS[1:0]=00B
//CMS[1:0]=00,配置TIMx为边沿对齐模式,当DIR=0时,计数器向上计数;当DIR=1时,计数器向下计数;

计数器使用"内部时钟源"
如果从模式控制器被禁止,则CEN、DIR(TIMx_CR1 寄存器)和UG 位(TIMx_EGR 寄存器)是事实上
的控制位,并且只能被软件修改。只要CEN 位被写成1,预分频器的时钟就由内部时钟CK_INT 提供。
*/

void TIM1_COUNTERMODE_UP_Init(uint16_t arr,uint16_t psc);

//函数功能:TIM1中基本计数功能,并使能了更新中断,每次重装ARR值时会产生一次更新中断
//arr:自动重装值。
//psc:时钟预分频数
//TIM1_COUNTERMODE_UP_Init(20000,240);//若使用HSE,当arr=20000,psc=240时,则为200ms,误差为10us;
//TIM1_COUNTERMODE_UP_Init(20000,80);//若使用HSI,当arr=20000,psc=80时,则为200ms,误差为10us;
void TIM1_COUNTERMODE_UP_Init(uint16_t arr,uint16_t psc)
{
	TIM_Base_InitTypeDef TIM_Base_InitStructure;
//	TIM_HandleTypeDef  TIM1_HandleStructure;

	__HAL_RCC_TIM1_CLK_ENABLE(); //使能TIM1时钟
  HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0, 0); //设置中断优先级
  HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);         //使能TIM1中断

  TIM_Base_InitStructure.Period            = arr-1;
	//设置在下一个更新事件产生时,装入"自动重载入寄存器TIMx_ARR"的值
	//将(1600 - 1)写入"自动重载入寄存器TIMx_ARR",设置自动重装载值
  TIM_Base_InitStructure.Prescaler         = psc-1;
	//设置用来作为TIMx时钟频率除数的预分频值
	//将(1000-1)写入"预装载寄存器TIMx_PSC",的PSC[15:0],设置预分频值
	//计数器的时钟频率CK_CNT=fCK_PSC/(PSC[15:0]+1)
  TIM_Base_InitStructure.ClockDivision = TIM_CLOCKDIVISION_DIV1; //时钟不分频,则tDTS=tCK_INT
	//若使用HSE,计算公式:arr*psc/24000000/1,当arr=20000,psc=240时,则为200ms,误差为10us;
	//若使用HSI,计算公式:arr*psc/8000000/1,当arr=20000,psc=80时,则为200ms,误差为100us;
  TIM_Base_InitStructure.CounterMode   = TIM_COUNTERMODE_UP;     //计数器向上计数
  TIM_Base_InitStructure.RepetitionCounter = 1 - 1;
	//不重复计数
	//将(1-1)写入"重复计数寄存器TIMx_RCR"中的REP[7:0],设置"重复计数器值"
  TIM_Base_InitStructure.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
	//"自动重装载寄存器"没有缓冲
	//不允许将"TIMx自动重新加载寄存器TIMx_ARR"的值被装入缓冲区;

	TIM_Base_SetConfig(TIM1,&TIM_Base_InitStructure);
	//选择计数器模式:向上计数
	//设置时钟分频因子:时钟不分频,则tDTS=tCK_INT
	//设置自动重装载:"自动重装载寄存器"没有缓冲
	//设置自动重装载值:TIM_Base_InitStructure.Period
	//设置预分频值:TIM_Base_InitStructure.Prescaler
	//设置"重复计数器值":TIM_Base_InitStructure.RepetitionCounter
  //启动更新事件:将TIMx_EGR中的UG位置1,由软件产生更新事件

  _HAL_TIM_ENABLE_IT(TIM1, TIM_IT_UPDATE);
	//将"TIMx DMA/中断使能寄存器TIM3_DIER"的UIE=1,允许计数器更新产生中断
	_HAL_TIM_ENABLE(TIM1);//计数器使能,开始计数

//  TIM1_HandleStructure.Instance = TIM1; 
//	HAL_TIM_Base_Start_IT(&TIM1_HandleStructure);
	//TIM1使能启动,开始计数,并使能中断
}

//函数功能:定时器中断服务程序
//200ms中断一次
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
  if (_HAL_TIM_GET_FLAG(TIM1,TIM_FLAG_UPDATE) != RESET)
  {//计数器更新事件
    if (_HAL_TIM_GET_IT_SOURCE(TIM1, TIM_IT_UPDATE) != RESET)
    {
      _HAL_TIM_CLEAR_IT(TIM1, TIM_IT_UPDATE);
      MCU_LED_Toggle();
    }
  }
}
#ifndef __MyTimer_H
#define __MyTimer_H

#include "py32f0xx_hal.h"

#define _HAL_TIM_ENABLE(__INSTANCE__)                 ((__INSTANCE__)->CR1|=(TIM_CR1_CEN))
//计数器使能,开始计数

#define _HAL_TIM_DISABLE(__INSTANCE__) \
  do { \
    if (((__INSTANCE__)->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
    { \
      if(((__INSTANCE__)->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
      { \
        (__INSTANCE__)->CR1 &= ~(TIM_CR1_CEN); \
      } \
    } \
  } while(0)
//计数器不使能,停止计数

#define _HAL_TIM_MOE_ENABLE(__INSTANCE__)             ((__INSTANCE__)->BDTR|=(TIM_BDTR_MOE))
//将"TIMx刹车和死区寄存器(TIMx_BDTR)"中的MOE=1,开启OCx和OCxN输出,即使能"TIMx_CH1和TIMx_CH1N"输出

#define _HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__INSTANCE__)  (__INSTANCE__)->BDTR &= ~(TIM_BDTR_MOE)
//将"TIMx刹车和死区寄存器(TIMx_BDTR)"中的MOE=0,关闭OCx和OCxN输出,即不使能"TIMx_CH1和TIMx_CH1N"输出

#define _HAL_TIM_MOE_DISABLE(__INSTANCE__) \
  do { \
    if (((__INSTANCE__)->CCER & TIM_CCER_CCxE_MASK) == 0UL) \
    { \
      if(((__INSTANCE__)->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \
      { \
        (__INSTANCE__)->BDTR &= ~(TIM_BDTR_MOE); \
      } \
    } \
  } while(0)
//在"TIMx捕获/比较使能寄存器TIMx_CCER"中,如果"OCx禁止输出或捕获禁止",且"OCxNE禁止输出"
//则将"TIMx刹车和死区寄存器(TIMx_BDTR)"中的MOE=0,关闭OCx和OCxN输出,即不使能"TIMx_CH1和TIMx_CH1N"输出

#define _HAL_TIM_ENABLE_IT(__INSTANCE__, __INTERRUPT__)    ((__INSTANCE__)->DIER |= (__INTERRUPT__))
//根据__INTERRUPT__,将TIMx DMA/中断使能寄存器(TIM3_DIER)的对应位置1,使能相应的中断
//TIM_IT_UPDATE,允许定时器更新中断,UIE=1
//TIM_IT_CC1,允许捕获/比较1中断,CC1IE=1
//TIM_IT_CC2,允许捕获/比较2中断,CC2IE=1
//TIM_IT_CC3,允许捕获/比较3中断,CC3IE=1
//TIM_IT_CC4,允许捕获/比较4中断,CC4IE=1
//TIM_IT_COM,允许COM事件中断,COMIE=1
//TIM_IT_TRIGGER,允许触发中断,TIE=1
//TIM_IT_BREAK,允许刹车中断,BIE=1

#define _HAL_TIM_DISABLE_IT(__INSTANCE__, __INTERRUPT__)   ((__INSTANCE__)->DIER &= ~(__INTERRUPT__))
//根据__INTERRUPT__,将TIMx DMA/中断使能寄存器(TIM3_DIER)的对应位清除,不使能相应的中断
//TIM_IT_UPDATE,禁止定时器更新中断,UIE=0
//TIM_IT_CC1,禁止捕获/比较1中断,CC1IE=0
//TIM_IT_CC2,禁止捕获/比较2中断,CC2IE=0
//TIM_IT_CC3,禁止捕获/比较3中断,CC3IE=0
//TIM_IT_CC4,禁止捕获/比较4中断,CC4IE=0
//TIM_IT_COM,禁止COM事件中断,COMIE=0
//TIM_IT_TRIGGER,禁止触发中断,TIE=0
//TIM_IT_BREAK,禁止刹车中断,BIE=0

#define _HAL_TIM_ENABLE_DMA(__INSTANCE__, __DMA__)         ((__INSTANCE__)->DIER |= (__DMA__))
//根据__INTERRUPT__,将TIMx DMA/中断使能寄存器(TIMx_DIER)的对应位置1,使能相应的DMA请求
//TIM_DMA_UPDATE,允许更新的DMA请求,UDE=1
//TIM_DMA_CC1,允许捕获/比较1的DMA请求,CC1DE=1
//TIM_DMA_CC2,允许捕获/比较2的DMA请求,CC2DE=1
//TIM_DMA_CC3,允许捕获/比较3的DMA请求,CC3DE=1
//TIM_DMA_CC4,允许捕获/比较4的DMA请求,CC4DE=1
//TIM_DMA_COM,允许COM的DMA请求,COMDE=1
//TIM_DMA_TRIGGER,允许触发DMA请求,TDE=1

#define _HAL_TIM_DISABLE_DMA(__INSTANCE__, __DMA__)        ((__INSTANCE__)->DIER &= ~(__DMA__))
//根据__INTERRUPT__,将TIMx DMA/中断使能寄存器(TIMx_DIER)的对应位置1,不使能相应的DMA请求
//TIM_DMA_UPDATE,禁止更新的DMA请求,UDE=0
//TIM_DMA_CC1,禁止捕获/比较1的DMA请求,CC1DE=0
//TIM_DMA_CC2,禁止捕获/比较2的DMA请求,CC2DE=0
//TIM_DMA_CC3,禁止捕获/比较3的DMA请求,CC3DE=0
//TIM_DMA_CC4,禁止捕获/比较4的DMA请求,CC4DE=0
//TIM_DMA_COM,禁止COM的DMA请求,COMDE=0
//TIM_DMA_TRIGGER,禁止触发DMA请求,TDE=0

#define _HAL_TIM_GET_FLAG(__INSTANCE__, __FLAG__)          (((__INSTANCE__)->SR &(__FLAG__)) == (__FLAG__))
//根据__FLAG__,若"TIMx状态寄存器(TIMx_SR)"中相应的位置1,则返回1
//TIM_FLAG_UPDATE,若UIF=1,建立"更新事件"
//TIM_FLAG_CC1,若CC1IF=1,如果通道CC1配置为输出模式,则建立"CC1输出事件";
//TIM_FLAG_CC1,若CC1IF=1,如果通道CC1配置为输入模式,则建立"CC1捕获事件"
//TIM_FLAG_CC2,若CC2IF=1,如果通道CC2配置为输出模式,则建立"CC2输出事件";
//TIM_FLAG_CC2,若CC2IF=1,如果通道CC2配置为输入模式,则建立"CC2捕获事件"
//TIM_FLAG_CC3,若CC3IF=1,如果通道CC3配置为输出模式,则建立"CC3输出事件";
//TIM_FLAG_CC3,若CC3IF=1,如果通道CC3配置为输入模式,则建立"CC3捕获事件"
//TIM_FLAG_CC4,若CC4IF=1,如果通道CC4配置为输出模式,则建立"CC4输出事件";
//TIM_FLAG_CC4,若CC4IF=1,如果通道CC4配置为输入模式,则建立"CC4捕获事件";
//TIM_FLAG_COM,若COMIF=1,则建立"COM事件"
//TIM_FLAG_TRIGGER,若TIF=1,则建立"触发事件"
//TIM_FLAG_BREAK,若BIF=1,则建立"刹车事件"
//TIM_FLAG_CC1OF,若CC1OF=1,则表示"计数器x的值被捕获到TIMx_CCR1寄存器"
//TIM_FLAG_CC2OF,若CC2OF=1,则表示"计数器x的值被捕获到TIMx_CCR2寄存器"
//TIM_FLAG_CC3OF,若CC3OF=1,则表示"计数器x的值被捕获到TIMx_CCR3寄存器"
//TIM_FLAG_CC4OF,若CC4OF=1,则表示"计数器x的值被捕获到TIMx_CCR4寄存器"

#define _HAL_TIM_CLEAR_FLAG(__INSTANCE__, __FLAG__)        ((__INSTANCE__)->SR = ~(__FLAG__))
//这么写的原因,因为定时器只能做某一种功能,不能同时实现多种功能
//根据__FLAG__,若"TIMx状态寄存器(TIMx_SR)"中相应的位置0,则返回1
//TIM_FLAG_UPDATE,若UIF=1,建立"更新事件"
//TIM_FLAG_CC1,令CC1IF=0,如果通道CC1配置为输出模式,则清除"CC1输出事件";
//TIM_FLAG_CC1,令CC1IF=0,如果通道CC1配置为输入模式,则清除"CC1捕获事件"
//TIM_FLAG_CC2,令CC2IF=0,如果通道CC2配置为输出模式,则清除"CC2输出事件";
//TIM_FLAG_CC2,令CC2IF=0,如果通道CC2配置为输入模式,则清除"CC2捕获事件"
//TIM_FLAG_CC3,令CC3IF=0,如果通道CC3配置为输出模式,则清除"CC3输出事件";
//TIM_FLAG_CC3,令CC3IF=0,如果通道CC3配置为输入模式,则清除"CC3捕获事件"
//TIM_FLAG_CC4,令CC4IF=0,如果通道CC4配置为输出模式,则清除"CC4输出事件";
//TIM_FLAG_CC4,令CC4IF=0,如果通道CC4配置为输入模式,则清除"CC4捕获事件";
//TIM_FLAG_COM,令COMIF=0,则清除"COM事件"
//TIM_FLAG_TRIGGER,令TIF=0,则清除"触发事件"
//TIM_FLAG_BREAK,令BIF=0,则清除"刹车事件"
//TIM_FLAG_CC1OF,令CC1OF=0,则清除建立的事件(计数器x的值被捕获到TIMx_CCR1寄存器)
//TIM_FLAG_CC2OF,令CC2OF=0,则清除建立的事件(计数器x的值被捕获到TIMx_CCR2寄存器)
//TIM_FLAG_CC3OF,令CC3OF=0,则清除建立的事件(计数器x的值被捕获到TIMx_CCR3寄存器)
//TIM_FLAG_CC4OF,令CC4OF=0,则清除建立的事件(计数器x的值被捕获到TIMx_CCR4寄存器)

#define _HAL_TIM_GET_IT_SOURCE(__INSTANCE__, __INTERRUPT__) ((((__INSTANCE__)->DIER & (__INTERRUPT__)) \
                                                             == (__INTERRUPT__)) ? SET : RESET)
//根据__INTERRUPT__,若"TIMx DMA/中断使能寄存器(TIM3_DIER)的对应位置1,则返回1
//TIM_IT_UPDATE,若UIE=1,返回1,当前允许定时器更新中断
//TIM_IT_CC1,若CC1IE=1,返回1,当前允许捕获/比较1中断
//TIM_IT_CC2,若CC2IE=1,返回1,当前允许捕获/比较2中断
//TIM_IT_CC3,若CC3IE=1,返回1,当前允许捕获/比较3中断
//TIM_IT_CC4,若CC4IE=1,返回1,当前允许捕获/比较4中断
//TIM_IT_COM,若COMIE=1,返回1,当前允许COM事件中断
//TIM_IT_TRIGGER,若TIE=1,返回1,当前允许触发中断
//TIM_IT_BREAK,若BIE=1,返回1,当前允许刹车中断

#define _HAL_TIM_CLEAR_IT(__INSTANCE__, __INTERRUPT__)      ((__INSTANCE__)->SR = ~(__INTERRUPT__))
//根据__INTERRUPT__,将"TIMx状态寄存器(TIMx_SR)"中相应的位置0,取消中断标志位
//TIM_IT_UPDATE,令UIE=0,不允许定时器更新中断
//TIM_IT_CC1,令CC1IE=0,不允许捕获/比较1中断
//TIM_IT_CC2,令CC2IE=0,不允许捕获/比较2中断
//TIM_IT_CC3,令CC3IE=0,不允许捕获/比较3中断
//TIM_IT_CC4,令CC4IE=0,不允许捕获/比较4中断
//TIM_IT_COM,令COMIE=0,不允许COM事件中断
//TIM_IT_TRIGGER,令TIE=0,不允许触发中断
//TIM_IT_BREAK,令BIE=0,不允许刹车中断

#define _HAL_TIM_IS_TIM_COUNTING_DOWN(__INSTANCE__)    (((__INSTANCE__)->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR))
//读"TIMx控制寄存器1(TIMx_CR1)"的DIR位,若返回值为1,则表示该计数器为向下计数;否则为向上计数

#define _HAL_TIM_SET_PRESCALER(__INSTANCE__, __PRESC__)       ((__INSTANCE__)->PSC = (__PRESC__))
//将(__PRESC__)写入"预装载寄存器TIMx_PSC",的PSC[15:0],设置预分频值
//计数器的时钟频率CK_CNT=fCK_PSC/(PSC[15:0]+1)

#define _HAL_TIM_SET_COUNTER(__INSTANCE__, __COUNTER__)  ((__INSTANCE__)->CNT = (__COUNTER__))
//将(__COUNTER__)的值写入"TIMx计数器(TIMx_CNT)"

#define _HAL_TIM_GET_COUNTER(__INSTANCE__)  ((__INSTANCE__)->CNT)
//读"TIMx计数器(TIMx_CNT)"的值

#define _HAL_TIM_SET_AUTORELOAD(__INSTANCE__, __AUTORELOAD__) \
  do{                                                    \
    (__INSTANCE__)->ARR = (__AUTORELOAD__);  \
  } while(0)
//将(__AUTORELOAD__)写入"自动重载入寄存器TIMx_ARR",设置自动重装载值

#define _HAL_TIM_GET_AUTORELOAD(__INSTANCE__)  ((__INSTANCE__)->ARR)
//从"自动重载入寄存器TIMx_ARR"中,读取"自动重装载值"

#define _HAL_TIM_SET_CLOCKDIVISION(__INSTANCE__, __CKD__) \
  do{                                                   \
    (__INSTANCE__)->CR1 &= (~TIM_CR1_CKD);  \
    (__INSTANCE__)->CR1 |= (__CKD__);       \
  } while(0)
//设置"时钟分频因子"
//将TIM1控制寄存器1(TIM1_CR1)的CKD[1:0]置00B
//TIM_CLOCKDIVISION_DIV1,则(__CKD__)=00B:时钟分频因子tDTS=tCK_INT
//TIM_CLOCKDIVISION_DIV2,则((__CKD__)=01B:时钟分频因子tDTS=2*tCK_INT
//TIM_CLOCKDIVISION_DIV4,则((__CKD__)=10B:时钟分频因子tDTS=4*tCK_INT

#define _HAL_TIM_GET_CLOCKDIVISION(__INSTANCE__)  ((__INSTANCE__)->CR1 & TIM_CR1_CKD)
//从"TIMx控制寄存器1(TIM1_CR1)"中,读取CKD[1:0]位值,就是"时钟分频因子"
//将TIM1控制寄存器1(TIM1_CR1)的CKD[1:0]置00B
//返回值为TIM_CLOCKDIVISION_DIV1,表示时钟分频因子tDTS=tCK_INT
//返回值为TIM_CLOCKDIVISION_DIV2,表示时钟分频因子tDTS=2*tCK_INT
//返回值为TIM_CLOCKDIVISION_DIV4,表示时钟分频因子tDTS=4*tCK_INT

#define TIMx_RESET_ICPRESCALERVALUE(__INSTANCE__, __CHANNEL__) \
  ( ( (__CHANNEL__) == TIM_CHANNEL_1) ? ( (__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_IC1PSC ) :\
    ( (__CHANNEL__) == TIM_CHANNEL_2) ? ( (__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_IC2PSC ) :\
    ( (__CHANNEL__) == TIM_CHANNEL_3) ? ( (__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_IC3PSC ) :\
    ( (__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_IC4PSC ) )
//设置"输入捕获模式,Input Capture mode"
//如果(__CHANNEL__)为TIM_CHANNEL_1,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获1预分频器C1PSC[1:0]
//如果(__CHANNEL__)为TIM_CHANNEL_2,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获2预分频器C2PSC[1:0]
//如果(__CHANNEL__)为TIM_CHANNEL_3,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR2)"中的输入/捕获3预分频器C3PSC[1:0]

#define TIMx_SET_ICPRESCALERVALUE(__INSTANCE__, __CHANNEL__, __ICPSC__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 |= (__ICPSC__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCMR1 |= ((__ICPSC__) << 8U)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 |= (__ICPSC__)) :\
   ((__INSTANCE__)->CCMR2 |= ((__ICPSC__) << 8U)))
//设置"输入捕获模式,Input Capture mode"
//若(__CHANNEL__)=TIM_CHANNEL_1,则用(__ICPSC__)设置"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获1预分频器C1PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_2,则(__ICPSC__)设置"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获2预分频器C2PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_3,则(__ICPSC__)设置"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的输入/捕获3预分频器C3PSC[1:0]

#define _HAL_TIM_GET_ICPRESCALER(__INSTANCE__, __CHANNEL__)  \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 & TIM_CCMR1_IC1PSC) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__INSTANCE__)->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 & TIM_CCMR2_IC3PSC) :\
   (((__INSTANCE__)->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U)
//在"输入捕获模式"中,
//若(__CHANNEL__)=TIM_CHANNEL_1,则读取"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获1预分频器C1PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_2,则读取"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获2预分频器C2PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_3,则读取"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的输入/捕获3预分频器C3PSC[1:0]

#define _HAL_TIM_SET_COMPARE(__INSTANCE__, __CHANNEL__, __COMPARE__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCR1 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCR2 = (__COMPARE__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCR3 = (__COMPARE__)) :\
   ((__INSTANCE__)->CCR4 = (__COMPARE__)))
//设置"CCx的预装载值":
//若(__CHANNEL__)=TIM_CHANNEL_1,则将(__COMPARE__)写入TIMx捕获/比较寄存器1(TIMx_CCR1)中的CCR1[15:0],表示预装载值
//若(__CHANNEL__)=TIM_CHANNEL_2,则将(__COMPARE__)写入TIMx捕获/比较寄存器2(TIMx_CCR2)中的CCR2[15:0],表示预装载值
//若(__CHANNEL__)=TIM_CHANNEL_3,则将(__COMPARE__)写入TIMx捕获/比较寄存器3(TIMx_CCR3)中的CCR3[15:0],表示预装载值
//若(__CHANNEL__)=TIM_CHANNEL_4,则将(__COMPARE__)写入TIMx捕获/比较寄存器4(TIMx_CCR4)中的CCR3[15:0],表示预装载值

#define _HAL_TIM_GET_COMPARE(__INSTANCE__, __CHANNEL__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCR1) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCR2) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCR3) :\
   ((__INSTANCE__)->CCR4))
//读取"CCx的预装载值":
//若(__CHANNEL__)=TIM_CHANNEL_1,则从TIMx捕获/比较寄存器1(TIMx_CCR1)中的CCR1[15:0]读取预装载值
//若(__CHANNEL__)=TIM_CHANNEL_2,则从TIMx捕获/比较寄存器2(TIMx_CCR2)中的CCR2[15:0]读取预装载值
//若(__CHANNEL__)=TIM_CHANNEL_3,则从TIMx捕获/比较寄存器3(TIMx_CCR3)中的CCR3[15:0]读取预装载值
//若(__CHANNEL__)=TIM_CHANNEL_4,则从TIMx捕获/比较寄存器3(TIMx_CCR4)中的CCR3[15:0]读取预装载值

#define _HAL_TIM_ENABLE_OCxPRELOAD(__INSTANCE__, __CHANNEL__)    \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 |= TIM_CCMR1_OC1PE) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCMR1 |= TIM_CCMR1_OC2PE) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 |= TIM_CCMR2_OC3PE) :\
   ((__INSTANCE__)->CCMR2 |= TIM_CCMR2_OC4PE))
//开启TIMx_CCRy寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_1,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC1PE位置1,开启TIMx_CCR1寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_2,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC2PE位置1,开启TIMx_CCR2寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_3,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC3PE位置1,开启TIMx_CCR3寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_4,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC4PE位置1,开启TIMx_CCR4寄存器的预装载功能

#define _HAL_TIM_DISABLE_OCxPRELOAD(__INSTANCE__, __CHANNEL__)    \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_OC1PE) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_OC2PE) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_OC3PE) :\
   ((__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_OC4PE))
//禁止TIMx_CCRy寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_1,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC1PE位置0,禁止TIMx_CCR1寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_2,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC2PE位置0,禁止TIMx_CCR2寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_3,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC3PE位置0,禁止TIMx_CCR3寄存器的预装载功能
//若(__CHANNEL__)=TIM_CHANNEL_4,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC4PE位置0,禁止TIMx_CCR4寄存器的预装载功能

#define _HAL_TIM_ENABLE_OCxFAST(__INSTANCE__, __CHANNEL__)    \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 |= TIM_CCMR1_OC1FE) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCMR1 |= TIM_CCMR1_OC2FE) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 |= TIM_CCMR2_OC3FE) :\
   ((__INSTANCE__)->CCMR2 |= TIM_CCMR2_OC4FE))
//开启"比较x快速输出"功能,加快CCx输出对触发器x输入事件的响应
//若(__CHANNEL__)=TIM_CHANNEL_1,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC1FE位置1,开启"比较1快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_2,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC2FE位置1,开启"比较2快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_3,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC3FE位置1,开启"比较3快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_4,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC4FE位置1,开启"比较4快速输出"功能

#define _HAL_TIM_DISABLE_OCxFAST(__INSTANCE__, __CHANNEL__)    \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_OC1FE) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCMR1 &= ~TIM_CCMR1_OC2FE) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_OC3FE) :\
   ((__INSTANCE__)->CCMR2 &= ~TIM_CCMR2_OC4FE))
//禁止"比较x快速输出"功能,不用加快CC输出对触发器输入事件的响应
//若(__CHANNEL__)=TIM_CHANNEL_1,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC1FE位置0,禁止"比较1快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_2,则将"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的OC2FE位置0,禁止"比较2快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_3,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC3FE位置0,禁止"比较3快速输出"功能
//若(__CHANNEL__)=TIM_CHANNEL_4,则将"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的OC4FE位置0,禁止"比较4快速输出"功能

#define _HAL_TIM_URS_ENABLE(__INSTANCE__)  ((__INSTANCE__)->CR1|= TIM_CR1_URS)
//将"TIMx控制寄存器1(TIM1_CR1)"中的URS位置1
//允许在"计数器溢出/下溢"时,产生一个更新中断或DMA请求;

#define _HAL_TIM_URS_DISABLE(__INSTANCE__)  ((__INSTANCE__)->CR1&=~TIM_CR1_URS)
//将"TIMx控制寄存器1(TIM1_CR1)"中的URS位置0
//允许在"计数器溢出/下溢"时,产生一个更新中断或DMA请求;
//允许在"TIMx_EGR中的UG位置1"时,产生一个更新中断或DMA请求;
//允许在"从模式控制器产生更新"时,产生一个更新中断或DMA请求;



#define _HAL_TIM_SET_ICPRESCALER(__INSTANCE__, __CHANNEL__, __ICPSC__) \
  do{                                                    \
    TIMx_RESET_ICPRESCALERVALUE((__INSTANCE__), (__CHANNEL__));  \
    TIMx_SET_ICPRESCALERVALUE((__INSTANCE__), (__CHANNEL__), (__ICPSC__)); \
  } while(0)
//使用(__ICPSC__)设置通道为(__CHANNEL__)的"输入捕获预分频器"的值
//设置"输入捕获模式,Input Capture mode"
//如果(__CHANNEL__)为TIM_CHANNEL_1,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获1预分频器C1PSC[1:0]
//如果(__CHANNEL__)为TIM_CHANNEL_2,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获2预分频器C2PSC[1:0]
//如果(__CHANNEL__)为TIM_CHANNEL_3,则清除"TIMx捕获/比较模式寄存器1(TIMx_CCMR2)"中的输入/捕获3预分频器C3PSC[1:0]
//设置"输入捕获模式,Input Capture mode"
//若(__CHANNEL__)=TIM_CHANNEL_1,则用(__ICPSC__)设置"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获1预分频器C1PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_2,则(__ICPSC__)设置"TIMx捕获/比较模式寄存器1(TIMx_CCMR1)"中的输入/捕获2预分频器C2PSC[1:0]
//若(__CHANNEL__)=TIM_CHANNEL_3,则(__ICPSC__)设置"TIMx捕获/比较模式寄存器2(TIMx_CCMR2)"中的输入/捕获3预分频器C3PSC[1:0]

#define TIMx_RESET_CAPTUREPOLARITY(__INSTANCE__, __CHANNEL__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCER &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\
   ((__INSTANCE__)->CCER &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP)))
//设置"输入/捕获x的输出极性"
//TIMx捕获/比较使能寄存器(TIMx_CCER)
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1P时,令CC1P=0;CC1P=0表示"输入/捕获1输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1NP时,令CC1NP=0;CC1NP=0表示"输入/捕获1互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2P时,令CC2P=0;CC2P=0表示"输入/捕获2输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2NP时,令CC2NP=0;CC2NP=0表示"输入/捕获2互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3P时,令CC3P=0;CC3P=0表示"输入/捕获3输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3NP时,令CC3NP=0;CC3NP=0表示"输入/捕获3互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4P时,令CC4P=0;CC4P=0表示"输入/捕获4输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4NP时,令CC4NP=0;CC4NP=0表示"输入/捕获4互补输出极性"为高电平有效,否则为低电平有效

#define TIMx_SET_CAPTUREPOLARITY(__INSTANCE__, __CHANNEL__, __POLARITY__) \
  (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__INSTANCE__)->CCER |= (__POLARITY__)) :\
   ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__INSTANCE__)->CCER |= ((__POLARITY__) << 4U)) :\
   ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__INSTANCE__)->CCER |= ((__POLARITY__) << 8U)) :\
   ((__INSTANCE__)->CCER |= (((__POLARITY__) << 12U))))
//设置"输入/捕获x的输出极性"
//TIMx捕获/比较使能寄存器(TIMx_CCER)
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1P时,令CC1P=1;CC1P=0表示"输入/捕获1输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1NP时,令CC1NP=1;CC1NP=0表示"输入/捕获1互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2P时,令CC2P=1;CC2P=0表示"输入/捕获2输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2NP时,令CC2NP=1;CC2NP=0表示"输入/捕获2互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3P时,令CC3P=1;CC3P=0表示"输入/捕获3输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3NP时,令CC3NP=1;CC3NP=0表示"输入/捕获3互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4P时,令CC4P=1;CC4P=0表示"输入/捕获4输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4NP时,令CC4NP=1;CC4NP=0表示"输入/捕获4互补输出极性"为高电平有效,否则为低电平有效

#define _HAL_TIM_SET_CAPTUREPOLARITY(__INSTANCE__, __CHANNEL__, __POLARITY__)    \
  do{                                                                     \
    TIMx_RESET_CAPTUREPOLARITY((__INSTANCE__), (__CHANNEL__));               \
    TIMx_SET_CAPTUREPOLARITY((__INSTANCE__), (__CHANNEL__), (__POLARITY__)); \
  }while(0)
//设置"输入/捕获x的输出极性"
//TIMx捕获/比较使能寄存器(TIMx_CCER)
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1P时,令CC1P=0;CC1P=0表示"输入/捕获1输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1NP时,令CC1NP=0;CC1NP=0表示"输入/捕获1互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2P时,令CC2P=0;CC2P=0表示"输入/捕获2输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2NP时,令CC2NP=0;CC2NP=0表示"输入/捕获2互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3P时,令CC3P=0;CC3P=0表示"输入/捕获3输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3NP时,令CC3NP=0;CC3NP=0表示"输入/捕获3互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4P时,令CC4P=0;CC4P=0表示"输入/捕获4输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4NP时,令CC4NP=0;CC4NP=0表示"输入/捕获4互补输出极性"为高电平有效,否则为低电平有效
//设置"输入/捕获x的输出极性"
//TIMx捕获/比较使能寄存器(TIMx_CCER)
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1P时,令CC1P=1;CC1P=0表示"输入/捕获1输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_1,(__POLARITY__)=TIM_CCER_CC1NP时,令CC1NP=1;CC1NP=0表示"输入/捕获1互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2P时,令CC2P=1;CC2P=0表示"输入/捕获2输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_2,(__POLARITY__)=TIM_CCER_CC2NP时,令CC2NP=1;CC2NP=0表示"输入/捕获2互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3P时,令CC3P=1;CC3P=0表示"输入/捕获3输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_3,(__POLARITY__)=TIM_CCER_CC3NP时,令CC3NP=1;CC3NP=0表示"输入/捕获3互补输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4P时,令CC4P=1;CC4P=0表示"输入/捕获4输出极性"为高电平有效,否则为低电平有效
//当(__CHANNEL__)=TIM_CHANNEL_4,(__POLARITY__)=TIM_CCER_CC4NP时,令CC4NP=1;CC4NP=0表示"输入/捕获4互补输出极性"为高电平有效,否则为低电平有效	
#endif /* __MyTimer_H */
#include "py32f0xx_hal.h"
#include "SystemClock.h"
#include "USART2.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "delay.h"
#include "LED.h"
#include "TIM1_COUNTERMODE_UP.h"
#include "SystemClock.h"

const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{
	HSE_Config();
	HAL_Init();//systick初始化
  delay_init();
	HAL_Delay(1000);

	MCU_LED_Init();
	USART2_Init(115200);
	printf("%s",CPU_Reset_REG);
	TIM1_COUNTERMODE_UP_Init(20000,240);//若使用HSE,当arr=20000,psc=240时,则为200ms,误差为10us;
//	TIM1_COUNTERMODE_UP_Init(20000,80);//若使用HSI,当arr=20000,psc=80时,则为200ms,误差为10us;

  while (1)
  {
		delay_ms(100);
  }
}
#include "SystemClock.h"
#include "py32f0xx_hal.h"

void HSE_Config(void);
void HSI_Config(void);

//函数功能:初始化"HSI,HSE,LSI振荡器",HSE用作系统时钟(SYSCLK),同时配置"AHB时钟(HCLK)和APB时钟(PCLK)"
void HSE_Config(void)
{
	HAL_StatusTypeDef retData;
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  //配置HSE,HSI和LSI振荡器
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON; //开启HSI
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; //HSI不分频
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz;    //配置HSI输出时钟为4MHz
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_8MHz;      //配置HSI输出时钟为8MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz;   //配置HSI输出时钟为16MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_22p12MHz;//配置HSI输出时钟为22.12MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz;   //配置HSI输出时钟为24MHz

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;      //开启HSE
  RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz; //HSE工作频率范围16M~32M

  RCC_OscInitStruct.LSIState = RCC_LSI_ON;      //开启LSI

	retData=HAL_RCC_OscConfig(&RCC_OscInitStruct);//初始化HSI,HSE,LSI振荡器
  if ( retData!= HAL_OK)//初始化振荡器失败
  {
  }

  //初始化"系统时钟(SYSCLK),AHB时钟(HCLK)和APB时钟(PCLK)"
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;//SYSCLK的源选择为HSE
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;//AHB时钟(HCLK)不分频,输出为APB时钟
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; //APB时钟(PCLK)分频器为2分频,输出为PCLK时钟
	retData=HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
	//初始化RCC系统时钟(小于24MHz,则使用FLASH_LATENCY_0;大于24MHz且小于48MHz,则使用FLASH_LATENCY_1)
  if ( retData!= HAL_OK)//初始化RCC系统时钟失败
  {
  }
}

//函数功能:初始化"HSI振荡器",用作系统时钟(SYSCLK),同时配置"AHB时钟(HCLK)和APB时钟(PCLK)"
void HSI_Config(void)
{
	HAL_StatusTypeDef retData;
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  //配置HSI振荡器
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;//选择振荡器类型为HSI
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;//开启HSI
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;//不分频
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz;//配置HSI输出时钟为4MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_8MHz;//配置HSI输出时钟为8MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz;//配置HSI输出时钟为16MHz
//  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_22p12MHz;//配置HSI输出时钟为22.12MHz
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz; //配置HSI输出时钟为24MHz
	retData=HAL_RCC_OscConfig(&RCC_OscInitStruct);

  if(retData != HAL_OK)//初始化振荡器失败
  {
  }

  //初始化"系统时钟(SYSCLK),AHB时钟(HCLK)和APB时钟(PCLK)"
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;  //RCC系统时钟类型
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;//SYSCLK的源选择为HSI
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;    //AHB时钟(HCLK)不分频,输出为APB时钟
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;     //APB时钟(PCLK)分频器为1分频,输出为PCLK时钟
	retData=HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
	初始化RCC系统时钟(小于24MHz,则使用FLASH_LATENCY_0;大于24MHz且小于48MHz,则使用FLASH_LATENCY_1)

  if( retData!=HAL_OK)初始化RCC系统时钟失败
  {
  }
}

四、测试结果 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《动手学深度学习 Pytorch版》 4.7 前向传播、反向传播和计算图

4.7.1 前向传播 整节理论&#xff0c;详见书本。 4.7.2 前向传播计算图 整节理论&#xff0c;详见书本。 4.7.3 反向传播 整节理论&#xff0c;详见书本。 4.7.4 训练神经网络 整节理论&#xff0c;详见书本。 练习 &#xff08;1&#xff09;假设一些标量函数 X X X…

Wireshark把DDoS照原形

1 前言 MTU、 传输速度、 拥塞控制&#xff0c;还是各种重传&#xff0c;TCP传输相关的核心概念&#xff1a; 学习了RFC规范和具体的Linux实现通过案例&#xff0c;把这些知识灵活运用了起来 这种种还是在协议规范这大框架内的讨论&#xff0c;默认前提就是通信两端是遵照TC…

Activating More Pixels in Image Super-Resolution Transformer(HAT)超分

摘要 基于Transformer的方法在低级视觉任务&#xff08;如图像超分辨率&#xff09;上表现出令人印象深刻的性能。然而&#xff0c;我们发现这些网络只能通过归因分析利用有限的输入信息空间范围。这意味着Transformer的潜力在现有网络中仍未得到充分利用。为了激活更多输入像…

yolov7添加 iRMB模块

复制过来 yolo.py添加 yaml文件随便换&#xff0c;建议换3x3的 pip install timm0.6.5&#xff0c;版本问题记得搞一下

DNG格式详解,DNG是什么?为何DNG可以取代RAW统一单反相机、苹果安卓移动端相机拍摄输出原始图像数据标准

返回图像处理总目录&#xff1a;《JavaCV图像处理合集总目录》 前言 在DNG格式发布之前&#xff0c;我们先了解一下之前单反相机、苹果和安卓移动端相机拍照输出未经处理的原始图像格式是什么&#xff1f; RAW 什么是RAW&#xff1f; RAW是未经处理、也未经压缩的格式。可以…

基于开源模型搭建实时人脸识别系统(六):人脸识别(人脸特征提取)

文章目录 人脸识别的几个发展阶段基于深度学习的人脸识别技术的流程闭集和开集&#xff08;Open set&#xff09;识别人脸识别的损失Insightface人脸识别数据集模型选型参考文献结语人脸识别系统项目源码 前面我们讲过了人脸检测、人脸质量、人脸关键点、人脸跟踪&#xff0c;接…

微分中值定理

目录 费马定理 罗尔定理 拉格朗日中值定理 柯西中值定理 几个常用的泰勒公式 微分中值定理是微积分中的一个重要定理&#xff0c;它用于描述一个函数在某个区间内的平均变化率与该区间内某一点的瞬时变化率之间的关系。微分中值定理有两个主要形式&#xff1a;拉格朗日中值…

Kotlin Files Paths write ByteArray writeString写多行BufferedWriter

Kotlin Files Paths write ByteArray writeString写多行BufferedWriter import java.nio.file.Files import java.nio.file.Paths import java.nio.file.StandardOpenOptionfun main(args: Array<String>) {val filePath "./myfile.txt"val path Paths.get(…

【报错】springboot3启动报错

报错内容&#xff1a;Cannot load driver class: org.h2.Driver Error starting ApplicationContext. To display the condition evaluation report re-run your application with debug enabled. 解决; 通过源码分析&#xff0c;druid-spring-boot-3-starter目前最新版本是1…

微信小程序 写一个接口不会掉就不会停止的加载动画

我们可以在接口调用前执行 wx.showLoading({title: 加载中,mask: true })这个加载会在这一直转 显示这加载的动画 它不会自己停下来 而是需要你执行 wx.hideLoading()之后 这个加载动画才会停止 那么我们完全可以将wx.hideLoading()放在接口返回的回调中 这样 就达到了一个 …

LeetCode每日一题:2596. 检查骑士巡视方案(2023.9.13 C++)

目录 2596. 检查骑士巡视方案 题目描述&#xff1a; 实现代码与解析&#xff1a; bfs模拟 原理思路&#xff1a; 2596. 检查骑士巡视方案 题目描述&#xff1a; 骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中&#xff0c;骑士会从棋盘的 左上角 出发&#xff0c;并…

利用Semaphore实现多线程调用接口A且限制接口A的每秒QPS为10

前段时间在群里面发现有个群友抛出一个实际需求&#xff1a;需要通过一个接口拉取数据&#xff0c;这个接口有每秒10QPS限制&#xff0c;请问如何实现数据拉去效率最大化且限制调用拉取接口每秒10PQPS&#xff1f;我觉得这个需求挺有意思的&#xff0c;跟某群友讨论&#xff0c…

CopyOnWriteArrayList源码分析

其中唯一的线程安全 List 实现就是 CopyOnWriteArrayList。 特点 由于读取操作不会对原有数据进行修改&#xff0c;因此&#xff0c;对于每次读取都进行加锁其实是一种资源浪费。相比之下&#xff0c;我们应该允许多个线程同时访问 List 的内部数据&#xff0c;毕竟对于读取操…

企业邮箱选择指南:最适合跨境贸易的解决方案推荐

随着全球贸易的不断发展&#xff0c;外贸公司越来越依赖高效的沟通和协作工具。在众多企业邮箱选择中&#xff0c;哪一种最适合外贸公司的需求呢&#xff1f;让我们一起来看看外贸公司常用的企业邮箱解决方案。 对于外贸公司而言&#xff0c;可靠性是选择企业邮箱的首要考虑因…

LC1798. 你能构造出连续值的最大数目(JAVA)

LC1798. 你能构造出连续值的最大数目 题目描述贪心算法代码演示 题目描述 难度 - 中等 Leetcode - 1798. 你能构造出连续值的最大数目 给你一个长度为 n 的整数数组 coins &#xff0c;它代表你拥有的 n 个硬币。第 i 个硬币的值为 coins[i] 。如果你从这些硬币中选出一部分硬币…

前端构建工具 webpack 笔记

1、了解 webpack 1、定义&#xff1a;本质上&#xff0c;webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具&#xff0c;当 webpack 处理应用它会在内部从一个或多个入口点构建一个依赖图(dependency graph)&#xff0c;然后将你项目中所程序时&#xff0c;需的…

YOLO物体检测系列3:YOLOV3改进解读

&#x1f388;&#x1f388;&#x1f388;YOLO 系列教程 总目录 YOLOV1整体解读 YOLOV2整体解读 YOLOV3提出论文&#xff1a;《Yolov3: An incremental improvement》 1、YOLOV3改进 这张图讲道理真的过分了&#xff01;&#xff01;&#xff01;我不是针对谁&#xff0c;在…

《C++ Primer》第3章 字符串、向量和数组(二)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 3.3 标准库类型vector&#xff08;P86&#xff09; vector 表示对象的序列&#xff0c;其中所有对象的类型相同&#xff0c;每个对象都有一个与之对应的索引。vector 容纳着其他对象&#xff0c;所以常被称…

Linux内核4.14版本——drm框架分析(11)——DRM_IOCTL_MODE_ADDFB2(drm_mode_addfb2)

目录 1. drm_mode_addfb2 2. drm_internal_framebuffer_create 3. drm_fb_cma_create->drm_gem_fb_create->drm_gem_fb_create_with_funcs 4. drm_gem_fb_alloc 4.1 drm_helper_mode_fill_fb_struct 4.2 drm_framebuffer_init 5. 调用流程图 书接上回&#xff0c;使…

springboot对接postgres

安装postgres 注意:下述链接方式会自动创建数据库steven_russell,若需要创建其他数据库&#xff0c;可以手动执行命令创建数据库 docker run --name postgres \ -p 5432:5432 \ -e POSTGRES_USERsteven_russell \ -e POSTGRES_PASSWORD123456 \ -itd --privilegedtrue postgre…