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

嵌入式项目:STM32刷卡指纹智能门禁系统

 本文详细介绍基于STM32的刷卡指纹智能门禁系统。

 获取资料/指导答疑/技术交流/选题/帮助,请点链接:
https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt

1 系统功能

1.1 功能概述

        本系统由STM32硬件端(下位机)和QT管理平台(上位机)构成,两者通过WiFi无线连接,采用TCP协议通信。

硬件端:STM32及外设模块(RC522刷卡、AS608指纹、OLED显示、ESP8266 WiFi、舵机开门、蜂鸣器、LED);

管理平台:用QT实现并在电脑运行。

主要功能:系统登录、建立连接及通信、录入用户、查看用户、删除用户、刷卡开门、指纹开门、查看开门记录、管理员开门、退出登录等。

系统的管理员界面及STM32硬件端实物图如下:

1.2 主要功能

1.2.1 系统登陆

运行管理平台需要先登录,登录界面如下:

登录后进入管理员系统,界面如下:

1.2.2 连接通信

        上位机与下位机通信需要先建立连接,首先电脑要连接STM32硬件端WiFi模块发射的WiFi(wifi: hello-esp8266,密码:6个8),然后在管理员界面输入IP并点击连接,连接成功后在OLED屏上会显示在线状态,如下:

1.2.3 添加用户

在管理员界面点击“添加用户”,再输入用户信息,点击确定,然录入新卡,接着采集指纹录入(需采集2次并且一致),以上步骤无误后提示录入成功,如下:

1.2.4 查看用户

在管理员界面点击“用户列表”可查看用户,如下:

1.2.5 删除用户

在用户列表上选中某个用户,再点击“删除用户”,即可将该用户删除,如下:

1.2.6 刷卡开门

用已录入的卡去刷卡,能够开门并在OLED屏显示开门成功,如下:

1.2.7 指纹开门

用已录入的指纹去刷指纹,能够开门并在OLED屏显示开门成功,如下:

1.2.8 管理员开门

在管理员界面点击“开门”,可开门并在OLED屏显示开门成功,如下:

1.2.9 查看开门记录

在管理员界面点击“历史记录”,可查看开门记录,如下:

1.2.10 退出登陆

在管理员界面点击“退出”,可退出管理员系统,回到登陆界面,如下:

2 系统硬件

2.1 原理图

2.2 PCB

3 软件实现

3.1 STM32软件

3.1.1 主函数main

        在main函数中,主要完成系统及外设模块的初始化,还有一个重要的模块:time service的初始化以及注册3个不同间隔执行的函数,分别是0间隔(相当于while(1))、100ms间隔、1000ms的间隔执行,主体程序均可在这3个不同间隔执行的函数中运行。

Main程序如下:

int main(void)
{// 配置系统时钟72M,使用外部晶振system_clock_config();delay_init();// 调试打印串口初始化usart_init(115200);printf("\n hello stm32.\r\n");/* 硬件模块驱动初始化 */led_init();		//LED初始化beep_init();	//蜂鸣器初始化oled_init();	// OLED初始化rc522_init();	// RC522 rfid模块初始化// 指纹模块AS608初始化:usart3用于AS608usart3_init(AS608_UART_BAUDRATE, as608_data_recv);as608_init(usart3_send, as608_finger_event_cb);// wifi通信初始化wifi_proto_init();/* time service需要timer提供时钟 */timsrv_init();TIM2_init(72-1, 1000-1, timer_timeout_cb);	// 1ms 定时TIM2_start();// 注册任务,执行间隔以ms为单位timsrv_register_task(0, task_while);timsrv_register_task(100, task_100ms);timsrv_register_task(1000, task_1000ms);//舵机初始化:PWM3为舵机提供pwmpwm3_init(72-1, 20000-1);	//舵机要求:频率1MHz,周期20mspwm3_start();servo_init(20000, pwm3_set_pulse);// 显示主界面ui_show_destop();ui_show_online(false);memset(&g_sys_info, 0, sizeof(system_info_t));g_sys_info.work_mode = WORK_MODE_NORMAL;while(1){// 主任务:根据时间间隔执行注册的任务timsrv_tasks_running();}
}

3.1.2 事件处理process

事务处理主要是上述time service注册的3个不同间隔执行的函数,如下:

/* 0间隔执行,相当于while(1)执行 */
void task_while(void)
{//wifi接收数据处理wifi_data_handle();// 服务器协议处理server_proto_handle();}/* 每间隔100ms执行一次 */
void task_100ms(void)
{static uint8_t card_wait = 0;uint8_t card_id[8];int ret, i;//扫描读卡,每次读到卡间隔2Sif(card_wait == 0) {ret = rc522_read_card(card_id);if(ret == 0) {beep_on();timsrv_set_delay_work(100, beep_off);proto_0x11_sendCardnum(card_id);card_wait = 1;printf("get card: ");for(i=0; i<8; i++)printf("%02X ", card_id[i]);printf("\n");}}else{if(card_wait ++ >= 20)card_wait = 0;}//指纹模块运行处理as608_run_process();
}/* 每间隔1000ms执行一次 */
void task_1000ms(void)
{static int num = 0;printf("%s: %d\r\n", __FUNCTION__, num);num ++;
}

3.1.3 外设事件处理

外设像WiFi、指纹模块AS608等有事件回调的处理,如下:

//wifi模块事件回调处理函数
int wifi_event_cb(wifi_event_e event, int param)
{printf("wifi event: %d, param: %d\n", event, param);switch(event){case WIFI_EVE_TCP_CONNECT: 		//TCP连接g_sys_info.online = true;led_on();ui_show_online(true);break;case WIFI_EVE_TCP_DISCONNECT: 	//TCP断开g_sys_info.online = false;led_off();ui_show_online(false);break;default:break;}return 0;
}//指纹模块事件回调处理函数
int as608_finger_event_cb(as608_event_e event, int param)
{printf("as608 event: %d, param: %d\n", event, param);switch(event){case AS608_EVE_GET_FINGER:	//检测到指纹按下beep_on();timsrv_set_delay_work(100, beep_off);break;case AS608_EVE_SEARCH_FINGER:	//识别到识别proto_0x14_recognFingerId(param);break;case AS608_EVE_ADD_WAIT_FINGER:		//添加指纹:等待指纹break;case AS608_EVE_ADD_1ST_FINGER:	//添加指纹:采集第一个指纹beep_on();timsrv_set_delay_work(100, beep_off);proto_0x13_addFingerResult(1);break;case AS608_EVE_ADD_2ND_FINGER:	//添加指纹:采集第二个指纹beep_on();timsrv_set_delay_work(100, beep_off);proto_0x13_addFingerResult(2);break;case AS608_EVE_ADD_RESULT:	//添加指纹结果if(param == 0)proto_0x13_addFingerResult(0);elseproto_0x13_addFingerResult(4);break;case AS608_EVE_ADD_TIMEOUT:		//添加指纹超时proto_0x13_addFingerResult(3);break;default:break;}	return 0;
}

3.1.3 通信协议处理

        STM32需要跟上位机QT交互,因此需要通信协议,以解析通信的内容及作相关处理。例如STM32端读到卡片需发送给QT端以判断是否开门、若要开门QT端还要发送开门指纹给STM32让其执行开门动作。

STM32主动发送协议的部分代码:

int proto_0x11_sendCardnum(unsigned char *cardnum)	//发送卡号
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;data_len += proto_add_param(data_buf, ID_CARD_NUM, 8, cardnum);proto_makeup_packet(0x11, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}
int proto_0x13_addFingerResult(unsigned char result)		//发送添加指纹结果
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;printf("add finger result %d\n", result);data_len += proto_add_param(data_buf, ID_ADD_FINGER_RES, 1, &result);proto_makeup_packet(0x13, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}int proto_0x14_recognFingerId(int id)	//发送识别到的指纹
{unsigned char data_buf[64];int data_len = 0;int pack_len = 0;data_len += proto_add_param(data_buf, ID_FINGER_ID, 4, (unsigned char *)&id);proto_makeup_packet(0x14, data_buf, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &pack_len);server.send(proto_tmp_buf, pack_len);return 0;
}

STM32接收到协议的处理:

static int server_proto_dispatch(uint8_t *pack, int len)
{uint8_t cmd = 0;uint8_t *data = NULL;int data_len = 0;int ack_len = 0;int ret;ret = proto_packet_analy(pack, len, &cmd, &data_len, &data);if(ret != 0)return -1;printf("ptoto cmd: 0x%02x, pack_len: %d, data_len: %d\n", cmd, len, data_len);switch(cmd){case 0x03:ret = server_0x03_heartbeat(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x10:ret = server_0x10_opendoor(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x12:ret = server_0x12_toWorkmode(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;case 0x15:ret = server_0x15_delete_finger(data, data_len, proto_tmp_buf, sizeof(proto_tmp_buf), &ack_len);break;default:printf("error: cmd 0x%02x not found!\r\n", cmd);break;}/* send ack data */if(ret==0 && ack_len>0){proto_makeup_packet(cmd, proto_tmp_buf, ack_len, proto_recv_buf, sizeof(proto_recv_buf), &data_len);server.send(proto_recv_buf, data_len);}return 0;
}

3.2 QT软件

3.2.1 UI界面布局

在Qt creator中布局UI界面,如下:

3.2.2 按钮槽函数处理

        按钮的槽函数是通过信号与槽机制实现的。当用户点击按钮时,按钮会发出一个 clicked() 信号,开发者可以将其连接到一个自定义的槽函数上,以处理按钮点击事件。

void MainWindow::on_connectBtn_clicked()	//点击连接
{if(ui->connectBtn->isChecked()){QString svr_ip;svr_ip = ui->serverIpEdit->text();qDebug() << "server ip" << svr_ip;client->connectToHost(svr_ip, DEFAULT_SERVER_PORT);}else{client->disconnectFromHost();}
}void MainWindow::on_addUserBtn_clicked()	//添加用户
{if(ui->addUserBtn->isChecked()){ui->userIdEdit->clear();ui->userNameEdit->clear();ui->phoneEdit->clear();ui->addUserWidget->setHidden(false);g_sys_info.work_mode = WORK_MODE_ADD_USER;g_sys_info.add_step = ADD_STEP_USERINFO;proto_0x12_toWorkmode(1, 1, 0);}else{to_destop_window();g_sys_info.work_mode = WORK_MODE_NORMAL;proto_0x12_toWorkmode(0, 0, 0);}
}void MainWindow::on_userListBtn_clicked()		//用户列表
{if(ui->userListBtn->isChecked()){set_table_view(SQL_TABLE_USER);ui->tableView->setHidden(false);}else{ui->tableView->setHidden(true);}
}void MainWindow::on_delUserBtn_clicked()		//删除用户
{user_info_t user;QString tips;int id;if(!ui->userListBtn->isChecked())return;QModelIndex cur_index = ui->tableView->currentIndex();if(cur_index.row() == -1)return;id = sqlmodel->data(sqlmodel->index(cur_index.row(), 0)).toInt();memset(&user, 0, sizeof(user_info_t));sql_user_read(id, &user);tips = QString("是否删除用户<%1>?").arg(user.name);if(QMessageBox::No == QMessageBox::question(this, "注意", tips, QMessageBox::Yes|QMessageBox::No, QMessageBox::No))return;proto_0x15_delete_finger(user.finger);sql_user_del(id);sqlmodel->select();sqlmodel->submitAll();
}void MainWindow::on_historyBtn_clicked()		//历史记录
{if(ui->historyBtn->isChecked()){set_table_view(SQL_TABLE_HISTORY);ui->tableView->setHidden(false);}else{ui->tableView->setHidden(true);}
}void MainWindow::on_openDoorBtn_clicked()	//开门
{if(!mainwindow->tcp_connect)return;proto_0x10_opendoor(1);history_info_t history;memset(&history, 0, sizeof(history_info_t));QDateTime dtime = QDateTime::currentDateTime();QString str_dtime = dtime.toString("yyyy-MM-dd hh:mm:ss");history.time = dtime.toTime_t();strncpy(history.time_str, str_dtime.toLatin1().data(), TIME_STR_LEN);strncpy(history.name, "管理员", USER_NAME_LEN);sql_history_write(&history);
}void MainWindow::on_exitBtn_clicked()	//退出
{loginDialog_init();delete this;
}

3.2.3 SQL数据库

用户数据是用SQLite数据库存储的,建立2个数据表:用户表(用户信息)、记录表(开门历史);数据库的操作就是插入添加、删除、查询等动作。

创建数据表:

static int sql_create_user_tbl(void)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("create table if not exists %1(""%2 int primary key not null,""%3 char(32),""%4 char(16), ""%5 char(32), ""%6 int);").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_PHONE).arg(SQL_COL_CARD).arg(SQL_COL_FINGER);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_create_history_tbl(void)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("create table if not exists %1(""%2 int primary key not null,""%3 char(32),""%4 int, ""%5 char(32), ""%6 char(32), ""%7 int);").arg(SQL_TABLE_HISTORY).arg(SQL_COL_TIME).arg(SQL_COL_TIME_STR).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_CARD).arg(SQL_COL_FINGER);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}添加、删除、读取:
int sql_user_add(user_info_t *user)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("insert into %1(%2,%3,%4,%5,%6) ""values(%7,'%8','%9','%10',%11);").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(SQL_COL_NAME).arg(SQL_COL_PHONE).arg(SQL_COL_CARD).arg(SQL_COL_FINGER).arg(user->id).arg(user->name).arg(user->phone).arg(user->card).arg(user->finger);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_user_del(int id)
{QString sql_cmd;int ret = 0;sql_mutex.lock();sql_cmd = QString("delete from %1 where %2=%3;").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(id);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;ret = -1;}sql_mutex.unlock();return ret;
}int sql_user_read(int id, user_info_t *user)
{QString sql_cmd;int ret = -1;sql_mutex.lock();sql_cmd = QString("select * from %1 where %2=%3;").arg(SQL_TABLE_USER).arg(SQL_COL_ID).arg(id);qDebug() << sql_cmd;if(!sqlquery->exec(sql_cmd)){qDebug() << "sql exec failed!" ;sql_mutex.unlock();return -1;}if(sqlquery->next()){user->id = sqlquery->value(0).toInt();strcpy(user->name, (char *)sqlquery->value(1).toString().toLocal8Bit().data());strcpy(user->phone, (char *)sqlquery->value(2).toString().toLocal8Bit().data());strcpy(user->card, (char *)sqlquery->value(3).toString().toLocal8Bit().data());user->finger = sqlquery->value(4).toInt();ret = 0;}sql_mutex.unlock();return ret;
}

获取资料/指导答疑/技术交流/选题/帮助,请点链接:
https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt

如有任何问题,请联系作者,谢谢!
- - - 曾哥,专注嵌入式。

相关文章:

嵌入式项目:STM32刷卡指纹智能门禁系统

本文详细介绍基于STM32的刷卡指纹智能门禁系统。 获取资料/指导答疑/技术交流/选题/帮助&#xff0c;请点链接&#xff1a; https://gitee.com/zengzhaorong/share_contact/blob/master/stm32.txt 1 系统功能 1.1 功能概述 本系统由STM32硬件端&#xff08;下位机&#xff09;…...

LeetCode 热题100 141. 环形链表

LeetCode 热题100 | 141. 环形链表 大家好&#xff0c;今天我们来解决一道经典的算法题——环形链表。这道题在 LeetCode 上被标记为简单难度&#xff0c;要求我们判断一个链表中是否存在环。下面我将详细讲解解题思路&#xff0c;并附上 Python 代码实现。 题目描述 给定一个…...

以绘图(绘制点、直线、圆、椭圆、多段线)为例子 通过设计模式中的命令模式实现

为了在命令模式的基础上实现撤销&#xff08;Undo&#xff09;和回退&#xff08;Redo&#xff09;功能&#xff0c;我们可以在每个命令类中记录一些必要的状态&#xff0c;允许我们撤销之前的操作&#xff0c;并在需要时回退操作。常见的做法是使用一个命令堆栈来存储历史命令…...

鹏哥c语言数组(初阶数组)

前言&#xff1a; 对应c语言视频54集 内容&#xff1a; 一维数组的创建 数组是一组相同元素的集合&#xff0c; 数组的创建方式 type_t就是数组的元素类型&#xff0c;const_n是一个常量表达式&#xff0c;用来指定数组的大小 c99标准之前的&#xff0c;数组的大小必须是…...

利用go-migrate实现MySQL和ClickHouse的数据库迁移

1. 背景 在使用gorm时 , 尽管已经有了自动建表和钩子函数 . 但是在面临希望了解到数据库的变更 , 和插入一些系统字段时 , 以及最关键的数据库迁移的工作 . gorm显得稍微有点不便 . 在了解到migrate这项技术后 , 就使用go-migrate开发了一个可以迁移MySQL和ClickHouse数据库的…...

计算机毕业设计SpringBoot+Vue.js企业客户管理系统(源码+LW文档+PPT+讲解+开题报告)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

jmeter 如何做移动端的测试 特别是兼容性测试

JMeter本身主要是一款用于性能测试和功能测试的工具,虽然它并非专门为移动端测试设计,但可以通过一些方式来对移动端应用进行测试,以下从测试准备、测试过程及注意事项等方面为你详细介绍: 一、测试准备 (一)环境搭建 JMeter安装与配置:确保JMeter已经正确安装在测试机…...

深度学习技术全景图:从基础架构到工业落地的超级进化指南

&#x1f50d; 目录导航 基础架构革命训练优化秘技未来战场前瞻 &#x1f9e9; 一、基础架构革命 1.1 前馈神经网络&#xff08;FNN&#xff09; ▍核心结构 import torch.nn as nnclass FNN(nn.Module):def __init__(self):super().__init__()self.fc1 nn.Linear(784, 25…...

vllm部署LLM(qwen2.5,llama,deepseek)

目录 环境 qwen2.5-1.5b-instruct 模型下载 vllm 安装 验证安装 vllm 启动 查看当前模型列表 OpenAI Completions API&#xff08;文本生成&#xff09; OpenAI Chat Completions API&#xff08;chat 对话&#xff09; vllm 进程查看&#xff0c;kill llama3 deep…...

基于SpringBoot的“古城景区管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“古城景区管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 系统首页界面 系统注册界面 景…...

如何防止 Docker 注入了恶意脚本

根据您的描述&#xff0c;攻击者通过 CentOS 7 系统中的 Docker 注入了恶意脚本&#xff0c;导致自动启动名为 “masscan” 和 “x86botnigletjsw” 的进程。这些进程可能用于网络扫描或其他恶意活动。为了解决这一问题&#xff0c;建议您采取以下步骤&#xff1a; 1. 停止并删…...

使用python接入腾讯云DeepSeek

本文主要从提供SSE方式接入DeepSeek&#xff0c;并通过fastapi websocket对外提供接入方法。 参考文档&#xff1a; 腾讯云大模型&#xff1a;https://cloud.tencent.com/document/product/1759/109380 fastAPI官网&#xff1a;https://fastapi.tiangolo.com/ WebSocketManager…...

【MySQL】服务正在启动或停止中,请稍候片刻后再试一次【解决方案】

问题呈现 在使用MySQL的过程中我们可能会遇到以上的情况 解决方法 首先以管理员身份打开命令行窗口&#xff0c;注意是管理员身份&#xff0c;不然无权限访问。输入命令tasklist| findstr "mysql"&#xff0c;用于查找mysql的残留进程。这个时候我们就会看到一个…...

测试工程师玩转DeepSeek之Prompt

以下是测试工程师使用DeepSeek的必知必会提示词指南&#xff0c;分为核心场景和高效技巧两大维度&#xff1a; 一、基础操作提示模板 1. 测试用例生成 "作为[金融系统/物联网设备/云服务]测试专家&#xff0c;请为[具体功能模块]设计测试用例&#xff0c;要求&#xff1…...

【PyTorch】2024保姆级安装教程-Python-(CPU+GPU详细完整版)-

一、准备工作 pytorch需要python3.6及以上的python版本 我是利用Anaconda来管理我的python。可自行安装Anaconda。 Anaconda官网 Free Download | Anaconda 具体Anaconda安装教程可参考 https://blog.csdn.net/weixin_43412762/article/details/129599741?fromshareblogdet…...

精选案例展 | 智己汽车—全栈可观测驱动智能化运营与成本优化

本案例为“观测先锋 2024 可观测平台创新应用案例大赛”精选案例&#xff0c;同时荣获IT168“2024技术卓越奖评选-年度创新解决方案”奖。 项目背景 近年来&#xff0c;中国汽车行业进入转型升级阶段&#xff0c;智能网联技术成为行业发展的核心。车联网、自动驾驶等技术的加速…...

MySQL 使用 `WHERE` 子句时 `COUNT(*)`、`COUNT(1)` 和 `COUNT(column)` 的区别解析

文章目录 1. COUNT() 函数的基本作用2. COUNT(*)、COUNT(1) 和 COUNT(column) 的详细对比2.1 COUNT(*) —— 统计所有符合条件的行2.2 COUNT(1) —— 统计所有符合条件的行2.3 COUNT(column) —— 统计某一列非 NULL 的记录数 3. 性能对比3.1 EXPLAIN 分析 4. 哪种方式更好&…...

Linux运维——网络管理

Linux网络管理 一、Linux网络应用要点二、命令常见用法2.1、curl2.1.1、发送GET请求2.1.2、发送POST请求2.1.3、设置请求头2.1.4、处理cookies2.1.5、处理重定向2.1.6、调试和详细信息2.1.7、使用代理2.1.8、文件上传2.1.9、其它常用选项2.1.10、综合示例 2.2、wget2.2.1、基本…...

STM32CUBEIDE FreeRTOS操作教程(十三):task api 任务访问函数

STM32CUBEIDE FreeRTOS操作教程&#xff08;十三&#xff09;&#xff1a;task api 任务访问函数 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板…...

Jmeter+Jenkins接口压力测试持续集成

项目介绍 接口功能测试应用&#xff1a; http://www.weather.com.cn/data/cityinfo/<city_code>.html 测试功能&#xff1a;获取对应城市的天气预报 请求方法&#xff1a;Get 压测脚本开发工具&#xff1a;jmeter 源码脚本位置&#xff1a; https://github.com/shife…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...