STM32入门基础

GPIO

<1>说明

· 引脚电平:0~3.3V,部分可达到5V(参考引脚定义,带FT的就可以)

同时 GPIO有两个模式

输出模式:进行端口高低电平的输出,用于驱动LED,蜂鸣器等

输入模式:读取端口高低电平的电压/电平,用于按键输入,ADC电压采集等

<2>基本结构

 APB2外设时钟总线,所有的GPIO都是挂载再APB2上的,其中GPIO的名称是按照GPIO A/B/C来命名的,每个外设都有15个引脚,编号为0~15

<3>GPIO模式

GPIO库函数编码

(1)使用RCC开启GPIO的时钟

(2)使用GPIO_Init()初始化GPIO

(3)使用输出/输入函数控制GPIO口

一个涉及到RCC和GPIO两个外设

1.常用的RCC外设时钟控制函数 AHB/APB2/APB1(最主要就这三个,其他几乎不用)

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

2.GPIO库函数

// 参数写入GPIOX,所指定的GPIO外设就会被复位
void GPIO_DeInit(GPIO_TypeDef* GPIOx);

//可以复位AFIO外设
void GPIO_AFIODeInit(void);

//GPIO初始化函数,我们需要先定义一个结构体变量,然后赋值,最后调用这个函数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

//可以把结构体变量变成一个默认值
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

/***********下面四个为GPIO的读取函数********/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

/*************读写GPIO口的函数**************/
//设置指定的端口为高电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//设定指定的端口为低电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
//前面的参数为选择端口,最后为指定写入数据值(Bit_SET  / Bit_RESET)
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);


//剩下的这些我们现在还不会用到
//锁定GPIO配置
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

//配置AFIO的事件输出功能函数
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);

//配置引脚重映射函数
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

//EXTI GPIO开启
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);

3,开启流程(GPIO初始化)

//1.开启RCC外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  /*uint32_t RCC_APB2Periph*/, ENABLE);

//2.开启GPIO
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //选择模式
/*AIN模式输入,IN_FLOATING浮空输入,IPD下拉输入,IPU上拉输入
OUT_OD开漏输出(低电平有驱动力,高电平没有),PUT_PP推挽输出,AF则为复用 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;        //选择引脚

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//选择频率

GPIO_Init(GPIOA, &GPIO_InitStructure);           //初始化

EXTI中断函数

<1>中断

中断 : 在主程序运行过程中,出现特定的中断触发条件,使得CPU暂停当前正在运行的程序,而去处理中断程序,完成后,又返回原来被暂停的位置继续工作

中断优先 : 当有多个中断开始时,CPU会根据事情的轻重响应更加紧急的中断

中断嵌套 : 一个中断正常进行,又来一个更高级的中断,会先去做刚来的高级的中断,然后依次返回

  

<2>NVIC

 68个可屏蔽中断通道,包含EXTI,TIM,ADC,USART,SPI,IIC,RTC等多个外设

NVIC:NVIC的中断优先级由优先级寄存器的4位(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级

抢占优先级高的可以进行中断嵌套,响应优先级高的可以进行优先排队,抢占优先级和响应优先级均相同的按中断号排队

<3>EXTI:(Extern Interrupt)外部中断

EXTI可以检测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序

支持的触发方式:上升沿/下降沿/双边沿/软件触发

支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断

通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒

触发响应方式:中断响应/事件响应

AFIO选择中断引脚,外部中断的9-5,15-10会触发同一个中断函数,再根据标志位来区分到底是哪个中断进来的

配置数据选择器,只有一个Pin接到EXTI  

<4>配置步骤:

第一步,配置RCC,把设计到的外设时钟都打开

第二步,配置GPIO,选择端口为输入模式

第三步,配置AFIO,选择使用的一路GPIO,连接到后面的EXTI

第四步,配置EXTI,选择边沿触发方式,选择触发响应方式

第五步,配置NVIC,给中断选择一个合适的优先级

<5>库函数说明

首先,EXTI本身是不需要打开什么时钟的,所以前面正常打开GPIO就可以了

AFIO也使用RCC使能

void GPIO_EXTILineConfig(GPIO_PortSourceGPIOB /*引脚所在的源*/,GPIO_PinSource14 /*第14个中断线路);

 这个函数,可以让14号引脚的电平顺利通过AFIO,进入到后级EXTI电路中

EXTI库函数:

//调用他,可以清除EXTI的配置,恢复为默认的上电状态
void EXTI_DeInit(void);

//初始化EXTI,方法与GPIO相同
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

//参数传递的结构体变量赋一个默认值
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

//软件触发外部中断
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);


//下面为模板函数
//读写中断标志位
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
//清楚中断标志
void EXTI_ClearFlag(uint32_t EXTI_Line);
//只能读写中断标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

EXTI_Init参数

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);//选择中断线路
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);///选择自己的引脚相同线路就好
	
	EXTI_InitTypeDef EXTI_InitStructure;//定义外部中断结构体
	EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;//设置中断线
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;//开启中断线路
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
	EXTI_Init(&EXTI_InitStructure);//写入参数

NVIC内核外设库函数

//中断分组,参数是中断分组的方式
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

// NVIC初始化函数,根据结构体参数初始化
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);


void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
//系统低功耗配置
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);

分组在整个流程中只要进行一次就可以了,如果模块化要注意选择是同一个,可以选择放在主函数里

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组

NVIC结构体初始化内容

	//我们选择了两个分组,那么我们就配置两个
    NVIC_InitTypeDef NVIC_InitStructure;//定义NVIC结构体
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//设置中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//通道使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//写入参数



	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//设置中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//通道使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//写入参数

中断服务函数

在STM32中,每个通道的中断服务函数名字都是固定的

void EXTI0_IRQHandler(void)//线路0中断函数
void EXTI1_IRQHandler(void)//线路1中断函数

获取标志位

if (EXTI_GetITStatus(EXTI_Line0) == SET)//判断中断挂起位

服务函数结束后清除标志位

	EXTI_ClearITPendingBit(EXTI_Line0);//清除中断挂起标志位

定时器


TIM(Timer)定时器 

<1> 简介 

· 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断

· 16位计数器、预分频、自动重装寄存器的时基单元,在72M计数时钟下可以实现最大59.65s的定时

· 不仅具备基本的定时器中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

· 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

· 对72MHz计72个数就是1MHz,也就是1us的时间,计72000个数,那就是1KHz也就是1ms的时间

59.65s =65536 · 65536 · 1/72M/(中断频率倒数),

· STM32的定时器支持级联的模式:一个定时器的输出当做另一个定时器的输入最大定时时间就是59.65s · 65536 · 65536

· STM32F103C8T6有TIM1/2/3/4四个定时器

 基本定时器有三个重要的定时器,这三个我们称一起为时基单元

下面是我们常选择的基本定时器

· 这三个定时器连内部定时器,也就是ck_int

· 预分频器(PSC):对输入的基准频率提前进行一个分频的操作
实际分频系数 = 预分频器的值 + 1,最大可以写65535即65536分频


· 计数器(CNT):也是16位,值可以从0~65535,当计数器的值自增(自减)到目标值时,产生中断,完成定时


· 自动重装寄存器():也是16位当计数值等于自动重装值时,就是计时的时间到了,就会产生一个中断信号,并且清零计数器,计数器自动开始下一次的计数计时,计数值等于自动重装值的中断一般叫做“更新中断”,此更新中断就会通往NVIC,再配置好NVIC的定时器通道,定时器上的更新中断就会得到CPU的响应了,对应的事件叫做“更新事件”,更新事件不会触发中断,但可以触发内部其他电路的工作

————————————

我们在通用定时器内,不仅可选择内部时钟,也可以选择外部TIMX_ETR引脚上的外部时钟

基本结构

定时器触发中断,我们可以选择RCC触发的内部时钟(定时器中断计数),也可以选择ETR引脚提供的外部时钟模式2.

也可以选择触发输入当作外部时钟(模式1),对应的为ETR外部时钟,ITRx其他1定时器,Tix输入捕获通道

编码器模式为编码器独有的模式

预分频器时序

 · 计数器技术频率 : CK_CNT = CK_PSC / (PSC+1)

计数器时序

 · 计数器溢出频率 : CK_CNT_OV = CK_CNT / (ARR + 1)

通过设置ARPE,就可以选择有无预装的情况

开启定时器步骤

  1. 第一步,RCC开启时钟
  2. 第二步,选择时基单元的时钟源
  3. 第三步,配置时基单元
  4. 第四步,配置输出中断控制,允许更新中断输出到NVIC
  5. 第五步,配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
  6. 第六步,运行控制
  7. 第七步,使能计数器

输出比较说明

· OC——输出比较

· 输出比较可以通过CNT和CRR寄存器值的关系,来对输出电平进行 1, 0 ,翻转 

· 每个通用定时器/高级都有4个输出比较通道

PWM

· 可通过一系列脉冲的宽度进行调制

输出比较模式

TIM库函数

// 恢复配置
void TIM_DeInit(TIM_TypeDef* TIMx);

/********时基单元**********************
// 时基单元的配置,第一个选择TIMX的某个定时器,第二个结构体,包含了配置时基单元的一些参数
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
********************end***************/

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct);

//结构体变量赋一个默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct);

//使能计数器,对应图中运行控制(运行控制)
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);


void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

//输出中断控制 使能中断输出信号,1.选择定时器 2.配置哪个中断输出, 3.状态为使能/失能
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

void TIM_GenerateEvent(TIM_TypeDef* TIMx, uint16_t TIM_EventSource);
void TIM_DMAConfig(TIM_TypeDef* TIMx, uint16_t TIM_DMABase, uint16_t TIM_DMABurstLength);
void TIM_DMACmd(TIM_TypeDef* TIMx, uint16_t TIM_DMASource, FunctionalState NewState);


//下面四个对应时基单元的时钟选择部分

/****************时钟源选择********************
//选择内部时钟,选择定时器即可
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

//选择ITRX其他定时器时钟,1.选择定时器 2.选择接入哪个其他定时器
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

//选择TIX捕获通道的函数 2.选择具体引脚 3.输入极性与滤波器
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);

//选择ETR通过外部时钟模式1输入时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);


//选择ETR通过外部时钟模式2输入时钟
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);、

//配置引脚预分频等等
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
*****************end file**********************************************/


//单独写入预分频值 3.写入模式
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);


void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectCCDMA(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
void TIM_UpdateDisableConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_UpdateRequestConfig(TIM_TypeDef* TIMx, uint16_t TIM_UpdateSource);
void TIM_SelectHallSensor(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_SelectOnePulseMode(TIM_TypeDef* TIMx, uint16_t TIM_OPMode);
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
void TIM_SelectMasterSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_MasterSlaveMode);

//给计数器写入一个值函数
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

//给自动重装器写入一个值函数
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);

//获取当前计数器的值函数
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

//获取当前预分频器的值函数
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

定时器初始化示例:

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启TIM2时钟
	
//因为如果不写默认的就是使用内部时钟,所以我们可以选择不写这个
	TIM_InternalClockConfig(TIM2);//使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义时基单元结构体
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置不分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//ARR自动重装值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//PSC不分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级定时器特有
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);//写入参数
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除更新标志位
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//中断输出
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	
	NVIC_InitTypeDef NVIC_InitStructure;//NVIC结构体
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//写入参数
	
	TIM_Cmd(TIM2, ENABLE);//开启定时器
}

猜你喜欢

转载自blog.csdn.net/ArtoriaLili/article/details/128777777