【蓝桥杯-单片机】基于定时器的倒计时程序设计
基于定时器的倒计时程序
题目如下所示:
实现过程中遇到的一些问题
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
相关文章:

【蓝桥杯-单片机】基于定时器的倒计时程序设计
基于定时器的倒计时程序 题目如下所示: 实现过程中遇到的一些问题 01 如何改变Seg_Buf数组的值数码管总是一致地显示0 1 2 3 4 5 首先这个问题不是在main.c中关于数码管显示部分的逻辑错误,就是发生在数码管的底层错误。 检查了逻辑部分ÿ…...

QT:三大特性
QT的三大特性: 1、信号与槽 2、内存管理 3、事件处理 1、信号与槽 当信号产生时,就会自动调用绑定的槽函数。 自定义信号: 类中需要添加O_OBJECT宏 声明: signals标签之下进行声明 定义: 信号不需要定义 …...
无服务器推理在大语言模型中的未来
服务器无服务器推理的未来:大型语言模型 摘要 随着大型语言模型(LLM)如GPT-4和PaLM的进步,自然语言任务的能力得到了显著提升。LLM被广泛应用于聊天机器人、搜索引擎和编程助手等场景。然而,由于LLM对GPU和内存的巨大需求,其在规…...

【linux】CentOS查看系统信息
一、查看版本号 在CentOS中,可以通过多种方法来查看版本号。以下是几种常用的方法: 使用cat命令查看/etc/centos-release文件: CentOS的版本信息存储在/etc/centos-release文件中。可以使用cat命令来显示该文件的内容,从而获得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框架实现社会保险管理系统项目【项目源码+论文说明】
摘要 改革开放的浪潮已近深深的键入人心,随之而带来了我国社会主义市场经济体制的不断完善和建立健全,作为国家基本保障之一的社会保险系统,我们不单单要把握社保金额的进展和状态,还需要对社会保障基金开展全面、科学、可持续的…...
24计算机考研调剂 | 江西理工大学
能源、化工、计算机(0854)等相关方向有3个调剂名额 考研调剂招生信息 学校:江西理工大学 专业:工学->治金工程 年级:2024 招生人数:3 招生状态:正在招生中 联系方式:********* (为保护个人隐私,联系方式仅限APP查看) 补充内容 能源、化工、计…...

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

Android StateLayout状态页
文章目录 Android StateLayout状态页概述源码使用源码下载 Android StateLayout状态页 概述 StateLayout(状态页)包含:加载中页面,错误页面,空页面,内含状态默认页面,支持自定义页面。 源码 …...

JetBrains数据库驱动下载失败解决方法
本方法可通用于解决PyCharm等JetBrains家的IDE下载数据库驱动问题。 在Jet家IDE内连接数据库时,mysql、sqlite等的驱动有部分在 https://download.jetbrains.com 网站上,可能由于网络问题无法访问。 解决方法是修改 JetBrains 路径下的 jdbc.drivers.xm…...
【vim 学习系列文章 16 -- vim 自动保存设置】
文章目录 vim 自动保存设置 vim 自动保存设置 在 Vim 编辑器中,你可以通过设置 updatetime 选项来控制自动保存的时间间隔。updatetime 的默认值是 4000 毫秒(4 秒),但你可以将其设置为 5000 毫秒(5 秒)以…...

python的O2O生鲜食品订购flask-django-nodejs-php
用户只能通过一些类似软件进行查看生鲜超市,这样的管理方式仍然是比较机械传统的,本文通过对市面上常见的线上管理系统与现实生活中结合问题的讨论,从一个微信小程序的O2O生鲜食品订购角度进行需求分析,提供一些新的思路ÿ…...
六、大模型-Prompt-API介绍
GPT-3.5 API 提供了一个名为 openai.ChatCompletion.create() 的端点,您可以使用该端点来与 ChatGPT 进行交互。以下是 openai.ChatCompletion.create() 的详细 API 说明: 请求参数: messages:一个数组,包含对话中的消…...

嵌入式安全性基础知识-计算机系统安全知识+信息安全基础+网络安全协议-嵌入式系统设计师备考笔记
0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记,未经本人许可,请勿转载,如发现本笔记内容的错误还望各位不吝赐教(笔记内容可能有误怕产生错误引导)。 本章的主要内容见下图: 1、计算机系统系统…...

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

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

如何使用 Elasticsearch 作为向量数据库
在今天的文章中,我们将很快地通过 Docker 来快速地设置 Elasticsearch 及 Kibana,并设置 Elasticsearch 为向量搜索。 拉取 Docker 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2 docker pull docker.elastic.co/kibana/kiba…...

高精度AI火灾烟雾检测算法,助力打造更加安全的楼宇环境
一、方案背景 近日,南京居民楼火灾事故导致15人死亡的新闻闹得沸沸扬扬,这一事件又激起了大家对楼宇火灾隐患的进一步担忧。事后我们除了思考政府、消防及物业部门应对此事的解决办法,我们还应该思考如何利用现有的技术帮助人们减少此类事情的…...
node和npm yarn包管理工具
node和包管理工具 今日目标: 1.dos常用指令 2.node的模块化 3.npm包管理工具 4.yarn的常用指令 5.node的内置模块 00-回顾 # Promose:作用:解决ajax请求响应顺序不可控的问题特性:1. Promise是一个构造函数,需要通过new关…...

鸿蒙Harmony应用开发—ArkTS(@Link装饰器:父子双向同步)
子组件中被Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。 说明: 从API version 9开始,该装饰器支持在ArkTS卡片中使用。 概述 Link装饰的变量与其父组件中的数据源共享相同的值。 限制条件 Link装饰器不能在Entry装饰的自定义组件中使用…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...