当前位置: 首页 > news >正文

【毕业设计】 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 硬件设计
    • 总体框架
    • **AB32VG1主控MCU**
  • 5 软件说明
    • 总体框架
  • 6 部分核心代码
  • 7 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于单片机的自动写字机器人设计与实现

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:5分

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


1 简介

基于RTthread的写字机控制系统,采用独立研发的运动控制系统,结合RTT的多线程,将运动控制分解,速度前馈、折线速度平滑优化。AB32VG1开发板作为UI交互和sd卡gc文件读取,采用串口将运动命令发送给STM32。STM32负责将串口接收到的G命令进行解析,运动计算、控制输出P合适的PWM频率和脉冲个数给4个电机。运动控制算法完全独立创作。 Halo项目是我9月初时候的一个自研3D打印机的固件,前期在工作中接触到Marlin(一款优秀的开源3D打印固件,提供了丰富的扩展功能,拥有完整成熟的生态),遂想自研一款基于国产芯片和操作系统的3D打印系统,能提供在咱国产的芯片中方便移植与运行,提供3D打印所需的所有功能,降低硬件成本和软件适配成本。

2 主要器件

  • STM32F4单片机
  • AB32VG1单片机
  • RT-Thread物联网操作系统
  • SD卡文件读取与发送
  • 速度前馈、折角优化、加速处理等算法

3 实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4 硬件设计

总体框架

AB32V负责GUI和SD卡文件,STM32负责运动控制

最初设想是采用两块AB32的板子,一个负责GUI人机交互和SD卡文件读取与发送,一块负责接收Gcode命令,完成速度前馈、折角优化、加速处理等算法,实现完整的运动控制算法。但实际在AB32上跑控制时,发现浮点运算会导致异常的问题,同时打印日志都经常遇到栈溢出导致系统崩溃,因此将运动控制算法移植到STM32F4的板子上运行,控制效果良好。

在这里插入图片描述

AB32VG1主控MCU

简介

开发板采用中科蓝讯的32位RISC-V指令集的AB32VG1型号MCU,主频120M。MCU有8M的Flash,和192K SRAM。支持3.0V-5.0V供电。
与一般MCU不同的是,这款MCU具有MPU模块,就是电源管理模块,支持Charge电路、BUCK电路、LDO电路等等,手册第十页给出了MPU模块的详细参数。
在这里插入图片描述
开发环境搭建

根据官方的指导,使用的是RT-thread官方stduio平台,先更新软件源代码至最新版,下载中科蓝讯软件包,下载RISC-V-GCC工具链,编译程序会用到。

在这里插入图片描述

软件包配置

在这里插入图片描述
接下来选择我们本次实验用到的软件包,wavplayer软件包、optparse软件包和multibutton软件包,实现通过板载按键控制声音的播放语音量的增减。
在这里插入图片描述
然后对软件包进行简单配置,按键的示例代码可以勾选也可以不勾选,后面要对此进行修改,改为评测板上的用户按键,optparse软件包默认即可。
在这里插入图片描述

5 软件说明

总体框架

在这里插入图片描述
代码树

在这里插入图片描述

6 部分核心代码

int main(void)
{
    rt_thread_mdelay(1000);
    serial_thread_init(NULL);
    while(1){
        //debug_error("Insufficient system memory");
        while(refresh_file_names("/") == 0){
            rt_thread_mdelay(1000);
        }
        uart_lcd_thread_init();
        rt_thread_mdelay(100);
        gui_into_print_list(NULL);
        while(1){
            rt_thread_mdelay(1000);;
        }
    }
    g_gcode_ringbuff = ringbuff_create(sizeof(uint8_t), 4096);
    if(g_gcode_ringbuff == NULL){
        debug_error("Insufficient system memory");
        while(1);
    }
    while(1){
        rt_thread_mdelay(1000);
        debug_info("rt - thread\r\n");
    }
    while (1)
    {
        list_cur_dir_files("/");

        if(dfs_file_open(&s_fd, get_cur_dif_file_name(0), O_RDONLY) < 0){
            debug_info("open file %s error", get_cur_dif_file_name(0));
            continue;
        }
        debug_info("open file %s ok", get_cur_dif_file_name(0));
        int read_bytes;
        uint8_t buff[512];
        int idx = 0;
        do{
            memset(buff, 0, sizeof(buff));
            read_bytes = dfs_file_read(&s_fd, buff, sizeof(buff));
            while(ringbuff_remin(g_gcode_ringbuff) < read_bytes){
                rt_thread_yield();
            }
            for(int i = 0; i < read_bytes; i++){
                ringbuff_push(g_gcode_ringbuff, &buff[i]);
            }
        }while(read_bytes > 0);
        dfs_file_close(&s_fd);
    }

    return RT_EOK;
}
/* 定时器超时回调函数 */
#if (defined SOC_AB32VG1)
RT_SECTION(".irq.timer")
#endif
static rt_err_t step_run_schdule(rt_device_t dev, rt_size_t size)
{
    extern motion_control_t *motion_control;
    if((motion_control->motion_step_z.ops->is_motion(&(motion_control->motion_step_z)) == true) ||
            (ringbuff_is_empty(motion_control->motion_step_z.step_drv->pulse_list) == false)){
        motion_control->motion_step_z.step_drv->ops-> \
                        timer_schdule(motion_control->motion_step_z.step_drv);

        return RT_EOK;
    }

    motion_control->motion_step_x.step_drv->ops-> \
            timer_schdule(motion_control->motion_step_x.step_drv);
    motion_control->motion_step_y.step_drv->ops-> \
            timer_schdule(motion_control->motion_step_y.step_drv);
    motion_control->motion_step_y_1.step_drv->ops-> \
                timer_schdule(motion_control->motion_step_y_1.step_drv);

    return RT_EOK;
}


/* 初始化挤出机 */
void fdm_extruder_init(void)
{
    if(false == temperature_register(&s_temperature_ntc, temperature_type_ntc)){
        return;
    }

    /* 初始化传感器接口 */
    if(false == temperature_init(&s_temperature_ntc,            /* 描述符 */
                                 TEMPERATURE_NTC_ADC_DEV_NAME,  /* 驱动名称 */
                                 TEMPERATURE_NTC_ADC_DEV_CHANNEL, /* 通道号 */
                                 12,                            /* adc精度 */
                                 ntc_mode_zm_1460,              /* ntc传感器型号 */
                                 4700)){                        /* 上拉电阻阻值 */

    }
}

void fdm_printer_test(void)
{
    /* 初始化所有的温度传感器 */
    //fdm_extruder_init();

    rt_pin_mode(49, PIN_MODE_OUTPUT);
    rt_pin_write(49, PIN_HIGH);

#if 0
    heater_t *heater;
    heater = heater_create(pid_type_position);
    /* 设置pid的三个参数,输出最大、最小值 */
    heater->pid->ops->init(heater->pid, 0.5, 0.5, 1, 100, 0);
    /* 设置调节的目标值 */
    heater->pid->ops->target_set(heater->pid, 30);
    /* 绑定温度传感器,设置pid的计算周期 */
    heater->ops->init(heater, 1, true, 3000, &s_temperature_ntc);
    /* 开始软件定时器 */
    heater->ops->start(heater);
#endif
    hard_task_t *hard_task;
    /* 创建硬实时任务对象 */
    hard_task = hard_task_creater();

    hard_task->ops->init(hard_task, STEP_SCHDULE_HWTIMER_DEV_NAME,
                         STEP_SCHDULE_TIMER_FREQ);//
    hard_task->ops->set_run(hard_task, step_run_schdule);

    hard_task->ops->start(hard_task, STEP_SCHDULE_FREQ);
}

7 最后

相关文章:

  • 花边新闻获取易语言代码
  • HTML5入门(1)——HTML基础
  • 计算机网络体概念
  • redis底层都有哪些数据结构?带你了解redis是如何存储数据的
  • 通道分离与合并、彩色图转换为灰度图、二值化
  • C语言经典算法实例4:判断回文数
  • 基于php+mysql的菜品食谱美食网
  • upload-labs靶场通关指南(第1-3关)
  • Android Studio 利用系统签名打包apk
  • 升级打怪课堂的题库更新了!
  • Excel·VBA数组排列函数
  • 高级程序员项目经理写好代码必备的三条基本素质;以及代码的现象和本质问题解读;
  • 猿创征文|多模态图像合成和编辑(MISE):Multimodal Image Synthesis and Editing: A Survey
  • 网络与信息安全基础知识-- Internet及应用
  • 中秋邀请共赏图数据库-蚂蚁集团图数据TuGraph 正式开源
  • [NodeJS] 关于Buffer
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Laravel 中的一个后期静态绑定
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Node + FFmpeg 实现Canvas动画导出视频
  • Python - 闭包Closure
  • Python_网络编程
  • React-redux的原理以及使用
  • spring boot 整合mybatis 无法输出sql的问题
  • Vue2 SSR 的优化之旅
  • vue-cli在webpack的配置文件探究
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 构建工具 - 收藏集 - 掘金
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 终端用户监控:真实用户监控还是模拟监控?
  • Spring第一个helloWorld
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • (算法设计与分析)第一章算法概述-习题
  • (已解决)什么是vue导航守卫
  • .aanva
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .net 流——流的类型体系简单介绍
  • .net 设置默认首页
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .Net环境下的缓存技术介绍
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .net中调用windows performance记录性能信息
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @NestedConfigurationProperty 注解用法
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • [C++]C++入门--引用
  • [C++11 多线程同步] --- 条件变量的那些坑【条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)】
  • [EFI]Atermiter X99 Turbo D4 E5-2630v3电脑 Hackintosh 黑苹果efi引导文件
  • [github全教程]github版本控制最全教学------- 大厂找工作面试必备!
  • [HackMyVM]靶场 Wild
  • [i.MX]飞思卡尔IMX6处理器的GPIO-IOMUX_PAD说明
  • [Java][Android][Process] ProcessBuilder与Runtime差别