普中STM32F103ZET6 使用 TIM4 的 CH3 通道输出 PWM控制蜂鸣器声音大小。

STM32F10xxx参考手册–119页
在这里插入图片描述

#include "pwm.h"

/*******************************************************************************
* 函 数 名         : TIM3_CH2_PWM_Init
* 函数功能		   : TIM3通道2 PWM初始化函数
* 输    入         : per:重装载值
					 psc:分频系数
* 输    出         : 无
*******************************************************************************/
void TIM3_CH2_PWM_Init(u16 per,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//改变指定管脚的映射,TIM3_CH2--->> PB5	
	
	TIM_TimeBaseInitStructure.TIM_Period = per;//自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置向上计数模式
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OC2Init(TIM3,&TIM_OCInitStructure);//输出比较通道2初始化
	
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR2 上的预装载寄存器
	TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器
	
	TIM_Cmd(TIM3,ENABLE);//使能定时器
}

void TIM4_CH3_PWM_Init(u16 per,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);//改变指定管脚的映射,TIM3_CH2->>本来就是TIM4_REMAP = 0,所以重映射默认就是PB8,如果设置以后就变成PD14
	
	TIM_TimeBaseInitStructure.TIM_Period = per;//自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置向上计数模式
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OC3Init(TIM4,&TIM_OCInitStructure);//输出比较通道2初始化
	
	TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能TIMx在 CCR2 上的预装载寄存器
	TIM_ARRPreloadConfig(TIM4,ENABLE);//使能预装载寄存器
	
	TIM_Cmd(TIM4,ENABLE);//使能定时器
}



#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "time.h"
#include "pwm.h"


int main()
{
	u16 i=0;
	u8 fx=0;
	
	SysTick_Init(72);//Tclk=72
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组 分 2 组
	
	LED_Init();
	BEEP_Init();

//	TIM3_CH2_PWM_Init(500,72-1);//定时500us,Tout= ((per)*(psc+1))/Tclk=(500*72)/72000000=5/100000s=500us
	TIM4_CH3_PWM_Init(1000,72-1);
	
	while(1)
	{

		if(fx==0)
		{
			i++;
			if(i==500)
			{
				fx=1;
			}
		}
		else
		{
			i--;
			if(i==0)
			{
				fx=0;
			}
		}
			//TIM_SetCompare2(TIM3,i);//i值最大可以取499,因为ARR最大值是499.
			TIM_SetCompare3(TIM4,i);
			delay_ms(10);	
	}
}

//GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);
//改变指定管脚的映射,TIM3_CH2->>本来就是TIM4_REMAP = 0,所以重映射默认就是PB8,如果设置以后就变成PD14

  • 6
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
步骤如下: 1. 打开STM32CubeMX软件,在Pinout选项卡中将PF4配置为TIM5_CH4功能。 2. 在Configuration选项卡中,选择TIM5,并启用PWM输出模式。 3. 配置TIM5的时钟源和分频系数,以及PWM的周期和占空比。 4. 在代码中初始化TIM5,并启用PWM输出。 5. 在主循环中更新PWM占空比,以改变输出波形。 下面是示例代码: ``` #include "stm32f1xx_hal.h" TIM_HandleTypeDef htim5; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM5_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM5_Init(); HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_4); while (1) { // Update PWM duty cycle to change output waveform __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, 500); HAL_Delay(1000); __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, 1000); HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_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(); } 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(); } } static void MX_TIM5_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim5.Instance = TIM5; htim5.Init.Prescaler = 7199; htim5.Init.CounterMode = TIM_COUNTERMODE_UP; htim5.Init.Period = 999; htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_PWM_Init(&htim5) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim5); } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOF_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); } void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim_pwm) { if (htim_pwm->Instance == TIM5) { __HAL_RCC_TIM5_CLK_ENABLE(); } } void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (htim->Instance == TIM5) { __HAL_RCC_GPIOF_CLK_ENABLE(); /**TIM5 GPIO Configuration PF4 ------> TIM5_CH4 */ GPIO_InitStruct.Pin = GPIO_PIN_4; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); } } void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim_pwm) { if (htim_pwm->Instance == TIM5) { __HAL_RCC_TIM5_CLK_DISABLE(); } } void Error_Handler(void) { while (1) { } } ``` 在上面的示例代码中,PWM的周期为10ms,占空比从50%到100%不断变化,即输出的波形周期为10ms,高电平占空比从50%到100%不断变化。可以根据需要修改周期和占空比,以输出不同的波形。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值