【GD32F427开发板试用】基于蓝牙的远程步进电机控制

news2024/12/26 11:14:28

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:寒冰1988

一、前言

接上篇文章【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;
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    unsigned char Data[]={"this is a UART0 Test Demo\r\n" };
    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;
}

四、效果展示

参考如下视频,通过手机依次发送“0”、“1”、“2”、“3”、“4”等控制指令,从而实现LED灯的亮灭、步进电机的停止、正转、反转灯功能。

https://www.bilibili.com/video/BV1bW4y1K7rA​www.bilibili.com/video/BV1bW4y1K7rA

五、后记

基于蓝牙控制步进电机的开发工作上周完成,因为一些时间,本篇文章耽搁了一些。两篇试用涉及的内容本身难度不大,都是基于手中有的模块完成,是嵌入式开发的一些基本功,希望能给初学者一些启发。通过这些开发工作对GD32本身的开发流程也做了一个初步的学习,接下来会根据时间,上RTOS,进而开发一些更有意思的应用。

六、参考资料

  1. GD32F427V-START-V1.0.pdf
  2. GD32F4xx_gujiankushiyongzhinan_V1.0.pdf
  3. GD32F4xx_User_Manual_Rev2.7_CN.pdf
  4. GD32F427xx_Datasheet_Rev1.2.pdf
  5. GD32427V_START_Demo_Suites\Projects\01_GPIO_Running_LED
  6. DX-BT04-E 蓝牙模块技术手册2022.01.07.pdf
  7. 28BYJ-48单极性步进电机

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186741.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pytest-Allure测试报告

Allure 模块下载 pip install allure-pytest包下载 https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/此处我选择下载最新的&#xff0c;版本上可以选择不是最新的&#xff0c;2.9.0的。下载zip或者tgz后缀格式的都可以。 配置环境变量 找到解压…

RPA自动办公01——Uibot的安装和基础用法

本期开始RPA的学习流程。 RPA是机器人自动化流程的简写&#xff0c;目的在于减少重复性的劳动&#xff0c;而且上手很简单&#xff0c;无需编程就能用。 本系列使用Uibot 软件&#xff0c;其下载地址在&#xff1a;来也科技流程创造者&#xff08;UiBot Creator&#xff09; …

searchableSelect 插件使用

<script type"text/javascript" src"//searchableSelect.js"></script> <script>function getUserServer() {var _this 自定义封装接口请求、弹窗等方法;_this.getAjax("get","//xxxxx/server", {}, function(res)…

前端异常监控平台Sentry安装配置使用及问题

前言&#xff1a;Sentry是一款开源的异常监控平台,支持各种语言的SDK&#xff0c;通过对应SDK可以收集错误信息和性能数据&#xff0c;并可以再后台web页面中查看相关信息。官方地址&#xff1a;安装说明&#xff1a;https://develop.sentry.dev/self-hosted/后台使用说明&…

1.1计算机组成结构:CPU组成、冯·诺依曼结构与哈佛结构、嵌入式芯片术语

1.1计算机组成结构&#xff1a;CPU组成、冯诺依曼结构与哈佛结构、嵌入式芯片术语计算机组成结构CPU组成运算器控制器冯诺依曼结构与哈佛结构冯诺依曼结构哈佛结构嵌入式——芯片术语计算机组成结构 CPU组成 CPU分成两个部分&#xff0c;包括运算器和控制器。 CPU是计算机中核…

Linux之环境搭建

目录 一、VMware 二、centos7的安装 三、Mysql安装 四、 前端项目部署 1.确保前台项目能用 2.将前台项目打包npm run build 3.做ip/host主机映射 4.完成Nginx动静分离的default.conf的相关配置 5.将前端构件号的dist项目&#xff0c;上传到云服务器/usr/local/... …

[Swift]SDK开发

本文主要介绍使用swift语言制作framework Demo:https://github.com/Gamin-fzym/CMSDK 一、创建工程 1.创建目录 这里我创建了一个“CMSDK”目录 2.打开Xcode新建workspace放入CMSDK目录 这里命名为“CMSDK” 3.打开CMSDK.xcworkspace新建SDK工程放入CMSDK目录 这里还是命…

06 CSS-盒子模型【尚硅谷JavaWeb教程】

06 CSS-盒子模型【尚硅谷JavaWeb教程】 JAVAWEB的学习笔记 学习视频来自&#xff1a;https://www.bilibili.com/video/BV1AS4y177xJ/?vd_source75dce036dc8244310435eaf03de4e330 不同的浏览器导致前端展示页面不一样&#xff0c;盒子的大小的不同。&#xff08;所以前端要考虑…

奇迹mu开服教程

奇迹mu开服教程&#xff1a;开服服务端的架设及开服注意事项服务器推荐奇迹开服需要准备什么&#xff1f;开服大概成本分析奇迹MU商业服务端版本&#xff1a;1.02W、1.03H、1.03K、S6EP3、S7EP2、S9EP2&#xff1b;HE网站系统&#xff1a;绑定域名授权&#xff0c;功能可定制&a…

Jenkins部署项目一(物理机器部署SpringBoot项目)

一、Jenkins部署SpringBoot项目 设备&#xff1a;MacOS 准备工作 1.已安装java开发工具包JDK 2.已安装依赖管理工具Maven 3.已安装代码版本控制工具Git 4.已安装Jenkins learn-moon代码地址&#xff1a;https://github.com/BillDavidup/learn-moon SSH: gitgithub.com:Bil…

【学Vue就跟玩一样】如何使用集中式状态管理的Vuex以及如何模块化编码+命名空间

1.vuex是什么一个专门在Vue中实现集中式状态管理的一个Vue插件,可以对vue应用中多个组件的共享状态进行集中式的管理(读取/写入)&#xff0c;也是一种组件间通信的方式&#xff0c;并且适用于任意组件间通信2.什么时候使用Vuex1.多个组件依赖于同一状态2.来自不同组件的行为需要…

Goland入门指南(使用Goland创建并运行项目)

在文章《Goland下载和安装》详细介绍了 Goland 的安装和破解&#xff0c;本节我们来介绍一下怎么使用 Goland 来创建并运行一个项目。 创建项目 首先&#xff0c;在“文件”菜单中找到“New”&#xff0c;并在下一级菜单中选择“Project”来创建一个新项目。 为项目选择一个…

【vim】C语言代码提示

前言 常见的C语言提示插件是YouCompleteMe&#xff0c;这个插件安装比较麻烦&#xff0c;在这推荐一款coc.nvim这个插件&#xff0c;github仓库地址&#xff1a;https://github.com/neoclide/coc.nvim/ 下面是安装步骤。 一、安装 nodejs 1、终端命令安装 curl -sL instal…

SpringMVC DispatcherServlet源码(2) 扫描Controller创建HandlerMapping流程

Spring MVC向容器注册一个RequestMappingInfoHandlerMapping组件&#xff0c;他会扫描容器中的Controller组件&#xff0c;创建RequestMappingInfo并注册HandlerMethod映射关系。 本文将阅读Spring MVC源码分析上述流程。 RequestMappingHandlerMapping组件 Creates Request…

java ssm校园兼职发布与互动平台的设计与实现

该系统基于B/S即所谓浏览器/服务器模式&#xff0c;应用JSP技术&#xff0c;选择MySQL作为后台数据库。系统主要包括个人中心、用户管理、企业管理、企业信息管理、兼职信息管理、职位申请管理、职位类型管理、交流中心、留言反馈、系统管理等功能模块。 使用校园兼职发布与互动…

JavaWeb:会话技术之Session

Cookie已经能完成一次会话多次请求之间的数据共享&#xff0c;之前我们还提到过Session也可以实现&#xff0c;那么&#xff1a; 什么是Session&#xff1f;Session如何来使用&#xff1f;Session是如何实现的&#xff1f;Session的使用注意事项有哪些&#xff1f; 1. Sessio…

SpringCloud学习笔记 - 熔断降级 - Sentinel

1. Sentinel熔断降级概述 1.1. 熔断降级要解决的问题 除了流量控制以外&#xff0c;对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块&#xff0c;可能是另外的一个远程服务、数据库&#xff0c;或者第三方 API 等。例如&…

海康Visionmaster-VM权限设置、软件设置、方案设置和运行策略

权限设置 权限设置可设置是否配置管理员、技术员和操作员权限和配置密码&#xff0c;并设置不同角色人员的权限。 权限导入导出可对当前软件权限设置模块的配置以txt格式文档进行导入或导出。 打开启用加密时&#xff0c;需设置管理员密码。设置完成后&#xff0c;软件以管理员…

如何把Node项目部署到服务器上

1. 如何合理选购一台服务器 对于服务器的选择&#xff0c;我们主要有以下几种选择&#xff1a; 1. 阿里云&#xff1b; 2. 腾讯云&#xff1b; 3. 华为云&#xff1b; 4. 亚马逊云&#xff1b; 国内用户如果没有特殊需求可以选择前三种&#xff0c;这里我阿里云举例&…

【Vue】vue-devtools调试工具安装和配置

1. 安装 vue-devtools 调试工具vue 官方提供的 vue-devtools 调试工具&#xff0c;能够方便开发者对 vue 项目进行调试与开发。Chrome 浏览器在线安装 vue-devtools &#xff1a;https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpdFi…