你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F103单片机生成16路PWM波

[复制链接]
STMCU小助手 发布时间:2022-3-22 13:00
单片机输出pwm波在项目中是恨常用的一个功能,今天就总结一下用STM32F103C8T6单片机输出16路 pwm波。

使用keil5软件,用标准库函数来实现。

首先看定时器初始化
  1. void TIM1_PWM_Init(u16 arr, u16 psc)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitSturcture;

  6.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
  7.     //初始化IO口
  8.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
  9.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  12.     //设置 TIM ARR PSC
  13.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  14.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  15.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  16.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;                //向上计数模式
  17.     TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
  18.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);

  19.     //TIM1_CH1  PWM1 模式
  20.     TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
  21.     TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
  22.     TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;                        //输出高电平有效
  23.     TIM_OC1Init(TIM1, &TIM_OCInitSturcture);

  24.     //TIM1_CH2  PWM1 模式
  25.     TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
  26.     TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
  27.     TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;                 
  28.     TIM_OC2Init(TIM1, &TIM_OCInitSturcture);


  29.     //TIM1_CH3  PWM2 模式
  30.     TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
  31.     TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
  32.     TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;                 
  33.     TIM_OC3Init(TIM1, &TIM_OCInitSturcture);

  34.     //TIM1_CH4  PWM2 模式
  35.     TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
  36.     TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
  37.     TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;               
  38.     TIM_OC4Init(TIM1, &TIM_OCInitSturcture);


  39.     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);                                        //TIM1_CH1 使能预装载寄存器
  40.     TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);                                         //TIM1_CH2 使能预装载寄存器
  41.     TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);                                         //TIM1_CH3 使能预装载寄存器
  42.     TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);                                         //TIM1_CH4 使能预装载寄存器


  43.     TIM_Cmd(TIM1, ENABLE);                                //使能计数器
  44.     TIM_CtrlPWMOutputs(TIM1, ENABLE);        //主输出使能
  45. }
复制代码

初始化定时1的4个通道,对应IO口为 PA8,PA9,PA10,PA11,将这4个口都设置为PWM输出口。入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。

下来初始化定时器2

  1. void TIM2_PWM_Init(u16 arr, u16 psc)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitStructure;

  6.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);                          //使能定时器2时钟
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);                  //使能GPIO时钟

  8.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  9.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  12.     //初始化TIM2
  13.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  14.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  15.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  16.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  17.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

  18.         //初始化TIM2_CH1  PWM 模式
  19.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  20.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  21.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  22.     TIM_OC1Init(TIM2, &TIM_OCInitStructure);        

  23.     //初始化TIM2_CH2  PWM 模式
  24.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  25.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  26.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  27.     TIM_OC2Init(TIM2, &TIM_OCInitStructure);

  28.     //初始化TIM2_CH3  PWM 模式
  29.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  30.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  31.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  32.     TIM_OC3Init(TIM2, &TIM_OCInitStructure);

  33.     //初始化TIM2_CH4  PWM 模式
  34.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  35.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  36.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  37.     TIM_OC4Init(TIM2, &TIM_OCInitStructure);

  38.     //使能TIM2在CCR上的预装载寄存器
  39.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
  40.     TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
  41.     TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
  42.     TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

  43.     //使能TIM2
  44.     TIM_Cmd(TIM2, ENABLE);
  45. }
复制代码

这里要注意的是,定时器1是高级定时器,定时器2、3、4是通用定时器。只有高级定时器有重复计数寄存器,而通过定时器没有重复计数寄存器。定时器2初始化时,比定时器1少一行代码,这里要注意一下。

  1. TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
复制代码

重复计数寄存器主要作用如下:

7%I%HS)6%GNV72IVX1XIMRM.png

其余设置方法和定时器1基本一样,定时器2的4个通道对应的IO口为PA0,PA1,PA2,PA3.将这四个口设置为PWM输出模式。

入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。

下来设置定时器3

  1. void TIM3_PWM_Init(u16 arr, u16 psc)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitStructure;

  6.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);                                                        //使能定时器3时钟
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);        //使能GPIO时钟

  8.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  9.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  12.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  13.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  14.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15.     GPIO_Init(GPIOB, &GPIO_InitStructure);

  16.     //初始化TIM3
  17.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  18.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  19.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  20.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  21.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);

  22.     //初始化TIM3_CH1  PWM 模式
  23.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  24.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  25.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  26.     TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  27.     //初始化TIM3_CH2  PWM 模式
  28.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  29.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  30.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  31.     TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  32.     //初始化TIM3_CH3  PWM 模式
  33.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  34.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  35.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  36.     TIM_OC3Init(TIM3, &TIM_OCInitStructure);

  37.     //初始化TIM3_CH4  PWM 模式
  38.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  39.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  40.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  41.     TIM_OC4Init(TIM3, &TIM_OCInitStructure);

  42.     //使能TIM3在CCR上的预装载寄存器
  43.     TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
  44.     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
  45.     TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
  46.     TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
  47.     //使能TIM3
  48.     TIM_Cmd(TIM3, ENABLE);
  49. }
复制代码

设置方法和定时器2一样,定时器3的4个通道对应的IO口为PA6,PA7,PB0,PB1。将这四个口设置为PWM输出模式。

入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。

最后设置定时器4


  1. void TIM4_PWM_Init(u16 arr, u16 psc)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitStructure;

  6.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);                        //使能定时器4时钟
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);                  //使能GPIO时钟

  8.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  9.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  10.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.     GPIO_Init(GPIOB, &GPIO_InitStructure);


  12.     //初始化TIM4
  13.     TIM_TimeBaseInitStructure.TIM_Period = arr;
  14.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
  15.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  16.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  17.     TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);

  18.         //初始化TIM4_CH1  PWM 模式
  19.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  20.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  21.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  22.     TIM_OC1Init(TIM4, &TIM_OCInitStructure);
  23.         

  24.     //初始化TIM4_CH2  PWM 模式
  25.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  26.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  27.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  28.     TIM_OC2Init(TIM4, &TIM_OCInitStructure);

  29.     //初始化TIM4_CH3  PWM 模式
  30.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  31.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  32.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  33.     TIM_OC3Init(TIM4, &TIM_OCInitStructure);

  34.     //初始化TIM4_CH4  PWM 模式
  35.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  36.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  37.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  38.     TIM_OC4Init(TIM4, &TIM_OCInitStructure);

  39.     //使能TIM4在CCR上的预装载寄存器
  40.     TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
  41.     TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
  42.     TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
  43.     TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

  44.     //使能TIM4
  45.     TIM_Cmd(TIM4, ENABLE);
  46. }
复制代码

设置方法和定时器2一样,定时器4的4个通道对应的IO口为PB6,PB7,PB8,PB9。将这四个口设置为PWM输出模式。

入口参数arr用来设置定时器的自动重装载值,psc用于设置时钟分频系数。时钟默认为72MHZ。

这样总共16路的PWM初始化就完成了,下来看主函数设置

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "pwm.h"

  5. int main(void)
  6. {
  7.     u16 led_pwm_val = 0;

  8.     delay_init();       //延时函数初始化
  9.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  10.     //不分频。PWM频率=72000000/9000=8Khz
  11.     TIM1_PWM_Init(8999, 0);
  12.     TIM2_PWM_Init(8999, 0);
  13.     TIM3_PWM_Init(8999, 0);
  14.     TIM4_PWM_Init(8999, 0);
  15.     led_pwm_val = 899;
  16.     while(1)
  17.     {
  18.         if(led_pwm_val < 8999)
  19.             led_pwm_val++;
  20.         else
  21.             led_pwm_val = 0;

  22.         TIM_SetCompare1(TIM1, led_pwm_val);                            //TIM1_CH1    PA8
  23.         TIM_SetCompare2(TIM1, led_pwm_val);                                //TIM1_CH2    PA9
  24.         TIM_SetCompare3(TIM1, led_pwm_val);                                //TIM1_CH3    PA10
  25.         TIM_SetCompare4(TIM1, led_pwm_val);                                //TIM1_CH4    PA11

  26.         TIM_SetCompare1(TIM2, led_pwm_val);                                //TIM2_CH1          PA0
  27.         TIM_SetCompare2(TIM2, led_pwm_val);                                //TIM2_CH2    PA1
  28.         TIM_SetCompare3(TIM2, led_pwm_val);                                //TIM2_CH3    PA2
  29.         TIM_SetCompare4(TIM2, led_pwm_val);                                //TIM2_CH4    PA3

  30.         TIM_SetCompare1(TIM3, led_pwm_val);                           //TIM3_CH1          PA6
  31.         TIM_SetCompare2(TIM3, led_pwm_val);                                //TIM3_CH2    PA7
  32.         TIM_SetCompare3(TIM3, led_pwm_val);                                //TIM3_CH3    PB0
  33.         TIM_SetCompare4(TIM3, led_pwm_val);                                //TIM3_CH4    PB1

  34.         TIM_SetCompare1(TIM4, led_pwm_val);                                //TIM4_CH1     PB6
  35.         TIM_SetCompare2(TIM4, led_pwm_val);                                //TIM4_CH2     PB7
  36.         TIM_SetCompare3(TIM4, led_pwm_val);                                //TIM4_CH3     PB8
  37.         TIM_SetCompare4(TIM4, led_pwm_val);                                //TIM4_CH4     PB9

  38.         delay_ms(1);
  39.     }
  40. }
复制代码

初始化时设置4个定时器的频率为8K,在while循环中调节占空比从0---100%变化。程序编译后烧写到单片机中,通过示波器就能观察到PWM波形变化了。

这里先用软件仿真看一下效果




收藏 1 评论0 发布时间:2022-3-22 13:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版