pwm输出是玩航模的重要目标之一
问题描述
`之前学习的树莓派,最近又来到了Arm,手里有几块stm32f103c8t6的板子,放着也是浪费,就想用来学习使用一下!
主函数如下:
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_rcc.h"
#include "tim3pwm.h"
void Delay(u32 count)
{
u32 i=0;
for(;i<count;i++);
}
void RCC_Config(void)
{
SystemInit(); //配置系统时钟为72M
RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE ); /* GPIOB clock enable */
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3,ENABLE );/* TIM3 clock enable */
RCC_APB2PeriphClockCmd (RCC_APB2Periph_AFIO,ENABLE );
//PB4,5用作定时器tim3的PWM输出引脚,要部分重映射配置,所以需要开启AFIO时钟。
}
void LED_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_14| GPIO_Pin_15;//* 配置pb14,pb15可以作为刹车或正反用的控制端,带led可以显示控制状态 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); // 设置led关
// GPIO_InitTypeDef GPIO_InitStructure;
// **********RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PB端口时钟
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15 ;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB端口
// GPIO_SetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); // 关闭所有LED
}
int main(void)
{
RCC_Config();
LED_GPIO_Config();
TIM3_GPIO_Config();
TIM3_Mode_Config();
//TIM3 PWM波输出初始化,TIM3频率72000000/720=100khz
//PWM波频率100 000/200=500hz 2ms
Delay(30000000);
while(1) //主循环
{
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制关闭,开启led显示
// TIM3->CCR1 =150;
TIM_SetCompare1(TIM3,150);//Ch1占空比75/1000*20=1.5ms
TIM_SetCompare3(TIM3,150);//Ch1占空比75/1000*20=1.5ms
Delay(99000000);
// GPIO_SetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制,关闭led显示
// TIM_SetCompare3(TIM3,140);
// Delay(60000000);
// GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制关闭,开启led显示
// TIM_SetCompare3(TIM3,15);
// Delay(20000000);
// GPIO_SetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制,关闭led显示
// TIM_SetCompare3(TIM3,16);
// Delay(60000000);
// GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制关闭,开启led显示
// TIM_SetCompare3(TIM3,18);
// Delay(20000000);
// TIM_SetCompare3(TIM3,17);
// Delay(20000000);
// TIM_SetCompare3(TIM3,16);
// Delay(20000000);
// GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15 ); //刹车等控制关闭,开启led显示
// TIM_SetCompare3(TIM3,15);
// Delay(20000000);
}
}
包含的文件tim3pwm.c用于tim3的设置如下:
#include "tim3pwm.h"
/* 配置TIM3复用输出PWM时用到的I/O pb4,pb5,pb0,pb1 */
void TIM3_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_0| GPIO_Pin_1;
/* 配置TIM3复用输出PWM时用到的I/O引脚pb4,pb5,pb0,pb1;pb14,pb15可以作为刹车或正反用的控制端,带led可以显示控制状态 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE );
//设置pb4,5管脚部分重映射功能,tim3的CH1为pb4,ch2为pb5,ch3为pb0,ch4为pb1
}
/*配置TIM3输出的PWM信号的模式,如周期、极性、占空比 */
void TIM3_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* PWM信号电平跳变值 */
u16 CCR1_Val = 150;
u16 CCR2_Val = 150;
u16 CCR3_Val = 150;
u16 CCR4_Val = 150;
/* -----------------------------------------------------------------------
TIM3 Configuration: generate 2 PWM signals with 2 different duty cycles:
TIM3CLK = 72 MHz, Prescaler = 720-1, TIM3 counter clock = 72 MHz./720=100 000hz
TIM3 ARR Register = 200-1 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
TIM3 Frequency = 100 000/200=500Hz,2ms
TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100
TIM1 Channel2 duty cycle = (TIM1_CCR2/ TIM1_ARR)* 100
----------------------------------------------------------------------- */
//初始化TIM3
TIM_TimeBaseStructure.TIM_Prescaler =720-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_Period = 200-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel 1, PWM1模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;150/200*2=1.5ms
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄存器
// //初始化TIM3 Channel 2, PWM1模式
// TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
// TIM_OCInitStructure.TIM_Pulse = CCR2_Val;//150/200*2=1.5ms
// TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
// TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
// TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
//初始化TIM3 Channel 3, PWM1模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;//150/200*2=1.5ms
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR3上的预装载寄存器
//初始化TIM3 Channel 4, PWM1模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;//150/200*2=1.5ms
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC24
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR4上的预装载寄存器
TIM_ARRPreloadConfig(TIM3, ENABLE);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE); //使能TIM3
TIM_CtrlPWMOutputs(TIM3, ENABLE);
}
原因分析:
本来的目的是把tim3的4个管脚全用上的,用了部分重映射,pb4,5,0,1,但是调试下来pb4,5没有输出,pb0,1可以正常输出500hz频率,时间1.5ms的信号,用于控制无刷电机和舵机!
就是说现在只能输出两路!
还有一个问题是有这种说法,一路tim最好输出一路信号,最好两个管脚不要太近,现在pb0,1太近了,哪怕pb0,4能用也行啊!
希望大侠能给看看,为什么部分重映射没有成功!