OpenEdv-开源电子网

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

STM32F103产生多路PWM部分端口不输出

[复制链接]

1

主题

4

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2019-8-20
在线时间
18 小时
发表于 2019-9-22 14:01:56 | 显示全部楼层 |阅读模式
3金钱
图片中是输出结果:

下面这是配置文件
#include "pwm.h"
/**
* PWM输出驱动代码  
* PWM通道引脚对应示意图
* PA1  - TIM2_CH2     --->  PWM1     --->  风扇1
* PA3  - TIM2_CH4     --->  PWM2     --->  风扇2
* PB1  - TIM3_CH4     --->  PWM4     --->  风扇3
* PC7  - TIM8_CH2     --->  PWM5     --->  风扇4
* PC9  - TIM8_CH4     --->  PWM6     --->  水泵1
* PA11 - TIM1_CH4     --->  PWM3     --->  水泵2
**/

void PWM_GPIO_Configuration(void) //端口初始化
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8, ENABLE); //使能TIM1 & TIM8时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); //使能TIM2 & TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); //启动GPIO
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //启动AFIO

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//端口速率为50Mhz

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_11;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化A端口

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化B端口

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_9;
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化C端口
}

//Step3. TIM模块初始化
//arr:自动重装值
//psc:时钟预分频数
void PWM_TIM_Init(u16 freq) //不分频。频率freq=72000/(自动重装值arr+1),freq为频率值,此处频率以kHz为单位
{
//  ------------------------通用配置-------------------------------freq

TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;//初始化TIM的固定格式, 根据TIM_TimeBaseInitStruct中指定的参数初始化,TIMx的时间基数单位
TIM_OCInitTypeDef TIM_OCInitStructure;// 根据TIM_OCInitStruct中指定的参数初始化外设TIMx

//TIM1基本计数器设置(设置PWM频率)
//频率=TIM1_CLK/(ARR+1)
TIM_BaseInitStructure.TIM_Period = 72000/freq-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_BaseInitStructure.TIM_Prescaler =0; //设置用来作为TIMx时钟频率除数的预分频值
TIM_BaseInitStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_BaseInitStructure.TIM_RepetitionCounter = 0x0000;

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;  //当定时器计数值小于CCR1_Val时为高电平
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;       //在空闲时输出高  
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;    //指定在空闲状态下的TIM输出比较引脚的状态。仅供TIM1和TIM8有效。

TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
//  ------------------------初始化单个通道-------------------------------
// PA1 ---- TIM2_CH2  ---> 风扇1
TIM_TimeBaseInit(TIM2, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //通道预装载使能
// TIM_CtrlPWMOutputs(TIM2,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM2, ENABLE);  //使能TIMx

// PA3 ---- TIM2_CH4  ---> 风扇2
TIM_TimeBaseInit(TIM2, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //通道预装载使能
// TIM_CtrlPWMOutputs(TIM2,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM2, ENABLE);  //使能TIMx

// PB1 ---- TIM3_CH4  ---> 风扇3
TIM_TimeBaseInit(TIM3, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //通道预装载使能
// TIM_CtrlPWMOutputs(TIM3,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM3, ENABLE);  //使能TIMx

// PC7 ---- TIM8_CH2  ---> 风扇4
TIM_TimeBaseInit(TIM8, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //通道预装载使能
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM8, ENABLE);  //使能TIMx

// PC9 ---- TIM8_CH4  ---> 水泵1
TIM_TimeBaseInit(TIM8, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC4Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);  //通道预装载使能
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM8, ENABLE);  //使能TIMx
// PA11 ---- TIM1_CH4  ---> 水泵2
TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OC4Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx,使能对应通道
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //通道预装载使能
// TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE);  //使能TIMx

}
void PWM_Init(u16 arr) //包含定时器初始化和端口初始化,freq为频率值,此处频率以kHz为单位
{
PWM_GPIO_Configuration();
PWM_TIM_Init(arr);
}
void PWM_Change(u8 Pwmx,u16 DutyCycle) //更改PWM的输出频率和占空比,Pwmx为第几路信号1~4-->FAN1~4,5-->PUMP1,6-->PUMP2,DutyCycle为占空比,以20kHz计算
{
switch(Pwmx)
    {
        case 1:  //FAN1
   TIM_SetCompare2(TIM2,DutyCycle*3599/100);
        break;
        case 2:  //FAN2
   TIM_SetCompare4(TIM2,DutyCycle*3599/100);
        break;
        case 3:  //FAN3
   TIM_SetCompare4(TIM3,DutyCycle*3599/100);
        break;
        case 4:  //FAN4
   TIM_SetCompare2(TIM8,DutyCycle*3599/100);
        break;
        case 5:  //PUMP1
   TIM_SetCompare4(TIM8,DutyCycle*3599/100);
        break;
        case 6:  //PUMP2
   TIM_SetCompare4(TIM1,DutyCycle*3599/100);
        break;
        default:break;
    }
}
麻烦看一下为什么后面三路不输出,谢谢啦~


捕获.PNG
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2019-9-23 02:11:26 | 显示全部楼层
回复

使用道具 举报

7

主题

175

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1327
金钱
1327
注册时间
2019-7-11
在线时间
165 小时
发表于 2019-9-23 08:38:07 | 显示全部楼层
高级定时器还需要这一句TIM_CtrlPWMOutputs(TIMx,ENABLE);
世界和平
回复

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2018-12-17
在线时间
8 小时
发表于 2019-9-25 18:02:39 | 显示全部楼层
1 8 高级定时器操作和其余定时器不一样
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-28 11:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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