ARM技术论坛
直播中

世态薄凉

8年用户 1179经验值
私信 关注
[经验]

基于蓝牙的远程步进电机控制简介

一、前言

接上篇文章【GD32F427开发板试用】基于蓝牙模块的远程点灯演示,本篇是第二篇,基于调通的蓝牙模块添加对步进电机的控制。实现步进电机的控制以后就可以进一步延申实现车辆的前进、后退、转向和简单的机械臂控制等功能。

二、硬件环境
2.1 步进电机简介本次实验采用的步进电机型号为28BYJ-48,为外径28毫米四相八拍式永磁减速型步进电机,该款型号步进电机支持如下三种驱动方式:

本文的实现中选用八拍模式,各组管脚的控制逻辑如下图所示:


2.2 ULN2003驱动板由于单片机本身的驱动能力不足,因此通常会使用ULN2003来驱动电机。


2.3 设备连接采用PC7-PC10四根管脚来控制电机的相位,采用移动电源给电机驱动板提供5V的输入,蓝牙模块的链接参见上篇文章。


三、软件实现
3.1 相位控制逻辑按照2.1章节中介绍,以此拉高PC7-PC10,实现相位的控制,代码如下
  #define A_ON gpio_bit_set(GPIOC, GPIO_PIN_7)
  #define A_OFF gpio_bit_reset(GPIOC, GPIO_PIN_7)
  #define B_ON gpio_bit_set(GPIOC, GPIO_PIN_8)
  #define B_OFF gpio_bit_reset(GPIOC, GPIO_PIN_8)
  #define C_ON gpio_bit_set(GPIOC, GPIO_PIN_9)
  #define C_OFF gpio_bit_reset(GPIOC, GPIO_PIN_9)
  #define D_ON gpio_bit_set(GPIOC, GPIO_PIN_10)

  #define D_OFF gpio_bit_reset(GPIOC, GPIO_PIN_10)

3.2 配置GPIO的模式
参照PC6的配置,将PC7-PC10配置为GPIO-OUTPUT模式,代码如下
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10);

  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

组要注意是如果管脚反转过快过着过慢会出现电机振动但是不转的现象,通过多次实验,将每循环的的延时定位2ms,参见完整代码motor_forward()motor_backoff两个函数。

3.3 蓝牙的控制根据之前的定义,发送“0”字符(对应ASII码0x30)关闭LED灯,发送“1”字符(对应ASII码0x31)开启LED灯,继续增加“2”字符代表电机停止,“3”代表正转,“4”代表反转;


3.4 完整代码  #include “gd32f4xx.h”
  #include “gd32f427v_start.h”
  #include “systick.h”
  #include 《stdio.h》
  #define A_ON gpio_bit_set(GPIOC, GPIO_PIN_7)
  #define A_OFF gpio_bit_reset(GPIOC, GPIO_PIN_7)
  #define B_ON gpio_bit_set(GPIOC, GPIO_PIN_8)
  #define B_OFF gpio_bit_reset(GPIOC, GPIO_PIN_8)
  #define C_ON gpio_bit_set(GPIOC, GPIO_PIN_9)
  #define C_OFF gpio_bit_reset(GPIOC, GPIO_PIN_9)
  #define D_ON gpio_bit_set(GPIOC, GPIO_PIN_10)
  #define D_OFF gpio_bit_reset(GPIOC, GPIO_PIN_10)
  void UART0_Transmit(unsigned char *Data,unsigned int Lenth)
  {
  int i=0;
  for(i=0;i《Lenth;i++)
  {
  usart_data_transmit(USART0,Data[i]);
  while(RESET == usart_flag_get(USART0, USART_FLAG_TC));
  }
  }
  void motor_stop(void)
  {
  gpio_bit_reset(GPIOC, GPIO_PIN_7);
  gpio_bit_reset(GPIOC, GPIO_PIN_8);
  gpio_bit_reset(GPIOC, GPIO_PIN_9);
  gpio_bit_reset(GPIOC, GPIO_PIN_10);
  return;
  }
  void motor_forward(void)
  {
  int i = 8, rotation = 0;
  for(rotation=0; rotation《1000; rotation++)
  {
  switch(i)
  {
  case 0:
  A_ON; B_OFF; C_OFF; D_OFF;
  break;
  case 1:
  A_ON; B_ON; C_OFF; D_OFF;
  break;
  case 2:
  A_OFF; B_ON; C_OFF; D_OFF;
  break;
  case 3:
  A_OFF; B_ON; C_ON; D_OFF;
  break;
  case 4:
  A_OFF; B_OFF; C_ON; D_OFF;
  break;
  case 5:
  A_OFF; B_OFF; C_ON; D_ON;
  break;
  case 6:
  A_OFF; B_OFF; C_OFF; D_ON;
  break;
  case 7:
  A_ON; B_OFF; C_OFF; D_ON;
  break;
  }
  i--;
  if(i==0) i=8;
  delay_1ms(2);
  }
  return;
  }
  void motor_backoff(void)
  {
  int i = 0, rotation = 0;
  for(rotation=0; rotation《1000; rotation++)
  {
  switch(i)
  {
  case 0:
  A_ON; B_OFF; C_OFF; D_OFF;
  break;
  case 1:
  A_ON; B_ON; C_OFF; D_OFF;
  break;
  case 2:
  A_OFF; B_ON; C_OFF; D_OFF;
  break;
  case 3:
  A_OFF; B_ON; C_ON; D_OFF;
  break;
  case 4:
  A_OFF; B_OFF; C_ON; D_OFF;
  break;
  case 5:
  A_OFF; B_OFF; C_ON; D_ON;
  break;
  case 6:
  A_OFF; B_OFF; C_OFF; D_ON;
  break;
  case 7:
  A_ON; B_OFF; C_OFF; D_ON;
  break;
  }
  i++;
  if(i==8) i=0;
  delay_1ms(2);
  }
  return;
  }
  /*!
  rief main function
  param[in] none
  param[out] none
  
etval none
  */
  int main(void)
  {
  unsigned char Data[]={“this is a UART0 Test Demo
” };
  unsigned char rxbuf[16] = {0}, ch = 0;
  int i = 0, ret=0, j=0;
  /* configure systick */
  systick_config();
  /* enable clock */
  rcu_periph_clock_enable(RCU_GPIOC);
  rcu_periph_clock_enable(RCU_GPIOB);
  rcu_periph_clock_enable(RCU_USART0);
  /* configure GPIO port */
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
  /* reset GPIO pin */
  gpio_bit_reset(GPIOC, GPIO_PIN_6);
  gpio_bit_reset(GPIOC, GPIO_PIN_7);
  gpio_bit_reset(GPIOC, GPIO_PIN_8);
  gpio_bit_reset(GPIOC, GPIO_PIN_9);
  gpio_bit_reset(GPIOC, GPIO_PIN_10);
  /* configure the USART0 TX pin and USART0 RX pin */
  gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6);
  gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7);
  /* configure USART0 TX as alternate function push-pull */
  gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  /* configure USART0 RX as alternate function push-pull */
  gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
  gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  /* USART configure */
  usart_deinit(USART0);
  usart_baudrate_set(USART0, 9600U);
  usart_receive_config(USART0, USART_RECEIVE_ENABLE);
  usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
  usart_enable(USART0);
  //ch = 0x30;
  while(1) {
  while (RESET == usart_flag_get(USART0, USART_FLAG_RBNE));
  ch = usart_data_receive(USART0);
  if (ch == 0x30) {
  /* turn off LED2 */
  gpio_bit_reset(GPIOC, GPIO_PIN_6);
  ch = 0;
  }
  if (ch == 0x31) {
  /* turn on LED2 */
  gpio_bit_set(GPIOC, GPIO_PIN_6);
  ch = 0;
  }
  if (ch == 0x32) {
  /* motor stop */
  motor_stop();
  ch = 0;
  }
  if (ch == 0x33) {
  /* motor forward */
  motor_forward();
  ch = 0;
  }
  if (ch == 0x34) {
  /* motor backoff */
  motor_backoff();
  ch = 0;
  }
  //ch ++;
  //if(ch == 0x35) ch = 0x30;
  //delay_1ms(1000);
  }
  return 0;
  }





原作者:兆易创新GD32 MCU 寒冰1988·


更多回帖

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