STM32
直播中

李慧

7年用户 857经验值
私信 关注
[问答]

如何去实现STM32103定时器3输出四路PWM呢

如何去实现STM32103定时器3输出四路PWM呢?怎样通过串口去控制四个舵机呢?

回帖(1)

h1654155275.6260

2021-12-13 12:12:44
正点原子精英板PWM输出略改一下
STM32103定时器3输出四路PWM
通过串口控制四个舵机
timer.c

若是没用到中断之类的 只输出PWM 定时器这样初始话就够了

#include "timer.h"
void TIM3_PWM_Init(u16 arr,u16 psc)//arr:自动重装值  //psc:时钟预分频数
{  GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //使能定时器3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
        
        GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   
                                GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE) ; //关闭JTAG,保留SW做调试用
                       
                                //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形        GPIOB.5
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_0|GPIO_Pin_1; //TIM_CH2  CH3 CH1   4 5 PB0   
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
        
                                //初始化TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
        
        //结构体赋值     
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
                               
                                //初始化TIM3 Channe1 PWM模式
                                TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
                               
                                //初始化TIM3 Channe2 PWM模式  
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
        
        //初始化TIM3 Channe3 PWM模式         
        TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
        TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
                               
                                //初始化TIM3 Channe4 PWM模式         
        TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
        TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
                               
        TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}


四路定时器全部初始化


helm.h
#ifndef __HELM_H
#define __HELM_H         
#include "sys.h"
#include "timer.h"
#include "delay.h"


void Helm_Init(void);


void Helm_1_Up(void);
void Helm_1_Down(void);


void Helm_2_Up(void);
void Helm_2_Down(void);


void Helm_3_Up(void);
void Helm_3_Down(void);
void Ctrl_Sum(void);


#endif


helm.c
#include "helm.h"
#include "timer.h"
#include "usart.h"
static u16 pwmval1=249;//1.5ms->90度   //500是1ms  750是 1.5ms
static u16 pwmval2=249;
static u16 pwmval3=249;
static u16 pwmval4=249;
void Helm_Init(void)
{
        TIM_SetCompare1(TIM3,pwmval1);//PB4
        TIM_SetCompare2(TIM3,pwmval2);//PB5
        TIM_SetCompare3(TIM3,pwmval3);//PB0
        TIM_SetCompare4(TIM3,pwmval4);//PB1
}


void Helm_1_Up(void)
{
        pwmval1+=50;//
        if(pwmval1>1249)
                pwmval1=1249;
        TIM_SetCompare1(TIM3,pwmval1);
}




void Helm_1_Down(void)
{
        pwmval1-=50;//
        if(pwmval1<249)
                pwmval1=249;
        TIM_SetCompare1(TIM3,pwmval1);
}




void Helm_2_Up(void)
{
        pwmval2+=50;//
        if(pwmval2>1249)
                pwmval2=1249;
        TIM_SetCompare2(TIM3,pwmval2);
}




void Helm_2_Down(void)
{
        pwmval2-=50;//
        if(pwmval2<249)
                pwmval2=249;
        TIM_SetCompare2(TIM3,pwmval2);
}




void Helm_3_Up(void)
{
        pwmval3+=50;//
        if(pwmval3>1249)
                pwmval3=1249;
        TIM_SetCompare3(TIM3,pwmval3);
}




void Helm_3_Down(void)
{
        pwmval3-=50;//
        if(pwmval3<249)
                pwmval3=249;
        TIM_SetCompare3(TIM3,pwmval3);
}




void Helm_4_Up(void)
{
        pwmval4+=50;//
        if(pwmval4>1249)
                pwmval4=1249;
        TIM_SetCompare4(TIM3,pwmval4);
}




void Helm_4_Down(void)
{
        pwmval4-=50;//
        if(pwmval4<249)
                pwmval4=249;
        TIM_SetCompare4(TIM3,pwmval4);
}




void  Ctrl_Sum(void)
{
if(USART_RX_STA&0x8000)
                {                                          
                       
                                if(USART_RX_BUF[0]=='#')
                                {
                                       
                                        if(USART_RX_BUF[1]=='H')//PB4
                                        {
                                                if(USART_RX_BUF[2]=='1')//角度+
                                                {
                                                        Helm_1_Up();
                                                }
                                                if(USART_RX_BUF[2]=='0')//角度-
                                                {
                                                        Helm_1_Down();
                                                }
                                        }
                                       
                                       
                                                if(USART_RX_BUF[1]=='M')//PB5
                                        {
                                                if(USART_RX_BUF[2]=='1')//角度+
                                                {
                                                        Helm_2_Up();
                                                }
                                                if(USART_RX_BUF[2]=='0')//角度-
                                                {
                                                        Helm_2_Down();
                                                }
                                        }
                                       
                                       
                                                if(USART_RX_BUF[1]=='D')//PB0
                                        {
                                                if(USART_RX_BUF[2]=='1')//角度+
                                                {
                                                        Helm_3_Up();
                                                }
                                                if(USART_RX_BUF[2]=='0')//角度-
                                                {
                                                        Helm_3_Down();
                                                }
                                        }
                                       
                                                        if(USART_RX_BUF[1]=='T')//PB1
                                        {
                                                if(USART_RX_BUF[2]=='1')//角度+
                                                {
                                                        Helm_4_Up();
                                                }
                                                if(USART_RX_BUF[2]=='0')//角度-
                                                {
                                                        Helm_4_Down();
                                                }
                                        }
                                       


                               
                        USART_RX_STA=0;
                }
       
               
               


}         
}


main.c
#include "delay.h"
#include "sys.h"
#include "timer.h"
#include "usart.h"
#include "helm.h"
int main(void)
{               
        delay_init();                     //延时函数初始化          
        uart_init(115200);
        TIM3_PWM_Init(9999,143);         //周期=(arr+1)*(psc+1)/CLK
        //10000下  20ms  则 500表示1ms  可调区间0.5-2.5ms     即250-1250
   Helm_Init();
         
         while(1)
        {
               
                Ctrl_Sum();
               
        }
}


重点分析

timer.c中 因为部分重映射了 PB脚又是JTAG的复位脚 所以要关闭JTAG
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE) ; //关闭JTAG,保留SW做调试用
程序作用

这个代码是通过串口输入#D1 #D2 等指令调节四个不同的舵机角度。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分