OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2385|回复: 2

stm32F103 PB8的PWM输出

[复制链接]

19

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-10-8
在线时间
75 小时
发表于 2020-1-7 16:51:56 | 显示全部楼层 |阅读模式
10金钱
void GPIO_PWM_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        // 让GPIOC与复用时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);   
        //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                //复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_PinRemapConfig(GPIO_Remap_TIM4  , ENABLE);                //将PC9用做tim_3 ch4 完全重映射
        //GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE );       
        //GPIO_PinRemapConfig(GPIO_Remap_TIM4 , ENABLE);
        //GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 , ENABLE);                //将PB8用做tim_3 ch4 完全重映射
        //GPIO_PinRemapConfig(GPIO_Remap_I2C1,ENABLE);
}

void set_freq_DY(u16 freq,u8 Duty_ycle)                //freq 频率    Duty_ycle 占空比
{
        int RAfreq;
        int cal_value;                        //储存计算出的arr的值
        Freq = freq;               
        Duty = Duty_ycle;
       
        RAfreq = freq*1000;
        cal_value = 72000000 / RAfreq;                        //不分频率为72MHz
       
        TIM3_PWM_Init(cal_value, 0);                                //cal_value为arr的值  0为不分频
       
        CCR3_TIM = Duty * cal_value / 100;
        TIM_SetCompare4(TIM4,CCR3_TIM);   //重置装载值
        if(CCR3_TIM == cal_value)
        {
                GPIO_SetBits(GPIOB,GPIO_Pin_8);
        }
       
}
//PWM 初始化
void TIM3_PWM_Init(u16 arr,u16 psc)
{   

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
       
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

TIM_TimeBaseStructure.TIM_Period = arr;                                                 //重新装载值
TIM_TimeBaseStructure.TIM_Prescaler = psc;                                                //分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;                                //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //上拉模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
       
       
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            //用PWM1模式        
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                                 
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;                      //上升沿触发      

TIM_OC3Init(TIM4, &TIM_OCInitStructure);           //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);                //TIM4_OC3通道
//使能TIMx在CCR4上的预装载寄存器
TIM_Cmd(TIM4, ENABLE);                                                        //使能TIM3

}

无标题.png

最佳答案

查看完整内容[请看2#楼]

STM32F103C8T6 TIM4 同时配置4路PWM输出 转载,网址http://blog.sina.com.cn/s/blog_19db67b480102yidu.html 首先我们来了解一下PWM的概念,PWM(Pulse Width Modulation)即为脉冲宽度调制。放到我们这里,简单点说,就是利用单片机产生指定占空比和指定频率的方波。例如,单片机输出了一个高电平0.5s,低电平0.5s的方波。那么,这个方波的占空比为0.5/(0.5+0.5)=50%,高低电平各占一半,频率为周期(0.5s+0.5s)的倒数, ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2018-10-8
在线时间
75 小时
 楼主| 发表于 2020-1-7 16:51:57 | 显示全部楼层
STM32F103C8T6 TIM4 同时配置4路PWM输出
转载,网址http://blog.sina.com.cn/s/blog_19db67b480102yidu.html



首先我们来了解一下PWM的概念,PWM(Pulse Width Modulation)即为脉冲宽度调制。放到我们这里,简单点说,就是利用单片机产生指定占空比和指定频率的方波。例如,单片机输出了一个高电平0.5s,低电平0.5s的方波。那么,这个方波的占空比为0.5/(0.5+0.5)=50%,高低电平各占一半,频率为周期(0.5s+0.5s)的倒数,即为1Hz。如果高电平为0.2s,低电平为0.8s则占空比为0.2/(0.2+0.8)=20%,其他情况依次类推。

以单片机STM32F103C8T6为例讲解PWM的产生,通过单片机的内部定时器,可以在IO口输出相应的PWM信号。该单片机有8个定时器,即TIM1~TIM8。其中,TIM1、TIM8为高级定时器,每个都可以产生多达7路PWM信号,从7个IO口同时输出。TIM2~TIM5为通用定时器,每个同时产生4路PWM信号。TIM6、TIM7为基本定时器无法产生PWM信号。

实现功能:

配置TIM4的4路PWM同时输出频率为1Hz的信号,其中:

第一路(TIM4_CH1)占空比10%

第二路(TIM4_CH2)占空比20%

第三路(TIM4_CH3)占空比50%

第四路(TIM4_CH4)占空比80%

第一步:确定TIM4的4路PWM输出对应的IO口。

查看官方数据手册《STM32F103x8_B增强型系列中容量产品数据手册》,P20页,截图如下:

                                                  STM32F103C8T6TIM4同时配置4路PWM输出

TIM4的PWM通道TIM4_CH1~TIM4_CH4对应GPIO依次为:PB6~PB9。

int main(void)

{

       TIM4_PWM_Init(7999,8999);//方波频率1Hz

       TIM_SetCompare1(TIM4, 799);//占空比10%

       TIM_SetCompare2(TIM4,1599);//占空比20%  

       TIM_SetCompare3(TIM4,3999);//占空比50%

       TIM_SetCompare4(TIM4,6399);//占空比80%



       while(1);//主循环     

}

第二步:方波频率计算--void TIM4_PWM_Init(u16 arr,u16 psc);

1.定时器TIM4的输入时钟CLK为72MHz,决定了输出PWM的频率最高低于72MHz;

2.CLK经过预分频计数器,进行了psc+1分频,输入时钟降为72MHz/(psc+1);

3.分频之后,再计数(arr+1)次后才算完成一个周期的PWM输出,因此频率又降低了(arr+1)倍;

4.PWM频率=72MHz/(psc+1)/(arr+1)

5.根据参数72MHz/(7999+1)/(8999+1) = 1Hz.

第三步:占空比设置--void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t  Compare1);

1.定时器TIM4的计数寄存器从0累加到arr循环,通过将计数寄存器的值N和Compare1进行比较;

2.在一个周期内,N 小于Compare1时输出高,N大于Compare1输出低;(或者设置为相反)

3.因此占空比:(Compare1+1)/(arr+1);

4.依据参数,10%占空比Compare1=799,即10%=(799+1)/(7999+1),其他依次类推。

  

void TIM4_PWM_Init(u16 arr,u16 psc)

{

       GPIO_InitTypeDef GPIO_InitStructure;

       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

       TIM_OCInitTypeDef  TIM_OCInitStructure;

      

       //使能定时器TIM4时钟,注意TIM4时钟为APB1,而非APB2

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

       //使能PWM输出GPIO口时钟

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);

                                                                             

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//定时器TIM4的PWM输出通道1,TIM4_CH1

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

      

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//定时器TIM4的PWM输出通道1,TIM4_CH2

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO



      

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//定时器TIM4的PWM输出通道3,TIM4_CH3

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO





       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//定时器TIM4的PWM输出通道2,TIM4_CH4

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO





      

       TIM_TimeBaseStructure.TIM_Period = arr;//自动重装值

       TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数

       TIM_TimeBaseStructure.TIM_ClockDivision = 0;

       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式

       TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化TIM4



       //初始化TIM4_CH1的PWM模式

       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置PWM模式1

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

       TIM_OCInitStructure.TIM_Pulse = 0; //

       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性为高

       TIM_OC1Init(TIM4, &TIM_OCInitStructure);//初始化TIM4_CH1

      

       //初始化TIM4_CH2的PWM模式

       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

       TIM_OCInitStructure.TIM_Pulse = 0;

       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

       //TIM4_CH2初始化,注意为OC2,而不是OC1,下面两个通道依次类推。

       TIM_OC2Init(TIM4, &TIM_OCInitStructure);

      

       //初始化TIM4_CH3的PWM模式

       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

       TIM_OCInitStructure.TIM_Pulse = 0;

       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

       TIM_OC3Init(TIM4, &TIM_OCInitStructure);

      

       //初始化TIM4_CH4的PWM模式

       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

       TIM_OCInitStructure.TIM_Pulse = 0;

       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

       TIM_OC4Init(TIM4, &TIM_OCInitStructure);



       //使能4个通道的预装载寄存器

       TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC1

       TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC2

       TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC3

       TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC4

      

       TIM_ARRPreloadConfig(TIM4, ENABLE); //使能重装寄存器

      

       TIM_Cmd(TIM4, ENABLE);//使能定时器TIM4,准备工作

}

  

分享:
回复

使用道具 举报

15

主题

1061

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
3625
金钱
3625
注册时间
2019-8-14
在线时间
1054 小时
发表于 2020-1-7 18:35:40 | 显示全部楼层
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-19 11:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表