STM32单片机-PWM波形输出

目录:

一、引脚映像与寄存器

1、定时器引脚复用功能映像

2、定时器

1)定时器介绍   2)定时器时钟分割

二、定时器PWM产生原理

三、STM32产生PWM的配置


一、引脚映像与寄存器

1、定时器引脚复用功能映像

2、定时器

1)定时器介绍

STM32中一共有11个定时器,其中TIM6、TIM7是基本定时器;TIM2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器,以及2个看门狗定时器和1个系统嘀嗒定时器SysTick。

其中TIM1和TIM8能够产生3对WM互补输出,常用于三相电机的驱动,时钟由APB2的输出产生;

TIM2~TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。

--------------------------------

2)定时器时钟分割

这三种不同的采样频率基准是通过设置控制寄存器TIMx_CR1中的CKD(时钟分频因子)来实现的,手册上有详细的说明:

TIM_TimeBaseStructure.TIM_ClockDivision = 0;  //设置时钟分割:TDTS = Tck_tim
//等同于
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //设置时钟分割:TDTS = Tck_tim
STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上和外部触发输入通路上,它们的作用是滤除输入信号上的高频干扰。

二、定时器PWM产生原理

通用定时器可以利用GPIO引脚进行脉冲输出,配置为比较输出、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。

举例说明定时器的PWM输出工作过程:

若配置脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR被配置为N,即TIMx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。

而在TIMx_CNT计数的同时,TIMx_CNT计数值X会与比较寄存器TIMx_CCR预先存储的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(低电平);反之,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(高电平)。

如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,输出PWM占空比:A/(N+1) 。

三、STM32产生PWM的配置

根据以上重映像表,我们使用定时器3的通道2作为PWM的输出引脚,所以需要对PB5引脚进行配置。

1、IO口操作代码

GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);

//使能GPIO外设和AFIO复用功能模块时钟
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //选择Timer3部分重映像

//选择定时器3的通道2作为PWM的输出引脚TIM3_CH2->PB5 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化引脚

2、初始化定时器

void TIM3_PWM_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  //定义初始化结构体
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  //使能定时器3时钟
    
    //初始化TIM3
    TIM_TimeBaseStructure.TIM_Period = arr;  //自动重装载寄存器值
    TIM_TimeBaseStructure.TIM_Prescaler =psc;  //TIMx预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;  //时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  //根据以上功能对定时器进行初始化
}

3、设置TIM3_CH2的PWM模式,使能TIM3的CH2输出

TIM_OCInitTypeDef  TIM_OCInitStructure;  //定义结构体
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;  //选择定时器模式,TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;  //输出比较极性低
TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据结构体信息进行初始化
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能定时器TIM2在CCR2上的预装载值

4、使能定时器3

TIM_Cmd(TIM3, ENABLE);  //使能定时器TIM3

经过以上的操作,定时器3的第二通道已经可以正常工作并输出PWM波了,只是其占空比和频率固定,可以通过改变TIM3_CCR2控制占空比。修改占空比的函数:TIM_SetCompare2(TIM3,n);  n不同,占空比不同。

5、修改pwm波形的占空比

编写一个函数:void TIM3_PWM_Init(u16 arr,u16 psc);将以上所有的代码都加进来这个函数中,只要在main函数中调用该函数进行初始化,然后使用TIM_SetCompare2()函数修改PWM的占空比就可以在PB5脚得到需要的PWM波形了。

关于频率以及占空比的计算方法例子:
int main(void)
{
  TIM3_PWM_Init(9999,143);  //频率=72*10^6/(9999+1)/(143+1)=50Hz
  TIM_SetCompare2(TIM3,4999);   //得到占空比为50%的PWM波形
  while(1);
}

竹坞无尘水槛清,相思迢递隔重城。秋阴不散霜飞晚,留得残荷听雨声。觉得不错,动动发财的小手点个赞哦!

  • 14
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 要在STM32F103C8T6单片机输出PWM波,可以按照以下步骤进行操作: 1. 配置GPIO为复用功能,并设置对应的复用功能映射 2. 配置定时器,设置PWM模式,并计算出预分频器和计数器的值,使得定时器的时钟频率为所需的PWM波频率 3. 配置定时器的通道,使其输出PWM波形,设置占空比和极性等参数 以下是一个简单的代码示例,演示如何在STM32F103C8T6单片机输出PWM波: ```c #include "stm32f10x.h" // 定义所需的PWM波频率和占空比 #define PWM_FREQUENCY 1000 // 1kHz #define PWM_DUTY_CYCLE 50 // 50% int main(void) { // 初始化系统时钟 SystemInit(); // 打开GPIOB和TIM3的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 配置GPIOB.0为复用功能 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置TIM3为PWM模式 TIM_TimeBaseInitTypeDef TIM_InitStructure; TIM_InitStructure.TIM_Period = (SystemCoreClock / PWM_FREQUENCY) - 1; TIM_InitStructure.TIM_Prescaler = 0; TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_InitStructure); // 配置TIM3通道1为PWM输出 TIM_OCInitTypeDef TIM_OC_InitStructure; TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_InitStructure.TIM_Pulse = ((SystemCoreClock / PWM_FREQUENCY) * PWM_DUTY_CYCLE / 100) - 1; TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OC_InitStructure); // 启动TIM3计数器 TIM_Cmd(TIM3, ENABLE); // 程序循环 while (1) { // do something } } ``` 以上代码示例中,我们使用GPIOB.0作为PWM输出口,以1kHz的频率输出50%的占空比PWM波形。你可以根据具体的需要,修改代码中的频率和占空比参数。 ### 回答2: STM32F103C8T6单片机是一款功能强大的ARM Cortex-M3内核的微控制器,可以实现PWM波的输出。 首先,我们需要在单片机上配置相应的引脚作为PWM输出引脚。通常,该单片机引脚具有多种功能,包括GPIO(通用输入输出),AF(复用功能),TIM(定时器功能)等。在这个例子中,我们将选择一个TIM定时器引脚作为PWM输出引脚。 其次,我们需要初始化定时器来生成PWM波。首先,我们需要选取一个可用的定时器,然后设置预分频器和周期来确定PWM波的频率。预分频器决定了定时器时钟的频率,周期则决定了PWM波的频率。另外,我们还需要设置占空比,以控制PWM波的高电平时间。占空比可以通过设置定时器的比较寄存器来实现。 最后,我们需要启动定时器,并根据需要设置输出引脚的极性。如果需要反向输出PWM波(即高电平变为低电平),我们可以设置输出比较模式为反向输出。否则,我们可以选择正常输出模式。 简而言之,要在STM32F103C8T6单片机上实现PWM波的输出,我们需要选择一个合适的引脚作为PWM输出引脚,初始化定时器来生成PWM波,并设置输出引脚的极性。通过适当地配置预分频器、周期和占空比,我们可以控制PWM波的频率和高电平时间。 ### 回答3: STM32F103C8T6是一款基于ARM Cortex-M3内核的高性能微控制单元。要实现该单片机输出PWM波,步骤如下: 1. 配置GPIO引脚:选择一个合适的引脚作为PWM输出引脚,并将其对应的GPIO引脚设置为复用模式。 2. 配置定时器:选择一个合适的定时器,配置其工作模式和时钟源,并设置PWM模式。 3. 配置定时器输出比较通道:选择一个合适的比较通道,并设置比较值和输出模式。 4. 设置PWM占空比:通过改变比较值来调整PWM占空比。 5. 启动定时器:使能定时器和比较通道的输出。 具体的代码实现如下: #include "stm32f10x.h" void PWM_Configuration() { // Step 1: 配置GPIO引脚 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选择引脚为GPIO_Pin_0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 引脚速度为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIOA为所选引脚所在的GPIO // Step 2: 配置定时器 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 使能TIM2时钟 TIM_TimeBaseStructure.TIM_Period = 999; // 设置定时器周期为1000-1 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 设置预分频器为7200-1 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频为1 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Step 3: 配置定时器输出比较通道 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 设置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 允许输出 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性为高 TIM_OC1Init(TIM2, &TIM_OCInitStructure); // 比较通道1 // Step 4: 设置PWM占空比 TIM_SetCompare1(TIM2, 500); // 设置通道1的比较值为500 // Step 5: 启动定时器 TIM_Cmd(TIM2, ENABLE); } int main() { PWM_Configuration(); while(1) { // 无需其他操作,单片机会一直输出PWM波形 } } 以上就是使用STM32F103C8T6单片机输出PWM波的步骤和代码实现。通过配置GPIO引脚、定时器和比较通道,再调整比较值来设置PWM占空比,最后启动定时器即可实现输出PWM波形
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱上电路设计

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值