0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 基于的单片机的移动硬盘设计与实现
🥇学长这里给一个题目综合评分(每项满分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 简介
基于stm32的嵌入式移动网盘 设计思路:使用stm32+Wi-Fi模块+SD卡,搭建一个嵌入式的迷你网盘,支持云端操作(增删改查)端侧的文件。 主要解决的问题:需要解决终端挂载的SD卡如何能被云端(公网服务器)访问,并能够支持修改。 项目创新点:借助终端外挂的大容量SD卡,基于Wi-Fi网络传输,实现网盘的功能,有望解决云服务器低成本扩容的问题。
2 主要器件
- stm32单片机
- RT-Thread物联网操作系统
- TG7100C Wi-Fi模组
- 云端简单服务器程序,用于下发对SDCARD的查看和控制;
- Wi-Fi热点的管理连接
3 实现效果
4 设计原理
硬件部分
主要使用了stm32和一个TG7100CWi-Fi模组。
stm32主控MCU
stm32是一颗基于RISC-V的MCU,性价比非常高,不管是开发板还是芯片,都比较便宜,具体参数如下:
利用RT-Thread Studio(https://www.rt-thread.org/page/studio.html)进行开发。此外,需要安装Bluetrum开发板支持以及RISC-V-GCC编译器,如图:
stm32:充当主控,使用其SDIO接口,用于读取SD的内容。还使用其串口,用于链接Wi-Fi模组。
TG7100CWi-Fi模组
Wi-Fi模组:充当网络通讯模块,解决网络连接的问题。主要使用了其Wi-Fi功能和串口连接。
TG-12F模块采用平头哥TG7100C芯片,TG7100C 是智能新一代高集成 Wi-Fi 和 BLE 组合芯片。无线子系统包含 2.4G 射频、Wi-Fi 802.11b/g/n 和 BLE 基带/MAC 设计。微控制器子系统包含一个低功耗 32 位 RISC CPU、高速缓存和存储器。电源管理单元提供灵活的设置实现低功耗模式,并支持多种安全功能。
模组接线
TG-12F接出两个串口:一个指令串口,用于指令交互和数据传输;一个日志串口,用于输出模组运行日志。电源供电3.3V。
日志串口(uart1):gpio12(RX) gpio21(TX) 波特率:921600
AT串口(uart0): gpio7(RX) gpio16(TX) 波特率:115200
软件设计
整个演示方案,软件部分分为三大块:
1 云端的一个简单的服务器程序,用于下发对SDCARD的查看和控制;
1)识别SDCARD的挂载
2)新增命令行功能,可以下发对SDCARD的控制
3)网络报文的控制传输,命令协议的处理
2 stm32的固件程序
1)串口协议的组包、解析
2)命令行返回数据的获取以及组包发送
3)对接Wi-Fi模组,对网络连接、发送、接收、关闭的协议处理
3 Wi-Fi模组的固件程序
1)串口协议的组包、解析
2)Wi-Fi热点的管理连接
3)stm32的网络连接请求管理(串口转网络TCP、TCP转串口)
5 部分核心代码
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <rtthread.h>
#include <rthw.h>
extern int tcp_send(uint8_t *buf_out, uint16_t len);
extern int tcp_recv(uint8_t *buf_out, uint16_t len);
int report_sdcard_name(char *name)
{
uint8_t buf[128];
snprintf(buf, sizeof(buf), "sdcard-name:%s", name);
return tcp_send(buf, strlen(buf));
}
static char g_rsp_data[4096];
static int g_rsp_offset;
int hook_finsh_rsp_data(const char *fmt, ...)
{
va_list args;
rt_size_t length;
va_start(args, fmt);
length = rt_vsnprintf(&g_rsp_data[g_rsp_offset], sizeof(g_rsp_data) - 1, fmt, args);
if (length > RT_CONSOLEBUF_SIZE - 1) {
length = RT_CONSOLEBUF_SIZE - 1;
}
g_rsp_offset += length;
va_end(args);
return 0;
}
int excute_sdcard_opration(char *ip, char *port, char *sdcard_name)
{
char buf[256];
int len;
int ret;
tcp_sem_init();
while (1) {
tcp_connect(ip, port);
report_sdcard_name(sdcard_name);
while (1) {
memset(buf, 0, sizeof(buf));
ret = tcp_recv(buf, sizeof(buf));
if (ret <= 0) {
break;
}
rt_kprintf("recv %s\n", buf);
if (!strncmp("cmd:ls", buf, 6)) {
g_rsp_offset = 0;
ls("/");
tcp_send(g_rsp_data, g_rsp_offset);
} else if (!strncmp("cmd:df", buf, 6)) {
g_rsp_offset = 0;
df("/");
tcp_send(g_rsp_data, g_rsp_offset);
}
}
tcp_close();
}
return ret;
}
#include <rtthread.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#define UART_WIFI_AP_CONN 0xB0
#define UART_WIFI_AP_CONN_ACK 0xB1
#define UART_WIFI_TCP_CONN 0xB2
#define UART_WIFI_TCP_CONN_ACK 0xB3
#define UART_WIFI_TCP_SEND 0xB4
#define UART_WIFI_TCP_SEND_ACK 0xB5
#define UART_WIFI_TCP_RECV 0xB6
#define UART_WIFI_TCP_RECV_ACK 0xB7
#define UART_WIFI_TCP_CLOSE 0xB8
#define UART_WIFI_TCP_CLOSE_ACK 0xB9
extern int uart_tcp_ack_send(uint8_t cmd, uint8_t *data, uint16_t len);
static struct rt_semaphore tcp_sem;
static int g_tcp_fd;
static int g_tcp_ret;
static uint8_t *g_tcp_buf;
static int g_tcp_buf_len;
int tcp_sem_init(void)
{
rt_sem_init(&tcp_sem, "tcp_sem", 0, RT_IPC_FLAG_PRIO);
}
static int tcp_sem_take(uint32_t timeout_ms)
{
int ret;
uint32_t tick = timeout_ms / 1000 * RT_TICK_PER_SECOND;
ret = rt_sem_take(&tcp_sem, tick);
return ret;
}
static void tcp_sem_release(void)
{
rt_sem_release(&tcp_sem);
}
int tcp_connect(const char *ip, char *port)
{
uint8_t buf[128] = {0};
char ip_str[16] = {0};
char port_str[6] = {0};
snprintf(ip_str, sizeof(ip_str), "%s", ip);
snprintf(port_str, sizeof(port_str), "%s", port);
memcpy(buf, ip_str, sizeof(ip_str));
memcpy(buf + sizeof(ip_str), port_str, sizeof(port_str));
uart_tcp_ack_send(UART_WIFI_TCP_CONN, buf, sizeof(ip_str) + sizeof(port_str));
tcp_sem_take(60000);
rt_kprintf("%s: fd: %d\n", __func__, g_tcp_fd);
return 0;
}
int tcp_connect_ack(uint8_t *buf, uint16_t len)
{
if (buf[7] == 0xFF) {
g_tcp_fd = -1;
} else {
g_tcp_fd = buf[7];
}
tcp_sem_release();
return 0;
}
int tcp_send(uint8_t *buf_in, uint16_t len)
{
uint8_t *buf = (uint8_t *)rt_malloc(len + 3);
if (g_tcp_fd < 0) {
return -1;
}
buf[0] = g_tcp_fd & 0xFF;
buf[1] = len >> 8;
buf[2] = len & 0xFF;
memcpy(&buf[3], buf_in, len);
uart_tcp_ack_send(UART_WIFI_TCP_SEND, buf, len + 3);
tcp_sem_take(30000);
rt_kprintf("%s: ret: %d\n", __func__, g_tcp_ret);
rt_free(buf);
return len;
}
int tcp_send_ack(uint8_t *buf, uint16_t len)
{
g_tcp_ret = buf[7] << 8 | buf[8];
tcp_sem_release();
return 0;
}
int tcp_recv(uint8_t *buf_out, uint16_t len)
{
uint8_t buf[16] = {0};
if (g_tcp_fd < 0) {
return -1;
}
buf[0] = g_tcp_fd & 0xFF;
buf[1] = len >> 8;
buf[2] = len & 0xFF;
g_tcp_buf = buf_out;
uart_tcp_ack_send(UART_WIFI_TCP_RECV, buf, 3);
tcp_sem_take(60000);
rt_kprintf("%s: ret: %d\n", __func__, g_tcp_ret);
return g_tcp_ret;
}
int tcp_recv_ack(uint8_t *buf, uint16_t len)
{
g_tcp_ret = buf[7] << 8 | buf[8];
g_tcp_buf_len = len - 8 - 2;
memcpy(g_tcp_buf, &buf[9], g_tcp_buf_len);
hexdump("recv_data", g_tcp_buf, g_tcp_buf_len);
tcp_sem_release();
return 0;
}
int tcp_close(void)
{
uint8_t buf[128] = {0};
if (g_tcp_fd < 0) {
return -1;
}
buf[0] = g_tcp_fd & 0xFF;
uart_tcp_ack_send(UART_WIFI_TCP_CLOSE, buf, 1);
tcp_sem_take(10000);
rt_kprintf("%s: fd: %d\n", __func__, g_tcp_fd);
g_tcp_fd = -1;
return 0;
}
int tcp_close_ack(uint8_t *buf, uint16_t len)
{
g_tcp_ret = buf[7];
tcp_sem_release();
return 0;
}
5 最后
|