找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3273|回复: 1
收起左侧

STM32F4+A3984芯片简单的步进电机控制程序

[复制链接]
ID:498764 发表于 2019-3-26 22:05 | 显示全部楼层 |阅读模式
采用A3984驱动芯片
同时也兼容不部分驱动器
控制主要包括三点:PWM脉冲输出,DIR方向选择,EN控制使能
采用定时器输出比较模式

单片机源程序如下:
  1. #include "stm32f4xx.h"
  2. #include "MicroStepDriver.h"
  3. #include "bsp_debug_usart.h"
  4. #include "mpu6050.h"

  5. /**
  6.   * @brief  主函数
  7.   * @param  无  
  8.   * @retval 无
  9.   */
  10. int main(void)
  11. {
  12. //          signed int step;          //步数
  13. //    signed int now_place;     //当前角度

  14.         //步进电机初始化
  15.         MSD_Init();

  16.     while(1)
  17.   {

  18.         }
  19.                           
  20. }
  21. /*********************************************END OF FILE**********************/
复制代码
  1. #include "MicroStepDriver.h"
  2. #include <stdio.h>
  3. #include <math.h>
  4. //系统加减速参数
  5. //speedRampData srd;
  6. ////记录步进电机的位置
  7. //int stepPosition = 0;
  8. ////系统电机、串口状态
  9. //struct GLOBAL_FLAGS status = {FALSE, FALSE,TRUE};

  10. /**

  11.   * @brief  定时器中断优先级配置

  12.   * @param  无

  13.   * @retval 无

  14.   */
  15. static void TIM_NVIC_Config(void)

  16. {
  17.     NVIC_InitTypeDef NVIC_InitStructure;
  18.     // 设置中断组为0
  19.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);               
  20.         // 设置中断来源
  21.     NVIC_InitStructure.NVIC_IRQChannel = MSD_PULSE_TIM_IRQ;        
  22.         // 设置抢占优先级
  23.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;         
  24.         // 设置子优先级
  25.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;       
  26.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  27.     NVIC_Init(&NVIC_InitStructure);

  28. }
  29. /**

  30.   * @brief  初始化电机驱动用到的引脚

  31.   * @param  无

  32.   * @retval 无

  33.   */
  34. static void MSD_GPIO_Config(void)
  35. {
  36.     GPIO_InitTypeDef GPIO_InitStructure;

  37.     //电机脉冲输出 GPIO 初始化
  38.     MSD_PULSE_AHBxClock_FUN(MSD_PULSE_GPIO_CLK, ENABLE);
  39.     GPIO_InitStructure.GPIO_Pin =  MSD_PULSE_PIN;
  40.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  41.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  42.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  43.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  44.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  45.     GPIO_Init(MSD_PULSE_PORT, &GPIO_InitStructure);
  46.       /*  连接 PXx 到 定时器输出通道*/
  47.     GPIO_PinAFConfig(MSD_PULSE_PORT,MSD_PULSE_PIN_SOURCE,MSD_PULSE_PIN_AF);
  48.    
  49.     //电机方向输出 GPIO 、细分、reset、sleep初始化
  50.     MSD_DIR_AHBxClock_FUN(MSD_DIR_GPIO_CLK, ENABLE);
  51.     GPIO_InitStructure.GPIO_Pin =  MSD_DIR_PIN;
  52.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  53.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  54.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  55.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  56.     GPIO_Init(MSD_DIR_PORT, &GPIO_InitStructure);
  57.     GPIO_ResetBits(MSD_DIR_PORT,MSD_DIR_PIN);
  58.                
  59.         //电机使能输出 GPIO 初始化
  60.     MSD_ENA_AHBxClock_FUN(MSD_ENA_GPIO_CLK, ENABLE);
  61.     GPIO_InitStructure.GPIO_Pin =  MSD_ENA_PIN;
  62.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  63.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  64.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  65.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  66.     GPIO_Init(MSD_ENA_PORT, &GPIO_InitStructure);
  67.     GPIO_ResetBits(MSD_ENA_PORT,MSD_ENA_PIN);
  68. }


  69. ///*
  70. // * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
  71. // * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
  72. // * 另外三个成员是通用定时器和高级定时器才有.
  73. // *-----------------------------------------------------------------------------
  74. // *typedef struct
  75. // *{ TIM_Prescaler            都有
  76. // *  TIM_CounterMode                   TIMx,x[6,7]没有,其他都有
  77. // *  TIM_Period               都有
  78. // *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有
  79. // *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有
  80. // *}TIM_TimeBaseInitTypeDef;
  81. // *-----------------------------------------------------------------------------
  82. // */

  83. /* ----------------   PWM信号 周期和占空比的计算--------------- */
  84. // ARR :自动重装载寄存器的值
  85. // CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 168M/(psc+1)
  86. // PWM 信号的周期 T = (ARR+1) * (1/CLK_cnt) = (ARR+1)*(PSC+1) / 72M
  87. // 占空比P=CCR/(ARR+1)

  88. static void TIM_Mode_Config(void)
  89. {
  90.   // 开启定时器时钟,即内部时钟CK_INT=168M
  91.         MSD_PULSE_TIM_APBxClock_FUN(MSD_PULSE_TIM_CLK,ENABLE);

  92.     /*--------------------时基结构体初始化-------------------------*/
  93.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  94.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  95.     // 自动重装载寄存器的值,累计TIM_Period+1个周期后产生一个更新或者中断
  96.         TIM_TimeBaseStructure.TIM_Period=MSD_PULSE_TIM_PERIOD;       
  97.         // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
  98.         TIM_TimeBaseStructure.TIM_Prescaler= MSD_PULSE_TIM_PSC;       
  99.         // 时钟分频因子 ,配置死区时间时需要用到
  100.         TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;               
  101.         // 计数器计数模式,设置为向上计数
  102.         TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;               
  103.         // 重复计数器的值,最大值为255
  104.         //TIM_TimeBaseStructure.TIM_RepetitionCounter=0;       
  105.         // 初始化定时器
  106.         TIM_TimeBaseInit(MSD_PULSE_TIM, &TIM_TimeBaseStructure);

  107.         /*--------------------输出比较结构体初始化-------------------*/               
  108.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  109.         // 配置为PWM模式2
  110.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  111.         // 输出使能
  112.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  113.         // 互补输出禁能
  114.         TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
  115.         // 设置占空比大小
  116.         TIM_OCInitStructure.TIM_Pulse = MSD_PULSE_TIM_PERIOD/2;
  117.         // 输出通道电平极性配置
  118.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  119.         // 输出通道空闲电平极性配置
  120.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  121.    
  122.         MSD_PULSE_OCx_Init(MSD_PULSE_TIM, &TIM_OCInitStructure);
  123.     //使能TIM1_CH1预装载寄存器
  124.         MSD_PULSE_OCx_PreloadConfig(MSD_PULSE_TIM, TIM_OCPreload_Enable);
  125.     //使能TIM1预装载寄存器
  126.     TIM_ARRPreloadConfig(MSD_PULSE_TIM, ENABLE);
  127.    
  128.     //设置中断源,只有溢出时才中断
  129.     TIM_UpdateRequestConfig(MSD_PULSE_TIM,TIM_UpdateSource_Regular);
  130.         // 清除中断标志位
  131.         TIM_ClearITPendingBit(MSD_PULSE_TIM, TIM_IT_Update);
  132.     // 使能中断
  133.     TIM_ITConfig(MSD_PULSE_TIM, TIM_IT_Update, ENABLE);
  134.         // 使能计数器
  135.         TIM_Cmd(MSD_PULSE_TIM, ENABLE);
  136. }
  137. /**

  138.   * @brief  初始化电机相关的外设

  139.   * @param  无

  140.   * @retval 无

  141.   */
  142. void MSD_Init(void)
  143. {
  144.     MSD_GPIO_Config();
  145.    
  146.     TIM_NVIC_Config();

  147.     TIM_Mode_Config();   
  148. }


  149. /*********************************************END OF FILE**********************/
复制代码

  1. #include "mpu6050.h"
  2. #include "string.h"

  3. struct STime                stcTime;
  4. struct SAcc                 stcAcc;
  5. struct SGyro                 stcGyro;
  6. struct SAngle         stcAngle;
  7. struct SMag                 stcMag;
  8. struct SDStatus stcDStatus;
  9. struct SPress         stcPress;
  10. struct SLonLat         stcLonLat;
  11. struct SGPSV                 stcGPSV;

  12. //unsigned char [250];

  13. //CopeSerialData为串口中断调用函数,串口每收到一个数据,调用一次这个函数。
  14. //处理串口接收到的陀螺仪数据
  15. void CopeSerialData(unsigned char ucData)
  16. {
  17.         static unsigned char ucRxBuffer[250];
  18.         static unsigned char ucRxCnt = 0;       
  19.        
  20.         ucRxBuffer[ucRxCnt++]=ucData;
  21.         if (ucRxBuffer[0]!=0x55) //数据头不对,则重新开始寻找0x55数据头
  22.         {
  23.                 ucRxCnt=0;
  24.                 return;
  25.         }
  26.         if (ucRxCnt<11) {return;}//数据不满11个,则返回
  27.         else
  28.         {
  29.                 switch(ucRxBuffer[1])
  30.                 {
  31.                         case 0x50:        memcpy(&stcTime,&ucRxBuffer[2],8);break;//memcpy为编译器自带的内存拷贝函数,需引用"string.h",将接收缓冲区的字符拷贝到数据共同体里面,从而实现数据的解析。
  32.                         case 0x51:        memcpy(&stcAcc,&ucRxBuffer[2],8);break;
  33.                         case 0x52:        memcpy(&stcGyro,&ucRxBuffer[2],8);break;
  34.                         case 0x53:        memcpy(&stcAngle,&ucRxBuffer[2],8);break;
  35.                     case 0x54:        memcpy(&stcMag,&ucRxBuffer[2],8);break;
  36.                         case 0x55:        memcpy(&stcDStatus,&ucRxBuffer[2],8);break;
  37.                         case 0x56:        memcpy(&stcPress,&ucRxBuffer[2],8);break;
  38.                         case 0x57:        memcpy(&stcLonLat,&ucRxBuffer[2],8);break;
  39.                         case 0x58:        memcpy(&stcGPSV,&ucRxBuffer[2],8);break;
  40.                 }
  41.                 ucRxCnt=0;
  42.         }
  43. }
复制代码


所有资料51hei提供下载:
定时器.7z (355.16 KB, 下载次数: 37)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:741018 发表于 2020-5-20 20:30 来自手机 | 显示全部楼层
有电路图吗
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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