【BUG】滴答定时器的时间片轮询与延时冲突
SysTick定时器实现延时与时间戳的深度分析与问题解决指南
1. SysTick基础原理
1.1 SysTick的功能与核心配置
SysTick是ARM Cortex-M内核的系统定时器,常用于以下场景:
- 时间戳:通过周期性中断记录系统运行时间(如
tick_ms
计数器)。 - 延时:基于轮询或中断模式实现精确的微秒/毫秒级延时。
- 关键寄存器:
寄存器 功能描述 示例配置 CTRL
控制使能、中断、时钟源选择 0x0007
(启用+中断+HCLK)LOAD
设置重装载值(决定中断周期) SystemCoreClock/1000-1
VAL
当前计数值(可写0重置) 0x00000000
1.2 SysTick的典型初始化
// 1ms中断配置(假设系统时钟48MHz)
void SysTick_Init(void) {SysTick->LOAD = 48000 - 1; // 48MHz/1000 = 48000 ticks/msSysTick->VAL = 0; // 清空计数值SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; // 开启中断+启用NVIC_SetPriority(SysTick_IRQn, 15); // 最低优先级
}
1.3 实现时间戳
// 全局变量声明(必须加volatile!)
volatile uint32_t tick_ms = 0;void SysTick_Handler(void) {tick_ms++; // 每次中断递增
}// 获取当前时间戳(毫秒)
uint32_t Get_Tick(void) {return tick_ms;
}// 初始化SysTick为1ms中断
void SysTick_Init(void) {SysTick_Config(SystemCoreClock / 1000); // 1ms触发一次中断NVIC_SetPriority(SysTick_IRQn, 15); // 最低优先级
}
1.4 实现延时函数
// 微秒级延时(轮询模式,无中断)
void delay_us(uint32_t us) {SysTick->LOAD = 48 * us; // 48MHz下48 ticks/μsSysTick->VAL = 0; // 清空计数器SysTick->CTRL |= 0x05; // 启用定时器(HCLK + 无中断)while (!(SysTick->CTRL & 0x10000)); // 等待计数完成SysTick->CTRL = 0; // 关闭定时器
}
2. 时间戳与延时混用的冲突机制
2.1 问题本质
当 延时函数直接操作SysTick寄存器(如修改LOAD
、VAL
、CTRL
)时,会破坏SysTick的原有中断配置,导致:
- 时间戳停滞:中断周期被篡改或中断被禁用,
tick_ms
计数器无法更新。 - 标志位失效:依赖
tick_ms
的time_1ms_flag
/time_1s_flag
无法触发。 - 优先级冲突:如果在延时期间关闭中断,时间戳更新完全被冻结。
2.2 关于“延时导致SysTick中断关闭”的解释
核心结论:
无论是短延时(如500µs)还是长延时(如2s),只要调用您原始的delay_us()
函数,SysTick中断都会被永久关闭。这不仅限于长延时,而是所有调用此函数的情况都会触发该问题。以下是详细分析:
1. delay_us
函数的致命错误
您的原始delay_us
函数存在一个关键错误:
// 原delay_us函数末尾:
SysTick->CTRL = 0x00000004; // 关闭定时器,关闭中断!
此操作将SysTick控制寄存器(CTRL
)的TICKINT
位设为0
(禁止中断),导致中断被永久关闭。
2. 短延时的典型破坏流程
假设调用一次delay_us(500)
(500微秒),步骤如下:
-
原始SysTick配置:
LOAD
= 48,000(1ms周期)CTRL
=0x0007
(启用定时器 + 使能中断)
-
进入
delay_us(500)
时:SysTick->LOAD = 48 * 500; // 24,000(500μs周期) SysTick->VAL = 0; SysTick->CTRL = 0x00000005; // 开启定时器 **但禁用中断**
-
延时结束时:
SysTick->CTRL = 0x00000004; // 关闭定时器 + 保持中断禁用
此时:
- 中断被禁用(
TICKINT
位为0)。 - 定时器停止计数(
ENABLE
位为0)。
- 中断被禁用(
-
后果:
- SysTick中断不再触发,
tick_ms
停止递增。 - 所有依赖时间戳的应用逻辑(如
time_1s_flag
)失效。
- SysTick中断不再触发,
3. “短延时”不等于“无害”
误区澄清:短延时(如500µs)的破坏效果与延时长度无关,而是因函数末尾的CTRL = 0x04
导致中断被禁用!
操作 | 结果 |
---|---|
调用一次delay_us(500) | SysTick中断永久关闭 |
调用一次delay_us(100) | SysTick中断永久关闭 |
4. 长延时只是多次触发同一问题
当调用delay_ms(2000)
(由2000次delay_us(1000)
组成)时:
- 每次调用
delay_us(1000)
后CTRL
都被设为0x04
。 - 最终结果仍然是:最后一次延时结束时,SysTick中断保持关闭。
3. 详细Bug实例分析
3.1 Bug复现代码
// main_control函数片段
void main_control(void) {if (time_1s_flag) { // 依赖SysTick中断触发time_1s_flag = 0;send(); // 调用含长延时的函数}
}// 发送SOS信号的函数
void send() {transmit_data("SOS"); delay_ms(2000); // 阻塞式延时
}
3.2 运行流程与故障机理
-
初始状态:
SysTick
每1ms触发中断,递增tick_ms
,每秒置位time_1s_flag
。
-
第一次触发
time_1s_flag
:main_control
进入并调用send()
。send()
调用delay_ms(2000)
。
-
执行
delay_ms(2000)
期间:- 每次调用
delay_us(1000)
会覆盖LOAD
和CTRL
:SysTick->CTRL = 0x05; // 启用计数器,关闭中断 // ...等待完成... SysTick->CTRL = 0x04; // 关闭计数器,保持中断禁用
- 关键破坏点:最后一次
delay_us
结束时,SysTick的CTRL
为0x04
(中断被禁用)。
- 每次调用
-
延时结束后:
- SysTick中断无法恢复(
TICKINT
位为0),tick_ms
停止更新。 time_1s_flag
永远不会再次触发,程序停留在main_control
中无法处理其他任务。
- SysTick中断无法恢复(
4. 解决方案及代码实现
4.1 方案1:使用独立定时器实现延时
Step1:配置TIM2作为专用延时定时器
// TIM2初始化(1MHz时钟)
void TIM2_Init(void) {RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 开启TIM2时钟TIM2->PSC = 48 - 1; // 48MHz → 1MHzTIM2->ARR = 0xFFFF; // 自动重载值TIM2->CR1 |= TIM_CR1_CEN; // 启动TIM2
}
Step2:重新实现延时函数(依赖TIM2)
void delay_us(uint32_t us) {TIM2->CNT = 0; // 复位计数while (TIM2->CNT < us) {} // 轮询模式
}void delay_ms(uint32_t ms) {delay_us(ms * 1000);
}
优点:
- SysTick专用于时间戳,TIM2处理延时,零冲突。
- 全流程无需操作SysTick寄存器,稳定性高。
4.2 方案2:安全共享SysTick(需严格上下文保存)
修改后的延时函数
void delay_us(uint32_t us) {uint32_t origLOAD = SysTick->LOAD;uint32_t origVAL = SysTick->VAL;uint32_t origCTRL = SysTick->CTRL;// 禁用中断,设为轮询模式SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;SysTick->LOAD = 48 * us; // 1us = 48 ticks @48MHzSysTick->VAL = 0;SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;// 等待完成(通过COUNFLAG而非VAL判断)while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));// 恢复原始配置(确保中断重新启用)SysTick->CTRL = origCTRL; SysTick->LOAD = origLOAD;SysTick->VAL = origVAL;
}
关键点分析:
- 寄存器保存与恢复:确保每次延时结束后,SysTick的中断上下文完全恢复。
- COUNFLAG使用:直接查询标志位,避免
VAL
的中间值干扰。
4.3 方案3:非阻塞延时设计(消除主循环阻塞)
重构send
为状态机
void send(void) {static uint32_t start_time = 0;static enum { IDLE, WAITING } state = IDLE;switch (state) {case IDLE:transmit_data(); start_time = Get_Tick();state = WAITING;break;case WAITING:if (Get_Tick() - start_time >= 2000) { // 非阻塞检查2秒state = IDLE;}break;}
}
优势:
delay_ms()
被移除,主循环始终保持响应。- 即使时间戳被意外冻结,程序逻辑也不会完全卡死(但仍需处理时钟异常)。
5. 验证调试流程
5.1 SysTick中断状态检查
-
断点调试:
- 在
SysTick_Handler
设置断点,确保每次SysTick中断触发。 - 检查调用
delay_us
后,中断是否依然能触发。
- 在
-
寄存器监视:
- 观察
SysTick->CTRL
的TICKINT
位是否始终为1。 - 确认
LOAD
和VAL
在延时结束后恢复原值。
- 观察
5.2 标志位行为验证
-
逻辑分析仪测试:
- 监控
time_1ms_flag
和tick_ms
在延时期间的时序。
- 监控
-
代码埋点:
void SysTick_Handler(void) {tick_ms++;static uint32_t last_tick = 0;if (tick_ms - last_tick >= 1000) {time_1s_flag = 1;last_tick = tick_ms;}// ...其他逻辑...
}
- 添加调试变量
last_tick
,确认每秒触发一次。
6. 总结:核心设计原则
原则 | 说明 |
---|---|
单一职责 | SysTick仅用于时间戳,延时用独立定时器(TIM2/TIM3等)实现。 |
非阻塞设计 | 避免在主循环或中断中使用delay_ms 等阻塞函数,改用状态机或定时器回调。 |
临界区保护 | 操作共享硬件资源(如SysTick)时,禁用中断并保存上下文。 |
优先级管理 | SysTick中断优先级设为最低,防止被其他中断抢占导致抖动。 |
严格测试 | 使用动态监测工具(如逻辑分析仪、调试器)验证时间戳精度和标志响应速度。 |
终极建议:在资源允许的情况下,优先采用 独立定时器方案(如TIM2+TIM3组合),从根本上消除硬件冲突风险,确保系统实时性和稳定性。
相关文章:
【BUG】滴答定时器的时间片轮询与延时冲突
SysTick定时器实现延时与时间戳的深度分析与问题解决指南 1. SysTick基础原理 1.1 SysTick的功能与核心配置 SysTick是ARM Cortex-M内核的系统定时器,常用于以下场景: 时间戳:通过周期性中断记录系统运行时间(如tick_ms计数器&…...
基于EFISH-SCB-RK3576/SAIL-RK3576的智能快递分拣机技术方案
(国产化替代J1900的物流自动化解决方案) 一、硬件架构设计 高速视觉识别系统 多目立体成像: 双MIPI-CSI接入16K线阵相机(扫描速度5m/s),支持0.1mm级条形码破损识别NPU加速YOLOv7算法࿰…...
The 2022 ICPC Asia Xian Regional Contest(E,L)题解
E Find Maximum 题意: 首先,通过观察与打表,可以发现: 规律: 对于非负整数 x,函数 f(x) 的值等于: 将 xx 写成三进制后,各个位数的数字之和 该三进制数的位数。 例如,…...
Jmeter 安装包与界面汉化
Jmeter 安装包: 通过网盘分享的文件:CSDN-apache-jmeter-5.5 链接: https://pan.baidu.com/s/17gK98NxS19oKmkdRhGepBA?pwd1234 提取码: 1234 Jmeter界面汉化:...
《Python星球日记》 第70天:Seq2Seq 与Transformer Decoder
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、Seq2Seq模型基础1. 什么是Seq2Seq模型?2. Encoder-Decoder架构详解1️⃣编码器(Encoder)2️⃣解码器(Decoder)3. 传统Seq2Seq模型的局限性…...
【Linux】基础指令(Ⅱ)
目录 1. mv指令 2. cat指令 3.echo指令 补:输出重定向 4. more指令 5. less指令 6. head指令和tail指令 7.date指令 时间戳: 8. cal指令 9. alias指令 10.grep指令 1. mv指令 语法:mv [选项]... 源文件/目录 目标文件/目录 …...
【Python3教程】Python3基础篇之输入与输出
博主介绍:✌全网粉丝23W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…...
mysql的一个缺点
最近再移植一个从oracle转mysql的项目,喜提一个报错: You cant specify target table A016 for update in FROM clause 对应的程序代码: public void setCurrent(String setId, String pk, String userId) throws SysException {String[]…...
【C/C++】高阶用法_笔记
1. 模板元编程(TMP)与编译时计算 (1) 类型萃取与 SFINAE 类型萃取(Type Traits):利用模板特化在编译时推断类型属性。 template<typename T> struct is_pointer { static constexpr bool value false; };templ…...
AMS3xxi激光测距仪安装调试维护详解
一、应用原理介绍 如下图,AMS3xxi激光测距发出的激光通过特定反光板返回后,利用“时间飞行法”原理进行距离 测量。测量中若遮挡光束传播会导致测距失败,产品报警。 二、固定和调节位置说明 在安装板上,使用 4 个 M5 螺钉锁 AMS…...
建筑IT数字化突围:建筑设计企业的生存法则重塑
困局:铅笔与键盘的撕裂之痛 晨光中的设计院里,总工老张的办公桌上堆叠着三摞图纸:左边是刚收尾的住宅施工图,中间夹着结构专业提资的变更单,右边是甲方连夜发来的方案调整意见。这是他从业28年来的日常,也…...
VTK|类似CloudCompare的比例尺实现2-vtk实现
文章目录 实现类头文件实现类源文件调用逻辑关键问题缩放限制问题投影模式项目git链接实现类头文件 以下是对你提供的 ScaleBarController.h 头文件添加详细注释后的版本,帮助你更清晰地理解每个成员和方法的用途,尤其是在 VTK 中的作用: #ifndef SCALEBARCONTROLLER_H #de…...
Java高频面试之并发编程-17
volatile 和 synchronized 的区别 在 Java 并发编程中,volatile 和 synchronized 是两种常用的同步机制,但它们的适用场景和底层原理有显著差异。以下是两者的详细对比: 1. 核心功能对比 特性volatilesynchronized原子性不保证复合操作的原…...
最优化方法Python计算:有约束优化应用——近似线性可分问题支持向量机
二分问题的数据集 { ( x i , y i ) } \{(\boldsymbol{x}_i,y_i)\} {(xi,yi)}, i 1 , 2 , ⋯ , m i1,2,\cdots,m i1,2,⋯,m中,特征数据 { x i } \{\boldsymbol{x}_i\} {xi}未必能被一块超平面按其标签值 y i ∈ { − 1 , 1 } y_i\in\{-1,1\} yi∈…...
Excel中批量对多个结构相同的工作表执行操作,可以使用VBA宏来实现
【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实…...
Spring的Validation,这是一套基于注解的权限校验框架
为了保证数据的正确性、完整性,作为一名后端开发工程师,不能仅仅依靠前端来校验数据,还需要对接口请求的参数进行后端的校验。 controller 全局异常处理器 在项目中添加一个全局异常处理器,处理校验异常 RestControllerAdvice p…...
鸿蒙OSUniApp 开发的下拉刷新与上拉加载列表#三方框架 #Uniapp
使用 UniApp 开发的下拉刷新与上拉加载列表 前言 最近在做一个小程序项目时,发现列表的加载体验对用户至关重要。简单的一次性加载全部数据不仅会导致首屏加载缓慢,还可能造成内存占用过大。而分页加载虽然解决了这个问题,但如果没有良好的…...
VastBase的日常操作记录
---------需要命令启动数据库操作------------------- [vastbasedmz-neo4j01 ~]$ vb_ctl start [2025-05-13 09:41:54.515][10224][][vb_ctl]: vb_ctl started,数据目录是 /home/vastbase/data/vastbase [2025-05-13 09:41:54.728][10224][][vb_ctl]: 等待服务端进程启动 ... …...
企业级IP代理解决方案:负载均衡与API接口集成实践
在全球化业务扩张与数据驱动决策的背景下,企业级IP代理解决方案通过负载均衡技术与API接口集成,可有效应对高频请求、反爬机制及合规风险。以下是基于企业级场景的核心实践要点: 一、负载均衡与IP代理的深度协同 动态IP池的负载均衡策略 轮询…...
智能手表项目风险评估与应对计划书
📘 智能手表项目风险评估与应对计划书 项目名称:Aurora Watch S1 版本号:v1.0 编制人:XXX(项目经理) 日期:2025年xx月xx日 一、概述 本计划书旨在识别Aurora Watch S1智能手表项目全过程中可能…...
Java基础之静态代理和动态代理
一、静态代理 定义: 代理类与被代理类在编译期就已确定,代理类需要手动编写并实现与被代理类相同的接口 1.核心角色: Subject(抽象主题):定义业务方法的接口 RealSubject(真实主题ÿ…...
观成科技:加密C2框架Vshell流量分析
一、工具介绍 Vshell是一款功能全面的红队工具,其设计兼顾隐蔽性与灵活性,尤其适合模拟网络攻击和测试防御体系。该工具支持TCP、UDP、KCP、WebSocket、DNS、DOH、DOT等多种协议。内置隧道代理功能,支持正向和反向连接模式,可以适…...
麒麟环境下Selenium的使用
本文主要介绍了在内网环境下、服务主机无域名的情况下,为了抓取内网其他系统网页数据,安装使用Selenium的方,并详细介绍了离线安装python依赖包的方法。服务主机操作系统为麒麟V10 SP3。 一. 查看可以安装的浏览器安装包 1. 更新软件包索引 首先确保软件包列表是最新的:…...
Protocol Buffers 全流程通俗讲解
Protocol Buffers 全流程通俗讲解(从 0 到进阶) 目录 序列化到底为什么要选 Protobuf?核心原理:一眼看懂二进制编码10 分钟跑通「写 .proto → 生成代码 → 读写数据」.proto 文件 8 条黄金法则(小白友好版&…...
从故障到防护:抗晃电保护装置如何提升电网可靠性?
安科瑞刘鸿鹏 摘要 随着工业自动化水平的提升,生产设备对供电连续性和稳定性的依赖程度越来越高,电网中的电压暂降(俗称“晃电”)问题对工业生产构成了严重威胁。特别是在化工、冶金、半导体等高敏感行业,晃电引发的…...
Three.js知识框架
一、Three.js 基础概念 1. Three.js 简介 是什么? 基于 WebGL 的 3D JavaScript 库,用于在浏览器中渲染 3D 场景。 核心优势 简化 WebGL 的复杂 API,提供高层封装。 跨平台(支持桌面和移动端)。 适用场景 3D 可视…...
5.14本日总结
一、英语 背诵list30,复习list1 二、数学 完成30讲第13讲课后题,学习14讲部分内容 三、408 完成计网5.1,5.2题目 四、总结 在高数14讲内容学完之前写完13讲的所有题目,预计20号学完14讲内容,408的进度要加快,本…...
数据结构学习之链表学习:单链表
在之前顺序表的学习过程中,我们知道顺序表中头插和中插的复杂度是O(N)。那我们可不可以将其降低为O(1)呢?可不可以不增容想用就用想扔就扔而不会浪费一点空间呢?那就是我们今天的内容࿱…...
技术债务积累,如何进行有效管理
识别和评估技术债务、明确技术债务的优先级、制定系统的还债计划、持续监控与预防技术债务产生是有效管理技术债务积累的重要策略。其中尤其要注重识别和评估技术债务,只有准确识别技术债务的种类和严重程度,才能制定出高效且有针对性的解决方案…...
[20250514] 脑机接口行业调研报告(2024年最新版)
脑机接口行业调研报告(2024年最新版) 1. 调研报告 2. 相关企业...
【HTTPS基础概念与原理】SSL/TLS协议演进史:从SSLv3到TLS 1.3
以下是 SSL/TLS协议演进史 的详细解析,从SSLv3到TLS 1.3,涵盖各版本的核心特点、重大漏洞及淘汰原因: 1. SSLv3(Secure Sockets Layer 3.0) • 发布时间:1996年(Netscape开发) • 核…...
JVM 与云原生的完美融合:引领技术潮流
最近佳作推荐: Java 大厂面试题 – 揭秘 JVM 底层原理:那些令人疯狂的技术真相(New) Java 大厂面试题 – JVM 性能优化终极指南:从入门到精通的技术盛宴(New) Java 大厂面试题 – JVM 深度剖析&…...
【进程控制二】进程替换和bash解释器
【进程控制二】进程替换 1.exec系列接口2.execl系列2.1execl接口2.2execlp接口2.3execle 3.execv系列3.1execv3.2总结 4.实现一个bash解释器4.1内建命令 通过fork创建的子进程,会继承父进程的代码和数据,因此本质上还是在执行父进程的代码 进程替换可以将…...
如何查看打开的 git bash 窗口是否是管理员权限打开
在 git bash 中输入: net session >nul 2>&1 && (echo Ok) || (echo Failed) 显示 OK 》是管理员权限; 显示 Failed 》不是管理员权限。 如何删除此步生成的垃圾文件: 新建一个 .txt 文件,输入以下代码…...
ubuntu 22.04 wifi网卡配置地址上网
通过network-manager配置 确定是否存在usb网卡的驱动 rootgpu-server:/etc/netplan# lsmod | grep rt2800usbrt2800usb 32768 0rt2x00usb 24576 1 rt2800usbrt2800lib 139264 1 rt2800usbrt2x00lib 73728 3 rt2800us…...
让 Cursor 教我写 MCP Client
文章目录 1. 写在最前面2. 动手实现一个 MCP Client2.1 How 天气查询 Client2.1.1 向 Cursor 提问的艺术2.1.2 最终成功展示2.1.3 client 的代码 3. MCP 协议核心之一总结3.1 SSE vs WebSocket 4. 碎碎念5. 参考资料 1. 写在最前面 学习了 MCP Server 的实现后,刚好…...
GoogleTest:GMock2 EXPECT_CALL
GoogleTest:GMock初识-CSDN博客 简单的介绍了GMock工作的方式 GMock其实是比较复杂的,先上一个例子,然后再仔细的解读: //not_ready_class.hpp #include <string>class Person { public:virtual ~Person() = default;virtual std::string name() = 0;virtual int a…...
自注意力机制(Self-Attention)前向传播手撕
题目 实现Transformer中自注意力机制的前向传播代码 思路与代码 自注意力机制(Self-Attention)是自然语言处理和深度学习中的一种核心机制,最早在 Transformer 模型中被提出。它的核心思想是:让序列中的每个元素都能动态关注整个…...
华硕服务器-品类介绍
目录 一、核心产品线解析 1. 机架式服务器 2. 塔式服务器 3. 高密度计算服务器 二、关键技术与模组配置 1. 主板与管理模块 2. 电源与散热 3. 存储与网络 三、应用场景与行业解决方案 1. 人工智能与高性能计算 2. 云计算与虚拟化 3. 边缘计算与工业物联网 一、核心…...
【Ansible基础】Ansible设计理念与无代理架构深度解析
目录 1 Ansible概述与核心设计理念 1.1 Ansible的核心设计哲学 1.2 Ansible与其他配置管理工具的对比 2 Ansible无代理架构详解 2.1 无代理架构工作原理 2.2 无代理架构的优势 2.3 无代理架构的局限性 3 Ansible核心组件与架构 3.1 Ansible核心组件架构 组件说明&…...
利用vba替换word中多个表格,相邻单元格的文字
目录 一、效果图1、替换前2、替换后 二、敲代码1、开发者工具→vba编辑器,点击插入模块2、键入以下代码3、代码编辑完成后,开发者工具→运行宏,选择对应名称,运行 一、效果图 标题估计没说明白,上图 1、替换前 2、替…...
动态多因子策略
策略其核心思想是通过多种技术指标的结合,动态调整交易信号,以实现更精准的市场进出和风险管理。 交易逻辑思路 1. 初始化与数据更新: - 在每个Bar的开盘时,更新当日的最高价、最低价和收盘价。 - 计算短期和长期的移动平均线&…...
STC32G12K128实战:串口通信
STC32G12K128芯片写一个按键通过串口1发送字符串的程序。首先,确认芯片的串口1配置。STC32G系列通常使用UART1,相关的寄存器是P_SW1来选择引脚。默认情况下,UART1的TX是P3.1。 接下来是设置定时器作为波特率发生器。通常用定时器2,…...
基于javaweb的SpringBoot高校图书馆座位预约系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
一种资源有限单片机处理cJSON数据的方法
一般单片机处理cJSON格式的数据都直接使用cJSON库,但对于Ram较小的单片机,由于资源有限,这并不合适,但我们可以根据cJSON数据的特定格式,使用土方法,直接对字符进行查找裁剪即可 //截取字符串str中字符a与…...
【2025版】Spring Boot面试题
文章目录 1. Spring, Spring MVC, SpringBoot是什么关系?2. 谈一谈对Spring IoC的理解3. Component 和 Bean 的区别?4. Autowired 和 Resource 的区别?5. 注入Bean的方法有哪些?6. 为什么Spring 官方推荐构造函数注入?…...
C++——类和对象(1)
文章目录 一、前言二、类和对象上2.1 类的定义2.1.1 定义格式一2.1.2 定义格式二2.1.3 注意点 2.2 访问限定符2.2.1 访问限定符的用法 2.3 类域2.4 类的实例化2.4.1 实例化的概念2.4.2 实例化具体举例2.4.3类的实例化对象大小 2.5 this指针2.5.1 this指针的概念2.5.6 this指针的…...
【行为型之观察者模式】游戏开发实战——Unity事件驱动架构的核心实现策略
文章目录 🎯 观察者模式(Observer Pattern)深度解析一、模式本质与核心价值二、经典UML结构三、Unity实战代码(玩家血量监控系统)1. 定义观察者接口与主题基类2. 实现具体主题(玩家血量)3. 实现…...
Java基础语法之数组
数组 一、认识数组 1.什么是数组 数组就是一个容器,用来存一批同种类型的数据。 举例 20, 10, 80, 60, 90 int[] arr {20, 10, 80, 60, 90};张三, 李四, 王五 String[] names {"张三", "李四", "王五"};2.为什么要使用数组 假设…...
Vue3学习(组合式API——计算属性computed详解)
目录 一、计算属性computed。 Vue官方提供的案例。(普通写法与计算属性写法) 使用计算属性computed重构——>简化描述响应式状态的复杂逻辑。 (1)计算属性computed小案例。 <1>需求说明。(筛选原数组——>得新数组) &…...