一. 使用STM32定时器通道pin连接LED,用定时器计数方式,控制LED以2s的频率周期性地亮-灭。
1.工程创建
2.设置RCC
选择CCR模式
3.设置SYS
选择Serial Wire
4.配置led灯
选中A1作为led的输出管脚
5.配置定时器
选择tim2,将Tim2的时钟源设置为Internal clock,设置分频系数为71,向上计数模式,计数周期为50000
6.配置NVIC
勾选时钟中断
7.配置时钟
将HCLK改为72
8.生成项目
9.代码编写
添加定时器启动代码
HAL_TIM_Base_Start_IT(&htim2); //打开定时器TIM2
重写定时器回调中断函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//灯亮一秒,灭一秒,则中断产生20次改变一次电平
static uint32_t time_cnt =0; //记录中断次数
if(htim->Instance == TIM2)
{
if(++time_cnt >= 20) //判断是否已经达到一秒
{
time_cnt =0; //点灯用的中断次数归零
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1); //改变LED所接引脚的电平
}
}
}
10.实验结果
二.采用定时器pwm模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒
1.工程创建
2.设置RCC
选择CCR模式
3.设置SYS
选择Serial Wire
4.设置TIM2
选择internal clock ,设置为 PWM Generation CH2, 分频系数设置为71,计数模式设置为Up,Counter Period 设置为500
5.设置NVIC
6.配置USART1
7.配置时钟
8.创建项目
9.代码编写
创建全局变量
uint16_t pwm=0; //占空比
开启TIM2的PWM的通道2
在main主函数中添加如下代码
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
在主函数 while 循环里加入如下代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
while(pwm<500)
{
pwm = pwm + 10;
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
HAL_Delay(20);//延时20毫秒
}
while(pwm>0)
{
pwm = pwm - 10;
__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
HAL_Delay(20);
}
}
10.实验效果
11.观察波形
(1).点开魔法棒工具
(2).设置debug相关
(3).点击开始调试
(4).打开symbol view窗口
(5).输入PORTA.1
(6).点击开始查看波形
三.采用定时器的另外一个通道,编程采集上面的pwm输出信号,获得其周期和脉宽,并重定向输出到串口显示
1.工程建立
2.设置RCC
选择CCR模式
3.设置SYS
选择Serial Wire
3.配置tim1、2、3
4.配置USART1
5.创建项目
6.代码编写
在usart.c和main.c中添加头文件
#include "string.h"
#include "stdio.h"
重定义printf函数和相关配置
在主函数下面定义:
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
定义全局变量
uint8_t i = 0;
float Duty = 0;
float Frequency = 0;
uint16_t Cap_val1 = 0;
uint16_t Cap_val2 = 0;
mian主函数编写
在while(1)前添加
printf("串口通信测试\r\n");
HAL_TIM_Base_Start_IT(&htim2); // 使能定时器及其更新中断
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 使能定时器及其PWM输出
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); // 使能定时器及其输入捕获
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); // 使能定时器及其输入捕获
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 10); // 设置一个PWM波形进行测量
在while(1)循环中添加
// 串口发送 频率 占空比
printf("Cap_val1 is :%d , Cap_val2 is : %d \r\n", Cap_val1, Cap_val2);
printf("Duty is :%0.2f%% Frequency is : %0.2f ms\r\n", Duty, Frequency);
HAL_Delay(1000);
添加捕获回调函数
// 定时输入捕获回调函数 计算占空比和频率
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM1)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
Cap_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
}
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
{
Cap_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
Duty = 100 - (float)Cap_val2 / (float)Cap_val1 * 100;
Frequency = 0.001 * Cap_val1;
}
}
}