【嵌入式-stm32电位器控制以及旋转编码器控制LED亮暗】
嵌入式-stm32电位器控制LED亮暗
- 任务1
- 代码1
- Key.c
- Key.h
- Timer.c
- Timer.h
- PWM.c
- PWM.h
- main.c
- 实验现象1
- 任务2
- 代码2
- Key.c
- Key.h
- main.c
- 实验现象2
- 问题与解决
- 总结
源码框架取自江协科技,在此基础上做扩展开发。
任务1
本文主要介绍利用stm32f103C8T6实现电位器控制PWM的占空比大小来改变LED亮暗程度,按键实现使用定时器非阻塞式,其中一个按键切换3个LED的控制状态,另一个按键是重置当前的LED为熄灭状态。
代码1
Key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "oled.h"
#include "PWM.h"
#include "AD.h"
#include "Key.h"
#include <stdio.h>extern uint16_t ADValue; //定义AD值变量
uint8_t Key_Num;
/*** 函 数:按键初始化* 参 数:无* 返 回 值:无*/
void Key_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
} // 定义模式枚举
typedef enum { MODE_PWM_CH2 = 0, MODE_PWM_CH3, MODE_PWM_CH4, MODE_MAX
} PWM_MODE; // 全局变量
volatile PWM_MODE currentMode = MODE_PWM_CH2;
volatile uint16_t pwmValue = 0;
volatile uint8_t resetFlag = 0;
volatile uint8_t systemActive = 0; //新增系统激活标志// 初始化显示函数
void Initial_Display(void) { // 清屏 OLED_Clear(); // 显示初始状态 OLED_ShowString(1, 1, "System Ready"); OLED_ShowString(2, 1, "Active KEY1 "); // 初始化时关闭所有LED PWM_SetCompare2(0); PWM_SetCompare3(0); PWM_SetCompare4(0);
} uint8_t Key_GetNum(void)
{uint8_t Temp; Temp = Key_Num; //读取按键键值Key_Num = 0; //清零,防止重复触发return Temp;
}uint8_t Key_GetState(void)
{if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) == 0){return 1;}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10) == 0){return 2;}return 0; //无按键按下
}void Key_Tick(void)
{static uint8_t Count; //静态计数器,记录中断次数static uint8_t CurrState, PrevState;Count++;if(Count >= 20) //20ms执行一次按键扫描(中断周期为1ms){Count = 0;PrevState = CurrState; //保存前一次按键状态CurrState = Key_GetState(); //读取当前按键状态//检测按键释放动作(下降沿)if(CurrState == 0 && PrevState != 0){Key_Num = PrevState; //记录按键值(1或者2)}}
}// 设置PWM的函数
void SetPWM(uint16_t value) { switch (currentMode) { case MODE_PWM_CH2: PWM_SetCompare2(value); break; case MODE_PWM_CH3: PWM_SetCompare3(value); break; case MODE_PWM_CH4: PWM_SetCompare4(value); break; }
} // 更新显示模式函数
void Update_ModeDisplay(void) { // 清除原有模式显示 OLED_Clear(); // 根据当前模式显示 switch (currentMode) { case MODE_PWM_CH2: OLED_ShowString(1, 1, "Mode: CH2"); break; case MODE_PWM_CH3: OLED_ShowString(1, 1, "Mode: CH3"); break; case MODE_PWM_CH4: OLED_ShowString(1, 1, "Mode: CH4"); break; } // 显示初始PWM值 OLED_ShowString(2, 1, "PWM: 0");
} /*OLED显示70.5%函数*/
void ShowPwm_Percent(uint8_t Line, uint8_t Colum, uint16_t pwmValue)
{char str[16];uint16_t integer = pwmValue / 10; //整数部分如70uint16_t decimal = pwmValue % 10; //小鼠部分如5sprintf(str, "%4d.%1d%%",integer,decimal);OLED_ShowString(Line,Colum,str);
}// 按键控制函数
void Key_control(void) { uint8_t keyNum = Key_GetNum(); // 处理按键1:模式切换 if (keyNum == 1) { // 重置标志清零 resetFlag = 0; if(systemActive == 0){systemActive = 1;currentMode = MODE_PWM_CH2;Update_ModeDisplay();}else{// 切换模式 currentMode++; if (currentMode >= MODE_MAX) { currentMode = MODE_PWM_CH2; } // 更新模式显示 Update_ModeDisplay(); } } // 处理按键2:重置为全暗 if (keyNum == 2) { // 设置重置标志 resetFlag = 1; // 将当前通道设置为0 SetPWM(0); pwmValue = 0; // 显示PWM值 OLED_ShowNum(2, 5, pwmValue, 3); } // 仅在非重置状态下读取ADC和设置PWM if (resetFlag == 0 && systemActive) { // 读取ADC并设置PWM //uint16_t adcValue = AD_GetValue(); pwmValue = (AD_GetValue() * 1000)/ 4095 ; // 设置当前通道PWM SetPWM(pwmValue); // 显示PWM值 OLED_ShowNum(3, 1, pwmValue, 4); // 直接显示pwmValue的值 ShowPwm_Percent(2, 4, pwmValue);//OLED_ShowNum(2, 5, pwmValue, 3); }
}
Key.h
#ifndef __KEY_H
#define __KEY_Hvoid Key_Init(void);
uint8_t Key_GetNum(void);
void Key_control(void);
void Initial_Display(void);
void SetPWM(uint16_t value);
void Key_Tick(void);
uint8_t Key_GetState(void);#endif
Timer.c
#include "stm32f10x.h" // Device headervoid Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);TIM_InternalClockConfig(TIM3);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 1000 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM3, TIM_FLAG_Update);TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM3, ENABLE);
}/*
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
*/
Timer.h
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);#endif
PWM.c
#include "stm32f10x.h" // Device header/*** 函 数:PWM初始化* 参 数:无* 返 回 值:无*/void TIM2_PWM_Init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;GPIO_InitTypeDef GPIO_InitStruct; // 打开定时器2时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //GPIO采用复用推挽输出模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1; //TIM2同时产生三路PWM波 在管脚123 a11GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度50MHZGPIO_Init(GPIOA,&GPIO_InitStruct); //初始化函数 让刚刚配置的参数 输入到对应寄存器里面// 配置定时器2为PWM模式TIM_TimeBaseStructure.TIM_Period = 999; // PWM周期TIM_TimeBaseStructure.TIM_Prescaler = 720; // 72MHz/(71+1) = 1MHz,计数频率为1MHzTIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);// 配置TIM2通道2为PWM模式TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比0%TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC2Init(TIM2, &TIM_OCInitStructure);TIM_OC3Init(TIM2, &TIM_OCInitStructure);TIM_OC4Init(TIM2, &TIM_OCInitStructure);// 使能TIM2TIM_Cmd(TIM2, ENABLE);
}
/*** 函 数:PWM设置CCR* 参 数:Compare 要写入的CCR的值,范围:0~1000* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比* 占空比Duty = CCR / (ARR + 1)*/void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2 ,Compare ); //设置CCR1的值
}
void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2 ,Compare ); //设置CCR1的值
}
void PWM_SetCompare4(uint16_t Compare)
{TIM_SetCompare4(TIM2 ,Compare ); //设置CCR1的值
}
PWM.h
#ifndef __PWM_H
#define __PWM_Hvoid TIM2_PWM_Init(void);void PWM_SetCompare2(uint16_t Compare);
void PWM_SetCompare3(uint16_t Compare);
void PWM_SetCompare4(uint16_t Compare);#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "sys.h"
#include "AD.h"
#include "PWM.h"
#include "Timer.h"/*全局变量*/
uint16_t ADValue; //定义AD值变量int main(void)
{/*模块初始化*/OLED_Init(); //OLED初始化Key_Init(); //按键初始化AD_Init(); //AD初始化TIM2_PWM_Init(); //定时器2PWM初始化Timer_Init();/*OLED显示静态字符*/Initial_Display();while (1){//KeyNum=Key_GetNum(); //获取键码值Key_control(); //按键PWM控制}
}//中断服务函数
//每次TIM3溢出时触发中断,调用Key_Tick()进行按键扫描
//清除中断标志,避免重复进入中断
void TIM3_IRQHandler(void)
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET){Key_Tick();TIM_ClearITPendingBit(TIM3, TIM_IT_Update);}
}
实验现象1
以下是通过电位器控制PWM输出大小的值进而调暗LED
通过网盘分享的文件:电位器改变PWM输出控制LED
链接: https://pan.baidu.com/s/1JrevfJ2GTsBqLyRb4Do39g 提取码: 6688
任务2
旋转编码器控制LED亮暗:
1、LED亮度控制:旋转编码器调节PWM占空比,控制LED亮度。
2、状态显示:OLED实时显示当前PWM占空比(格式为XX.X%)。
3、模式切换:通过独立按键切换PWM输出通道(如CH2、CH3、CH4)。
4、系统激活与重置:按键控制系统的启动和重置。
接线图片来自江协议科技
代码2
1、模块化代码架构
编码器驱动:通过外部中断检测旋转方向,更新计数值。
PWM生成:配置定时器(如TIM2)的PWM模式,动态调节占空比。
OLED显示:格式化显示占空比和模式信息。
主控制逻辑:整合按键、编码器和PWM功能,实现状态机控制。
Key.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "oled.h"
#include "PWM.h"
#include "AD.h"
#include "Key.h"
#include "Encoder.h"
#include <stdio.h>uint8_t Key_Num;
signed Key_Encoder_Count = 0;
/*** 函 数:按键初始化* 参 数:无* 返 回 值:无*/
void Key_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
} // 定义模式枚举
typedef enum { MODE_PWM_CH2 = 0, MODE_PWM_CH3, MODE_PWM_CH4, MODE_MAX
} PWM_MODE; // 全局变量
volatile PWM_MODE currentMode = MODE_PWM_CH2;
volatile uint16_t pwmValue = 0;
volatile uint8_t resetFlag = 0;
volatile uint8_t systemActive = 0; //新增系统激活标志// 初始化显示函数
void Initial_Display(void) { // 清屏 OLED_Clear(); // 显示初始状态 OLED_ShowString(1, 1, "System Ready"); OLED_ShowString(2, 1, "Active KEY1 "); // 初始化时关闭所有LED PWM_SetCompare2(0); PWM_SetCompare3(0); PWM_SetCompare4(0);
} uint8_t Key_GetNum(void)
{uint8_t Temp; Temp = Key_Num; //读取按键键值Key_Num = 0; //清零,防止重复触发return Temp;
}uint8_t Key_GetState(void)
{if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) == 0){return 1;}if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_10) == 0){return 2;}return 0; //无按键按下
}void Key_Tick(void)
{static uint8_t Count; //静态计数器,记录中断次数static uint8_t CurrState, PrevState;Count++;if(Count >= 20) //20ms执行一次按键扫描(中断周期为1ms){Count = 0;PrevState = CurrState; //保存前一次按键状态CurrState = Key_GetState(); //读取当前按键状态//检测按键释放动作(下降沿)if(CurrState == 0 && PrevState != 0){Key_Num = PrevState; //记录按键值(1或者2)}}
}// 设置PWM的函数
void SetPWM(uint16_t value) { switch (currentMode) { case MODE_PWM_CH2: PWM_SetCompare2(value); break; case MODE_PWM_CH3: PWM_SetCompare3(value); break; case MODE_PWM_CH4: PWM_SetCompare4(value); break; }
} // 更新显示模式函数
void Update_ModeDisplay(void) { // 清除原有模式显示 OLED_Clear(); // 根据当前模式显示 switch (currentMode) { case MODE_PWM_CH2: OLED_ShowString(1, 1, "Mode: CH2"); break; case MODE_PWM_CH3: OLED_ShowString(1, 1, "Mode: CH3"); break; case MODE_PWM_CH4: OLED_ShowString(1, 1, "Mode: CH4"); break; } // 显示初始PWM值 OLED_ShowString(2, 1, "PWM: 0");
} /*OLED显示70.5%函数*/
void ShowPwm_Percent(uint8_t Line, uint8_t Colum, uint16_t pwmValue)
{char str[16];uint16_t integer = pwmValue / 10; //整数部分如70uint16_t decimal = pwmValue % 10; //小鼠部分如5sprintf(str, "%4d.%1d%%",integer,decimal);OLED_ShowString(Line,Colum,str);
}// 按键控制函数
void Key_control(void) { uint8_t keyNum = Key_GetNum(); // 处理按键1:模式切换 if (keyNum == 1) { // 重置标志清零 resetFlag = 0; if(systemActive == 0){systemActive = 1;currentMode = MODE_PWM_CH2;Update_ModeDisplay();}else{// 切换模式 currentMode++; if (currentMode >= MODE_MAX) { currentMode = MODE_PWM_CH2; } // 更新模式显示 Update_ModeDisplay(); } } // 处理按键2:重置为全暗 if (keyNum == 2) { // 设置重置标志 resetFlag = 1; // 将当前通道设置为0 SetPWM(0); pwmValue = 0; // 显示PWM值 OLED_ShowNum(2, 5, pwmValue, 3); } // 仅在非重置状态下读取ADC和设置PWM if (resetFlag == 0 && systemActive) { Key_Encoder_Count += Encoder_Get();if(Key_Encoder_Count < 0){Key_Encoder_Count = 0;}if(Key_Encoder_Count > 100){Key_Encoder_Count = 100;}pwmValue = (Key_Encoder_Count * 10) ; // 设置当前通道PWM SetPWM(pwmValue); // 显示PWM值 OLED_ShowNum(3, 1, pwmValue, 4); // 直接显示pwmValue的值 ShowPwm_Percent(2, 4, pwmValue);//OLED_ShowNum(2, 5, pwmValue, 3); }
}
Key.h
#ifndef __KEY_H
#define __KEY_Hvoid Key_Init(void);
uint8_t Key_GetNum(void);
void Key_control(void);
void Initial_Display(void);
void SetPWM(uint16_t value);
void Key_Tick(void);
uint8_t Key_GetState(void);#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "sys.h"
#include "AD.h"
#include "PWM.h"
#include "Timer.h"
#include "Encoder.h"int main(void)
{/*模块初始化*/OLED_Init(); //OLED初始化Key_Init(); //按键初始化TIM2_PWM_Init(); //定时器2PWM初始化Timer_Init();Encoder_Init();/*OLED显示静态字符*/Initial_Display();while (1){Key_control(); //按键PWM控制}
}//中断服务函数
//每次TIM3溢出时触发中断,调用Key_Tick()进行按键扫描
//清除中断标志,避免重复进入中断
void TIM3_IRQHandler(void)
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET){Key_Tick();TIM_ClearITPendingBit(TIM3, TIM_IT_Update);}
}
实验现象2
问题与解决
一上电程序卡死,原因是Timer3的中断服务函数忘记清除相应的标志位。
总结
旋转编码器和电位器控制LED亮暗的区别
核心逻辑在于旋转编码器时中断服务函数检测旋转方向,更新计数值,而电位器时ADC采样。
相关文章:
【嵌入式-stm32电位器控制以及旋转编码器控制LED亮暗】
嵌入式-stm32电位器控制LED亮暗 任务1代码1Key.cKey.hTimer.cTimer.hPWM.cPWM.hmain.c 实验现象1任务2代码2Key.cKey.hmain.c 实验现象2问题与解决总结 源码框架取自江协科技,在此基础上做扩展开发。 任务1 本文主要介绍利用stm32f103C8T6实现电位器控制PWM的占空比…...
Mysql 中 ACID 背后的原理
在 MySQL 中,ACID 是事务处理的核心原则,用于保证数据库在执行事务时的可靠性、数据一致性和稳定性。ACID 是四个关键特性的首字母缩写,分别是:Atomicity(原子性)、Consistency(一致性ÿ…...
【算法】简单数论
模运算 a m o d b a − ⌊ a / b ⌋ b a\ mod \ b a - \lfloor a / b \rfloor \times b a mod ba−⌊a/b⌋b n m o d p n \ mod\ p n mod p得到的结果的正负至于被除数 n n n有关 模运算的性质: ( a b ) m o d m ( ( a m o d m ) ( b m o d m ) ) m o d m …...
mybatis慢sql无所遁形
痛点问题: 扫描项目的慢sql 并提出优化建议 开源项目地址:gitee:mybatis-sql-optimizer-spring-boot-starter: 这个starter可以帮助开发者在开发阶段发现SQL性能问题,并提供优化建议,从而提高应用程序的数据库访问效…...
MCP有哪些比较好的资源?
MCP(Model Context Protocol)是一种由Anthropic公司推出的开放协议,旨在为AI模型与开发环境之间提供统一的上下文交互接口。目前,围绕MCP协议的资源非常丰富,以下是一些比较好的MCP资源推荐: Smithery Smit…...
Nginx功能及应用全解:从负载均衡到反向代理的全面剖析
Nginx作为一款开源的高性能HTTP服务器和反向代理服务器,凭借其高效的资源利用率和灵活的配置方式,已成为互联网领域中最受欢迎的Web服务器之一。无论是作为HTTP服务器、负载均衡器,还是作为反向代理和缓存服务器,Nginx的多种功能广…...
FreeRTOS/任务创建和删除的API函数
任务的创建和删除本质就是调用FreeRTOS的API函数 API函数描述xTaskCreate()动态方式创建任务xTaskCreateStatic()静态方式创建任务vTaskDelete()删除任务 动态创建任务 任务的任务控制块以及任务的占空间所需的内存,均由FreeRTOS从FreeRTOS管理的堆中分配 静态创建…...
【jvm】GC评估指标
目录 1. 说明2. 吞吐量(Throughput)3. 暂停时间(Pause Time)4. 内存占用(Footprint)5. 频率(Frequency)6. 对象晋升率(Promotion Rate)7. 内存分配速率&#…...
数据集(Dataset)和数据加载器(DataLoader)-pytroch学习3
pytorch网站学习 处理数据样本的代码往往会变得很乱、难以维护;理想情况下,我们希望把数据部分的代码和模型训练部分分开写,这样更容易阅读、也更好维护。 简单说:数据和模型最好“分工明确”,不要写在一起。 PyTor…...
影响RTOS实时性的因素有哪些?
目录 1、任务调度延迟 2、中断处理延迟 3、系统负载 4、任务优先级反转 5、时钟精度 6、内存管理 影响RTOS实时性的因素主要包括任务调度延迟、中断处理延迟、系统负载、任务优先级反转、时钟精度、内存管理等。 1、任务调度延迟 任务调度器是RTOS的核心,当…...
二叉树 递归
本篇基于b站灵茶山艾府的课上例题与课后作业。 104. 二叉树的最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出&…...
ZLMediaKit 源码分析——[5] ZLToolKit 中EventPoller之延时任务处理
系列文章目录 第一篇 基于SRS 的 WebRTC 环境搭建 第二篇 基于SRS 实现RTSP接入与WebRTC播放 第三篇 centos下基于ZLMediaKit 的WebRTC 环境搭建 第四篇 WebRTC学习一:获取音频和视频设备 第五篇 WebRTC学习二:WebRTC音视频数据采集 第六篇 WebRTC学习三…...
【51单片机】2-6【I/O口】电动车简易防盗报警器实现
1.硬件 51最小系统继电器模块震动传感器模块433M无线收发模块 2.软件 #include "reg52.h" #include<intrins.h> #define J_ON 1 #define J_OFF 0sbit switcher P1^0;//继电器 sbit D0_ON P1^1;//433M无线收发模块 sbit D1_OFF P1^2; sbit vibrate …...
windows下载安装远程桌面工具RealVNC-Server教程(RealVNC_E4_6_1版带注册码)
文章目录 前言一、下载安装包二、安装步骤三、使用VNC-Viewer客户端远程连接,输入ip地址,密码完成连接 前言 在现代工作和生活中,远程控制软件为我们带来了极大的便利。RealVNC - Server 是一款功能强大的远程控制服务器软件,通过…...
C语言的操作系统
C语言的操作系统 引言 操作系统是一种系统软件,它管理计算机硬件和软件资源,并为计算机程序提供公共服务。在现代计算机科学中,操作系统是不可或缺的组成部分,而C语言则是实现高效操作系统的主要编程语言之一。本文将探讨C语言在…...
selectdb修改表副本
如果想修改doris(也就是selectdb数据库)表的副本数需要首先确定是否分区表,当前没有数据字典得知哪个表是分区的,只能先show partitions看结果 首先,副本数不应该大于be节点数 其次,修改期间最好不要跑业务…...
leetcode数组-有序数组的平方
题目 题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/ 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 输入:nums [-4,-1,0,3,10] 输出ÿ…...
【python中级】关于Cython 的源代码pyx的说明
【python中级】关于Cython 的源代码pyx的说明 1.背景2.编译3.语法1.背景 Cython 是一个编程语言和工具链,用于将 Python 代码(或类 Python 的代码)编译成 C 语言,再进一步生成高性能的 Python 扩展模块(.so 或 .pyd 文件)。 在 Python 中,.pyx 文件是 Cython 的源代码文…...
开放最短路径优先 - OSPF【LSA详细】
目录 LSA的头部结构 LSA类型 LSA数据包 LSA的主要作用是传递路由信息。 LSA的头部结构 共占20个字节,不同类型的LSA头部字段部分都是相同的。 链路状态老化时间(Link-State Age) 2个字节。指示该条LSA的老化时间,即它存在了多长时间,单位…...
PyTorch:解锁AI新时代的钥匙
揭开PyTorch面纱 对于许多刚开始接触人工智能领域的朋友来说,PyTorch这个名字或许既熟悉又陌生。熟悉在于它频繁出现在各类技术论坛和新闻报道中;而陌生则源于对这样一个强大工具背后运作机制的好奇。简单来说,PyTorch是一个开源库ÿ…...
欧几里得算法求最大公约数、最小公倍数
这段代码就是不断用较小数和余数来更新 a 和 b,直到余数变为 0,最后返回的 a 就是最大公约数。 #include <iostream> using namespace std;//最大公约数 int gcd(int a, int b){//这个循环表示只要 b 不是 0,就继续进行。//因为当 b …...
QEMU源码全解析 —— 块设备虚拟化(14)
接前一篇文章:QEMU源码全解析 —— 块设备虚拟化(13) 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM源码解析与应用》 —— 李强,机械工业出版社 特此致谢! 上一回开始解析VirtioDeviceClass的realize函数virtio_blk_device_realize(),再来回…...
深入理解AOP:面向切面编程的核心概念与实战应用
🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…...
3500 阶乘求和
3500 阶乘求和 ⭐️难度:中等 🌟考点:2023、思维、省赛 📖 📚 import java.util.Scanner;public class Main {public static void main(String[] args) {long sum 0;for(int i1;i<50;i) { // 之后取模都相等su…...
正则入门到精通
一、正则表达式入门 正则表达式本质上是一串字符序列,用于定义一个文本模式。通过这个模式,我们可以指定要匹配的文本特征。例如,如果你想匹配一个以 “abc” 开头的字符串,正则表达式可以写作 “^abc”,其中 …...
Mysql 行级锁在什么样的情况下会升级为表级锁?
在 MySQL 中,行级锁通常由 InnoDB 存储引擎使用,因为它支持高并发和细粒度的锁定。通常情况下,InnoDB 在执行诸如 UPDATE、DELETE 或 SELECT FOR UPDATE 等操作时,会为被修改的数据行加锁(行级锁)。但是&am…...
docker部署kkfileview
拉取 KKFileView 镜像 docker pull keking/kkfileview或指定版本 docker pull keking/kkfileview:4.1.0运行 KKFileView 容器 docker run -d \--name kkfileview \-p 8012:8012 \--restart always \keking/kkfileview-d:后台运行 -p 8012:8012:将容器…...
优选算法的妙思之流:分治——快排专题
专栏:算法的魔法世界 个人主页:手握风云 目录 一、快速排序 二、例题讲解 2.1. 颜色分类 2.2. 排序数组 2.3. 数组中的第K个最大元素 2.4. 库存管理 III 一、快速排序 分治,简单理解为“分而治之”,将一个大问题划分为若干个…...
蓝桥杯嵌入式第15届真题-个人理解+解析
个人吐槽 #因为最近蓝桥杯快要开始了,我舍不得米白费了,所以就认真刷刷模拟题,但是我感觉真题会更好,所以就看了一下上届的真题。不过它是真的长,我看着就头晕,但是还是把几个模块认真分析了一下就还是很容…...
数据库系统概述 | 第二章课后习题答案
本文为数据库系统概论(第五版)【高等教育出版社】部分课后答案 如有错误,望指正 👻 习题 👻 答案...
深入解析CPU主要参数:选购与性能评估指南
引言 中央处理器(CPU)作为计算机的"大脑",其性能直接决定了整机的运算能力和响应速度。无论是组装新电脑、升级旧系统还是选购笔记本电脑,理解CPU的关键参数都至关重要。本文将从技术角度全面解析CPU的各项主要参数&am…...
Lettuce与Springboot集成使用
一、Lettuce核心优势与Spring Boot集成背景 Lettuce特性 基于Netty的非阻塞I/O模型,支持同步/异步/响应式编程线程安全:共享单连接实现多线程并发操作,性能衰减低原生支持Redis集群、哨兵、主从架构,自动重连机制保障高可用Spring…...
【Kafka基础】ZooKeeper在Kafka中的核心作用:分布式系统中枢神经系统
在分布式系统的世界里,协调和管理多个节点间的状态是一项复杂而关键的任务。Apache Kafka作为一款高性能的分布式消息系统,其设计哲学是"专为单一目的而优化"——即高效处理消息流。为了实现这一目标,Kafka选择将集群协调管理的重任…...
专业的情商测评工具:EQ-i在线测评系统
专业的情商测评工具:EQ-i在线测评系统 基于巴昂情商量表的专业情商评估工具,帮助您更好地了解自己的情商水平。 什么是EQ-i? EQ-i(Emotional Quotient Inventory)是由Reuven Bar-On开发的情商量表,是国际上…...
Ubuntu安装Podman教程
1、先修改apt源为阿里源加速 备份原文件: sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup 修改源配置: vim sources.list删除里面全部内容后,粘贴阿里源: deb http://mirrors.aliyun.com/ubuntu/ focal main re…...
7.训练篇5-毕设
使用23w张数据集-vit-打算30轮-内存崩了-改为batch_size 8 我准备用23w张数据集,太大了,这个用不了,所以 是否保留 .stack() 加载所有图片?情况建议✅ 小数据集(<2w张,图像小)想加快速度可…...
java数据结构-哈希表
什么是哈希表 最理想的搜索方法 , 即就是在查找某元素时 , 不进行任何比较的操作 , 一次直接查找到需要搜索的元素 , 可以达到这种要求的方法就是哈希表. 哈希表就是通过构造一种存储结构 , 通过某种函数使元素存储的位置与其关键码位形成一 一映射的关系 , 这样在查找元素的时…...
Linux错误(6)X64向量指令访问地址未对齐引起SIGSEGV
Linux错误(6)X64向量指令访问地址未对齐引起SIGSEGV Author: Once Day Date: 2025年4月4日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: Linux实…...
SpringBoot配置文件多环境开发
目录 一、设置临时属性的几种方法 1.启动jar包时,设置临时属性 2.idea配置临时属性 3.启动类中创建数组指定临时属性 二、多环境开发 1.包含模式 2.分组模式 三、配置文件的优先级 1.bootstrap 文件优先: 2.特定配置文件优先 3.文件夹位置优…...
解锁健康密码:拥抱活力养生生活
在追求高品质生活的今天,健康养生成为了人们关注的焦点。它不仅关乎当下的生活质量,更是对未来的有力投资。 合理的饮食是健康养生的基石。一日三餐,应遵循 “五谷为养,五果为助,五畜为益,五菜为充” 的原则…...
手动将ModelScope的模型下载到本地
一、ModelScope 介绍 ModelScope 官网地址: https://www.modelscope.cn/home 模型库地址:https://www.modelscope.cn/models 文档中心:https://www.modelscope.cn/docs/home ModelScope旨在打造下一代开源的模型即服务共享平台,为…...
【Git】“warning: LF will be replaced by CRLF”的解决办法
一、原因分析 不同操作系统的换行符标准不同: • Windows:使用 CRLF(\r\n)表示换行; • Linux/Mac:使用 LF(\n)表示换行 Git 检测到本地文件的换行符与仓库设置或目标平台不兼容时…...
Linux常用基础命令应用
目录 一、文件与目录管理 1. 基础导航与查看 2. 文件操作核心命令 二、文本处理与日志分析 1. 查看与过滤 2. 组合命令与管道 三、系统管理与权限控制 1. 进程与资源监控 2. 权限与用户管理 四、网络与远程操作 1. …...
C++11可变参数模板单例模式
单例模式 该示例代码采用C11标准,解决以下问题: 通过类模板函数实现不同类型单例;单例类构造函数支持不同的个数;消除代码重复 示例代码 .h文件如下: //C11Singleton.h文件 #pragma oncetemplate <typename T&…...
JVM 有哪些垃圾回收器
垃圾收集算法 标记-复制算法(Copying): 将可用内存按容量划分为两个区域,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面, 然后再把已使用过的内存空间一次清理掉。 标记-清除算法(Mark-Sweep): 算法分为“标记” 和“清除”两个…...
6. 链式结构(Chain)的奥秘:从LLMChain到RouterChain
引言:从“单兵作战”到“流水线革命” 2023年某电商平台客服系统因处理复杂咨询需手动串联多个AI模块,平均响应时间长达12秒。引入LangChain链式架构后,工单处理速度提升8倍,错误率下降45%。本文将深入解析链式编程范式ÿ…...
TypeScript语言的操作系统原理
TypeScript语言的操作系统原理 引言 操作系统是计算机系统中最重要的组成部分之一,它为应用程序提供了一个运行环境,并管理着计算机硬件和软件资源。随着编程语言的发展,特别是TypeScript的流行,许多开发者开始探索将这种强类型…...
时间序列入门
时间序列入门 第一章 时间序列概述1.1 时间序列简介1.1.1 时间序列定义1.1.2 时间序列分量1.1.3 时间序列分类 第二章 时间序列绘图2.1 单变量时序绘制2.2 多变量时序绘制 第一章 时间序列概述 1.1 时间序列简介 1.1.1 时间序列定义 在进行时间序列之前,需要学习…...
VirtualBox安装FnOS
1.下载FnOS镜像 下载网址: https://www.fnnas.com/2.创建虚拟机 虚拟机配置如图所示(注意操作系统类型和网卡配置) (注意启动顺序) 3.启动虚拟机 网卡类型选择桥接的Virtual Adapter 如果没有IP地址或者IP地址无法…...
函数栈帧的创建与销毁
函数栈帧的创建与销毁 函数栈帧简介认识寄存器解析函数栈帧的创建与销毁 函数栈帧简介 我们在编程的过程中经常会听见函数栈帧这个词汇,那到底什么是函数栈帧呢?接下来就为大家解答一下,我们都知道,一个函数的创建是需要去开辟空…...