当前位置: 首页 > news >正文

电影网站建设的程序做网站推广常识题库及答案

电影网站建设的程序,做网站推广常识题库及答案,微信获客crm平台,有做公司网站STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG 文章目录 一、STM32 基础定时器1. 基本定时器简介2. 基本定时器框图3. 基本定时器相关寄存器4. 定时器溢出…STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG 文章目录 一、STM32 基础定时器1. 基本定时器简介2. 基本定时器框图3. 基本定时器相关寄存器4. 定时器溢出时间计算5. 基本定时器中断配置步骤6. 代码实现 二、STM32通用定时器1. 通用定时器简介2. 通用定时器框图1. 时钟源1. 内部时钟CK_INT2. 外部时钟模式1TI1, TI23. 外部时钟模式2ETR4. 内部触发输入ITRx 2. 控制器3. 时基单元4. 输入捕获5. 捕获/比较(公共)6. 输出比较 3. 通用定时器相关寄存器 三、 通用定时器输出PWM波1. 通用定时器PWM输出实验配置步骤2. 代码实现 四、通用定时器输入捕获实验1. 输入捕获测量脉冲宽度2. 输入捕获实验相关寄存器3. 通用定时器输入捕获配置步骤4. 代码实现 五、通用定时器脉冲计数实验1. 脉冲计数框图2. 相关寄存器3. 通用定时器脉冲计数配置步骤4. 代码实现 六、高级定时器输出指定个数PWM实验1. 高级定时器框图2. 重复计数器特性3. 相关寄存器4. 高级定时器输出指定个数PWM实验配置步骤5. 代码实现 七、高级定时器输出比较模式实验1. 输出比较模式功能2. 相关寄存器3. 高级定时器输出比较模式实验配置步骤4. 代码实现 八、高级定时器互补输出带死区控制实验1. 互补死区的理解2. 相关寄存器3. 高级定时器互补输出带死区控制实验配置步骤4. 代码实现 九、高级定时器PWM输入模式实验1. PWM输入工作原理2. 输入模式时序图3. 相关寄存器4. 高级定时器PWM输入模式实验配置步骤4. 代码实现 一、STM32 基础定时器 STM32定时器分类 STM32定时器特性表: 主要功能 定时器类型主要功能基本定时器没有输入输出通道常用作时基即定时功能通用定时器具有多路独立通道可用于输入捕获/输出比较也可用作时基高级定时器除具备通用定时器所有功能外还具备带死区控制的互补信号输出、刹车输入等功能可用于电机控制、数字电源设计等 1. 基本定时器简介 STM32F103有两个基本定时器TIM6和TIM7它们的功能完全相同资源是完全独立的可以同时使用。 主要特性 16位自动重载递增计数器16位可编程预分频器预分频系数1~65536用于对计数器时钟频率进行分频触发DAC的同步电路生成中断 和DMA请求。 定时原理: 2. 基本定时器框图 影子寄存器 实际起作用的寄存器用户不可直接访问。举个例子我们可以把预分频系数写入预分频器寄存器(TIMx_PSC)但是预分频器寄存器只是起到缓存数据的作用只有等到更新事件发生时预分频器寄存器的值才会被自动写入其影子寄存器中这时才真正起作用。 自动重载寄存器自动重载寄存器及其影子寄存器的作用在于自动重载寄存器是否具有缓冲作用还受到ARPE位的控制。 当该位置0时ARR寄存器不进行缓冲写入新ARR值会立即传送到ARR影子寄存器从而直接生效当该位置1时ARR寄存器进行缓冲写入新ARR值时不会立即被写入ARR影子寄存器而是要等到更新事件发生才会被写入ARR影子寄存器这时才生效。预分频器寄存器则没有这样相关的控制位这就是它们不同点。 更新事件的产生 软件产生将 TIMx_EGR 寄存器的位UG置 1产生更新事件后硬件会自动将 UG 位清零。硬件产生基本定时器的计数器(CNT)是一个递增的计数器当寄存器(TIMx_CR1)的CEN位置 1即使能定时器每来一个CK_CNT脉冲TIMx_CNT的值就会递增加1。当TIMx_CNT值与TIMx_ARR的设定值相等时TIMx_CNT的值就会被自动清零并且会生成更新事件如果开启相应的功能就会产生DMA请求、产生中断信号或者触发DAC同步电路)然后下一个 CK_CNT脉冲到来TIMx_CNT的值就会递增加1如此循环。在此过程中TIMx_CNT等于 TIMx_ARR时我们称之为定时器溢出因为是递增计数故而又称为定时器上溢。定时器溢出就伴随着更新事件的发生。 计数模式与溢出条件 递增计数模式实例说明 递减计数模式实例说明 中心对齐计数模式实例说明 3. 基本定时器相关寄存器 控制寄存器 1(TIMx_CR1) DMA/中断使能寄存器(TIMx_DIER) 状态寄存器(TIMx_SR) 计数器(TIMx_CNT) 预分频器(TIMx_PSC) 自动重装载寄存器(TIMx_ARR) 4. 定时器溢出时间计算 5. 基本定时器中断配置步骤 配置定时器基础工作参数 HAL_TIM_Base_Init()定时器基础MSP初始化 HAL_TIM_Base_MspInit() 使能更新中断并启动计数器 HAL_TIM_Base_Start_IT()设置优先级使能中断 HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ() 编写中断服务函数 TIMx_IRQHandler() HAL_TIM_IRQHandler()编写定时器更新中断回调函数 HAL_TIM_PeriodElapsedCallback()程序流程 6. 代码实现 功能使用定时器中断实现LED灯闪烁. 定时器中断初始化 void btim_timx_int_init(uint16_t psc, uint16_t per) {g_timx_handle.Instance TIM6;g_timx_handle.Init.Prescaler psc;g_timx_handle.Init.Period per;HAL_TIM_Base_Init(g_timx_handle);HAL_TIM_Base_Start_IT(g_timx_handle);}定时器基础MSP初始化函数 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) {if (htim-Instance TIM6){__HAL_RCC_TIM6_CLK_ENABLE();HAL_NVIC_SetPriority(TIM6_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM6_IRQn);} }定时器6中断服务函数 void TIM6_IRQHandler() {HAL_TIM_IRQHandler(g_timx_handle); }定时器溢出中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim-Instance TIM6){LED0_TOGGLE();} }主函数 #include ./SYSTEM/sys/sys.h #include ./SYSTEM/usart/usart.h #include ./SYSTEM/delay/delay.h #include ./BSP/LED/led.h #include ./BSP/KEY/key.h #include ./BSP/BEEP/beep.h #include ./BSP/EXTI/exti.h #include ./BSP/WDG/wdg.h #include ./BSP/TIMER/btim.hint main(void) {HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */btim_timx_int_init(7199, 4999);while(1){} } 二、STM32通用定时器 1. 通用定时器简介 通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合包括测量输入信号的脉冲宽度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的没有互相共享任何资源并且可以一起同步操作。 主要特性 16位递增、递减、中心对齐计数器计数值0~65535 16位预分频器分频系数1~65536 4个独立通道输入捕获输出比较PWM生成单脉冲模式输出 使用外部信号控制定时器且可实现多个定时器互连的同步电路 支持针对定位的增量编码器和霍尔传感器电路 触发输入作为外部时钟或者按周期的电流管理 2. 通用定时器框图 1. 时钟源 计数器时钟选择类型设置方法内部时钟(CK_INT)设置TIMx_SMCR的SMS000外部时钟模式1外部输入引脚(TIx)设置TIMx_SMCR的SMS111外部时钟模式2外部触发输入(ETR)设置TIMx_SMCR的ECE1内部触发输入(ITRx) 1. 内部时钟CK_INT 定时器TIM2~TIM7挂接在APB1总线上这些定时器的内部时钟CK_INT实际上来自APB1总线提供的时钟然后经过一个倍频器之后输出的时钟频率为72MHz。 2. 外部时钟模式1TI1, TI2 3. 外部时钟模式2ETR 4. 内部触发输入ITRx 2. 控制器 控制器包括触发控制器从模式控制器编码器接口 触发控制器用来提供触发信号给别的外设 从模式控制器可以控制计数器复位、启动、递增/递减、计数 编码器接口针对编码器计数 3. 时基单元 4. 输入捕获 TIMx_CH1~TIMx_CH4表示定时器的4个通道4个通道独立工作。IO端口通过复用功能与这些通道相连。配置好IO端口的复用功能后将需要测量的信号输入到相应的 IO端口输入捕获部分可以对输入的信号的上升沿下降沿或者双边沿进行捕获常见的测量有测量输入信号的脉冲宽度、测量PWM输入信号的频率和占空比等。 5. 捕获/比较(公共) 以通道1为例对应CCR1寄存器CC1G位可以产生软件捕获事件那么硬件捕获事件如何产生的以通道1输入为例CC1S[1:0]01,即IC1映射到TI1上CC1E位置1使能输入捕获比如不滤波、不分频ICF[3:0]00ICPS[1:0]00比如检测上升沿CC1P位置0接着就是等待测量信号的上升沿到来。当上升沿到来时IC1PS信号就会触发输入捕获事件发生计数器的值就会被锁存到捕获/比较影子寄存器里。当CCR1寄存器没有被进行读操作的时候捕获/比较影子寄存器里的值就会锁存到CCR1寄存器中那么程序员就可以读取CCR1寄存器得到计数器的计数值。检测下降沿同理。 6. 输出比较 首先程序员写CCR1寄存器即写入比较值。这个比较值需要转移到对应的捕获比较影子寄存器后才会真正生效。什么条件下才能转移compare transfer旁边的与门需要满足三个条件CCR1不在写入操作期间、CC1S[1:0]0配置为输出、OC1PE位置 0(或者OC1PE位置1并且需要发生更新事件这个更新事件可以软件产生或者硬件产生)。当CCR1寄存器的值转移到其影子寄存器后新的值就会和计数器的值进行比较它们的比较结果将会通过输出比较影响定时器的输出。 3. 通用定时器相关寄存器 控制寄存器1TIMx_CR1 从模式控制寄存器TIMx_SMCR DMA/中断使能寄存器TIMx_DIER 状态寄存器TIMx_SR 计数寄存器TIMx_CNT 预分频寄存器TIMx_PSC 自动重载寄存器TIMx_ARR 三、 通用定时器输出PWM波 通用定时器输出模式 PWM即脉冲宽度调制是利用微处理器的数字输出对模拟电路进行控制的一种非常有效的技术。让定时器产生PWM在计数器频率固定时PWM频率自动重载寄存器TIMx_ARR的值决定其占空比由捕获/比较寄存器TIMx_CCRx的值决定。 PWM模式 PWM控制寄存器 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 捕获/比较寄存器TIMx_CCR1/2/3/4 1. 通用定时器PWM输出实验配置步骤 配置定时器基础工作参数 HAL_TIM_PWM_Init()定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()使能输出并启动计数器 HAL_TIM_PWM_Start()修改比较值控制占空比(可选) __HAL_TIM_SET_COMPARE()使能通道预装载(可选) __HAL_TIM_ENABLE_OCxPRELOAD()相关库函数介绍 函数主要寄存器主要功能HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_PWM_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_PWM_ConfigChannel()CCMRx、CCRx、CCER配置PWM模式、比较值、输出极性等HAL_TIM_PWM_Start()CCER、CR1使能输出比较并启动计数器__HAL_TIM_SET_COMPARE()CCRx修改比较值__HAL_TIM_ENABLE_OCxPRELOAD()CCER使能通道预装载 2. 代码实现 功能使用TM3通道2由PB5复用输出PWM,PB5引脚连接了LED0,从而实现PWM输出控制LED0亮度。 程序流程 通用定时器PWM输出初始化函数 void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_pwm_chy;g_timx_pwm_chy_handle.Instance TIM3; //定时器选择g_timx_pwm_chy_handle.Init.Prescaler psc; //定时器分频g_timx_pwm_chy_handle.Init.Period arr;g_timx_pwm_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP; //定时器计数模式HAL_TIM_PWM_Init(g_timx_pwm_chy_handle); //初始化PWMtimx_oc_pwm_chy.OCMode TIM_OCMODE_PWM1; //模式选择PWM1timx_oc_pwm_chy.Pulse arr/2; //占空比为50%timx_oc_pwm_chy.OCNPolarity TIM_OCNPOLARITY_LOW; //输出比较极性为低HAL_TIM_PWM_ConfigChannel(g_timx_pwm_chy_handle, timx_oc_pwm_chy, TIM_CHANNEL_2); //配置定时器3通道2HAL_TIM_PWM_Start(g_timx_pwm_chy_handle, TIM_CHANNEL_2); //开启PWM通道 }定时器输出PWM MSP初始化函数 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM3){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_TIM3_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_5;gpio_init_struct.Mode GPIO_MODE_AF_PP;gpio_init_struct.Pull GPIO_PULLUP;gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, gpio_init_struct);__HAL_RCC_AFIO_CLK_ENABLE();__HAL_AFIO_REMAP_TIM3_PARTIAL(); //设置重映射,把TIM3通道2映射到PB5} }主函数 int main(void) {uint16_t ledrpwmval 0;uint8_t dir 1;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */gtim_timx_pwm_chy_init(500 - 1, 72 - 1);while(1){delay_ms(10);if(dir) ledrpwmval;else ledrpwmval--;if(ledrpwmval 300) dir 0;if(ledrpwmval 0) dir 1;__HAL_TIM_SET_COMPARE(g_timx_pwm_chy_handle, TIM_CHANNEL_2, ledrpwmval);} }四、通用定时器输入捕获实验 1. 输入捕获测量脉冲宽度 测量方法假定工作在递增计数模式首先设置通道x为上升沿捕获这样在t1时刻上升沿到来时就会发生捕获事件打开捕获中断捕获事件发生时会触发捕获中断。在捕获中断里将计数器值清零并设置通道x为下降沿捕获这样t2时刻下降沿到来时就会发生捕获事件和捕获中断。捕获事件发生时计数器的值会被锁存到捕获/比较寄存器中。在捕获中断内读取捕获/比较寄存器就可以获取高电平脉冲时间计数器计数的个数从而可以算出高电平脉冲的时间假定计数器没有溢出。 但是在t1到t2时间段定时器可能会产生N次溢出需要对定时器溢出做相应的处理防止高电平太长导致测量出错。在t1到t2时间内假定定时器溢出N次那么高电平时间内计数器计数的个数计算方法为N * (ARR 1) CCRx2CCRx2表示t2时间点捕获/比较寄存器的值。经过计算得到高电平脉宽时间内计数器计数个数后用这个个数乘以计数器的计数周期就可以得到高电平持续的时间。就是输入捕获测量高电平脉宽时间的整个过程。 STM32F103的定时器除了TM6和TM7其他定时器都有输入捕获功能。输入捕获简单的说就是通过检测TIMx_CHy上的边沿信号在边沿信号发生跳变比如上升沿/下降沿时会发生捕获事件将当前定时器的值(TIMx_CNT)锁存到对应通道的捕获/比较寄存器(TIMx_CCRy)里完成一次捕获。同时还可以配置捕获事件发生时是否触发捕获中断/DMA。另外还要考虑测量的过程中是否可能发生定时器溢出如果可能溢出还要做溢出处理。 2. 输入捕获实验相关寄存器 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 3. 通用定时器输入捕获配置步骤 配置定时器基础工作参数 HAL_TIM_IC_Init()定时器输入捕获MSP初始化 HAL_TIM_IC_MspInit() 配置输入通道映射、捕获边沿等 HAL_TIM_IC_ConfigChannel()设置优先级使能中断 HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()使能定时器更新中断 __HAL_TIM_ENABLE_IT()使能捕获、捕获中断及计数器 HAL_TIM_IC_Start_IT()编写中断服务函数 TIMx_IRQHandler() HAL_TIM_IRQHandler()编写更新中断和捕获回调函数 HAL_TIM_PeriodElapsedCallback() HAL_TIM_IC_CaptureCallback()相关函数的功能 函数主要寄存器主要功能HAL_TIM_IC_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_IC_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_IC_ConfigChannel()CCMRx、CCER配置通道映射、捕获边沿、分频、滤波等__HAL_TIM_ENABLE_IT()DIER使能更新中断等HAL_TIM_IC_Start_IT()CCER、DIER、CR1使能输入捕获、捕获中断并启动计数器HAL_TIM_IRQHandler()SR定时器中断处理公用函数处理各种中断HAL_TIM_PeriodElapsedCallback()无定时器更新中断回调函数由用户重定义HAL_TIM_IC_CaptureCallback()无定时器输入捕获回调函数由用户重定义 4. 代码实现 功能 1、使用TM5CH1来做输入捕获捕获PA0上的高电平脉宽并将脉宽时间通过串口打印出来然后通过按WKUP按键模拟输入高电平例程中能测试的最长高电平脉宽时间为 4194303us. 2、LED0闪烁指示程序运行。 通用定时器TIM5通道1输入捕获初始化函数 void gtim_timx_cap_chy_init(uint16_t arr, uint16_t psc) {TIM_IC_InitTypeDef timx_ic_cap_chy {0};//初始化定时器参数 g_timx_cap_chy_handle.Instance TIM5; //定时器5的基地址g_timx_cap_chy_handle.Init.Prescaler psc; //定时器的分频系数g_timx_cap_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP; //递增计数模式g_timx_cap_chy_handle.Init.Period arr; //自动重装载值HAL_TIM_IC_Init(g_timx_cap_chy_handle); //初始化//配置通道映射、捕获边沿、分频、滤波等timx_ic_cap_chy.ICPolarity TIM_ICPOLARITY_RISING; //配置捕获极性为上升沿timx_ic_cap_chy.ICSelection TIM_ICSELECTION_DIRECTTI; //映射到通道1timx_ic_cap_chy.ICPrescaler TIM_ICPSC_DIV1; //不进行分频timx_ic_cap_chy.ICFilter 0; //不进行滤波HAL_TIM_IC_ConfigChannel(g_timx_cap_chy_handle, timx_ic_cap_chy, TIM_CHANNEL_1); //初始化__HAL_TIM_ENABLE_IT(g_timx_cap_chy_handle, TIM_IT_UPDATE); //使能更新中断HAL_TIM_IC_Start_IT(g_timx_cap_chy_handle, TIM_CHANNEL_1); //开始捕获TIM5的通道1 }通用定时器输入捕获初始化函数 void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM5) //判断定时器是否正确{GPIO_InitTypeDef gpio_init_struct; //GPIO配置结构体__HAL_RCC_TIM5_CLK_ENABLE(); //使能定时器时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟gpio_init_struct.Pin GPIO_PIN_0; //配置引脚号gpio_init_struct.Mode GPIO_MODE_AF_PP; //配置复用推挽输出gpio_init_struct.Pull GPIO_PULLDOWN; //配置下拉模式gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH; //配置输出速度HAL_GPIO_Init(GPIOA, gpio_init_struct); //初始化HAL_NVIC_SetPriority(TIM5_IRQn, 1, 3); //设置中断优先级HAL_NVIC_EnableIRQ(TIM5_IRQn); //使能TIM5中断} }定时器TIM5中断服务函数 //定时器5中断服务函数 void TIM5_IRQHandler(void) {//HAL库中断公共处理函数HAL_TIM_IRQHandler(g_timx_cap_chy_handle); }定时器输入捕获中断处理回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim-Instance TIM5){if((g_timxchy_cap_sta 0x80) 0) //未成功捕获{if(g_timxchy_cap_sta 0x40) //捕获下降沿{g_timxchy_cap_sta | 0x80; //位7置1 代表成功捕获g_timxchy_cap_val HAL_TIM_ReadCapturedValue(g_timx_cap_chy_handle, TIM_CHANNEL_1); //保存当前计数器的值TIM_RESET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); //使能通道1为上降沿捕获}else //捕获上升沿{g_timxchy_cap_sta 0;g_timxchy_cap_val 0;g_timxchy_cap_sta | 0x40;__HAL_TIM_DISABLE(g_timx_cap_chy_handle); //失能定时器5__HAL_TIM_SET_COUNTER(g_timx_cap_chy_handle, 0); //计数器的值清0TIM_RESET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); //使能通道1为下降沿捕获__HAL_TIM_ENABLE(g_timx_cap_chy_handle); //使能定时器5}}} }定时器更新中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim-Instance TIM5){if((g_timxchy_cap_sta 0x80) 0) //未成功捕获{if(g_timxchy_cap_sta 0x40) //已经成功捕获{if((g_timxchy_cap_sta 0X3F) 0x3f) //高电平时间过长{TIM_RESET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1); //失能通道TIM_SET_CAPTUREPOLARITY(g_timx_cap_chy_handle, TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING); //使能通道1为下降沿捕获g_timxchy_cap_sta | 0x80; //标记成功捕获一次g_timxchy_cap_val 0xFFFF;}else //累积定时器溢出次数{g_timxchy_cap_sta;}}}}if(htim-Instance TIM6){LED0_TOGGLE();}if(htim-Instance TIM7){LED1_TOGGLE();} }主函数 int main(void) {uint32_t temp 0;uint8_t t 0;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */gtim_timx_cap_chy_init(0xFFFF, 72 - 1); //1MHzwhile(1){if(g_timxchy_cap_sta 0x80){temp g_timxchy_cap_sta 0x3F;temp temp * 65536; //溢出时间总和temp g_timxchy_cap_val; //溢出的总时间printf(HIGH:%d us\r\n, temp);g_timxchy_cap_sta 0; //开启下一次捕获}t;if(t 20){t 0;LED0_TOGGLE();}delay_ms(10);} } 主程序运行流程 中断程序运行流程 五、通用定时器脉冲计数实验 1. 脉冲计数框图 脉冲计数实验使用的时钟源是外部时钟模式1外部输入引脚(TIx)作为定时器的时钟源。实验中使用WK_UP按键按下产生的高电平脉冲作为定时器的计数器时钟每按下一次按键产生一次高电平脉冲计数器的值加一。 外部时钟模式1的外部输入引脚只能是通道1或者通道2对应的IO通道3或者通道4不可以。以通道1输入为例外部时钟源信号通过通道1输入后TI1分别要经过滤波器、边沿检测器后来到TI1FP1被触发输入选择器选择为触发源接着来到从模式控制器。从模式选择为外部时钟模式1这时候外部时钟源信号就会到达时基单元的预分频器后面就是经过分频后就作为计数器的计数时钟。 2. 相关寄存器 捕获/比较模式寄存器1/2TIMx_CCMR1/2 与输入捕获配置相同 捕获/比较使能寄存器TIMx_CCER 与输入捕获配置相同 从模式控制寄存器TIMx_SMCR 3. 通用定时器脉冲计数配置步骤 配置定时器基础工作参数 HAL_TIM_IC_Init()定时器输入捕获MSP初始化 HAL_TIM_IC_MspInit()配置定时器从模式等 HAL_TIM_SlaveConfigSynchro()使能输入捕获并启动计数器 HAL_TIM_IC_Start()获取计数器的值 __HAL_TIM_GET_COUNTER()设置计数器的值 __HAL_TIM_SET_COUNTER()相关库函数 函数主要寄存器主要功能HAL_TIM_IC_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_IC_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_SlaveConfigSynchro()SMCR、CCMRx、CCER配置定时器从模式、触发选择、分频、滤波等HAL_TIM_IC_Start()CCER、CR1使能输入捕获、启动计数器__HAL_TIM_GET_COUNTER()CNT获取计数器当前值__HAL_TIM_SET_COUNTER()CNT设置计数器的值 4. 代码实现 功能 使用TM2CH1做输入捕获我们将捕获PA0上的高电平脉宽并将脉宽进行计数通过串口打印出来。大家可以通过按WKUP按键输入高电平脉冲通过按KEY0重设当前计数。 LED0闪烁提示程序运行。 通用定时器脉冲计数初始化函数 void gtim_timx_cnt_chy_init(uint16_t psc) {TIM_SlaveConfigTypeDef timx_slave_config {0};g_timx_cnt_chy_handle.Instance TIM2; //定时器选择g_timx_cnt_chy_handle.Init.Prescaler psc; //定时器分频g_timx_cnt_chy_handle.Init.Period 65535;g_timx_cnt_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP; //定时器计数模式HAL_TIM_IC_Init(g_timx_cnt_chy_handle); //初始化PWMtimx_slave_config.SlaveMode TIM_SLAVEMODE_EXTERNAL1;timx_slave_config.InputTrigger TIM_TS_TI1F_ED;timx_slave_config.TriggerPolarity TIM_TRIGGERPOLARITY_RISING;timx_slave_config.TriggerFilter 0;HAL_TIM_SlaveConfigSynchro(g_timx_cnt_chy_handle, timx_slave_config);HAL_TIM_IC_Start(g_timx_cnt_chy_handle, TIM_CHANNEL_1); }主函数 int main(void) {uint16_t curcnt; //存储当前的计数值uint16_t oldcnt; //存储旧的计数值uint8_t key; //按键的键值uint8_t t; //延时时间HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */key_init();gtim_timx_cnt_chy_init(0); while(1){key key_scan(0);if(key 1){__HAL_TIM_SET_COUNTER(g_timx_cnt_chy_handle, 0);}curcnt __HAL_TIM_GET_COUNTER(g_timx_cnt_chy_handle);if(oldcnt ! curcnt){oldcnt curcnt;printf(CNT:%d\r\n, oldcnt);}t;if(t 20){t 0;LED0_TOGGLE();}delay_ms(10);} } 六、高级定时器输出指定个数PWM实验 1. 高级定时器框图 重复计数器 在基本定时器和通用定时器中定时器发生上溢或者下溢时会直接生成更新事件。但有重复计数器的定时器并不完全这样在定时器每次发生上溢或下溢时重复计数器的值会减一当重复计数器的值为0时再发生一次上溢或者下溢才会生成定时器更新事件。如果我们设置重复计数器寄存器的RCR的值为N那么更新事件将在定时器发生N1次上溢或下溢时发生。 输出比较 与通用定时器相比高级定时器多了带死区控制的互补输出功能。通道1、2、3都有互补输出通道DTG是死区发生器死区时间由DTG[7:0]位来配置。如果不使用互补通道和死区时间控制那么高级定时器TIM1和TIM8和通用定时器的输出比较部分使用方法基本一样只是要注意MOE位得置1定时器才能输出。 断路功能 断路功能也称刹车功能一般用于控制电机的刹车。F1系列有一个断路通道断路源可以是刹车输入引脚TIMx_BKIN也可以是一个时钟失败事件。时钟失败事件由复位时钟控制器中的时钟安全系统产生。系统复位后断路功能默认被禁止MOE位为低。 2. 重复计数器特性 计数器每次上溢或下溢都能使重复计数器减1减到0时再发生一次溢出就会产生更新事件。 如果设置RCR为N更新事件将在N1次溢出时发生。 3. 相关寄存器 控制寄存器1TIMx_CR1 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 事件产生寄存器TIMx_EGR 重复计数器寄存器TIMx_RCR 捕获/比较寄存器1/2/3/4TIMx_CCR1/2/3/4 断路和死区寄存器TIMx_BDTR 4. 高级定时器输出指定个数PWM实验配置步骤 配置定时器基础工作参数 HAL_TIM_PWM_Init()定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()设置优先级使能中断 HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()使能定时器更新中断 __HAL_TIM_ENABLE_IT()使能输出、主输出、计数器 HAL_TIM_PWM_Start()编写中断服务函数 TIMx_IRQHandler() HAL_TIM_IRQHandler()编写更新中断回调函数 HAL_TIM_PeriodElapsedCallback()具体函数功能 函数主要寄存器主要功能HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_PWM_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_PWM_ConfigChannel()CCMRx、CCRx、CCER配置PWM模式、比较值、输出极性等__HAL_TIM_ENABLE_IT()CCER使能更新中断等HAL_TIM_PWM_Start()CCER、CR1使能输出、主输出、启动计数器HAL_TIM_IRQHandler()SR定时器中断处理公用函数处理各种中断HAL_TIM_PeriodElapsedCallback()无定时器更新中断回调函数由用户重定义HAL_TIM_GenerateEvent()EGR通过软件产生事件__HAL_TIM_ENABLE()CR1启动计数器 5. 代码实现 功能 通过TIM8CH1(由PC6复用)输出PWM,然后为了指示PWM的输出情况我们用杜邦线将PC6和PE5引脚的排针连接起来从而实现PWM输出控制LED1(硬件已连接在PPE5引脚上)的亮灭。注意的点是PE5要设置成浮空输入避免引脚冲突我们在main函数中设置好了请看源码。上电默认输出5个PWM波连接好杜邦线后可以看见LED1亮灭五次。之后按一下按键KEYO,就会输出5个PWM波控制LED1亮灭五次。LED0闪烁提示系统正在运行。 高级定时器输出指定个数PWM初始化 void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_npwm_chy {0};g_timx_npwm_chy_handle.Instance TIM8;g_timx_npwm_chy_handle.Init.Prescaler psc;g_timx_npwm_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP; //向上计数模式g_timx_npwm_chy_handle.Init.Period arr;g_timx_npwm_chy_handle.Init.RepetitionCounter 0; //重复计数器初始值g_timx_npwm_chy_handle.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; /*使能TIMx_ARR进行缓冲 */HAL_TIM_PWM_Init(g_timx_npwm_chy_handle);timx_oc_npwm_chy.OCMode TIM_OCMODE_PWM1; //使用PWM1工作模式timx_oc_npwm_chy.Pulse arr / 2; //占空比设置为50%timx_oc_npwm_chy.OCPolarity TIM_OCPOLARITY_HIGH; //高电平有效HAL_TIM_PWM_ConfigChannel(g_timx_npwm_chy_handle, timx_oc_npwm_chy, TIM_CHANNEL_1); //进行初始化__HAL_TIM_ENABLE_IT(g_timx_npwm_chy_handle, TIM_IT_UPDATE); //允许更新中断HAL_TIM_PWM_Start(g_timx_npwm_chy_handle, TIM_CHANNEL_1); //开启对应的PWM通道 }高级定时器输出指定个数PWM MSP回调函数 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM8){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_TIM8_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_6;gpio_init_struct.Pull GPIO_PULLUP;gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH;gpio_init_struct.Mode GPIO_MODE_AF_PP;HAL_GPIO_Init(GPIOC, gpio_init_struct);HAL_NVIC_SetPriority(TIM8_UP_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);} }高级定时器设置PWM个数函数 void atim_timx_npwm_chy_set(uint8_t npwm) {if(npwm 0) return;g_npwm_remain npwm; //保存脉冲个数HAL_TIM_GenerateEvent(g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); //产生一次软件更新事件在中断里面处理脉冲输出__HAL_TIM_ENABLE(g_timx_npwm_chy_handle); //使能定时器TIM8 }定时器8中断服务函数 void TIM8_UP_IRQHandler(void) {HAL_TIM_IRQHandler(g_timx_npwm_chy_handle); }定时器更新中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(htim-Instance TIM8){if(g_npwm_remain){TIM8-RCR g_npwm_remain - 1;HAL_TIM_GenerateEvent(g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE);__HAL_TIM_ENABLE(g_timx_npwm_chy_handle);g_npwm_remain 0;}else{TIM8-CR1 ~(1 0);}} }主函数 void LED_init(void) {GPIO_InitTypeDef gpio_init_struct;gpio_init_struct.Pin GPIO_PIN_5;gpio_init_struct.Mode GPIO_MODE_INPUT; //设置为输入防止冲突(PC6)gpio_init_struct.Speed GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOE, gpio_init_struct); }int main(void) {uint8_t t 0;uint8_t key 0;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */ // usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */key_init();LED_init(); //需要重新配置PE5为输入模式防止冲突atim_timx_npwm_chy_init(5000 -1, 7200 - 1);atim_timx_npwm_chy_set(5); while(1){key key_scan(0);if(key 4){atim_timx_npwm_chy_set(6);}t;if(t 50){t 0;LED0_TOGGLE();}delay_ms(10);} } 七、高级定时器输出比较模式实验 1. 输出比较模式功能 输出比较模式下翻转功能作用是当计数器的值等于捕获/比较寄存器影子寄存器的值时 OC1REF发生翻转进而控制通道输出(OCx)翻转。通过翻转功能实现输出PWM的具体原理如下PWM频率由自动重载寄存器(TIMx_ARR)的值决定在这个过程中只要自动重载寄存器的值不变那么PWM占空比就固定为50%。可以通过捕获/比较寄存器(TIMx_CCRx)的值改变PWM的相位。 2. 相关寄存器 控制寄存器1TIMx_CR1 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 捕获/比较寄存器1/2/3/4TIMx_CCR1/2/3/4 TIM1/TIM8断路和死区寄存器TIMx_BDTR 3. 高级定时器输出比较模式实验配置步骤 配置定时器基础工作参数 HAL_TIM_OC_Init()定时器输出比较MSP初始化 HAL_TIM_OC_MspInit() 配置输出比较模式等 HAL_TIM_OC_ConfigChannel()使能通道预装载 __HAL_TIM_ENABLE_OCxPRELOAD()使能输出、主输出、计数器 HAL_TIM_OC_Start()修改捕获/比较寄存器的值 __HAL_TIM_SET_COMPARE()具体函数功能 函数主要寄存器主要功能HAL_TIM_OC_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_OC_MspInit无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_OC_ConfigChannel()CCMRx、CCRx、CCER设置输出比较模式、比较值、输出极性等__HAL_TIM_ENABLE_OCxPRELOAD()CCMRx使能通道预装载HAL_TIM_OC_Start()CR1、CCER、BDTR使能输出比较、主输出、启动计数器__HAL_TIM_SET_COMPARE()CCRx修改捕获/比较寄存器的值 4. 代码实现 功能 使用输出比较模式的翻转功能通过定时器8的4路通道输出占空比固定为50%、相位分别是25%、50%、75%和100%的PWM。 高级定时器输出比较初始化 void atim_timx_comp_pwm_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_comp_pwm {0};g_timx_comp_pwm_handle.Instance TIM8;g_timx_comp_pwm_handle.Init.Prescaler psc;g_timx_comp_pwm_handle.Init.CounterMode TIM_COUNTERMODE_UP; //向上计数模式g_timx_comp_pwm_handle.Init.Period arr;g_timx_comp_pwm_handle.Init.RepetitionCounter 0; //重复计数器初始值HAL_TIM_PWM_Init(g_timx_comp_pwm_handle);timx_oc_comp_pwm.OCMode TIM_OCMODE_TOGGLE; //模式选择翻转timx_oc_comp_pwm.OCPolarity TIM_OCPOLARITY_HIGH; //极性选择高电平HAL_TIM_OC_ConfigChannel(g_timx_comp_pwm_handle, timx_oc_comp_pwm, TIM_CHANNEL_1);HAL_TIM_OC_ConfigChannel(g_timx_comp_pwm_handle, timx_oc_comp_pwm, TIM_CHANNEL_2);HAL_TIM_OC_ConfigChannel(g_timx_comp_pwm_handle, timx_oc_comp_pwm, TIM_CHANNEL_3);HAL_TIM_OC_ConfigChannel(g_timx_comp_pwm_handle, timx_oc_comp_pwm, TIM_CHANNEL_4);//使能通道预装载__HAL_TIM_ENABLE_OCxPRELOAD(g_timx_comp_pwm_handle, TIM_CHANNEL_1);__HAL_TIM_ENABLE_OCxPRELOAD(g_timx_comp_pwm_handle, TIM_CHANNEL_2);__HAL_TIM_ENABLE_OCxPRELOAD(g_timx_comp_pwm_handle, TIM_CHANNEL_3);__HAL_TIM_ENABLE_OCxPRELOAD(g_timx_comp_pwm_handle, TIM_CHANNEL_4);//使能输出、主输出、计数器HAL_TIM_OC_Start(g_timx_comp_pwm_handle, TIM_CHANNEL_1);HAL_TIM_OC_Start(g_timx_comp_pwm_handle, TIM_CHANNEL_2);HAL_TIM_OC_Start(g_timx_comp_pwm_handle, TIM_CHANNEL_3);HAL_TIM_OC_Start(g_timx_comp_pwm_handle, TIM_CHANNEL_4); }定时器输出比较MSP函数 void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM8){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_TIM8_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();gpio_init_struct.Mode GPIO_MODE_AF_PP; //推挽复用gpio_init_struct.Pin GPIO_PIN_6;gpio_init_struct.Pull GPIO_NOPULL; //没有上下拉gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOC, gpio_init_struct);gpio_init_struct.Pin GPIO_PIN_7;HAL_GPIO_Init(GPIOC, gpio_init_struct);gpio_init_struct.Pin GPIO_PIN_8;HAL_GPIO_Init(GPIOC, gpio_init_struct);gpio_init_struct.Pin GPIO_PIN_9;HAL_GPIO_Init(GPIOC, gpio_init_struct);} }主函数 int main(void) {uint8_t t 0;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */key_init();atim_timx_comp_pwm_init(1000 - 1, 72 - 1);__HAL_TIM_SET_COMPARE(g_timx_comp_pwm_handle, TIM_CHANNEL_1, 250 - 1);__HAL_TIM_SET_COMPARE(g_timx_comp_pwm_handle, TIM_CHANNEL_2, 500 - 1);__HAL_TIM_SET_COMPARE(g_timx_comp_pwm_handle, TIM_CHANNEL_3, 750 - 1);__HAL_TIM_SET_COMPARE(g_timx_comp_pwm_handle, TIM_CHANNEL_3, 1000 - 1);while(1){ t;if(t 50){t 0;LED0_TOGGLE();}delay_ms(10);} } 程序运行结果 八、高级定时器互补输出带死区控制实验 1. 互补死区的理解 互补输出 ​ CH1输出黄色的PWM互补通道CH1N输出绿色的PWM两个信号恰好是相反的CH1的PWM为高电平期 间CH1N的PWM则是低电平反之亦然这就是互补输出。 带死区控制的互补输出 CH1输出的PWM和CH1N输出的PWM在高低电平转换期间插入了一段时间才实现互补输出。这段时间称为死区时间。上图箭头所指的区域就是死区时间两段时间相同。 死区互补控制H桥 当Q1和Q4导通电流的方向是从左到右当Q2和Q3导通电流的方向是从右到左。因为元器件具有延时特性控制信号经过OC1传输到电机需要一定的时间。由于元器件的特性就会直接导致直接使用互补输出信号驱动H桥存在短路现象。为了避免这种情况就有了带死区控制的互补输出来驱动H桥。用户必须根据与输出相连接的器件及其特性电平转换器的固有延迟、开关器件产生的延迟来调整死区时间。 死区时间计算 2. 相关寄存器 控制寄存器1TIMx_CR1 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 捕获/比较寄存器1/2/3/4TIMx_CCR1/2/3/4 TIM1/TIM8断路和死区寄存器TIMx_BDTR 对应的结构框图 刹车断路功能 发生刹车后 3. 高级定时器互补输出带死区控制实验配置步骤 配置定时器基础工作参数 HAL_TIM_PWM_Init()定时器PWM输出MSP初始化 HAL_TIM_PWM_MspInit() 配置PWM模式/比较值等 HAL_TIM_PWM_ConfigChannel()配置刹车功能、死区时间等 HAL_TIMEx_ConfigBreakDeadTime()使能输出、主输出、计数器 HAL_TIM_PWM_Start()使能互补输出、主输出、计数器 HAL_TIMEx_PWMN_Start()相关函数功能 函数主要寄存器主要功能HAL_TIM_PWM_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_PWM_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_PWM_ConfigChannel()CCMRx、CCRx、CCER配置PWM模式、比较值、输出极性等HAL_TIMEx_ConfigBreakDeadTime()BDTR配置刹车功能、死区时间等HAL_TIM_PWM_Start()CCER、CR1使能输出、主输出、启动计数器HAL_TIMEx_PWMN_Start()CCER、CR1使能互补输出、主输出、启动计数器 4. 代码实现 功能 利用TIM1_CH1(PE9)输出70%占空比的PWM波它的互补输出通道(PE8)则是输出30%占空比的PWM波。刹车功能当给刹车输入引脚(PE15)输入高电平时进行刹车即PE8和PE9停止输出PWM波。LED0闪烁指示程序运行。 高级定时器互补输出初始化函数 void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_cplm_pwm {0};g_timx_cplm_pwm_handle.Instance TIM1; //定时器选择g_timx_cplm_pwm_handle.Init.Prescaler psc; //定时器分频g_timx_cplm_pwm_handle.Init.Period arr;g_timx_cplm_pwm_handle.Init.CounterMode TIM_COUNTERMODE_UP; //定时器计数模式g_timx_comp_pwm_handle.Init.ClockDivision TIM_CLOCKDIVISION_DIV4; //CKD[1:0] 10HAL_TIM_PWM_Init(g_timx_cplm_pwm_handle); //初始化PWMtimx_oc_cplm_pwm.OCMode TIM_OCMODE_PWM1; //模式选择PWM模式1timx_oc_cplm_pwm.OCPolarity TIM_OCPOLARITY_HIGH; //OC1高电平有效timx_oc_cplm_pwm.OCNPolarity TIM_OCPOLARITY_HIGH; //OC1N高电平有效timx_oc_cplm_pwm.OCIdleState TIM_OCIDLESTATE_RESET; //当MOE 0, OC1 1;timx_oc_cplm_pwm.OCNIdleState TIM_OCNIDLESTATE_RESET;//当MOE 0, OC1x 1;HAL_TIM_PWM_ConfigChannel(g_timx_cplm_pwm_handle, timx_oc_cplm_pwm, TIM_CHANNEL_1);//设置死区参数g_sbreak_dead_time_config.OffStateRunMode TIM_OSSR_DISABLE; //运行模式下的关闭状态选择g_sbreak_dead_time_config.OffStateIDLEMode TIM_OSSI_DISABLE; //空闲模式下的关闭状态选择g_sbreak_dead_time_config.LockLevel TIM_LOCKLEVEL_OFF; //寄存器锁定配置g_sbreak_dead_time_config.BreakState TIM_BREAK_ENABLE; //断路输入使能控制g_sbreak_dead_time_config.BreakPolarity TIM_BREAKPOLARITY_HIGH; //断路输入极性g_sbreak_dead_time_config.AutomaticOutput TIM_AUTOMATICOUTPUT_ENABLE; //自动恢复输出使能控制HAL_TIMEx_ConfigBreakDeadTime(g_timx_cplm_pwm_handle, g_sbreak_dead_time_config);HAL_TIM_PWM_Start(g_timx_cplm_pwm_handle, TIM_CHANNEL_1); //启动定时器的正常输出HAL_TIMEx_PWMN_Start(g_timx_cplm_pwm_handle, TIM_CHANNEL_1); //启动定时器的互补输出 }定时器设置输出比较值死区时间 void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg) {//设置比较寄存器的值__HAL_TIM_SET_COMPARE(g_timx_cplm_pwm_handle, TIM_CHANNEL_1, ccr);//单独进行死区时间的设置g_sbreak_dead_time_config.DeadTime dtg;HAL_TIMEx_ConfigBreakDeadTime(g_timx_cplm_pwm_handle, g_sbreak_dead_time_config); }主函数 int main(void) {uint8_t t 0;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */key_init();//设置1khz的周期atim_timx_cplm_pwm_init(1000 - 1, 72 - 1);//设置TIM捕获比较寄存器值,从而控制占空比为70%atim_timx_cplm_pwm_set(700 - 1, 100);while(1){ t;if(t 50){t 0;LED0_TOGGLE();}delay_ms(10);} } 程序运行流程 程序运行结果 九、高级定时器PWM输入模式实验 1. PWM输入工作原理 确定定时器的时钟源本代码使用内部时钟CK_INT时钟频率为72MHz计数频率确定了测量精度。确定PWM输入的通道PWM输入模式下测量PWMPWM信号输入只能从通道1或通道2输入。确定IC1和IC2的捕获边沿以通道 1CH1输入 PWM 为例一般设置 IC1 捕获边沿为上升沿捕获IC2 捕获边沿为下降沿捕获。选择触发输入信号选择TI1FP1或TI2FP2。从模式选择复位模式在出现所选触发输入TRGI上升沿时重新初始化计数器并生成一个寄存器更新事件。读取一个PWM周期内计数器的计数个数以及高电平期间计数个数再结合计数器的计数周期最终通过计算得到输入的PWM周期和占空比等参数。 2. 输入模式时序图 假设计数器的计数频率是72MHz那我们就可以计算出PWM的周期、频率和占空比等参数。由计数器的计数频率为72Hz可以得到计数器计一个数的时间是13.8ns(即测量的精度是13.8ns)。知道了测量精度再来计算PWM的周期PWM周期(41)*(1/72000000)69.4ns那么PWM的频率就是14.4MHz。占空比 (21)/(41)3/5(即占空比为60%)。 3. 相关寄存器 从模式控制寄存器TIMx_SMCR 捕获/比较模式寄存器1/2TIMx_CCMR1/2 捕获/比较使能寄存器TIMx_CCER 捕获/比较寄存器1/2/3/4TIMx_CCR1/2/3/4 DMA中断使能寄存器TIMx_DIER 4. 高级定时器PWM输入模式实验配置步骤 配置定时器基础工作参数 HAL_TIM_IC_Init()定时器捕获输入MSP初始化 HAL_TIM_IC_MspInit()配置IC1/2映射、捕获边沿等 HAL_TIM_IC_ConfigChannel()配置从模式触发源等 HAL_TIM_SlaveConfigSynchro()设置优先级使能中断 HAL_NVIC_SetPriority() HAL_NVIC_EnableIRQ()使能捕获、捕获中断及计数器 HAL_TIM_IC_Start_IT() HAL_TIM_IC_Start()编写中断服务函数 TIMx_IRQHandler()编写输入捕获回调函数 HAL_TIM_IC_CaptureCallback()函数具体功能 函数主要寄存器主要功能HAL_TIM_IC_Init()CR1、ARR、PSC初始化定时器基础参数HAL_TIM_IC_MspInit()无存放NVIC、CLOCK、GPIO初始化代码HAL_TIM_IC_ConfigChannel()CCMRx、CCER配置通道映射、捕获边沿、分频、滤波等HAL_TIM_SlaveConfigSynchro()SMCR、CCER配置从模式、触发源、触发边沿等HAL_TIM_IC_Start_IT()CCER、DIER、CR1使能输入捕获、捕获中断并启动计数器HAL_TIM_IRQHandler()SR定时器中断处理公用函数处理各种中断HAL_TIM_IC_CaptureCallback()无定时器输入捕获回调函数由用户重定义 4. 代码实现 功能 首先通过TM3_CH2(PB5)输出PWM波。然后把PB5输出的PWM波用杜邦线接入PC6(定时器8通道1)最后通过串口打印PWM波的脉宽和频率等信息。通过LED1闪烁来提示程序正在运行。 通用定时器PWM输出初始化函数 void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc) {TIM_OC_InitTypeDef timx_oc_pwm_chy;g_timx_pwm_chy_handle.Instance TIM3;g_timx_pwm_chy_handle.Init.Prescaler psc;g_timx_pwm_chy_handle.Init.Period arr;g_timx_pwm_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP;HAL_TIM_PWM_Init(g_timx_pwm_chy_handle);timx_oc_pwm_chy.OCMode TIM_OCMODE_PWM1;timx_oc_pwm_chy.Pulse arr / 2;timx_oc_pwm_chy.OCPolarity TIM_OCPOLARITY_LOW;HAL_TIM_PWM_ConfigChannel(g_timx_pwm_chy_handle, timx_oc_pwm_chy, TIM_CHANNEL_2);HAL_TIM_PWM_Start(g_timx_pwm_chy_handle, TIM_CHANNEL_2); }定时器输出PWM MSP初始化函数 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM3){GPIO_InitTypeDef gpio_init_struct;__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_TIM3_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_5;gpio_init_struct.Mode GPIO_MODE_AF_PP; /* 推挽复用 */gpio_init_struct.Pull GPIO_PULLUP; /* 上拉 */gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH; /* 高速 */HAL_GPIO_Init(GPIOB, gpio_init_struct);__HAL_RCC_AFIO_CLK_ENABLE();__HAL_AFIO_REMAP_TIM3_PARTIAL();} }PWM输入模式初始化函数 void atim_timx_pwmin_chy_init(void) {TIM_SlaveConfigTypeDef slave_config {0};TIM_IC_InitTypeDef tim_ic_pwmin_chy {0};g_timx_pwmin_chy_handle.Instance TIM8; /* 定时器8 */g_timx_pwmin_chy_handle.Init.Prescaler 0; /* 定时器预分频系数 */g_timx_pwmin_chy_handle.Init.CounterMode TIM_COUNTERMODE_UP; /* 递增计数模式 */g_timx_pwmin_chy_handle.Init.Period 65535; /* 自动重装载值 */HAL_TIM_IC_Init(g_timx_pwmin_chy_handle);/* 从模式配置IT1触发更新 */slave_config.SlaveMode TIM_SLAVEMODE_RESET; /* 从模式复位模式 */slave_config.InputTrigger TIM_TS_TI1FP1; /* 定时器输入触发源TI1FP1 */slave_config.TriggerPolarity TIM_TRIGGERPOLARITY_RISING; /* 上升沿检测 */slave_config.TriggerFilter 0; /* 不滤波 */HAL_TIM_SlaveConfigSynchro(g_timx_pwmin_chy_handle, slave_config);/* IC1捕获上升沿触发TI1FP1 */tim_ic_pwmin_chy.ICPolarity TIM_ICPOLARITY_RISING; /* 上升沿检测 */tim_ic_pwmin_chy.ICSelection TIM_ICSELECTION_DIRECTTI; /* 选择输入端IC1映射到TI1 */tim_ic_pwmin_chy.ICPrescaler TIM_ICPSC_DIV1; /* 不分频 */tim_ic_pwmin_chy.ICFilter 0; /* 不滤波 */HAL_TIM_IC_ConfigChannel(g_timx_pwmin_chy_handle, tim_ic_pwmin_chy, TIM_CHANNEL_1);/* IC2捕获下降沿触发TI1FP2 */tim_ic_pwmin_chy.ICPolarity TIM_ICPOLARITY_FALLING; /* 下降沿检测 */tim_ic_pwmin_chy.ICSelection TIM_ICSELECTION_INDIRECTTI; /* 选择输入端IC2映射到TI1 */HAL_TIM_IC_ConfigChannel(g_timx_pwmin_chy_handle, tim_ic_pwmin_chy, TIM_CHANNEL_2);HAL_TIM_IC_Start_IT(g_timx_pwmin_chy_handle, TIM_CHANNEL_1);HAL_TIM_IC_Start(g_timx_pwmin_chy_handle, TIM_CHANNEL_2); }定时器输入捕获MSP初始化函数 void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) {if(htim-Instance TIM8){GPIO_InitTypeDef gpio_init_struct {0};__HAL_RCC_TIM8_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();gpio_init_struct.Pin GPIO_PIN_6;gpio_init_struct.Mode GPIO_MODE_AF_PP;gpio_init_struct.Pull GPIO_PULLDOWN;gpio_init_struct.Speed GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOC, gpio_init_struct);/* TIM1/TIM8有独立的输入捕获中断服务函数 */HAL_NVIC_SetPriority(TIM8_CC_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);} }定时器8输入捕获中断服务函数 void TIM8_CC_IRQHandler(void) {HAL_TIM_IRQHandler(g_timx_pwmin_chy_handle); /* 定时器共用处理函数 */ }PWM输入模式重新启动捕获函数 void atim_timx_pwmin_chy_restart(void) {sys_intx_disable(); /* 关闭中断 */g_timxchy_pwmin_sta 0; /* 清零状态,重新开始检测 */g_timxchy_pwmin_hval0;g_timxchy_pwmin_cval0;sys_intx_enable(); /* 打开中断 */ }定时器输入捕获中断处理回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if(htim-Instance TIM8){if(g_timxchy_pwmin_sta 0){if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1){g_timxchy_pwmin_hval HAL_TIM_ReadCapturedValue(g_timx_pwmin_chy_handle, TIM_CHANNEL_2) 1 1;g_timxchy_pwmin_cval HAL_TIM_ReadCapturedValue(g_timx_pwmin_chy_handle, TIM_CHANNEL_1) 1 1;g_timxchy_pwmin_sta 1;}}} }主函数 int main(void) {uint8_t t 0;double ht, ct, f, tpsc;HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */delay_init(72); /* 延时初始化 */usart_init(115200); /* 串口初始化为115200 */led_init(); /* 初始化LED */gtim_timx_pwm_chy_init(10 - 1, 72 - 1);TIM3-CCR2 3;atim_timx_pwmin_chy_init();while (1){delay_ms(10);t;if (t 20) /* 每200ms输出一次结果,并闪烁LED0,提示程序运行 */{if (g_timxchy_pwmin_sta) /* 捕获了一次数据 */{printf(\r\n); /* 输出空,另起一行 */printf(PWM PSC :%d\r\n, g_timxchy_pwmin_psc); /* 打印分频系数 */printf(PWM Hight:%d\r\n, g_timxchy_pwmin_hval); /* 打印高电平脉宽 */printf(PWM Cycle:%d\r\n, g_timxchy_pwmin_cval); /* 打印周期 */tpsc ((double)g_timxchy_pwmin_psc 1) / 72; /* 得到PWM采样时钟周期时间 */ ht g_timxchy_pwmin_hval * tpsc; /* 计算高电平时间 */ct g_timxchy_pwmin_cval * tpsc; /* 计算周期长度 */f (1 / ct) * 1000000; /* 计算频率 */printf(PWM Hight time:%.3fus\r\n, ht); /* 打印高电平脉宽长度 */printf(PWM Cycle time:%.3fus\r\n, ct); /* 打印周期时间长度 */printf(PWM Frequency :%.3fHz\r\n, f); /* 打印频率 */ atim_timx_pwmin_chy_restart(); /* 重启PWM输入检测 */} LED1_TOGGLE(); /* LED1GREEN闪烁 */t 0;}} }声明资料来源战舰STM32F103ZET6开发板资源包 Cortex-M3权威指南(中文).pdfSTM32F10xxx参考手册_V10中文版.pdfSTM32F103 战舰开发指南V1.3.pdfSTM32F103ZET6中文版.pdf战舰V4 硬件参考手册_V1.0.pdf
http://www.dnsts.com.cn/news/207629.html

相关文章:

  • 台州网站seo外包变化型网页网站有哪些
  • 网站通用样式如何写网站开发需求文档
  • 深圳微信网站制作wordpress 自动
  • 自己如何创建一个网站网站应急响应机制建设
  • 网站建设虚拟空间网站注册要多少钱
  • 国家示范校建设专题网站免费网站开发
  • 凡科做的网站行不行松滋网站定制
  • 在哪家网站做外贸比较好android手机app开发
  • dedecms 门户网站长沙装修公司排名前十口碑推荐
  • 网站托管代运营wordpress 首页 摘要 插件
  • 网站制作咨询在线排名优化工具
  • 陈欧做聚美优品网站国外购物平台网页界面设计
  • 政务信息网站建设方案2019长沙企业网站建设优惠
  • php网站视频代码品牌设计与vi设计的区别
  • 具有口碑的柳州网站建设推荐logo模板
  • 湖南专业做网站公司有哪些高品质网站开发
  • 全网站开发是什么网站推广活动
  • 苏州网站建设自助建站收费章丘灵通环保设备在哪个网站上做的
  • 遵义招标网问答网站如何优化
  • 改变wordpress表前缀网站做了泛解析 为什么影响seo
  • 网站建设色系搭配百度 新网站 重定向过多
  • 营销型网站建设培训私密浏览器免费看片在线看
  • 临沂市建设局网站怎样免费建设个人网站
  • 网站信息建设总结南昌网站建设模板技术公司
  • phpcms 投资 网站源码wordpress主题 html5
  • 网站建设与维护视频教程重庆公司免费网站建设
  • 常用网站开发技术网站改版重新收录
  • 企业网站建设818gxwordpress知更鸟主题
  • 网站漏洞wordpress 大神
  • 四川省住房和城乡建设网站为啥浏览做的网站有移动条