嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册
一、要背的函数汇总(以例子形式)
1.GPIO相关
输出:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 | GPIO_PIN_9,GPIO_PIN_SET)
输入:HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)
翻转:HAL_GPIO_TogglePin(GPIOC,0xFF)
2.LCD相关
格式化输出:sprintf((char*)buf,"%d",val) (要包含stdio.h)
显示:LCD_DisplayStringLine(Line1,buf)
3.ADC相关
启动转换:HAL_ADC_Start(&hadc1)
获取数字量:HAL_ADC_GetValue(&hadc1)
4.I2C相关
开始:I2CStart()
停止:I2CStop()
发送:I2CSendByte(0xA0)
接收:I2CReceiveByte()
应答:I2CWaitAck()
非应答:I2CSendNotAck()
定时:HAL_Delay(5)
5.串口相关
初始化:MX_USART1_UART_Init()
串口发送:HAL_UART_Transmit(&huart1,(unsigned char *)&ch,1,50)
重定向:help搜retarget第三个
串口接收中断:HAL_UART_Receive_IT(&huart1,uart_buf,1)
中断回调:HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
6.DAC相关(12位右对齐)
设置数字量:HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,1365)
转换成模拟量:HAL_DAC_Start(&hdac1,DAC_CHANNEL_1)
7.RTC
获取时间:HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN)
获取日期:HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN)
8.PWM捕获
开启中断:HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)
中断回调:HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
获取计数器:tim2_cnt = __HAL_TIM_GetCounter(&htim2)
设置计数器: __HAL_TIM_SetCounter(&htim2,0)
9.PWM输出
启动输出:HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1)
二、流程
1.打开资源数据包,找到LCD参考程序并复制。
2.更改名字为G15302396,并更改MX文件为同名。
3.然后删除MDK-ARM中所有带LCD的文件和文件夹。
4.打开MX文件。根据题目要求和原理图,配置引脚。
5.选择MDK-ARM为v5,选择生成源文件头文件。
6.生成文件后,打开文件,配置魔术棒(微库、debug)
7.加入LCD的源文件(如果有I2C也要加)。
8.解决LCD和LED冲突问题并测试。(在三个Write函数前面加入u16 pout = GPIOC->ODR,在后面加入GPIOC->ODR = pout)
9.编译并编程。
三、LED
1.初始化
PD2选择GPIO输出。
2.编程
实现:输入八位数,点亮对应的灯。
void LED_Control(u8 led_ctrl)
{HAL_GPIO_WritePin(GPIOC,0xFF00,GPIO_PIN_SET)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,led_ctrl<<8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
四、Systick
1.初始化
无
2.编程
实现:所有灯每5ms闪烁一次。
__IO u32 ledTick = 0;
void LED_Process()
{if(uwTick - ledTick < 500) return ; ledTick = uwTick; HAL_GPIO_TogglePin(GPIOC,0xFF00)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
五、按键
1.初始化
PA0、PB0、PB1、PB2选择GPIO输入。
2.编程
带长按和松手检测的三行按键法。
#define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)
#define KEYPORT KB1 | (KB2<<1) | (KB3<<2) | (KB4<<3) | 0xf0u8 Trg;
u8 Cont;
void Key_Read()
{u8 ReadData = KEYPORT^0xff; // 1Trg = ReadData & (ReadData ^ Cont); // 2 Cont = ReadData; // 3
}__IO u32 keyTick = 0;
u8 key1_value = 0;
__IO u32 b4Tick = 0;
u8 lock = 0;
void Key_Process()
{if(uwTick - keyTick < 10) return ;keyTick = uwTick;Key_Read();if(Trg & 0x01){key1_value++;}if(Trg & 0x02){}if(Trg & 0x04){}if(Trg & 0x08){}if(Cont & 0x08){b4Tick++;}if(Trg == 0x00 && Cont == 0x00){if(b4Tick >= 100){b4Tick = 0;lock = 1;}else if(b4Tick != 0){b4Tick = 0;lock = 0;}}
}
六、LCD
1.初始化
无
2.编程
u8 val = 0;
void LCD_Process()
{u8 buf[20];sprintf((char*)buf,"%d",val);LCD_DisplayStringLine(Line1,buf);
}
注意点:使用sprintf要包含stdio.h
3.输出形式
固定长度、左对齐、自动补0、小数、十六进制和八进制、字符和字符串、百分号
sprintf((char*)buf,"%5d",4000); //固定长度sprintf((char*)buf,"-%5d",4000); //左对齐sprintf((char*)buf,"%05d",4000); //前面不够的位自动补0sprintf((char*)buf,"%5.2f",3.1415926); //显示小数,总长5位,小数点算1位,小数点后2位sprintf((char*)buf,"%x",15); //%x显示16进制,%o显示8进制sprintf((char*)buf,"%c",'a'); //%c显示字符,%s显示字符串sprintf((char*)buf,"%d %%",10); //输出百分号:%
七、ADC
1.初始化
PB15选择ADC2的15通道,配置成单端模式。
2.编程
u16 adc2_val;
float volt_r37;
void ADC_Process()
{HAL_ADC_Start(&hadc2);adc2_val = HAL_ADC_GetValue(&hadc2);volt_r37 = adc2_val*3.3f/4096.0f;
}
八、EEPROM
1.初始化
1.1 复制赛场给的i2c.c和i2c.h文件到源文件和头文件
1.2 生成文件后,把i2c.c加入工程
1.3 包含i2c.h
1.4 调用初始化函数I2CInit()
2.编程
流程:先在i2c.c编写EEPROM读写函数,再在头文件定义一下,然后编写主函数。
EEPROM读写:
void EEPROM_Write(u8 add,u8 dat)
{I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();HAL_Delay(5);
}u8 EEPROM_Read(u8 add)
{u8 dat;I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStart();I2CSendByte(0xa1);I2CWaitAck();dat = I2CReceiveByte();I2CSendNotAck();I2CStop();return(dat);
}
统计开机次数
u8 startup_times;int main(void)
{I2C_Init();startup_times = EEPROM_Read(0x10);startup_times++;EEPROM_Write(0x10,startup_times);
}
九、MCP4017
1.硬件
总阻值:100k
档位数:127
写入时的器件地址:0x5E
分压电阻:10k
写入x得到的电阻:x*100/0x7F (千欧)
PB14上得到的电位:3.3*R/(R+10)
2.初始化
2.1 PB14配置成ADC1的5通道,设置为单端模式
2.2 ADC转换的数量改成2,设置采样顺序Rank(先采样几通道),设置采样时间为最大。
3.编程
MCP4017写入函数(放在I2C里面):
void MCP4017_Write(u8 val)
{I2CStart();I2CSendByte(0x5E);I2CWaitAck();I2CSendByte(val);I2CWaitAck();I2CStop();
}
ADC采样(多通道采样只要重复使用start就可以切换通道)
u16 adc1_val,adc2_val;
float volt_r37,volt_r38,volt_mcp;
void ADC_Process(void)
{//rank1HAL_ADC_Start(&hadc1);volt_mcp = HAL_ADC_GetValue(&hadc1)/4095.0f*3.3f;//rank2HAL_ADC_Start(&hadc1);adc1_val = HAL_ADC_GetValue(&hadc1);volt_r37 = adc2_val/4095.0f*3.3f;HAL_ADC_Start(&hadc2);adc2_val = HAL_ADC_GetValue(&hadc2);volt_r38 = adc1_val/4095.0f*3.3f;
}
//……
int main()
{MCP4017_Write(0x3F);while(1);{ADC_Process();}
}
十、串口通信
1.初始化
1.1 配置PA9、PA10为TX、RX
1.2 把USART设置为异步收发Asyn
1.3 配置波特率
1.4 开启中断
2.编程
流程:先重定向printf,再在初始化中开启中断,再定义中断回调函数
重定向(写在usart.c中)
int fputc(int ch,FILE *f)
{HAL_UART_Transmit(&huarl1,(unsigned char *)&ch,1,50);return ch;
}
串口接收固定字长
#include "string.h" //要用memset函数
u8 uart_buf[2];
u8 rx_buf[10];
u8 rx_cnt=0;
_IO uint32_t uartTick=0;
void UART_Process()
{if(uwTick-uartTick<50) return;uartTick=uwTick;rx_cnt=0;memset(rx_buf,'\0',sizeof(rx_buf));
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{uartTick=uwTick;rx_buf[rx_cnt++]=uart_buf[0];if(rx_cnt==3){LED_Control(rx_buf[1]);rx_cnt=0;}HAL_UART_Receive_IT(&huart1,uart_buf,1);
}
int main()
{MX_USART1_UART_Init();HAL_UART_Receive_IT(&huart1,uart_buf,1);while(1){RxIdle_Process();}
}
串口接收带帧尾的不定长
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{uartTick=uwTick;rx_buf[rx_cnt++]=uart_buf[0];if(rx_buf[0]=='\n'){LED_Control(rx_buf[1]);rx_cnt=0;}HAL_UART_Receive_IT(&huart1,uart_buf,1);
}
注意点:使用memset,要包含string.h
十一、DAC
1.初始化
1.1 配置PA4为DAC1的1通道输出,PA5为DAC1的2通道输出。
1.2 设置DAC输出模式为:输出到外部引脚(connected to external pin)
2.编程
void DAC_Process(void)
{HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_L,1365);HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);//PA4输出1.1VHAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_12B_L,2730);HAL_DAC_Start(&hdac1,DAC_CHANNEL_2);//PA5输出2.2V
}
十二、RTC
1.初始化
1.1 启动RTC,勾选两个Activate
1.2 设置两个分频,让32KHz分频为1Hz,所以两个分频分别是31和999
1.3 设置时、分、秒分别为23、59、59
1.4 设置日期
2.编程
RTC_TimeTypeDef rtc_time;
RTC_DateTypeDef rtc_date;
void RTC_Process()
{HAL_RTC_GetTime(&hrtc,&rtc_time,RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc,&rtc_date,RTC_FORMAT_BIN);
}
u8 buf[20];
void LCD_Process()
{LCD_SetBackColor(Black);LCD_SetTextColor(White);sprintf((char*)buf,"%2d,%2d,%2d",rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds);LCD_DisplayStringLine(Line1,buf);
}
注意:RTC_TimeTypeDef rtc_time可以不用背,直接仿照MX_RTC_Init(void)里面的第一第二行就行了,定义的这个结构体就是HAL_RTC_GetTime()的第二个变量。
十三、PWM捕获
1.初始化
1.1 配置需要捕获的引脚为TIM
1.2 对应的TIM设置为输入捕获模式
1.3 使能中断
1.4 设置分频值为79,ARR为最高值。
2.编程
捕获双路频率:
u32 tim2_cnt = 0;
u32 tim3_cnt = 0;
u32 f40 = 0;
u32 f39 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim == &htim2){tim2_cnt = __HAL_TIM_GetCounter(&htim2);__HAL_TIM_SetCounter(&htim2,0);f40 = 1000000/tim2_cnt;//得到频率HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);}else if(htim == &htim3){tim3_cnt = __HAL_TIM_GetCounter(&htim3);__HAL_TIM_SetCounter(&htim3,0);f39 = 1000000/tim3_cnt;//得到频率HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);}
}
int main()
{HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
}
捕获单路占空比:
u32 tim2_cnt1 = 0;
u32 tim2_cnt2 = 0;
u32 f40 = 0;
float d40 =0;
u8 tim2_state = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(tim2_state == 0){__HAL_TIM_SetCounter(&htim2,0); //开始计时TIM2->CCER |= 0x02; //开始下降沿中断tim2_state == 1;}else if(tim2_state == 1){tim2_cnt1 = __HAL_TIM_GetCounter(&htim2); //获取t1TIM2->CCER &= ~0x02; //开始上升沿中断tim2_state == 2;}else if(tim2_state == 2){tim2_cnt2 = __HAL_TIM_GetCounter(&htim2); //获取t2tim2_state == 0;f40 = 1000000/tim2_cnt2;//得到频率d40 = tim2_cnt1*100.0f/tim2_cnt2;//得到占空比}HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
}
int main()
{HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
}
十四、PWM输出
1.初始化
1.1 配置需要输出的引脚为TIM
1.2 对应的TIM设置为PWM输出模式
1.3 设置分频值为79,设置ARR,打开预装载,设置CCRx。
2.编程
u16 t2 = 499;
u16 t1 = 250;
void PWM_Out_Process()
{HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);TIM17->ARR = t2;TIM17->CCR1 = t1;
}
相关文章:
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册
一、要背的函数汇总(以例子形式) 1.GPIO相关 输出:HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8 | GPIO_PIN_9,GPIO_PIN_SET) 输入:HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) 翻转:HAL_GPIO_TogglePin(GPIOC,0xFF) 2.LCD相关 …...
doris2.0.7 安装
1,查看操作系统 lsb_release -a #Distributor ID: Ubuntu #Description: Ubuntu 22.04.3 LTS #Release: 22.04 #Codename: jammy 2,安装zip,mysql-client apt install mysql-client apt install zip 3,安装jdk apt inst…...

智慧园区水电能源监控管理系统
随着智慧城市的快速发展,智慧园区作为城市智能化的重要组成部分,其能源监控管理系统显得尤为关键。智慧园区水电能源监控管理系统,是利用先进的信息技术和自动控制技术,对园区内的水电能源使用进行实时监控、管理和优化的综合性智…...

Kafka基础/1
Kafka 概念 Kafka 是一个分布式的流媒体平台。 应用:消息系统、日志收集、用户行为追踪、流式处理 特点:高吞吐量、消息持久化、高可靠性、高扩展性 术语: broker:Kafka 的服务器,Kafka 当中每一台服务器…...
Jupyter Notebook中常见的快捷键
Jupyter Notebook的快捷键主要分为两种模式:命令模式和编辑模式。 在命令模式下,键盘输入用于运行程序命令,此时单元格框线是蓝色的; 在编辑模式下,可以往单元格中键入代码或文本,此时单元格框线是绿色的…...

《前端面试题》- JS基础 - call()、apply()、bind() 的区别
call 、bind 、 apply 这三个函数的功能都是改变this的指向问题,但是也存在一定的区别。 call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,apply 的所有参数都必须放在一个数组里面传进去bind 除了返回是函数以外,它 的参数和…...

开源软件技术社区方案
开源软件技术社区是一个由开发者、贡献者、用户和维护者组成的共享平台,主要目的是打造技术、软件产品良性互动、开源技术安全可控的软件生态环境,实现可复用应用或服务的快速部署与使用、完成资源与能力的高度共享、促进社区成员的共建共赢,…...
【开源书籍】深入讲解内核网络、Kubernetes、ServiceMesh、容器等云原生相关技术。
项目地址:GitHub - isno/theByteBook: ⭐ 【开源书籍】深入讲解内核网络、Kubernetes、ServiceMesh、容器等云原生相关技术。经历实践检验的 DevOps、SRE指南。如发现错误,谢谢提issue 深入架构原理与实践 这是什么? 这是一本关于架构设计…...

【C语言】“vid”Microsoft Visual Studio安装及应用(检验内存泄露)
文章目录 前言安装包获取配置VLD完成 前言 我们在写代码时往往容易存在内存泄漏的情况,所以存在这样一个名为VLD的工具用来检验内存泄漏,现在我来教大家安装一下 安装包获取 vld下载网址:https://github.com/KindDragon/vld/releases/tag/…...
Accuracy准确率,Precision精确率,Recall召回率,F1 score
真正例和真反例是被正确预测的数据,假正例和假反例是被错误预测的数据。然后我们需要理解这四个值的具体含义: TP(True Positive):被正确预测的正例。即该数据的真实值为正例,预测值也为正例的情况…...

系统架构最佳实践 -- 智慧图书管理系统架构设计
随着数字化时代的到来,智慧图书管理系统在图书馆和机构中扮演着重要的角色。一个优秀的图书管理系统不仅需要满足基本的借阅管理需求,还需要具备高效的性能、良好的扩展性和稳定的安全性。本文将讨论智慧图书管理系统的架构设计与实现,以满足…...

网络基础三——IP协议补充和Mac帧协议
全球网络及网段划分的理解 根据国家组织地区人口综合评估进行IP地址范围的划分; 假设前8位用来区分不同的国家,国际路由器负责全球数据传输,子网掩码为IP/8;次6位区分不同的省份,国内路由器负责全国数据的传输…...

人工智能——深度学习
4. 深度学习 4.1. 概念 深度学习是一种机器学习的分支,旨在通过构建和训练多层神经网络模型来实现数据的高级特征表达和复杂模式识别。与传统机器学习算法相比,深度学习具有以下特点: 多层表示学习:深度学习使用深层神经网络&a…...

postgresql uuid
示例数据库版本PG16,对于参照官方文档截图,可以在最上方切换到对应版本查看,相差不大。 方法一:自带函数 select gen_random_uuid(); 去掉四个斜杠,简化成32位 select replace(gen_random_uuid()::text, -, ); 官网介绍…...

【azure笔记 1】容器实例管理python sdk封装
容器实例管理python sdk封装 测试结果 说明 这是根据我的需求写的,所以有些参数是写死的,比如cpu核数和内存,你可以根据你的需要自行修改。前置条件: 当前环境已安装python3.8以上版本和azure cli并且已经登陆到你的账户 依赖安…...
Nestjs 中定义既可以捕获错误(Error)和又可以异常(Exception)的过滤器
Nestjs 中,使用基于 HttpException 定义过滤器的话,只能捕获 Http 带状态码(statusCode)的 Exception,不能捕获 throw new Error(‘xxx’) 抛出的错误。 以下是使用实现 ExceptionFilter 接口定义的一个不特定于平台(express 或 fastify,即无论使用这两个web服务框架的…...

GitHub 仓库 (repository) Branch - SSH clone URL - Clone in Desktop - Download ZIP
GitHub 仓库 [repository] Branch - SSH clone URL - Clone in Desktop - Download ZIP 1. Branch2. SSH clone URL3. Clone in Desktop4. Download ZIPReferences 1. Branch 显示当前分支的名称。从这里可以切换仓库内分支,查看其他分支的文件。 2. SSH clo…...

Training - 使用 WandB 配置 可视化 模型训练参数
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/137529140 WandB (Weights&Biases) 是轻量级的在线模型训练可视化工具,类似于 TensorBoard,可以帮助用户跟踪…...

N1922A是德科技N1922A功率传感器
181/2461/8938产品概述: N192XA 传感器是首款通过将直流参考源和开关电路集成到功率传感器中来提供内部调零和校准的传感器。此功能消除了与使用外部校准源相关的多个连接,从而最大限度地减少了连接器磨损、测试时间和测量不确定性。 连接到 DUT 时进行…...

最简洁的Docker环境配置
Docker环境配置 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Mac、Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...