基于STM32F103的四路PWM配置程序及个人见解

发布者:东土大唐88最新更新时间:2020-06-17 来源: eefocus关键字:STM32F103  四路PWM  配置程序 手机看文章 扫描二维码
随时随地手机看文章

平台:STM32F103系列


内容:生成四路PWM波


1、初始化配置


void Pwmpin_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

 

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

 

}


这一段为用到的引脚初始化配置,其中用到定时器3的通道1 、2、 3、 4,分别对应A口的6、7,B口的0、1。


void TIM_Config(void)

{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    TIM_OCInitTypeDef  TIM_OCInitStructure;

 

    //定时器配置

    TIM_TimeBaseStructure.TIM_Prescaler = 72 ;//设置72分频

    TIM_TimeBaseStructure.TIM_Period = 1000;//设置计数溢出大小,每计1000个数就产生一个更新事件

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分割

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置计数器模式为向上计数模式

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//将配置应用到TIM3中

    //PWM配置ch1

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //配置为PWM模式2

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

    TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //有效电平为低电平

 

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);//使能通道3

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

    //PWM配置ch2

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

    TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值

    

    TIM_OC2Init(TIM3, &TIM_OCInitStructure);//使能通道3

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

    //PWM配置ch3

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

    TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值

    

    TIM_OC3Init(TIM3, &TIM_OCInitStructure);//使能通道3

    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

    //PWM配置ch4

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

    TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值

    

    TIM_OC4Init(TIM3, &TIM_OCInitStructure);//使能通道3

    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

 

    //使能

    TIM_ARRPreloadConfig(TIM3, ENABLE);//使能TIM3重载寄存器ARR

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

}

这一段代码是配置PWM的重点,其中最为主要的是:


TIM_TimeBaseStructure.TIM_Prescaler = 72 ;//设置72分频

TIM_TimeBaseStructure.TIM_Period = 1000;//设置计数溢出大小,每计1000个数就产生一个更新事件

此两行代码确定了PWM波的频率,经过测试,此处配置完成后示波器显示的频率为1KHz,因此可知频率其计算方法为:


                                PWM频率=TIM3的时钟频率/(分频系数 x 计数溢出值)


2、设置四路PWM波占空比函数


void Timer3_PWM_SetDutyCycle(u8 ch, u16 Timer3_PWM_DutyCycle)

{

    switch (ch)

    {

    case 1:

        TIM_SetCompare1(TIM3, Timer3_PWM_DutyCycle );//通道1占空比

        break;

    case 2:

        TIM_SetCompare2(TIM3, Timer3_PWM_DutyCycle );//通道2占空比

        break;

    case 3:

        TIM_SetCompare3(TIM3, Timer3_PWM_DutyCycle );//通道3占空比

        break;

    case 4:

        TIM_SetCompare4(TIM3, Timer3_PWM_DutyCycle );//通道4占空比

        break;

    }

}

设置占空比主要是通过 ”TIM_SetComparex(TIM3,占空比);“这个库函数来设置,其中x代表相应的通道。


其中占空比的设置与初始化配置的时候的 “TIM_TimeBaseStructure.TIM_Period = 1000;”相关联,其关系是最大的占空比这个值不能大于1000。


其实我更愿意把 TIM_Period 叫做精度,假如设置这个值是100,那么我们能设置的值只有0-100,而设置为1000的时候我们能设置的值就从0-100,变成了0-1000。这就意味着可以做到更为精准的额PWM调控,当然若是想保持频率不变也必须遵循这个公式:PWM频率=TIM3的时钟频率/(分频系数 x 计数溢出值),相应的改大分频系数值。


至此PWM的初始化以及占空比改变函数就已结束。


3、测试主函数代码


#define duty 500

void TIM3_PWM_Init(void)

{

    Pwmpin_init();

    TIM_Cfg();

}

 

int main()

{

    TIM3_PWM_Init();

    while(1)

    {

        Timer3_PWM_SetDutyCycle(1,duty);

Timer3_PWM_SetDutyCycle(2,duty);

Timer3_PWM_SetDutyCycle(3,duty);

Timer3_PWM_SetDutyCycle(4,duty);

    }

}

编译过后通过示波器即可看到一个频率为1KHz,占空比为50%的波,或者通过keil软件仿真也可看到。

关键字:STM32F103  四路PWM  配置程序 引用地址:基于STM32F103的四路PWM配置程序及个人见解

上一篇:stm32库函数下,输出可调频率pwm
下一篇:STM32F103 实验 PWM输出

推荐阅读最新更新时间:2024-11-14 01:14

stm32f103 usb驱动 电脑无法识别的解决办法
1.usb所使用的IO口在设置为usb后自动分配功能,不需要再设置,一定要设置的话会被忽略,所以也没什么影响。 2.usb时钟配置只有两种可用:主频72M,usb时钟1.5分频;主频48M,usb时钟1分频。 3.PA12(USBP / D+)一定要接1.5k的上拉电阻,用于电脑识别设备,官方库使用了lO口控制了上拉,这样方便软件控制断开与重新连接,直接上拉到电源也是可以的,不过需要断开和重新连接时只能手动插拔。 4.stm32f103的can和usb不能同时使用,can的时钟打开后,电脑就会识别不出usb设备,所以两个功能都要用到的话,还是换成f105或f107,这两种型号是可以同时使用的。
[单片机]
STM32F103C8T6驱动ov2640拍照串口传输到上位机
使用环境(蓝色粗体字为特别注意内容) 1、软件环境:Keil MDK 5.15 2、硬件环境:STM32F103C8T6最小系统,OV2640摄像头模块 最近想玩玩摄像头,于是在网上找找性价比比较高的摄像头,之前用过OV7670这款摄像头,不过这款摄像头对单片机要求较高,一般的单片机驱动起来非常费劲,除非ARM级别的微处理器才能够胜任。要想使用低端单片机驱动的话需要加上FIFO模块,一加上这玩意价格就翻了3倍。。。。原来20块钱的东西涨到了70+,我的天。。。。于是找了大半天,终于找到OV2640这款摄像头,这摄像头是我目前遇到的性价比最高的摄像头了,竟然支持直接输出JPG格式的图片,最高支持1600*1200(200
[单片机]
<font color='red'>STM32F103</font>C8T6驱动ov2640拍照串口传输到上位机
STM32F103之USB(一)
初识USB 由于项目需求,需要USB这块,花了几天时间了解了下USB方面的知识,的确挺难的!USB是个挺难啃的家伙,当时看了一遍看的一头雾水,不过几天下来还是有所收获的。顺便记录下自己学习的过程,一遍以后查看。 一、USB介绍 USB(Univetsal Serial Bus)的缩写,即通用串行总线。是现在通讯设备中不可或缺的一部分,可以这么说,电子工程师不懂USB那就太OUT了。 二、USB的发展史 Ø1994年 Philips公司 Access.Bus规范(USB的前身) Ø1996年 Compaq、Intel、Microsoft、NEC USB1.0规范 Ø1997年 US
[单片机]
<font color='red'>STM32F103</font>之USB(一)
stm32 bootloader启动正常,APP程序会在时钟配置出错原因分析
实验环境 STM32F411芯片 HAL库 利用CubeMX生成的Bootloader和APP工程 现象描述 将Bootloader和APP程序分别下载到板子上,Bootlader程序可以正常运行,而APP程序会死在Error_Handler()的while(1)循环中。 具体调试发现程序是在执行HAL_RCC_OscConfig()函数的PLL 配置部分检测到当前PLL已经被配置为了系统时钟而返回了HAL_ERROR的返回值导致进入了Error_Handler()。为什么bootloader程序中的时钟配置没有问题,而APP中的时钟配置就会有问题呢? 分析 网上搜索了一下,发现了一种说法:PLL在启动之后便不能够重新配置。感
[单片机]
stm32 bootloader启动正常,APP<font color='red'>程序</font>会在时钟<font color='red'>配置</font>出错原因分析
stm32f103——时钟树的分析与配置
时钟树是用来对单片机系统和各个外设进行时钟配置的,因为不同的外设,其电路不同,对时钟频率的要求也就不同。所以需要我们对时钟源的频率进行改变,变成外设需要的时钟频率。 首先时钟树分为俩部分: 左边部分是时钟的来源,右边部分是时钟的去向: 各类时钟简括: 1.HSE时钟(高速外部时钟):来源为外部晶振,通常速度8Mhz。由RCC_CR时钟控制寄存器中的16:HSEON控制。 2.HSI时钟(高速内部时钟):来源为芯片内部,大小为8Mhz,当HSE故障时,系统时钟会自动切换到HSI,知道HSE启动成功,相当于HSE的替补。由RCC_CR时钟控制寄存器的位0:HSION控制。 3.PLLCLK(锁相环时钟):来源
[单片机]
<font color='red'>stm32f103</font>——时钟树的分析与<font color='red'>配置</font>
STM32F103单片机复位电路回顾
在设计“单片机控制线路板”时,一般需有4部分电路:“电源电路部分”、“晶振电路部分”、“复位电路部分”、“下载电路部分”;对不同的“IC芯片”,工作所需“电源电压”各不相同,大多为“+3.3V”或“+5.0V”;“晶振电路部分”和“复位电路部分”也需根据“芯片”对应的“datasheet”进行设计,特别是“复位电路部分”,必须参考手册,确定“低电平复位”还是“高电平复位”,否则会导致上电后“芯片无法复位工作”; 在“初代温控板V1.0”中,控制芯片为“STM32F103RCT6”,为“低电平复位”,但由于设计失误,未添加“复位电路”,如下所示: 复位电路图 如图“红色部分”所示,在“初代温控板V1.0”中,此部分电路被忽略,导
[单片机]
<font color='red'>STM32F103</font>单片机复位电路回顾
STM32F103--(三) USART实践
GPIO的后面很容易想到的应该就是通用同步/异步接受发送器(USART) 了。对于比较复杂点的程序而言,用led来调试显然是有点不太科学。所以,把USART口调试好后,有助于之后其它部分的调试。(把USART当成是调试输出口来用 ) 调试USART花了我一些时间,其实问题主要出现在一些很小的细节方面。比如发现发送的数据中夹杂这乱码,后来通过数据的二进制分析发现是奇偶校验位不小心打开了。如果排除这些小问题的话,整个工作应该是很容易的。 先上例程,然后标注,最后分析 USART的初始化 void UartInit(void) { USART_InitTypeDef USART_InitStructure;//声明一个USART初
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved