STM32多通道PWM输出及停止

STM32具有多个定时器,这里采用的是STM32F103C8T6高级定时器TIM1的四个通道(CH1,CH2,CH3,CH4)。

操作顺序

1.配置GPIO(根据stm32外设及其引脚映射,详解下方有图表)

2.配置TIM的PWM1模式

3.书写相应的函数

我们的目标是   

在PA8和PA9实现呼吸灯效果:1.PA8呼吸,PA9呼吸

                                                 2.PA8呼吸,PA9不呼吸


1。配置GPIO

由GPIO引脚映射表(下图)可知,TIM1的CH1---PA8,CH2---PA9,先拿这两个试试刀,我们的目标是在PA8和PA9实现呼吸灯效果:1.PA8呼吸,PA9呼吸

                                                 2.PA8呼吸,PA9不呼吸

 本图片来源于哔哩哔哩-江科大自化协-stm32入门教程资料,具体资料请移步哔哩哔哩-江科大自化协,如有侵权,请告知删除

由上图可知,在第29和30行,PA8引脚默认复用了USART1_CK和MCO和TIM1_CH1,PA9默认复用了USART1_TX和TIM1_CH2

故配置PA8和PA9为推挽输出模式

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//开启TIM1时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//推挽模式
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8 |GPIO_Pin_9;//配置PA8,PA9
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度选最快
	
	GPIO_Init (GPIOA ,&GPIO_InitStructure);

	

2.配置TIM1的pwm模式

首先是常规的定时器配置

先是ARR,PSC,CCR计算公式

 本图片来源于哔哩哔哩-江科大自化协-stm32入门教程资料,具体资料请移步哔哩哔哩-江科大自化协,如有侵权,请告知删除

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE );//开时钟
	TIM_InternalClockConfig (TIM1);//对不需要配置的项给默认值
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;//时钟分频
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;//向上计数
	TIM_TimeBaseInitStructure.TIM_Period=100-1;			//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;			//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit (TIM1 ,&TIM_TimeBaseInitStructure);

接下来是定时器输出(OC,即Output Compare)配置,然后分别是TIM1的CH1和CH2

		TIM_OCInitTypeDef TIM_OCInitStructure;//结构体初始化
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//开启PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//使能输出
	TIM_OCInitStructure.TIM_Pulse = 0;// 设置占空比大小,因为接下来的是OC1,所以是通道1的占空比
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);//TIM1的通道1
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能TIM1在CCR1(即通道1)上的预装载寄存器
	
	TIM_OCInitStructure.TIM_Pulse = 0;// 设置占空比大小	,同理是因为接下来的是OC2,所以是通道2的占空比
	TIM_OC2Init(TIM1, &TIM_OCInitStructure);//TIM1的通道2
	TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);//使能TIM1在CCR2(即通道2)上的预装载寄存器

这里我把两个通道的PWM都给了输出为0,后面可以再配置,如果你需要你可以先在这里配置,0-100的区间,因为我在上面是配置了ARR=99,PSC=719。

然后呢,是高级定时器必加函数和使能TIM1,配置了但是不工作可能是这个高级定时器使能函数没配TIM_CtrlPWMOutputs(TIM1, ENABLE);

	TIM_CtrlPWMOutputs(TIM1, ENABLE);//高级定时器必加
	
	TIM_Cmd (TIM1,ENABLE);//使能整个TIM1

以上就是void PWM_Init(void)的内容了,初始化配置ok

2.接下来是实现呼吸灯了,首先是介绍一个函数TIM_SetCompare1(TIM1,Compare );,它可以改变TIM1的pwm值,如果是TIM_SetCompare1,则是改变TIM1的通道1,若是TIM_SetCompare2,则是改变TIM1的通道2

先封装一下这个函数,便于理解

void PWM_Compare1(uint8_t Compare)	//PA8
{
		TIM_SetCompare1(TIM1,Compare );
}	

上面的Compare就是要改变的PWM占空比,0-100

对CH2一样封装

void PWM_Compare2(uint8_t Compare)	//PA9
{
		TIM_SetCompare2(TIM1,Compare );
}	

3.OK了,接下来是主函数

顺便提一下,uint8_t就是char,1字节

uint8_t i;
int main(void)
{
	PWM_Init();
	while(1)
	{
		for(i=0;i<100;i++)
		{
		PWM_Compare1(i);
			Delay_ms (10);
		}
		
 	}
}

对了还有Delay_ms()

void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}

以上是现象1代码,两灯同时呼吸

以下是现象2代码,红灯(PA8呼吸),黄灯(PA9)不亮,抱歉没有视频

uint8_t i;
int main(void)
{
	PWM_Init();
	while(1)
	{
		for(i=0;i<100;i++)
		{
		PWM_Compare1(i);	
		PWM_Compare2(i);
			Delay_ms (100);
		}
		
 	}
}

常见问题:1.没有添加

                     TIM_CtrlPWMOutputs(TIM1, ENABLE);//高级定时器必加
    
                     TIM_Cmd (TIM1,ENABLE);//使能整个TIM1

                  2.分别控制单通道需要分别应用不同OC1,OC2
                    TIM_OCInitStructure.TIM_Pulse = 0;
                    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
                    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
    
                    TIM_OCInitStructure.TIM_Pulse = 0;
                    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
                    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
                3.改变不同的通道的占空比(PWM)需要不同的TIM_SetCompare1(TIM1,Compare );

                        TIM_SetCompare1(TIM1,Compare );

                        TIM_SetCompare2(TIM1,Compare );

STM32 HAL库,要实现PA8引脚输出PWM信号,你需要按照以下步骤操作: 1. **初始化GPIO**: 首先,你需要初始化PA8所在的GPIO口,将其设置为推挽输出模式(GPIO_MODE_OUTPUT_PP),并关闭上拉电阻(GPIO_NOPULL)。例如: ```c GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_8; // PA8 pin GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // Push-Pull Output GPIO_InitStruct.Pull = GPIO_NOPULL; // No Pull-up or Pull-down HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); ``` 2. **初始化TIM**: 然后选择合适的定时器(如TIM2或TIM3),配置TIM_CHANNEL_1为PWM输出,并设置周期和占空比。这里假设你选择的是TIM2举例: ```c TIM_HandleTypeDef htim2; TIM_MasterConfigTypeDef sMasterConfig; // TIM2配置为PWM htim2.Instance = TIM2; htim2.Init.Prescaler = ...; // 根据你的需求设定预分频值 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = ...; // 设定周期,即最大计数值 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) Error_Handler(); sMasterConfig.MasterOutputState = TIM_MasterOutputState_Enable; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig); HAL_TIM_PWM_Init(&htim2); // 启动PWM模式 GPIO_InitStruct.Pin = GPIO_PIN_8; // Set the output channel GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // Configure the GPIO as alternate function push-pull GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF2_TIM2; // AF2映射到TIM2 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_TIM_PWM_ConfigChannel(&htim2, &htim2.Init.PwmOutput, TIM_CHANNEL_1); // 设置PA8为TIM2 Channel 1 ``` 3. **设置PWM频率和占空比**: 调用`HAL_TIM_PWM_SetCompare`设置每周期的高电平持续时间(占空比),然后`HAL_TIM_PWM_Start`启动PWM输出。 4. **更新占空比**: 如果需要动态改变占空比,通过`HAL_TIM_PWM_ChangeCompare`函数更新占空比值。 5. **清理资源**: 当不需要PWM输出时,记得释放资源,如关闭定时器和GPIO功能。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值