OpenEdv-开源电子网

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

STM32F4通过PWM控制电机

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-5-20
在线时间
2 小时
发表于 2017-5-20 16:05:27 | 显示全部楼层 |阅读模式
1金钱
通过红外遥控的上下键来调整电机转速的期望值,然后控制电机通过PID达到期望转速,并将实时转速显示在LCD上。现在的问题是按动遥控器电机没有动作,请大神帮忙

#include "control.h"
#include "led.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_rcc.h"
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//定时器 驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/4
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////          


//通用定时器3中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM3,ENABLE); //使能定时器3
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //响应优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
}
int speed;
int count=0;
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
                speed=count;
                count=0;
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}


//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//外部中断 驱动代码          
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2014/5/4
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved                                                                          
//////////////////////////////////////////////////////////////////////////////////

//外部中断0服务程序



//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
        delay_ms(10);        //消抖
        if(EXTI_GetITStatus(EXTI_Line2)!=RESET){
   count++;
         EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE2上的中断标志位
        }
}

void EXTIX_Init(void)
{
        NVIC_InitTypeDef   NVIC_InitStructure;
        EXTI_InitTypeDef   EXTI_InitStructure;
       


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
       

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//PE2 连接到中断线2

       

        /* 配置EXTI_Line2,3,4 */
        EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line4;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
  EXTI_Init(&EXTI_InitStructure);//配置


       
        NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中断2
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_InitStructure);//配置

          
}


        //TIM14 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc)
{                                                          
        //此部分需手动修改IO口设置
       
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);          //TIM14时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);         //使能PORTF时钟       
       
        GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
        GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9
          
        TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
       
        //初始化TIM14 Channel1 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
        TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

        TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器

  TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
       
        TIM_Cmd(TIM14, ENABLE);  //使能TIM14

                                                                                  
}  




#include "sys.h"
#include "delay.h"
#include "usart.h"

#include "lcd.h"
#include "remote.h"
#include "control.h"
//ALIENTEK 探索者STM32F407开发板 实验29
//红外遥控器实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com  
//广州市星翼电子科技有限公司  
//作者:正点原子 @ALIENTEK
extern int count,speed;


int main(void)
{
        u8 key,speed;
        int error3,error2,error1,prop,inte,diff,num;
        u8 t=0;       
        u8 *str=0;
        u16 led0pwmval=40;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);//设置系统中断优先级分组2
        delay_init(168);  //初始化延时函数
        uart_init(115200);                //初始化串口波特率为115200

        TIM14_PWM_Init(500-1,84-1);        //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.  

        LCD_Init();
        Remote_Init();                                //红外接收初始化                        
        TIM3_Int_Init(10000-1,8400-1);        //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数10000次为1s
  EXTIX_Init();       
        POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");       
        LCD_ShowString(30,70,200,16,16,"REMOTE TEST");       
        LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,110,200,16,16,"2014/5/7");
        LCD_ShowString(30,130,200,16,16,"KEYVAL:");       
        LCD_ShowString(30,150,200,16,16,"KEYCNT:");       
        LCD_ShowString(30,170,200,16,16,"SYMBOL:");            
        LCD_ShowString(30,190,200,16,16,"r:");            
                                                                                                                                                                                                         
        while(1)
        {
                TIM_SetCompare1(TIM14,led0pwmval);

                key=Remote_Scan();       
                if(key)
                {         
                        LCD_ShowNum(86,130,key,3,16);                //显示键值
                        LCD_ShowNum(86,150,speed,3,16);        //显示速度                  
                        switch(key)
                        {
                                case 98:str="SPEED UP";
                                        delay_ms(10);         
                                        led0pwmval+=2;//led0pwmval递减
                                        if(led0pwmval>300)led0pwmval=300;//led0pwmval到达300后,方向为递减
                                        TIM_SetCompare1(TIM14,led0pwmval);        //修改比较值,修改占空比
                                        error3=error2;
                                        error2=error1;
                                        error1=led0pwmval-count;
                                        prop=error1-error2;
                                        inte=error1;
                                        diff=error1-2*error2+error3;
                                        num=count;
                                        num=num+0.5*prop+0.1*inte+0.5+0.2*diff;       
                                        LCD_ShowxNum(100,190,speed,10,24,0);                               
                            TIM_SetCompare1(TIM14,num);       
                                        break;
                                case 168:str="SPEED DOWN";
                                        delay_ms(10);         
                                        led0pwmval-=2;//led0pwmval递减
                                        if(led0pwmval<10)led0pwmval=10;//led0pwmval到达300后,方向为递减
                                        TIM_SetCompare1(TIM14,led0pwmval);        //修改比较值,修改占空比
                                        error3=error2;
                                        error2=error1;
                                        error1=led0pwmval-count;
                                        prop=error1-error2;
                                        inte=error1;
                                        diff=error1-2*error2+error3;
                                        num=count;
                                        num=num+0.5*prop+0.1*inte+0.5+0.2*diff;               
                                        LCD_ShowxNum(100,190,speed,10,24,0);                                       
                            TIM_SetCompare1(TIM14,num);       
                                        break;       
                                                               
                        }
                        LCD_Fill(86,170,116+8*8,170+16,WHITE);        //清楚之前的显示
                        LCD_ShowString(86,170,200,16,16,str);        //显示SYMBOL
                }else delay_ms(10);          
                t++;
                if(t==20)
                {
                        t=0;
                       
                }
               
               
        }
}



实验29 红外遥控实验.zip

5.09 MB, 下载次数: 156

电机控制程序

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

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-5-20
在线时间
2 小时
 楼主| 发表于 2017-5-21 15:21:09 来自手机 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-5-21 18:37:36 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2017-5-20
在线时间
2 小时
 楼主| 发表于 2017-5-23 09:10:13 | 显示全部楼层
顶顶顶~
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-18 01:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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