c 做网站怎么发布/搜索引擎优化推广

c 做网站怎么发布,搜索引擎优化推广,福州网站怎么做,动态网站建设与维护1、数据包 我们使用上位机个单片机发送数据包时,规定包头和包尾,将我们需要发送的数据放在中间,数据的长度我们也可以自己规定。一般情况下HEX数据包我们使用固定长度数据包。而文本数据包使用是可变长度数据包。 2、HEX数据包 2.1、HEX固定…

1、数据包

  我们使用上位机个单片机发送数据包时,规定包头和包尾,将我们需要发送的数据放在中间,数据的长度我们也可以自己规定。一般情况下HEX数据包我们使用固定长度数据包。而文本数据包使用是可变长度数据包。在这里插入图片描述在这里插入图片描述

2、HEX数据包

2.1、HEX固定数据包收发

在这里插入图片描述①UART.c文件的代码如下

/*** 串口初始化,且开启中断* 参数:波特率*/
void UART_It_Init(unsigned int Baud)
{/* 串口寄存器的配置 */PCON &= 0x3F;	//PCON = 00xx xxxxSCON &= 0x0F;SCON |= 0x50;	//SCON = 0101 xxxx/* 配置T1的寄存器 */TMOD &= 0x0F;TMOD |= 0x20;	//TOMD = 0010 xxxxTH1 = 256 - (28800/Baud);//配置波特率TL1 = 256 - (28800/Baud);//配置波特率ET1 = 0;		//关闭T1溢出中断TR1 = 1;		//使能T1/* 使能串口中断 */ES = 1;			//使能串口中断EA = 1;			//使能中断总开关
}/***********中断服务函数*************/
/*** 中断服务函数*/
unsigned char Buffer[BUFF_Len];	//固定数据包缓存区
unsigned char Index = 0;		//缓存区索引
unsigned char Flag2 = 0;
void UART_Routine(void) interrupt 4
{	static unsigned char Status = 0;//状态机变量unsigned char ReceiveData;/* 若接收数据完成中断 RI = 1*/if(RI){RI = 0;ReceiveData = SBUF;/* 使用状态机对数据包进行处理 */switch(Status){case 0:if(ReceiveData == 0xFF)//是帧头0xFF{Status = 1;//改变状态变量Index = 0;}else{Status = 0;//不是帧头}break;case 1:Buffer[Index++] = ReceiveData;//接收数据if(Index >= BUFF_Len){Status = 2;//改变状态变量}break;case 2:if(ReceiveData == 0xFE)//判断是否位帧尾0xFE{Flag2 = 1;//将标志位置1}else{memset(Buffer,0,4);//清空数据包缓存区}Status = 0;break;	}}
}

②UART.h文件的代码如下

#ifndef __UART_H
#define __UART_H#include <reg51.h>		//包含51头文件,里面全是寄存器地址
#include <stdio.h>
#include <string.h>#define BUFF_Len 4void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)extern unsigned char Buffer[BUFF_Len];
extern unsigned char Flag2;#endif

③main.c文件的代码如下

#include "UART.h"void main(void)
{UART_It_Init(9600);		//9600波特率while(1){if(Flag2)			//Flag = 1,数据处理完成{Flag2 = 0;Send_Array(Buffer,BUFF_Len);//将数据发送出去}}
}

在这里插入图片描述

2.2、HEX可变数据包收发

①UART.c文件的代码如下

/*** 串口初始化,且开启中断* 参数:波特率*/
void UART_It_Init(unsigned int Baud)
{/* 串口寄存器的配置 */PCON &= 0x3F;	//PCON = 00xx xxxxSCON &= 0x0F;SCON |= 0x50;	//SCON = 0101 xxxx/* 配置T1的寄存器 */TMOD &= 0x0F;TMOD |= 0x20;	//TOMD = 0010 xxxxTH1 = 256 - (28800/Baud);//配置波特率TL1 = 256 - (28800/Baud);//配置波特率ET1 = 0;		//关闭T1溢出中断TR1 = 1;		//使能T1/* 使能串口中断 */ES = 1;			//使能串口中断EA = 1;			//使能中断总开关
}/***********中断服务函数*************/
/*** 中断服务函数*/
unsigned char Buffer[BUFF_Len];	//固定数据包缓存区
unsigned char Index = 0;		//缓存区索引
unsigned char Flag2 = 0;
void UART_Routine(void) interrupt 4
{	static unsigned char Status = 0;//状态机变量unsigned char ReceiveData;/* 若接收数据完成中断 RI = 1*/if(RI){RI = 0;ReceiveData = SBUF;/* 使用状态机对数据包进行处理 */switch(Status){case 0:if(ReceiveData == 0xFF)//是帧头0xFF{Status = 1;	//改变状态变量Index = 0;}else{Status = 0;	//不是帧头}break;case 1:if(ReceiveData == 0xFE)//判断是否为帧尾{Status = 0;	//改变状态变量Flag2 = 1;	//将标志位置1}else//不是帧尾{Buffer[Index++] = ReceiveData;//对数据进行处理}break;}}
}

②UART.h文件的代码如下

#ifndef __UART_H
#define __UART_H#include <reg51.h>		//包含51头文件,里面全是寄存器地址
#include <stdio.h>
#include <string.h>#define BUFF_Len 10void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)extern unsigned char Buffer[BUFF_Len];
extern unsigned char Flag2;
extern unsigned char Index;#endif

③main.c文件的代码如下

#include "UART.h"void main(void)
{UART_It_Init(9600);		//9600波特率while(1){if(Flag2)			//Flag = 1,数据处理完成{Flag2 = 0;Send_Array(Buffer,Index);//将数据发送出去}}
}

在这里插入图片描述

3、文本数据包

3.1、文本定长数据包收发

①UART.c文件的代码如下

/*** 串口初始化,且开启中断* 参数:波特率*/
void UART_It_Init(unsigned int Baud)
{/* 串口寄存器的配置 */PCON &= 0x3F;	//PCON = 00xx xxxxSCON &= 0x0F;SCON |= 0x50;	//SCON = 0101 xxxx/* 配置T1的寄存器 */TMOD &= 0x0F;TMOD |= 0x20;	//TOMD = 0010 xxxxTH1 = 256 - (28800/Baud);//配置波特率TL1 = 256 - (28800/Baud);//配置波特率ET1 = 0;		//关闭T1溢出中断TR1 = 1;		//使能T1/* 使能串口中断 */ES = 1;			//使能串口中断EA = 1;			//使能中断总开关
}/***********中断服务函数*************/
/*** 中断服务函数*/
unsigned char Buffer[BUFF_Len];	//固定数据包缓存区
unsigned char Index = 0;		//缓存区索引
unsigned char Flag2 = 0;
void UART_Routine(void) interrupt 4
{	static unsigned char Status = 0;//状态机变量unsigned char ReceiveData;/* 若接收数据完成中断 RI = 1*/if(RI){RI = 0;ReceiveData = SBUF;/* 使用状态机对数据包进行处理 */switch(Status){case 0:if(ReceiveData == '@')//是帧头'@'{Status = 1;	//改变状态变量Index = 0;}else{Status = 0;	//不是帧头}break;case 1:Buffer[Index++] = ReceiveData;//对数据进行处理if(Index >= 4){Status = 2;}break;case 2://判断是否为'\r'if(ReceiveData == '\r'){Status = 3;}else{Status = 0;memset(Buffer,0,4);//将缓冲区的数据清空}break;case 3://判断是否为'\n'if(ReceiveData == '\n'){Flag2 = 1;}else{memset(Buffer,0,4);//将缓冲区的数据清空}Status = 0;break;}}
}

②UART.h文件的代码如下

#ifndef __UART_H
#define __UART_H#include <reg51.h>		//包含51头文件,里面全是寄存器地址
#include <stdio.h>
#include <string.h>#define BUFF_Len 4void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)extern unsigned char Buffer[BUFF_Len];
extern unsigned char Flag2;
extern unsigned char Index;#endif

③main.c文件的代码如下

#include "UART.h"void main(void)
{UART_It_Init(9600);		//9600波特率while(1){if(Flag2)			//Flag = 1,数据处理完成{Flag2 = 0;Send_Array(Buffer,Index);//将数据发送出去}}
}

在这里插入图片描述

3.2、文本变长数据包收发

在这里插入图片描述
①UART.c文件的代码如下

/*** 串口初始化,且开启中断* 参数:波特率*/
void UART_It_Init(unsigned int Baud)
{/* 串口寄存器的配置 */PCON &= 0x3F;	//PCON = 00xx xxxxSCON &= 0x0F;SCON |= 0x50;	//SCON = 0101 xxxx/* 配置T1的寄存器 */TMOD &= 0x0F;TMOD |= 0x20;	//TOMD = 0010 xxxxTH1 = 256 - (28800/Baud);//配置波特率TL1 = 256 - (28800/Baud);//配置波特率ET1 = 0;		//关闭T1溢出中断TR1 = 1;		//使能T1/* 使能串口中断 */ES = 1;			//使能串口中断EA = 1;			//使能中断总开关
}/***********中断服务函数*************/
/*** 中断服务函数*/
unsigned char Buffer[BUFF_Len];	//固定数据包缓存区
unsigned char Index = 0;		//缓存区索引
unsigned char Flag2 = 0;
void UART_Routine(void) interrupt 4
{	static unsigned char Status = 0;//状态机变量unsigned char ReceiveData;/* 若接收数据完成中断 RI = 1*/if(RI){RI = 0;ReceiveData = SBUF;/* 使用状态机对数据包进行处理 */switch(Status){case 0:if(ReceiveData == '@')//是帧头'@'{Status = 1;	//改变状态变量Index = 0;}else{Status = 0;	//不是帧头}break;case 1:   if(ReceiveData == '\r')//接收的数据为\r,那么判断第二个数据是否为\n{Status = 2;//状态置2}else{Buffer[Index++] = ReceiveData;//对数据进行处理 }break;   case 2:if(ReceiveData == '\n')//若再次接收的数据是\n{Flag2 = 1;//则代表接收结束Buffer[Index++] = '\0';//给接收到的数据添加结束符Status = 0;		//准备第二轮的接收}else//若数据不是\n{Buffer[Index++] = '\r';//将上一次的\r存储在缓冲区中Buffer[Index++] = ReceiveData;//将这一次接收到的数据存储在缓冲区中Status = 1;//状态置1}break;}}
}

②UART.h文件的代码如下

#ifndef __UART_H
#define __UART_H#include <reg51.h>		//包含51头文件,里面全是寄存器地址
#include <stdio.h>
#include <string.h>#define BUFF_Len 4void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)extern unsigned char Buffer[BUFF_Len];
extern unsigned char Flag2;
extern unsigned char Index;#endif

③main.c文件的代码如下

#include "UART.h"void main(void)
{UART_It_Init(9600);		//9600波特率while(1){if(Flag2)			//Flag = 1,数据处理完成{Flag2 = 0;Send_String(Buffer);//将数据发送出去}}
}

在这里插入图片描述

4、定时器中断超时数据包收发

在这里插入图片描述
通过定时器中断计数延时来判断数据包是否完整。通过判断接收到数据包后面的超时时间,来辨别数据包是否接受完整。例如:规定数据包的间隔为10ms。上位机发送4个字节的数据包。单片机接受到4个字节后,通过定时器中断计数,若在10ms后没有在接受到数据,那么这个数据包就是4个字节的数据。时间的间隔 > 1/波特率 * 数据帧位个数
①UART.c文件的代码如下

/*** 串口初始化,且开启中断* 参数:波特率*/
void UART_It_Init(unsigned int Baud)
{/* 串口寄存器的配置 */PCON &= 0x3F;	//PCON = 00xx xxxxSCON &= 0x0F;SCON |= 0x50;	//SCON = 0101 xxxx/* 配置T1的寄存器 */TMOD &= 0x0F;TMOD |= 0x20;	//TOMD = 0010 xxxxTH1 = 256 - (28800/Baud);//配置波特率TL1 = 256 - (28800/Baud);//配置波特率ET1 = 0;		//关闭T1溢出中断TR1 = 1;		//使能T1/* 使能串口中断 */ES = 1;			//使能串口中断EA = 1;			//使能中断总开关
}/***********中断服务函数*************/
/*** 中断服务函数*/
unsigned char Buffer[BUFF_Len];	//固定数据包缓存区
unsigned char Index = 0;		//缓存区索引
unsigned char Flag2 = 0;
unsigned char start_time = 0;
unsigned char time_cnt = 0;
void UART_Routine(void) interrupt 4
{	unsigned char ReceiveData;/* 若接收数据完成中断 RI = 1*/if(RI){start_time = 1;//打开软件定时器开始计数RI = 0;Buffer[Index++] = SBUF;//对数据进行处理if(Index >= BUFF_Len)//数据缓存区满了{Index = BUFF_Len;}time_cnt = 0;//接收一位数据,让它置0,不让定时器中断让它变大}
}

②UART.h文件的代码如下

#ifndef __UART_H
#define __UART_H#include <reg51.h>		//包含51头文件,里面全是寄存器地址
#include <stdio.h>
#include <string.h>#define BUFF_Len 4void UART_Init(unsigned int Baud);//串口初始化
void Send_Char(unsigned char ch);//发送一个字节的数据
void Send_Array(unsigned char* Array,unsigned char Len);//发送多个字节的数据
void Send_String(unsigned char* str);//发送字符串
char putchar(char ch);//printf()重定向void UART_It_Init(unsigned int Baud);//串口初始化(使能中断)extern unsigned char Buffer[BUFF_Len];
extern unsigned char Flag2;
extern unsigned char Index;#endif

③time.c文件的代码如下

#include "Time.h"/*** 定时器T0的初始化,且开启中断*/
void Time0It_Init(void)
{/* 设置T0的计数器为16,且时钟来源为晶振 TMOD = xxxx 0001 */TMOD &= 0xF0;			//将低4位置0TMOD |= 0x01;			//最低位置1/* 设置定时计数器的初始值,定时1ms */TH0 = ((65536 - 1000) >> 8);TL0 = (65536 - 1000) & 0x00FF;/* 启动T0 */TF0 = 0;				//清除标志位TR0 = 1;/* 开启中断 */ET0 = 1;				//使能定时器溢出中断EA = 1;					//开启总开关
}/********中断服务函数*******/
/*** T0的中断服务函数*/
extern unsigned char Flag2;
extern unsigned char start_time; 
extern unsigned char time_cnt;
void Time0_Rountine(void) interrupt 1
{	//这里不用清除标志位,硬件会自动清除TH0 = ((65536 - 1000) >> 8);TL0 = (65536 - 1000) & 0x00FF;if(start_time == 1)//表示串口开始接收数据{time_cnt++;if(time_cnt >= 10)//表示串口没有在接收数据了{start_time = 0;//关闭软件定时器time_cnt = 0;Flag2 = 1;}}
}

④main.c文件的代码如下

#include "UART.h"
#include "Time.h"void main(void)
{UART_It_Init(9600);		//9600波特率Time0It_Init();while(1){if(Flag2)			//Flag = 1,数据处理完成{Flag2 = 0;Send_Array(Buffer,Index);//将数据发送出去Index = 0;memset(Buffer,0,Index);//清除缓存区}}
}

在这里插入图片描述

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

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

相关文章

vs2022支持.netframework4.0

下载nuget包 .netframework4.0 解压nuget 复制到C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework 参考 https://www.cnblogs.com/bdqczhl/p/18670152 https://blog.csdn.net/xiaomeng1998_/article/details/135979884

《安富莱嵌入式周报》第350期:Google开源Pebble智能手表,开源模块化机器人平台,开源万用表,支持10GHz HRTIM的单片机,开源CNC控制器

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1YPKEeyEeM/ 《安富莱嵌入式周报》第350期&#xff1a;Google开…

Oracle临时表空间(基础操作)

临时表空间 临时表空间&#xff1a;用来存放用户的临时数据&#xff0c;临时数据在需要时被覆盖&#xff0c;关闭数据库后自动删除&#xff0c;其中不能存放永久性数据。 用户进程和服务器进程是一对一的叫做专用连接。 任何一个用户连到oracle数据库&#xff0c;oracle都会…

19.4.2 -19.4.4 新增、修改、删除数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 需要北风数据库的请留言自己的信箱。 19.4.2 新增数据 数据库数据的新增、修改和删除不同于查询&#xff0c;查询需要返回一个DbD…

若依系统环境搭建记录

开源若依系统网上资料也很全的&#xff0c;本篇博文记录下自己搭建环境过程中遇到的一些问题。 配置Maven和编辑器选择 我懒得配置Eclipse了&#xff0c;直接用vscode作为编辑器&#xff0c;后面构建运行都用命令行。 配置数据库连接 按照mysql5.7按网上教程即可&#xff1…

Redis——优惠券秒杀问题(分布式id、一人多单超卖、乐悲锁、CAS、分布式锁、Redisson)

#想cry 好想cry 目录 1 全局唯一id 1.1 自增ID存在的问题 1.2 分布式ID的需求 1.3 分布式ID的实现方式 1.4 自定义分布式ID生成器&#xff08;示例&#xff09; 1.5 总结 2 优惠券秒杀接口实现 3 单体系统下一人多单超卖问题及解决方案 3.1 问题背景 3.2 超卖问题的…

解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载

脚本地址: 项目地址: Gazer PosterBandit_v2.py 前瞻 之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍…

3D可视化定制:开启个性化消费新时代

3D可视化定制是一种将产品的三维模型与可视化技术相结合&#xff0c;以满足消费者个性化需求的服务。以下是对3D可视化定制的详细介绍&#xff1a; 一、定义与原理 3D可视化定制是指利用三维建模技术和可视化工具&#xff0c;为消费者提供一个直观、互动且高度个性化的定制平…

5种解决方式来应对deepseek暂时无法回答

在工作中&#xff0c;你是否常常遇到deepseek回复“暂时无法回答”的情况&#xff1f;根据某权威机构的调研数据显示&#xff0c;约73%的用户在使用此类工具时遇到过类似问题&#xff0c;这严重影响了工作效率和体验。本文将为你提供5种实测有效的解决方法&#xff0c;帮助你快…

单调队列与栈

一.题 1. 思路&#xff1a; 构建小压大的单调递减栈&#xff0c;对于每个栈的元素都进行处理并加到结果上 class Solution { public:int sumSubarrayMins(vector<int>& arr) {int stk[10000000],top 0;long long ans 0;for(int i 0;i<arr.size();i){while(top…

在带有Intel Arc GPU的Windows上安装IPEX-LLM

在带有Intel Arc GPU的Windows上安装IPEX-LLM 在带有Intel Arc GPU的Windows上安装IPEX-LLM先决条件安装 GPU 驱动安装 Visual Studio 2022 社区版安装 Intel oneAPI Base Toolkit安装 IPEX-LLM创建虚拟环境环境验证 可能遇到的问题 在带有Intel Arc GPU的Windows上安装IPEX-LL…

03-微服务01(服务拆分、RestTemplate,nacos、OpenFeign、日志)

之前我们学习的项目一是单体项目&#xff0c;可以满足小型项目或传统项目的开发。而在互联网时代&#xff0c;越来越多的一线互联网公司都在使用微服务技术。 从谷歌搜索指数来看&#xff0c;国内从自2016年底开始&#xff0c;微服务热度突然暴涨&#xff1a; 那么&#xff1…

2.SpringSecurity在mvc项目中的使用

SpringSecurity认证过程 参考 来源于黑马程序员&#xff1a; 手把手教你精通新版SpringSecurity 设置用户状态 用户认证业务里&#xff0c;我们封装User对象时&#xff0c;选择了三个构造参数的构造方法&#xff0c;其实还有另一个构造方法&#xff1a; public User(Strin…

Java数组二:数组的使用

for-each循环 打印数组所有元素 public class Demo04 {public static void main(String[] args) {int[] num {1,5,2,3,4};for (int num1:num) {System.out.println(num1);}} }多维数组 多维数组可以看成是数组的数组&#xff0c;比如二维数组就是一个特殊的一维数组&#x…

STM32HAL库快速入门教程——常用外设学习(2)

目录 一、STM32HAL库开发&#xff08;8&#xff09;——CubeMX配置DMA 1.1、什么是DMA&#xff1f; 1.2、内存内存之间的传输&#xff08;单次&#xff09; ​编辑 1.3、内存外设之间的传输&#xff08;ADC&#xff09; 二、STM32HAL库开发&#xff08;9&#xff09;——…

汽车ECU实现数据安全存储的一种方案

一、 综述 在车辆ECU中总是有一些密钥或重要数据需进行机密性保护&#xff0c;但因产品选型、成本等考虑&#xff0c;导致一些ECU的芯片不支持硬件安全模块&#xff08;例如HSM、TEE等&#xff09;。此时&#xff0c;为保障数据的机密性&#xff0c;可考虑通过软件实现数据的安…

十进制数到十六进制数的转换

十进制数x&#xff0c;若能表示为&#xff0c;n为大于等于0的整数。ni4j。i取值为0、1、2和3。综合i和j&#xff0c;若i为0&#xff0c;则该16进制数为1后面加j个0&#xff1b;若i为1&#xff0c;则该16进制数为2后面加j个0&#xff1b;若i为2&#xff0c;则该16进制数为4后面加…

基于YoloV11+PaddleOCR的车牌检测系统

文章目录 一、CCPD数据集进行处理1.1 从文件夹构建txt格式数据集1.2 运行脚本按照8&#xff1a;2划分训练集&#xff0c;测试集 二 、YOLOV11训练模型2.1 编写car_plate.yaml文件2.2 编写train脚本&#xff1a;2.3 训练过程 三、PaddleOCR识别车牌号3.1 安装paddleocr&#xff…

2月12日鸿蒙生态日日新PLOG,多款应用上架

2月12日鸿蒙生态日日新PLOG &#xff1a;北京医院挂号通、有度、远光商旅等多款应用上架&#xff1b;钉钉、得到、航班管家等多款重点应用功能更新。 ​​​

Python----PyQt开发(PyQt高级:手搓一个简单的记事本)

一、效果展示 二、设计PyQt界面 2.1、设置图标 self.setWindowIcon(QIcon(./images/icon/1.png)) # 窗口图标 2.2、设置标题 self.file_name 无标题-新建文本文档 # 默认文件名 self.setWindowTitle(self.file_name) # 窗口标题 2.3、添加菜单栏、工具栏、状态栏 # 创…