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

【蓝桥杯-单片机】基于定时器的倒计时程序设计

基于定时器的倒计时程序

题目如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现过程中遇到的一些问题

01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5

首先这个问题不是在main.c中关于数码管显示部分的逻辑错误,就是发生在数码管的底层错误。
检查了逻辑部分,没有发现问题
转而查找底层上面的错误。
底层的Seg.c是这样写的:

#include <Seg.h>unsigned char code Seg_Dula[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f ,0x00};
unsigned char code Seg_Wela[] = {0xfe ,0xfd ,0xfb,0xf7,0xef,0xdf};void Seg_Disp(unsigned char wela,dala)
{//消影P0 = 0x00;P2_6 = 1;P2_6 = 0;P0 = Seg_Wela[wela];P2_7 = 1;P2_7 = 0;P0 = Seg_Dula[wela];//问题出现在这里!P2_6 = 1;P2_6 = 0;
}

果然被我发现了,段选数组的索引写错了,写成了wela,这样无论如何,数码管的每一位都会按照传入的wela来显示(wela在main函数中即Seg_Pos,这个变量在0-5范围内循环)

	if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);

02 按下设置按键KEY4设置好倒计时参数后,该参数应该在什么时机传输给Time_Count倒计时变量用于倒计时呢?

(1)设置完就对Time_Count赋值

//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];//设置完就对Time_Count赋值!!!!!!}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}

如果这样的话,会导致切换回显示模式后已经倒计时了一段时间了,不是从设置的值开始倒计时的。想要切换回显示模式从设置的值开始倒计时,需要在切换回显示模式后,再对Time_Count赋值。

(2)在切换成显示模式后对Time_Count赋值

//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;if(Seg_Mode == 0)Time_Count = Set_Dat[Set_Dat_Index]  ;//切换到显示界面再对Time_Count赋值!!!!!!break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;//Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}

03 倒计时到0之后为什么数码管又变成55再倒计时呢?

这是因为Time_Count–,没有对其作任何限制的情况下,Time_Count减为0之后会再从255开始减递减(Time_Count是一个unsigned char类型的变量,该变量8bit,变量可以表示的范围为0-255)。而我们只让数码管显示到十位数,因此我们看到的就是数码管从55开始倒计时。

对中断服务函数代码作如下修改:

void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;//修改代码!!!!!!!!!!!!!!!!!!}}
}

修改代码之后数码管会停在00的位置。

在这里插入图片描述

至此,所有代码如下所示(不包含设置参数以1s为周期闪烁):

//头文件声明
#include <REGX52.H>
#include <Key.h>
#include <Seg.h>//动态数码管会用到数码管的底层?//变量声明
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量unsigned int Seg_Slow_Down;//数码管减速专用变量 500mschar:0-255.char不够用//动态数码管
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组unsigned char Seg_Mode;//数码管显示页面 0-显示 1-设置,默认为0
unsigned int Timer_1000ms;//1000ms标志位
unsigned char Time_Count = 30;//倒计时变量//按键
bit System_Flag;//0-暂停 1-开始倒计时unsigned char Set_Dat[3] = {15,30,60};//设置参数储存数组
unsigned char Set_Dat_Index = 1;//LED点亮标志位
bit Timer0Flag;//0-倒计时没有到0;1-倒计时到0//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;//if(Seg_Mode == 0)//Time_Count = Set_Dat[Set_Dat_Index];break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}/* 其他显示函数 */
//Led_Proc()
void Led_Proc()
{if(Time_Count == 0){P1 = 0x00;//LED全亮P2_3 = 0;//蜂鸣器使能}else{P1 = 0xff;//LED全灭P2_3 = 1;//蜂鸣器关闭}
}//Timer0Init()定时器0的中断初始化函数
void Timer0Init(void)		//1毫秒@12.000MHz
{//AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时//复制过来之后不要忘记加上两句话ET0 = 1;EA = 1;
}//Server定时器0的中断服务函数
//a++是先进行取值,后进行自增。++a是先进行自增,后进行取值
void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;}}
}
//主函数
void main()
{Timer0Init();//上电时立即调用定时器初始化函数while(1){//三大处理单元:按键、数码管、LEDKey_Proc();Seg_Proc();Led_Proc();}
}

04 如何实现设置参数以1s为周期闪烁?

(1)在变量声明区新增两个变量:
注:以1s为周期闪烁,即500ms亮,500ms灭。

unsigned int Timer_500ms;//500ms标志位
bit Seg_Flag;//数码管标志位,即控制数码管的亮灭

(2)在中断服务函数中

	if(++Timer_500ms == 500){Timer_500ms = 0;Seg_Flag ^= 1;//因为默认值为0,只需要对其取反即可,不需要赋值,可以用^=1来对一个变量取反}

(3)在数码管显示函数中

//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{
//		Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;
//		Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;
//修改如下:if(Seg_Flag == 1){Seg_Buf[4] = 10;Seg_Buf[5] = 10;}else{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}
}

05 最终版代码

//头文件声明
#include <REGX52.H>
#include <Key.h>
#include <Seg.h>//动态数码管会用到数码管的底层?//变量声明
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量unsigned int Seg_Slow_Down;//数码管减速专用变量 500mschar:0-255.char不够用//动态数码管
unsigned char Seg_Pos;//数码管扫描变量
unsigned char Seg_Buf[6] = {10,10,10,10,10,10};//数码管显示数据存放数组unsigned char Seg_Mode;//数码管显示页面 0-显示 1-设置,默认为0
unsigned int Timer_1000ms;//1000ms标志位
unsigned char Time_Count = 30;//倒计时变量//按键
bit System_Flag;//0-暂停 1-开始倒计时unsigned char Set_Dat[3] = {15,30,60};//设置参数储存数组
unsigned char Set_Dat_Index = 1;//设置参数闪烁
unsigned int Timer_500ms;//500ms标志位
bit Seg_Flag;//数码管标志位//LED点亮标志位
bit Timer0Flag;//0-倒计时没有到0;1-倒计时到0//按键处理函数Key_Proc()
void Key_Proc()
{if(Key_Slow_Down)return;Key_Slow_Down = 1;//按键减速程序//这三行要背下来Key_Val = Key_Read();//读取按下的键码值Key_Down = Key_Val &(Key_Val ^ Key_Old);//捕获下降沿Key_Old = Key_Val;//辅助扫描switch(Key_Down){//框架先搭好,内容先不写case 1:if(Seg_Mode == 0) System_Flag = 1;break;case 3:Seg_Mode ^= 1;//if(Seg_Mode == 0)//Time_Count = Set_Dat[Set_Dat_Index];break;case 4:if(Seg_Mode == 1){if(++Set_Dat_Index == 3) Set_Dat_Index = 0;Time_Count = Set_Dat[Set_Dat_Index];}break;case 2:if(Seg_Mode == 0) Time_Count = Set_Dat[Set_Dat_Index];break;}
}//信息显示函数Seg_Proc()
void Seg_Proc()
{if(Seg_Slow_Down)return;Seg_Slow_Down = 1;//数码管减速程序//现在没有要显示的信息,这里先空着。(模板以外的东西)Seg_Buf[0] = Seg_Mode + 1;if(Seg_Mode == 0)//显示模式{Seg_Buf[4] = Time_Count/10%10;//可以写成Time_Count/10嘛Seg_Buf[5] = Time_Count%10;}else//处于设置模式{
//		Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;
//		Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;if(Seg_Flag == 1){Seg_Buf[4] = 10;Seg_Buf[5] = 10;}else{Seg_Buf[4] = Set_Dat[Set_Dat_Index]/10%10;Seg_Buf[5] = Set_Dat[Set_Dat_Index]%10;}}
}/* 其他显示函数 */
//Led_Proc()
void Led_Proc()
{if(Time_Count == 0){P1 = 0x00;//LED全亮P2_3 = 0;//蜂鸣器使能}else{P1 = 0xff;//LED全灭P2_3 = 1;//蜂鸣器关闭}
}//Timer0Init()定时器0的中断初始化函数
void Timer0Init(void)		//1毫秒@12.000MHz
{//AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时//复制过来之后不要忘记加上两句话ET0 = 1;EA = 1;
}//Server定时器0的中断服务函数
//a++是先进行取值,后进行自增。++a是先进行自增,后进行取值
void Timer0Server() interrupt 1
{//定时器的初值一定要记得从上面复制过来TL0 = 0x18;		//设置定时初值TH0 = 0xFC;		//设置定时初值if(++Key_Slow_Down == 10) Key_Slow_Down = 0;if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;if(++Seg_Pos == 6) Seg_Pos = 0;Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos]);//模板以外的东西if(System_Flag == 1)//倒计时开始{if(++Timer_1000ms == 1000){Timer_1000ms = 0;Time_Count--;//相当于1s中减少一次(倒计时一次)if(Time_Count==255) Time_Count=0;}}if(++Timer_500ms == 500){Timer_500ms = 0;Seg_Flag ^= 1;//因为默认值为0,只需要对其取反即可,不需要赋值,可以用^=1来对一个变量取反}
}
//主函数
void main()
{Timer0Init();//上电时立即调用定时器初始化函数while(1){//三大处理单元:按键、数码管、LEDKey_Proc();Seg_Proc();Led_Proc();}
}

参考视频:https://www.bilibili.com/video/BV1TR4y1k7iz?p=6&vd_source=5af7b905774c79f1754cd4ab83975115

相关文章:

【蓝桥杯-单片机】基于定时器的倒计时程序设计

基于定时器的倒计时程序 题目如下所示&#xff1a; 实现过程中遇到的一些问题 01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5 首先这个问题不是在main.c中关于数码管显示部分的逻辑错误&#xff0c;就是发生在数码管的底层错误。 检查了逻辑部分&#xff…...

QT:三大特性

QT的三大特性&#xff1a; 1、信号与槽 2、内存管理 3、事件处理 1、信号与槽 当信号产生时&#xff0c;就会自动调用绑定的槽函数。 自定义信号: 类中需要添加O_OBJECT宏 声明: signals标签之下进行声明 定义&#xff1a; 信号不需要定义 …...

无服务器推理在大语言模型中的未来

服务器无服务器推理的未来&#xff1a;大型语言模型 摘要 随着大型语言模型(LLM)如GPT-4和PaLM的进步&#xff0c;自然语言任务的能力得到了显著提升。LLM被广泛应用于聊天机器人、搜索引擎和编程助手等场景。然而&#xff0c;由于LLM对GPU和内存的巨大需求&#xff0c;其在规…...

【linux】CentOS查看系统信息

一、查看版本号 在CentOS中&#xff0c;可以通过多种方法来查看版本号。以下是几种常用的方法&#xff1a; 使用cat命令查看/etc/centos-release文件&#xff1a; CentOS的版本信息存储在/etc/centos-release文件中。可以使用cat命令来显示该文件的内容&#xff0c;从而获得C…...

部署dagu_1.12.10+replicadb0.15.1+sqlline1.12

下载所需的文件并上传到服务器 dagu_1.12.10(选择适合自己的版本): https://gh.api.99988866.xyz/https://github.com/dagu-dev/dagu/releases/download/v1.12.10/dagu_1.12.10_linux_amd64.tar.gzreplicadb0.15.1(包含了sqlline1.12): https://download.csdn.net/download/u0…...

基于Java中的SSM框架实现社会保险管理系统项目【项目源码+论文说明】

摘要 改革开放的浪潮已近深深的键入人心&#xff0c;随之而带来了我国社会主义市场经济体制的不断完善和建立健全&#xff0c;作为国家基本保障之一的社会保险系统&#xff0c;我们不单单要把握社保金额的进展和状态&#xff0c;还需要对社会保障基金开展全面、科学、可持续的…...

24计算机考研调剂 | 江西理工大学

能源、化工、计算机&#xff08;0854&#xff09;等相关方向有3个调剂名额 考研调剂招生信息 学校:江西理工大学 专业:工学->治金工程 年级:2024 招生人数:3 招生状态:正在招生中 联系方式:********* (为保护个人隐私,联系方式仅限APP查看) 补充内容 能源、化工、计…...

Sentry(Android)源码解析

本文字数&#xff1a;16030字 预计阅读时间&#xff1a;40分钟 01 前言 Sentry是一个日志记录、错误上报、性能监控的开源框架&#xff0c;支持众多平台&#xff1a; 其使用方式在本文不进行说明了&#xff0c;大家可参照官方文档&#xff1a;https://docs.sentry.io/platforms…...

Android StateLayout状态页

文章目录 Android StateLayout状态页概述源码使用源码下载 Android StateLayout状态页 概述 StateLayout&#xff08;状态页&#xff09;包含&#xff1a;加载中页面&#xff0c;错误页面&#xff0c;空页面&#xff0c;内含状态默认页面&#xff0c;支持自定义页面。 源码 …...

JetBrains数据库驱动下载失败解决方法

本方法可通用于解决PyCharm等JetBrains家的IDE下载数据库驱动问题。 在Jet家IDE内连接数据库时&#xff0c;mysql、sqlite等的驱动有部分在 https://download.jetbrains.com 网站上&#xff0c;可能由于网络问题无法访问。 解决方法是修改 JetBrains 路径下的 jdbc.drivers.xm…...

【vim 学习系列文章 16 -- vim 自动保存设置】

文章目录 vim 自动保存设置 vim 自动保存设置 在 Vim 编辑器中&#xff0c;你可以通过设置 updatetime 选项来控制自动保存的时间间隔。updatetime 的默认值是 4000 毫秒&#xff08;4 秒&#xff09;&#xff0c;但你可以将其设置为 5000 毫秒&#xff08;5 秒&#xff09;以…...

python的O2O生鲜食品订购flask-django-nodejs-php

用户只能通过一些类似软件进行查看生鲜超市&#xff0c;这样的管理方式仍然是比较机械传统的&#xff0c;本文通过对市面上常见的线上管理系统与现实生活中结合问题的讨论&#xff0c;从一个微信小程序的O2O生鲜食品订购角度进行需求分析&#xff0c;提供一些新的思路&#xff…...

六、大模型-Prompt-API介绍

GPT-3.5 API 提供了一个名为 openai.ChatCompletion.create() 的端点&#xff0c;您可以使用该端点来与 ChatGPT 进行交互。以下是 openai.ChatCompletion.create() 的详细 API 说明&#xff1a; 请求参数&#xff1a; messages&#xff1a;一个数组&#xff0c;包含对话中的消…...

嵌入式安全性基础知识-计算机系统安全知识+信息安全基础+网络安全协议-嵌入式系统设计师备考笔记

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记&#xff0c;未经本人许可&#xff0c;请勿转载&#xff0c;如发现本笔记内容的错误还望各位不吝赐教&#xff08;笔记内容可能有误怕产生错误引导&#xff09;。 本章的主要内容见下图&#xff1a; 1、计算机系统系统…...

基于javaSpringboot+mybatis+layui的装修验收管理系统设计和实现

基于javaSpringbootmybatislayui的装修验收管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留…...

jenkins构建完成后部署到本机,无法读取容器外文件夹

项目背景&#xff1a; Dockerjenkins 构建完成后&#xff0c;要把打包的dist文件夹内容移动到网站目录 /www/wwwroot/xxxxxx 文件夹下&#xff1b;但是获取不到jenkins容器外的文件夹。 解决办法&#xff1a; 在容器中&#xff0c;添加挂载/映射本机目录&#xff0c;把网站…...

如何使用 Elasticsearch 作为向量数据库

在今天的文章中&#xff0c;我们将很快地通过 Docker 来快速地设置 Elasticsearch 及 Kibana&#xff0c;并设置 Elasticsearch 为向量搜索。 拉取 Docker 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2 docker pull docker.elastic.co/kibana/kiba…...

高精度AI火灾烟雾检测算法,助力打造更加安全的楼宇环境

一、方案背景 近日&#xff0c;南京居民楼火灾事故导致15人死亡的新闻闹得沸沸扬扬&#xff0c;这一事件又激起了大家对楼宇火灾隐患的进一步担忧。事后我们除了思考政府、消防及物业部门应对此事的解决办法&#xff0c;我们还应该思考如何利用现有的技术帮助人们减少此类事情的…...

node和npm yarn包管理工具

node和包管理工具 今日目标&#xff1a; 1.dos常用指令 2.node的模块化 3.npm包管理工具 4.yarn的常用指令 5.node的内置模块 00-回顾 # Promose:作用&#xff1a;解决ajax请求响应顺序不可控的问题特性&#xff1a;1. Promise是一个构造函数&#xff0c;需要通过new关…...

鸿蒙Harmony应用开发—ArkTS(@Link装饰器:父子双向同步)

子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明&#xff1a; 从API version 9开始&#xff0c;该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 限制条件 Link装饰器不能在Entry装饰的自定义组件中使用…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解

一、前言 在HarmonyOS 5的应用开发模型中&#xff0c;featureAbility是旧版FA模型&#xff08;Feature Ability&#xff09;的用法&#xff0c;Stage模型已采用全新的应用架构&#xff0c;推荐使用组件化的上下文获取方式&#xff0c;而非依赖featureAbility。 FA大概是API7之…...