第七周-定时器&PWM练习


一.STM32定时器中断

1.定时器简介

(1)什么是定时器
字面上理解是用来定时的机器,是存在于STM32单片机中的一个外设。STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM5、TIM6)。

(2)通用定时器功能
STM32的众多定时器中我们使用最多的是高级定时器和通用定时器,而高级定时器一般也是用作通用定时器的功能,其功能和特点包括:
位于低速的APB1总线上(APB1)
16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。
16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。
4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
① 输入捕获② 输出比较③ PWM 生成(边缘或中间对齐模式)④ 单脉冲模式输出

(3)计数模式
通用定时器可以向上计数、向下计数、向上向下双向计数模式。\n①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。\n②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

(4)定时器计数方法

Tout = ((arr+1)(psc+1))/Tclk ;
Tclk:定时器的输入时钟频率(单位MHZ)
Tout:定时器溢出时间(单位为us)
arr: 计数装载值\npsc: 时钟分频系数


2.CubeMX初始化设置

(1)芯片选用ATM32F103C8T6
(2)时钟配置
选择外部时钟,选择时钟源
在这里插入图片描述
在这里插入图片描述

(3)TIM2中断初始化
TIM2选择外部时钟作为时钟源,APB1时钟频率为72M,经过PSC72分频后定时器时钟频率为1Mhz,计数周期5000计满时间为0.005S,计数方式为向上计数。
在这里插入图片描述
打开定时中断器
在这里插入图片描述

(4)外设模块初始化
设PA3为GPIO_Outout
在这里插入图片描述
初始化USART1串口
在这里插入图片描述

(5)工程导出

3.编写代码

生成工程后打开,添加中断响应之后所需要的代码,在main.c文件中添加如下内容

extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart1;
uint8_t hello[]="hello windows!\r\n";   //串口发送字符串

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint16_t time_cnt1 =0;
	static uint16_t time_cnt2 =0;
	time_cnt1++;
	time_cnt2++;
	if(time_cnt1==400)
	{
	  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_3);
		time_cnt1=0;
	}
	if(time_cnt2==1000)
	{
		HAL_UART_Transmit(&huart1,hello,sizeof(hello),100);
		time_cnt2=0;
	}
}



4.效果展示

在这里插入图片描述

定时器呼吸灯

二、STM32呼吸灯(基于PWM脉冲宽度调制)

1.PWM简介

1.基本介绍
PWM(Pulse Width Modulation)即脉冲宽度调制,简称脉宽调制。它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术;它是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。PWM就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。

2.工作原理
STM32的每个通用定时器都有独立的4个通道可以用来作为:输入捕获、输出比较、PWM输出、单脉冲模式输出等。STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM输出。其中,高级定时器TIM1、TIM8可以同时产生7路PWM输出。PWM的工作模式:PWM模式1(向上计数) :计数器从0计数加到自动重装载值(TIMx_ARR),然后重新从0开始计数,并且产生一个计数器溢出事件PWM模式2(向下计数)计数器从自动重装载值(TIMx_ARR)减到0,然后重新从重装载值(TIMx_ARR)开始递减,并且产生一个计数器溢出事件
计数模式
在PWM输出模式下,除了CNT(计数器当前值)、ARR(自动重装载值)之外,还多了一个值CCRx(捕获/比较寄存器值)。当CNT小于CCRx时,TIMx_CHx通道输出低电平;当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平。
PWM的一个周期
定时器从0开始向上计数
当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数…循环此过程
至此一个PWM周期完成

2.CubeMX配置

(1)创建工程
在这里插入图片描述

(2)选取STM32F103C8T6芯片
在这里插入图片描述

(3)打开外部时钟,选择Crystal/Ceramic Resonator
在这里插入图片描述

(4)然后选择SYS,进行设置
在这里插入图片描述

(5)配置定时器3和4,如图选中TIM3,选择时钟源为Internal Clock,通道二选择PWMGeneration CH2。设置分频系数为71,计数周期为500。TIM4同样设置。
在这里插入图片描述

然后进行时钟配置
在这里插入图片描述

填写项目名和存储路径,勾选相应选项然后生成工程文件。
在这里插入图片描述
在这里插入图片描述

3.编写代码

修改main.c文件,定义两个变量存储占空比:添加在main函数外。

uint16_t duty_num1 = 10;   //存储占空比
uint16_t duty_num2 = 10;


在main函数里面添加如下代码,开启TIM3、TIM4的通道2,输出PWM。

//开启TIM3和TIM4的通道2,输出PWM
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);  
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);

在while循环里添加代码如下

	HAL_Delay(50);
		duty_num1 = duty_num1 + 10;
		duty_num2 = duty_num1 + 20;
		if(duty_num1 > 500)
		{
			duty_num1 = 0;
		}
		if(duty_num2 > 500)
		{
			duty_num2 = 0;
		}
		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,duty_num1);
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_2,duty_num2);
  }

main.c文件里的全部代码


#include "main.h"
#include "tim.h"
#include "gpio.h"


uint16_t duty_num1 = 10;   //存储占空比
uint16_t duty_num2 = 10;

void SystemClock_Config(void);
	
int main(void)
{
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);  //开启TIM3和TIM4的通道2,输出PWM
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
		while (1)
  {
		HAL_Delay(50);
		duty_num1 = duty_num1 + 10;
		duty_num2 = duty_num1 + 10;
		if(duty_num1 > 500)
		{
			duty_num1 = 0;
		}
		if(duty_num2 > 500)
		{
			duty_num2 = 0;
		}
		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,duty_num1);
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_2,duty_num2);
  }
  /* USER CODE END 3 */
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

4.效果展示

电路连接

在这里插入图片描述

呼吸灯

三、总结

这次实验又让我了解了有关与PWN的有关知识,就比如说PWM的有效电平我们可以自己设置等。在电路连接过程中也挺顺畅的,因为前几次的电路连接也让我非常的熟练。但在配置过程中要注意一些小细节。也始终定时学会了定时器的一些功能,了解到了一些它的原理,定时器的中断是通过设计达到设定值时触发中断,进行中断服务函数的处理函数,定时器中断相比软件延时更准确。通过此次实验,自己真的感觉学到了很对,收获很大

四.参考链接

http://www.mcublog.cn/stm32/2021_01/stm32cubemx-pwm-huxideng/

http://www.mcublog.cn/stm32/2021_01/stm32cubemx-dingshiqi-led/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值