IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【毕业设计】 基于单片机的放松按摩仪设计与实现 - 物联网 嵌入式 stm32 -> 正文阅读

[嵌入式]【毕业设计】 基于单片机的放松按摩仪设计与实现 - 物联网 嵌入式 stm32


0 前言

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

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

🚩 基于PID控制的智能平衡车设计与实现

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

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

🧿 选题指导, 项目分享:

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 简介

基于AB32的放松按摩仪,实现了40°热敷功能,气囊按摩功能,有温度显示,可按键切换

2 主要器件

  • 中科蓝讯的AB32VG1单片机
  • RT-Thread物联网操作系统
  • NTC温度采集模块
  • 碳钎维板热敷模块
  • 气囊按摩模块

3 实现效果

4 硬件设计

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软件包默认即可。
在这里插入图片描述

在这里插入图片描述

NTC温度采集:adc7 PE5

原理简介

NTC的电路如图所示

在这里插入图片描述

R66端的电压输出到单片机的引脚,中间有缩小系数。
具体的思路是,读取adc的电压(mV,这样更加精确),换算为电阻值,NTC在25度的时候是10K欧姆,R66是2K。那么电压就是v=2250*2/(2+NTC),计算出来就是mV的单位,图中电压是标记错误,实际是2.25V。
反推电阻R(多少千欧)=4500/V-2,然后根据这个电阻值,去计算温度值,NTC的分度表《MF52 系列 测温型 NTC 热敏电阻器》如下:

在这里插入图片描述

其他器件引脚

气囊按摩模块:

time3-定时器3

pwm PB0-pwm输出

PA4驱动使能脚

碳钎维板热敷模块

time5-定时器5

pwm PE1-pwm输出

PA5驱动使能脚

OLED:
SCL:PE6
SDA:PE7

按键
S2:PF1
S3:PF0
S4:PA2

5 软件说明

main线程负责初始化

int main(void)
{
//    led_init();
    button_init();
    Pwm_Init();
    temp_get_adc_init();
    display_init();

    rt_kprintf("Hello world!\n");
    while (1)
    {
        rt_thread_delay(500);
    }
}

display线程负责oled屏幕的显示

#include "display.h"
#include <oled.h>

static void display_entry(void *parameter)
{
    OLED_Clear();
    while(1)
    {
        OLED_ShowString(20,20, "start-up",16,1);
        OLED_ShowNum(0,0,(int)((temp*100)/100),2,12,1);
        OLED_ShowString(25,0, ".",16,1);
        OLED_ShowNum(30,0,(int)(temp*100)%100,2,12,1);
        OLED_Refresh();
        rt_thread_delay(100);
    }
}

rt_thread_t display=RT_NULL;
int display_init(void)
{
    OLED_Init();
    //创建显示线程 优先级设置为31
    display = rt_thread_create("display", display_entry, RT_NULL, 1024, 28, 5);
    //启动显示线程
    if(RT_NULL != display)
    {
        rt_thread_startup(display);
//        rt_kprintf("display_ok\n");
    }
    return 0;
}


temp_get_adc线程采集ntc的温度值并换算成摄氏度

rt_thread_t temp_get_adc=RT_NULL;
int temp_get_adc_init(void)
{
    rt_err_t ret = RT_EOK;

    /* 查找设备 */
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
        return RT_ERROR;
    }

    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
    /* 关闭通道 */
//    ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
    //创建温度采集线程
    temp_get_adc = rt_thread_create("temp_get_adc", temp_get_entry, RT_NULL, 1024, 11, 20);
    //启动线程
    if(RT_NULL != temp_get_adc)
    {
        rt_thread_startup(temp_get_adc);
    }
    return ret;
}

pwm_thread线程负责气泵磁阀的控制,temp_control线程负责温度的控制

rt_thread_t pwm_thread=RT_NULL,temp_control=RT_NULL;
int Pwm_Init(void)
{
    pwm_dev_t5 = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME5);
    RT_ASSERT(pwm_dev_t5 != RT_NULL);
    /* 设置PWM周期和脉冲宽度 */
    rt_pwm_set(pwm_dev_t5, PWM_DEV_CHANNEL0, period, pulse);
    /* 使能设备 */
    rt_pwm_enable(pwm_dev_t5, PWM_DEV_CHANNEL0);

    pwm_dev_t3 = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME3);
    RT_ASSERT(pwm_dev_t3 != RT_NULL);
    rt_pwm_set(pwm_dev_t3, PWM_DEV_CHANNEL1, period, pulse);
    rt_pwm_enable(pwm_dev_t3, PWM_DEV_CHANNEL1);
    rt_pin_mode(DIR1, PIN_MODE_OUTPUT);
    rt_pin_mode(DIR2, PIN_MODE_OUTPUT);
    //创建led线程
    pwm_thread = rt_thread_create("pwm_thread", pwm_entry, RT_NULL, 1024, 12, 10);
    temp_control = rt_thread_create("temp_control", temp_control_entry, RT_NULL, 1024, 9, 10);
    //启动led线程
    if(RT_NULL != pwm_thread)
        rt_thread_startup(pwm_thread);
    if(RT_NULL != temp_control)
        rt_thread_startup(temp_control);
    return 0;
}

button_thread定时器控制按键

rt_timer_t button_thread=RT_NULL;

int button_init(void)//按键初始化
{
    rt_pin_mode(S2, PIN_MODE_INPUT_PULLUP );//上拉输入
    rt_pin_mode(S3, PIN_MODE_INPUT_PULLUP );//上拉输入
    rt_pin_mode(S4, PIN_MODE_INPUT_PULLUP );//上拉输入

    S2_sem = rt_sem_create("S2", 0, RT_IPC_FLAG_FIFO);  //创建按键的信号量,当按键按下就释放信号量,在需要使用按键的地方获取信号量即可
    S3_sem = rt_sem_create("S3", 0, RT_IPC_FLAG_FIFO);
    S4_sem = rt_sem_create("S4", 0, RT_IPC_FLAG_FIFO);
    //创建邮箱
    key_mailbox = rt_mb_create("key_mailbox",5, RT_IPC_FLAG_FIFO);
    key2_mailbox = rt_mb_create("key_mailbox",5, RT_IPC_FLAG_FIFO);
    //创建定时器
    button_thread = rt_timer_create("button", button_entry, RT_NULL, 20, RT_TIMER_FLAG_PERIODIC);

    if(RT_NULL != button_thread)
    {
        rt_timer_start(button_thread);
//        rt_kprintf("timer_button\n");
    }
    return 0;
}

key_mailbox,key2_mailbox邮箱负责线程间的通信 按键和temp_control、pwm_thread的通信

int button_init(void)//按键初始化
{
    rt_pin_mode(S2, PIN_MODE_INPUT_PULLUP );//上拉输入
    rt_pin_mode(S3, PIN_MODE_INPUT_PULLUP );//上拉输入
    rt_pin_mode(S4, PIN_MODE_INPUT_PULLUP );//上拉输入

    S2_sem = rt_sem_create("S2", 0, RT_IPC_FLAG_FIFO);  //创建按键的信号量,当按键按下就释放信号量,在需要使用按键的地方获取信号量即可
    S3_sem = rt_sem_create("S3", 0, RT_IPC_FLAG_FIFO);
    S4_sem = rt_sem_create("S4", 0, RT_IPC_FLAG_FIFO);
    //创建邮箱
    key_mailbox = rt_mb_create("key_mailbox",5, RT_IPC_FLAG_FIFO);
    key2_mailbox = rt_mb_create("key_mailbox",5, RT_IPC_FLAG_FIFO);
    //创建定时器
    button_thread = rt_timer_create("button", button_entry, RT_NULL, 20, RT_TIMER_FLAG_PERIODIC);

    if(RT_NULL != button_thread)
    {
        rt_timer_start(button_thread);
//        rt_kprintf("timer_button\n");
    }
    return 0;
}

5 最后

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:18:15  更:2022-09-25 23:18:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 15:16:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码