【蓝桥杯嵌入式】第十三届省赛(第二场)

目录

0 前言

1 展示

1.1 源码

1.2 演示视频

1.3 题目展示

2 CubeMX配置(第十三届省赛第二场真题)

2.1 设置下载线

2.2 HSE时钟设置

2.3 时钟树配置

2.4 生成代码设置

2.5 USART1

2.5.1 基本配置

2.5.2 NVIC

2.5.3 DMA 

2.6 TIM

2.6.1 TIM2

2.6.2 TIM4

2.6.3 TIM6

3 引脚配置

4 代码相关定义、声明

4.1 变量声明

4.2 函数声明

5 主要函数

5.1 LCD

5.2 KEY

5.3 EEPROM

5.4 LED

5.5 PWM

5.6 定时器回调函数

5.7 串口回调函数

 5.8 串口

5.9 上电初始化

6 测试

7 做题感受


菜狗上线~~~


0 前言

  • 开发板:CT117E-M4(STM32G431RBT6)
  • 软件环境:CubeMX + Keil5
  • 涉及题目:第十三届蓝桥杯嵌入式省赛第二场真题

1 展示

1.1 源码

Gitee链接:

1.2 演示视频

B站链接:

1.3 题目展示


2 CubeMX配置(第十三届省赛第二场真题)

2.1 设置下载线

2.2 HSE时钟设置

2.3 时钟树配置

晶振一定要改成24M,晶振一定要改成24M,晶振一定要改成24M,主频80M

2.4 生成代码设置

2.5 USART1

2.5.1 基本配置

题目要求串口1波特率9600

2.5.2 NVIC

串口一定要使能NVIC

2.5.3 DMA 

添加两个DMA即可

2.6 TIM

2.6.1 TIM2

TIM2用作PWM输出功能,通过引脚PA1输出

配置成2KHz的PWM

定时器2也要使能NVIC

2.6.2 TIM4

TIM4做基准定时器,10ms定时,专门用来按键扫描

预分频系数80-1

重装载值10000-1

定时器4也要使能NVIC

2.6.3 TIM6

定时器65用来实现倒计时5S,不开定时器6也可以用定时器4实现,这里我不想让倒计时和按键有联系,就多开了一个定时器,配置如下

定时器6也要使能NVIC


3 引脚配置

  • 配置8个LED         PD2  outpp    PC8~PC15   outpp
  • 配置4个按键         PA0、PB0、PB1、PB2    配置为上拉输入模式
  • 配置串口1            PA9  PA10
  • PWM                   PA1(TIM2-CH2)


4 代码相关定义、声明

4.1 变量声明

主要的变量定义如下所示,用了两个结构体,一个是写参数的,一个是写标志位的

/* 定义结构体 */
struct Param_TypeDef
{u32 LED_Tick; // LED定时 函数减速u32 LCD_Tick; // LCD定时 函数减速u32 RX_Tick;  // RX 定时 函数减速u32 PWM_Tick; // PWM定时 函数减速u32 EEP_Tick; // EEPROM 定时u8 LED_State; // LED状态变量u16 Set_PA1_Freq; //u8 Set_PA1_Duty;u8 Shop_Num_X; // 购买数量Xu8 Shop_Num_Y; // 购买数量Yfloat Price_X; // 单价Xfloat Price_Y; // 单价Yu8 REP_X;	   // 库存Xu8 REP_Y;	   // 库存Yfloat All_Price; // 总价u8 last_rep_X; // 上次的Xu8 last_rep_Y; // 上次的Yfloat Last_Price_X; // 单价Xfloat Last_Price_Y; // 单价Y
};struct Flag_TypeDef
{bool LCD_Dir;u8 LCD_View;		 // LCD界面u8 Current_Platform; // 当前平台bool Key4_Press;	 // KEY4按下bool led2_state;
};extern struct Param_TypeDef param;
extern struct Flag_TypeDef flag;/* 定义结构体 */// 定义状态机状态
#define SHOP 0
#define PRICE 1
#define REP 2

4.2 函数声明

/* 函数声明 */
void LED_proc(void);
void LCD_Disp_proc(void);
void Key_proc_Loop(void);
void Power_Init(void); // 上电初始化
void RX_Proc(void); // 串口接收函数
void PWM_Set_Proc(void);
void EEPROM_Proc(void);

5 主要函数

5.1 LCD

LCD一共有三个界面,分别是购买界面、单价界面、库存界面,分别题目要求到的标题和内容~

这里的MYLCD_printf()函数是我自己封装的

// LCD显示
void LCD_Disp_proc(void)
{// 函数减速if (uwTick - param.LCD_Tick < 50)return;param.LCD_Tick = uwTick;// 执行任务if (flag.LCD_View == SHOP){ // 购买界面MYLCD_printf(Line1, "        SHOP         ");MYLCD_printf(Line3, "     X:%2d           ", param.Shop_Num_X);MYLCD_printf(Line4, "     Y:%2d           ", param.Shop_Num_Y);}else if (flag.LCD_View == PRICE){ // 单价界面MYLCD_printf(Line1, "        PRICE        ");MYLCD_printf(Line3, "     X:%.1f           ", param.Price_X);MYLCD_printf(Line4, "     Y:%.1f           ", param.Price_Y);}else if (flag.LCD_View == REP){ // 库存界面MYLCD_printf(Line1, "        REP          ");MYLCD_printf(Line3, "     X:%2d           ", param.REP_X);MYLCD_printf(Line4, "     Y:%2d           ", param.REP_Y);}
}

正常的LCD显示语句,每次都要使用之前清零,再用sprint函数拼接字符串再调用LCD的显示函数,为了显示的更加简洁我用可变参数列表封装了这三行代码~代码如下

// // 使用之前先清除显示数组,再填写内容
// memset(LCD_Show_text, '\0', sizeof(LCD_Show_text));
// sprintf(LCD_Show_text, "    LED:OFF     ");
// LCD_DisplayStringLine(Line5, (uint8_t *)LCD_Show_text);
void MYLCD_printf(unsigned char linex, char *format, ...)
{char LCD_Show_text[30];memset(LCD_Show_text, '\0', sizeof(LCD_Show_text));va_list arg;                          // 定义可变参数列表数据类型的变量argva_start(arg, format);                // 从format开始,接收参数列表到arg变量vsprintf(LCD_Show_text, format, arg); // 使用vsprintf打印格式化字符串和参数列表到字符数组中LCD_DisplayStringLine(linex, (uint8_t *)LCD_Show_text);va_end(arg); // 结束变量arg//	sprintf((char *)LCD_Show_text, str);
}

思路如下: 

  1. //先清除数组的内容
  2. // 定义可变参数列表数据类型的变量arg
  3. // 从format开始,接收参数列表到arg变量
  4. // 使用vsprintf打印格式化字符串和参数列表到字符数组中
  5. //LCD显示
  6. // 结束变量arg

5.2 KEY

按键处理函数,使用01Stdio的按键扫描函数,放在定时器4里10ms扫描一次

按键1是切换界面

按键2是购买数量,注意越界回滚

按键3是购买单价,注意越界回滚,这个但是是浮点数,这里就有说到了,浮点数的2.0f其实不准确,如果判断当前价格>2.0了就参数回滚,会出现1.9直接跳变到2.0,所以我们把比较的数值改成2.01f就完美解决了~~~

按键4 计算总计,串口上传数据,发送完成,单价清零

void Key_proc_Loop(void)
{if (bkey[1].short_flag == 1){flag.LCD_View++;if (flag.LCD_View >= 3)flag.LCD_View = 0; // 三个界面bkey[1].short_flag = 0;}if (bkey[2].short_flag == 1){if (flag.LCD_View == SHOP){ // 购买界面param.Shop_Num_X++;if (param.Shop_Num_X > param.REP_X) // 超过库存,越界回滚成0param.Shop_Num_X = 0;}else if (flag.LCD_View == PRICE){ // 单价界面param.Price_X += 0.1f;if (param.Price_X > 2.01f) // 注意浮点数param.Price_X = 1.0f;  // 越界回滚}else if (flag.LCD_View == REP){ // 库存界面param.REP_X++;}bkey[2].short_flag = 0;}if (bkey[3].short_flag == 1) //{if (flag.LCD_View == SHOP){ // 购买界面param.Shop_Num_Y++;if (param.Shop_Num_Y > param.REP_Y) // 超过库存,越界回滚成0param.Shop_Num_Y = 0;}else if (flag.LCD_View == PRICE){ // 单价界面param.Price_Y += 0.1f;if (param.Price_Y > 2.01f) // 注意浮点数param.Price_Y = 1.0f;  // 越界回滚}else if (flag.LCD_View == REP){ // 库存界面param.REP_Y++;}bkey[3].short_flag = 0;}if (bkey[4].short_flag == 1) //{if (flag.LCD_View == SHOP){ // 购买界面flag.Key4_Press = 1;param.REP_X -= param.Shop_Num_X;param.REP_Y -= param.Shop_Num_Y;param.All_Price = param.Shop_Num_X * param.Price_X + param.Shop_Num_Y * param.Price_Y;memset(USART_tx_string, '\0', sizeof(USART_tx_string)); // 变量清零sprintf(USART_tx_string, "X:%d,Y:%d,Z:%.1f", param.Shop_Num_X, param.Shop_Num_Y, param.All_Price);HAL_UART_Transmit_DMA(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string));// 发送完成,单价清零param.Shop_Num_X = 0;param.Shop_Num_Y = 0;}bkey[4].short_flag = 0;}
}

5.3 EEPROM

这个函数100ms调用一次,在函数里判断当前值和100ms以前的值是否相等,如果不相等,就说明数据变化了,就需要存储到EEPROM中,存到对应的地址里

要存储的单价是一位浮点数,乘以10变成整数存进去,读取的时候不要忘记除以10即可

这里的逻辑是先判断,后赋值,如果先赋值后判断,永远检测不出来数据跳变,这里要细细品味一下,有之前写的按键扫描的味道~

void EEPROM_Proc(void)
{if (uwTick - param.EEP_Tick < 100)return;param.EEP_Tick = uwTick;if (param.last_rep_X != param.REP_X){EEPROM_WriteByte(0, param.REP_X); // 剩余数量XHAL_Delay(10);}if (param.last_rep_Y != param.REP_Y){EEPROM_WriteByte(1, param.REP_Y); // 剩余数量YHAL_Delay(10);}if (param.Last_Price_X != param.Price_X){EEPROM_WriteByte(2, (param.Price_X * 10)); // 单价XHAL_Delay(10);}if (param.Last_Price_Y != param.Price_Y){EEPROM_WriteByte(3, (param.Price_Y * 10)); // 单价YHAL_Delay(10);}param.last_rep_X = param.REP_X;param.last_rep_Y = param.REP_Y;param.Last_Price_X = param.Price_X;param.Last_Price_Y = param.Price_Y; // 延迟赋值
}

5.4 LED

LED显示函数,只需要写一次即可,我们只需要修改param.LED_State这个变量,就能达到控制哪一位LED亮灭的状态

LED显示多用位运算,非常巧妙~

//LED驱动函数
void LED_Disp(unsigned char state)
{HAL_GPIO_WritePin(GPIOC, 0xFF00, GPIO_PIN_SET);		  // 先全部熄灭 1HAL_GPIO_WritePin(GPIOC, state << 8, GPIO_PIN_RESET); // 点亮 0HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);	  // 锁存器置高,使能HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); // 锁存器置低,失能
}
// LED处理函数
void LED_proc(void)
{static u8 led1, led2;// 函数减速if (uwTick - param.LED_Tick < 20)return;param.LED_Tick = uwTick;led1 = flag.Key4_Press << 0; // 5S内是1led2 = flag.led2_state << 1;param.LED_State = led1 | led2;LED_Disp(param.LED_State);
}

5.5 PWM

  • 设置频率,设置占空比,只修改变量即可
  • __HAL_TIM_SetAutoreload设置重装载值,80分频之后是1MHz = 1e6,用1e6/要设置的频率就是重装载值
  • __HAL_TIM_SetCompare设置比较值,设置高电平时间,即设置占空比,比较值=重装载值*占空比
void PWM_Set_Proc(void)
{if (uwTick - param.PWM_Tick < 100)return;param.PWM_Tick = uwTick;// 设置频率HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);param.Set_PA1_Freq = 2000;    //2000Hz__HAL_TIM_SetAutoreload(&htim2, 1e6 / param.Set_PA1_Freq - 1);// 设置占空比if (flag.Key4_Press == 1) // 5S内param.Set_PA1_Duty = 30;    //30%占空比elseparam.Set_PA1_Duty = 5;    //5%占空比__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, (1e6 / param.Set_PA1_Freq - 1) * param.Set_PA1_Duty / 100 + 1);    //设置占空比函数
}

5.6 定时器回调函数

定时器4专门用来10ms扫描一次按键

定时器6用来处理LED的5S点亮,和0.1S闪烁,使用标志位判断即可,这些都是常规操作~

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{static uint16_t LED_cnt, LED_cnt2;if (htim->Instance == TIM4){key_serv_double(); // 10ms按键处理}if (htim->Instance == TIM6) // 10ms进入一次 处理倒计时{if (flag.Key4_Press == 1){if (++LED_cnt >= 500){LED_cnt = 0;flag.Key4_Press = 0;}}if ((param.REP_X == 0) && (param.REP_Y == 0)) // 如果XY的库存都等于0{if (++LED_cnt2 >= 10){LED_cnt2 = 0; // 100msflag.led2_state = !flag.led2_state;}}elseflag.led2_state = 0;}
}

5.7 串口回调函数

// 串口的接收 回调函数
char USART_tx_string[50];
char rxdata[100];
uint8_t RX_Str_Data;
unsigned char rx_pointer; // 自己定义的指针,判断接收到哪了void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1) // 如果是USART1{param.RX_Tick = uwTick;rxdata[rx_pointer++] = RX_Str_Data;				// 接收到的字符串存放在这里HAL_UART_Receive_DMA(&huart1, &RX_Str_Data, 1); // 最后这个参数只能写1}
}

 5.8 串口

void RX_Proc(void)
{if (uwTick - param.RX_Tick < 50)return;param.RX_Tick = uwTick;// 执行任务if (rx_pointer == 1 && rxdata[0] == '?') // 如果收到一个数据,并且是#{memset(USART_tx_string, '\0', sizeof(USART_tx_string)); // 变量清零sprintf(USART_tx_string, "X:%.1f,Y:%.1f", param.Price_X, param.Price_Y);HAL_UART_Transmit_DMA(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string));}else if (rx_pointer > 0){}rx_pointer = 0;						  // 指针归位memset(rxdata, '\0', sizeof(rxdata)); // 变量清零
}

5.9 上电初始化

  1. LCD初始化
  2. 按键初始化
  3. 定时器初始化
  4. PWM初始化
  5. 串口DMA发送初始化
  6. 串口DMA接收初始化
  7. 检测是否第一次上电,如果是第一次上电,就初始化库存和单价
// 上电初始化
void Power_Init(void)
{LED_Disp(0x00); // 关掉所有LEDLCD_Init(); // LCD初始化LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);LCD_DrawLine(120, 0, 320, Horizontal);LCD_DrawLine(0, 160, 240, Vertical);HAL_Delay(150);LCD_Clear(Blue);LCD_DrawRect(70, 210, 100, 100);HAL_Delay(150);LCD_Clear(Blue);LCD_DrawCircle(120, 160, 50);HAL_Delay(150);LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);KEY_GPIO_Init(); // 手动初始化,防止忘记配置CubeMX// 定时器初始化HAL_TIM_Base_Start_IT(&htim4);HAL_TIM_Base_Start_IT(&htim6); // 用于倒计时//	// PWM初始化HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2); // 打开定时器2 通道2HAL_UART_Transmit_DMA(&huart1, (uint8_t *)USART_tx_string, strlen(USART_tx_string));HAL_UART_Receive_DMA(&huart1, &RX_Str_Data, 1); // IT改为DMA// 参数初始化if (EEPROM_ReadByte(111) != 11) // 第一次进入是不等于的{// 先执行这里的代码// 第一次就先初始化param.REP_X = 10; // 库存默认10param.REP_Y = 10; // 库存默认10param.Price_X = 1.0;param.Price_Y = 1.0f;EEPROM_WriteByte(111, 11); // 在111写111}else // 不是第一次上电{// 上电先读取EEPROMparam.REP_X = EEPROM_ReadByte(0);HAL_Delay(1);param.REP_Y = EEPROM_ReadByte(1);HAL_Delay(1);param.Price_X = EEPROM_ReadByte(2) / 10.0;HAL_Delay(1);param.Price_Y = EEPROM_ReadByte(3) / 10.0;HAL_Delay(1);}
}

6 测试

按键可以自行测试,这里我只展示串口部分的效果


7 做题感受

  • 注意浮点数的比较 2.0f与2.01f的区别,看上面5.2 KEY 按键3的解释
  • 串口收发不到数据,没使用rx_proc函数,然后重新配置了一下TX和RX的DMA就可以使用了
  • PWM没有输出,使用定时器2通道2,我写成了通道1,所以没有输出...
  • EEPROM存储的数据不能是小数;
  • 试题中比较难的部分是如何判定设备是否是第一次启动以及EEPROM连续读取需要一定的时间间隔
  • 总的来说,该试题还是比较简单的,就剩一些常见的解题模式框架,🚀🚀🚀!!!

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

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

相关文章

2.k8s架构

目录 k8s集群架构 控制平面 kube-apiserver kube-scheduler etcd kube-controller-manager node 组件 kubelet kube-proxy 容器运行时&#xff08;Container Runtime&#xff09; cloud-controller-manager 相关概念 k8s集群架构 一个Kubernetes集群至少包含一个控制…

【Django开发】前后端分离美多商城项目第6篇:用户部分,1. 业务说明【附代码文档】

美多商城项目4.0文档完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;美多商城&#xff0c;项目准备1.B2B--企业对企业,2.C2C--个人对个人,3.B2C--企业对个人,4.C2B--个人对企业,5.O2O--线上到线下,6.F2C--工厂到个人。项目准备&#xff0c;配置1. 修改set…

C++——智能指针

作者&#xff1a;几冬雪来 时间&#xff1a;2024年4月7日 内容&#xff1a;C内容智能指针讲解 目录 前言&#xff1a; 为什么需要智能指针&#xff1a; 普通智能指针书写&#xff1a; 智能指针发展历史与各种智能指针&#xff1a; 循环引用与弱指针&#xff1a; 定制删…

蚁剑修改特征性信息

前言 我们首先得知道蚁剑的流量特征&#xff1a; 编码器和解码器的特征&#xff1a;蚁剑自带的编码器和解码器具有明显的特点&#xff0c;可以通过更改配置文件来达到流量加密的目的1。例如&#xff0c;蚁剑支持多种编码方式&#xff0c;如base64、chr、rot13等&#xff0c;这…

thinkphp6中使用监听事件和事件订阅

目录 一&#xff1a;场景介绍 二&#xff1a;事件监听 三&#xff1a;配置订阅 一&#xff1a;场景介绍 在项目开发中有很多这样的场景&#xff0c;比如用户注册完了&#xff0c;需要通知到第三方或者发送消息。用户下单了&#xff0c;需要提示给客服等等。这些场景都有一个…

什么是多路复用器滤波器

本章将更深入地介绍多路复用器滤波器&#xff0c;以及它们如何用于各种应用中。您将了解到多路复用器如何帮助设计人员创造出更复杂的无线产品。 了解多路复用器 多路复用器是一组射频(RF)滤波器&#xff0c;它们组合在一起&#xff0c;但不会彼此加载&#xff0c;可以在输出之…

Linux 下安装 openjdk 17【详细步骤】

👉 目标 了解为什么不选择 oracle jdk17,而是选择 openjdk17linux 下安装 openjdk17 详细步骤为什么不选择 oracle jdk17? 官网:Java Downloads | Oracle 中国 官网描述:JDK 17 binaries are free to use in production and free to redistribute, at no cost, under t…

服务器开发 Socket 相关函数

Socket 函数 #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol)domain: AF_INET 这是大多数用来产生 socket 的协议&#xff0c;使用TCP或UDP来传输&#xff0c;用IPv4的地址 AF_INET6 与上面类似&#xff0c;不过…

opencv图像处理技术(阈值处理与图像平滑)

进行图像处理时&#xff0c;常常需要对图像进行预处理以提取所需的信息或改善图像质量。阈值处理和图像平滑是两种常见的预处理技术。 阈值处理 阈值处理是一种图像分割技术&#xff0c;其基本思想是将图像中的像素值与一个或多个预先设定的阈值进行比较&#xff0c;根据比较…

5分钟学会Rust语言如何操作JSON

JSON(JavaScript Object Notation)在Web开发中被广泛应用于数据交换。作为一种数据格式&#xff0c;JSON相较于XML来说&#xff0c;更易于阅读和写入&#xff0c;且数据解析性能强。Rust作为一门系统级编程语言&#xff0c;其与JSON的交互操作密切。本文将详细地描述在Rust中如…

循环双链表算法库构建

学习贺老师数据结构数据结构之自建算法库——循环双链表_数据结构编写一个程序linklist.cpp-CSDN博客 模仿单链表逻辑,实现双链表, 大差不差 v1.0: 实现基本功能 V1.0 1.主要功能: //(1)头插法建立循环双链表 void Create_Double_CyclicList_Head(DoubleLinkList_Cyclic *&am…

C++进阶(五) 哈希

1. unordered系列关联式容器 1.1 unordered_map 1.2 unordered_map的接口说明 2. 底层结构 2.1 哈希概念 2.2 哈希冲突 2.3 哈希函数 2.4 哈希冲突解决 2.4.1 闭散列 2.4.2 开散列 3. 模拟实现 3.1 unordered_set 3.2 unordered_map 4.哈希的应用 4.1 位图 4.1.…

HBase详解(2)

HBase 结构 HRegion 概述 在HBase中&#xff0c;会从行键方向上对表来进行切分&#xff0c;切分出来的每一个结构称之为是一个HRegion 切分之后&#xff0c;每一个HRegion会交给某一个HRegionServer来进行管理。HRegionServer是HBase的从节点&#xff0c;每一个HRegionServ…

华为海思2024春招数字芯片岗机试题(共9套)

huawei海思2024春招数字芯片岗机试题(共9套&#xff09;&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN huawei数字题目&#xff0c;谢绝白嫖哈&#xff09; 题目包含数字集成电路、System Verilog、Verilog2001、半导体制造技术、高级ASIC芯片综合、…

SpringCloud Alibaba Sentinel 实现熔断功能

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第十六篇&#xff0c;即使用 Sentinel 实现熔断功能。 二、 Ribbon 系列 首先我们新建两个服务的提供者…

【数据结构与算法】:快速排序和冒泡排序

一&#xff0c;快速排序 快速排序是一种比较复杂的排序算法&#xff0c;它总共有4种实现方式&#xff0c;分别是挖坑法&#xff0c;左右"指针"法&#xff0c;前后"指针"法&#xff0c;以及非递归的快速排序&#xff0c;并且这些算法中也会涉及多种优化措施…

1. 先简单看看项目吧

前言 就目前的前端生态而言&#xff0c;跨端开发基本算是每一个前端开发者必备的技能点之一了&#xff0c;随便看看各大招聘网站上关于前端岗位的招聘要求&#xff0c;几乎都要小程序开发了.... 另外由于Uni-app等这些跨端框架的产生&#xff0c;中小型企业对于Android/Ios等…

APP的UI设计规范

APP的设计规范是一系列原则和标准&#xff0c;旨在确保应用程序提供一致、易用且美观的用户体验。以下是一些关键的APP设计规范。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.一致性&#xff1a; 保持界面元素和交互行为的一致性…

网络协议——HTTP协议

目录 ​编辑 一&#xff0c;HTTP协议基本认识 二&#xff0c;认识URL 三&#xff0c;http协议的格式 1&#xff0c;发送格式 2&#xff0c;回应格式 四&#xff0c;服务端代码 五&#xff0c;http报文细节 1&#xff0c;Post与Get方法 2&#xff0c;Content_lenth 3&…

vscode教程

个人笔记&#xff08;整理不易&#xff0c;有帮助点个赞&#xff09; 笔记目录&#xff1a;学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔&#xff1a;工作总结随笔_8、以前工作中都接触过哪些类型的测试文档-CSDN博客 目录 一&#xff1a…