- 博客(194)
- 资源 (1)
- 收藏
- 关注
原创 RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
RCC_GetClocksFreq 函数的主要作用是获取当前 STM32 微控制器各个时钟源的频率值,并将这些值存储在传入的 RCC_ClocksTypeDef 结构体指针所指向的结构体变量中。RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) 是一个在 STM32(意法半导体推出的一系列 32 位微控制器)标准外设库中使用的函数,下面详细介绍它的作用、参数和使用示例。打印时钟频率:使用 printf 函数将获取到的各个时钟的频率值打印输出,方便开发者查看。
2025-04-23 09:57:25
601
原创 STM32的IO不用 ,是设置为输入还输出?
降低功耗:在输入模式下,引脚基本不向外输出电流,仅需消耗极小的电流来维持其输入状态的检测,这有助于降低整个系统的功耗。浮空输入:适用于引脚不需要外部上拉或下拉电阻的情况,此时引脚电平会处于不确定状态,直到外部有信号输入。按键按下时,引脚电平被拉低。避免短路风险:若将不用的引脚设置为输出模式,且该引脚意外与其他引脚或电源、地短路,可能会损坏芯片。综上所述,为了降低功耗、减少干扰和避免短路风险,通常将不用的 STM32 IO 引脚设置为输入模式,并根据具体需求选择合适的输入子模式。推荐设置为输入模式的原因。
2025-04-22 09:49:16
555
原创 WM_SetCreateFlags(WM_CF_MEMDEV);函数
内存设备是 emWin 中一种用于缓冲和绘制图形的机制,它在内存中创建一个与窗口大小相同的缓冲区,所有的绘图操作都会先在这个缓冲区中进行,然后再一次性将缓冲区的内容绘制到实际的显示设备上。,在创建窗口时就会为该窗口分配内存设备,后续对该窗口的绘图操作都会在这个内存设备上进行,从而利用内存设备的特性来提升窗口的绘制效果和性能。:内存设备可以方便地实现透明效果,通过在内存中处理透明度信息,在绘制到显示设备时可以根据透明度进行合成,实现窗口或控件的透明显示。
2025-04-18 13:36:59
507
原创 要引用一个文件中的 函数 是使用 extern 好还是包含头文件好?
原理:通过 #include 指令将头文件包含到当前源文件中,编译器会将头文件的内容插入到 #include 指令所在的位置,从而使当前源文件可以访问头文件中声明的函数、变量和类型等。灵活引用:当你只需要引用文件中的个别函数,不想引入整个头文件时,使用 extern 可以更精准地引用所需函数,避免引入不必要的定义和声明,减少编译时间和命名冲突的可能性。自动更新:当函数的原型发生变化时,只需要修改头文件中的声明,所有包含该头文件的源文件都会自动更新,无需手动修改每个源文件中的 extern 声明。
2025-04-16 09:17:39
834
原创 Qt绘画线段
头文件//==============================================================#ifndef WIDGET_H#define WIDGET_H#include QT_BEGIN_NAMESPACEnamespace Ui { class Widget; }QT_END_NAMESPACEclass Widget : public QWidget{Q_OBJECTpublic:private:Ui::Widget *ui;protect
2025-04-14 20:07:30
323
原创 usoc3 为什么 不能在中断服务函数中创建任务?
在中断服务函数中创建任务后,需要立即考虑新任务的调度问题,这会使中断处理流程变得复杂。而且,新创建的任务可能会改变系统的任务调度格局,导致原有的任务调度计划被打乱,增加了系统调度的不确定性。创建任务涉及到对系统资源的分配和数据结构的修改,如任务控制块(TCB)的初始化、就绪列表的更新等。中断服务函数执行时可能会打断其他任务的正常执行,如果在中断中创建任务,可能会导致这些资源在不一致的状态下被访问,引发数据冲突和错误。在中断服务函数中执行创建任务的代码会增加中断的处理时间,导致中断响应时间变长。
2025-04-13 10:26:42
100
原创 #include <QStyleFactory> 和#include <QStyleFactory.h> 的区别
符合 Qt 的头文件包含规范:Qt 采用了一种模块化的设计,每个类都有对应的头文件,并且推荐使用 <类名> 这种形式来包含头文件。跨平台一致性:不同的操作系统和编译器在处理头文件路径时可能存在差异,使用 <类名> 这种包含方式可以让 Qt 的构建系统自动处理这些差异,确保代码在不同平台上都能正确编译。可能存在兼容性问题:随着 Qt 版本的更新,头文件的组织结构可能会发生变化,使用 .h 扩展名的包含方式可能会因为找不到正确的头文件而导致代码无法编译。标准的 Qt 包含方式:#include。
2025-04-11 14:41:48
209
原创 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,
通过这两行代码,首先使能了 AFIO 外设的时钟,然后禁用了 JTAG 调试接口,从而释放了 GPIOA_15 引脚,使其可以被用作普通的 GPIO 引脚,以满足特定的应用需求。在基于 STM32 微控制器的开发中,以下这两行代码的主要作用是禁止 JTAG(Joint Test Action Group,联合测试行动小组)功能,从而使 GPIOA 的第 15 引脚(GPIOA_15)能够作为普通 GPIO 引脚使用。只有使能了 AFIO 的时钟,后续对引脚复用功能的配置才能生效。
2025-04-11 11:22:53
454
原创 OSTaskCreateExt()
灵活配置任务属性:相比基础的任务创建函数,OSTaskCreateExt 允许开发人员更细致地配置任务相关属性,如通过 opt 参数设置堆栈检查、清空等功能,通过 pext 扩展任务控制块存储额外信息等,满足不同应用场景对任务管理的多样化需求。:用于存储任务操作相关信息的选项,比如可通过它设置是否进行堆栈检查(OS_TASK_OPT_STK_CHK) 、是否清空堆栈(OS_TASK_OPT_STK_CLR)等。:定义一个指向数据结构的指针,用于扩展任务控制块(TCB) ,可存储一些与任务相关的额外信息。
2025-04-11 10:39:56
330
原创 va_start ( va_args, Flow ); va_end ( va_args ); 有什么作用?
va_end 用于结束对可变参数的访问。在函数使用完可变参数后,调用 va_end 来清理 va_list 相关的内部状态,比如将指针恢复到合适状态,防止出现内存泄露、堆栈损坏等潜在问题 ,确保程序的稳定性和安全性。通过这个参数,va_start 能确定可变参数在堆栈中的起始位置,让 va_list 类型变量指向可变参数列表的第一个参数,为后续使用 va_arg 宏获取可变参数做准备。va_start 用于初始化 va_list 类型的变量(这里是 va_args ) ,以便后续访问可变参数列表。
2025-04-11 09:48:17
448
原创 在.c 和 .h 文件中都对 USART_IOCtl() 函数添加 extern 修饰
声明与定义的区别:在 C 语言里,声明是告诉编译器某个标识符(函数、变量等)的存在及类型等信息,不分配内存;定义则是为标识符分配内存空间,对于函数来说就是实现函数体。在 .h 文件中用 extern 声明 USART_IOCtl 函数,是为了让包含该头文件的其他源文件知道有这么个函数及它的参数和返回值类型,这是合理的。usart.c 中的 extern 多余性:在 usart.c 中,既然已经是函数定义(有函数体实现),函数本身就已经确定其存在性了,不需要 extern 来再次强调它是外部链接属性。编译器在
2025-04-11 09:02:34
724
原创 UCOS-II 和 UCOS-III ,的差别大吗?
UCOS-II:使用固定优先级抢占式调度算法,每个任务都有一个唯一的优先级,高优先级任务可以随时抢占低优先级任务的 CPU 使用权。UCOS-II:支持的任务数量上限为 64 个(包含系统任务),这在一些小型嵌入式系统中足够使用,但对于复杂的大型系统而言,可能会受到任务数量的限制。UCOS-III:支持内存保护机制,通过设置内存保护区域,防止任务之间的非法内存访问,提高了系统的安全性和可靠性。UCOS-III:支持中断嵌套,允许在中断处理过程中响应更高优先级的中断,提高了系统的实时性和响应能力。
2025-04-09 08:53:44
728
原创 PC_VectSet(0x08, OSTickISR);是什么意思?
一般而言,OSTickISR 是系统时钟节拍中断服务子程序,它会在每个时钟节拍到来时被调用,主要用于更新系统的时钟信息、处理任务调度等操作。这行代码调用了 PC_VectSet 函数,其目的是把中断向量表中地址为 0x08 的中断向量设置为 OSTickISR。main 函数:在 main 函数中,调用 PC_VectSet 函数设置中断向量,然后模拟中断触发,调用对应的中断服务子程序。OSTickISR 函数:这是一个简单的中断服务子程序,当中断触发时,会输出一条信息。// 定义中断服务子程序类型。
2025-04-08 17:50:45
338
原创 myregexp\widget.cpp:15: error: variable ‘QRegularExpression re‘ has initializer but incomplete type?
报错信息 variable ‘QRegularExpression re’ has initializer but incomplete type 表明编译器在处理 QRegularExpression 类型的变量 re 时,无法识别该类型的完整定义,这通常是因为缺少必要的头文件包含。QRegularExpression 是 Qt 中用于处理正则表达式的类,若要使用它,必须包含 头文件。在使用 QRegularExpression 的源文件中添加 头文件的包含语句。
2025-04-05 22:17:26
420
原创 exit(0) 和 return 0区别
作用范围:return语句一般用于函数中,用来返回一个值并且终止函数的执行。在main函数里,return 0;意味着程序正常结束,返回给操作系统的退出状态码是0。在大多数系统中,退出状态码0表示程序成功执行,非零值则表示程序执行过程中出现了错误。都和程序的退出状态相关,不过它们的使用场景和具体作用有所不同。在main函数里,通常使用return 0;,程序会立即终止,main函数里后续的代码不会被执行。在这个例子中,main函数执行完printf语句后,使用return 0;// 下面的代码不会被执行。
2025-04-05 10:31:21
519
原创 testApp.c: In function ‘main’: testApp.c:15:8: warning: implicit declaration of function ‘chmod’ [-W
在这个修正后的代码中,我们添加了#include <sys/stat.h>来包含chmod函数的声明,并且把传递给exit函数的参数从字符串"-1"改成了整数-1。警告 2:passing argument 1 of ‘exit’ makes integer from pointer without a cast。#include <sys/stat.h> // 包含chmod函数的声明。#include <stdlib.h> // 包含exit函数的声明。// 修正为整数 -1。
2025-04-05 09:15:44
262
原创 testApp.c: In function ‘main’: testApp.c:19:12: warning: unknown conversion type character ‘:’ in fo
在这个修正后的代码中,%s被用作转换说明符,这表明要输出一个字符串,这样MY_FILE就可以正确地作为字符串参数传入printf函数。若你想输出文件名并表明文件不存在,要把%:改成%s,因为MY_FILE应该是一个字符串。这两条警告信息是由 C 语言编译器给出的,下面为你分析并解决这些问题。// 修正后的printf语句。
2025-04-05 08:59:40
128
原创 Sanity check user-configurable values”
检查 max_retries 是否为非负整数# 检查 timeout 是否为正整数# 检查 threshold 是否为非负数值。
2025-04-03 14:41:37
224
原创 #define LWIP_U32_DIFF(a, b) ((a) >= (b)? ((a) - (b)) : ((~(b) + (a)) + 1)),a 和b 都是无符号数,求结果?
不同版本的 LWIP 中,LWIP_U32_DIFF 的具体实现可能会有所不同,但基本功能都是为了正确计算两个无符号 32 位整数的差值并处理溢出情况。在 LWIP(轻量级网络协议栈)中,LWIP_U32_DIFF 通常是用于计算两个无符号 32 位整数差值的宏(macro)。
2025-04-03 14:02:01
567
原创 int main(int argc, char *argv[]) { QApplication a(argc, argv); Form w; w.show()}有什么作用?
在事件循环中,应用程序等待用户的输入(如鼠标点击、键盘输入等)和系统事件(如窗口的显示、隐藏等),并对这些事件进行相应的处理。int main(int argc, char *argv[]):这是 C++ 程序的入口函数,argc 表示命令行参数的个数,argv 是一个指向字符数组的指针,其中每个元素都是一个指向命令行参数的字符串的指针。总之,main 函数中的这几行代码对于 Qt 应用程序的正常启动和运行是必不可少的,它们完成了应用程序的初始化、窗口创建和显示以及事件循环的启动等关键步骤。
2025-04-02 08:59:25
692
原创 MyButton *button = new MyButton(this); 和 MyButton *button = new MyButton(); 的区别
调用的是带参数的构造函数,这里的 this 指针指向当前对象(一般是所在类的实例 )。在 MyButton 类的构造函数内部,可利用这个指针建立与当前对象的关联,比如设置父子关系(在 GUI 编程中确定按钮属于哪个窗口等容器 ),或者获取当前对象的一些属性、调用其方法等。:由于和传入对象存在关联,当关联对象(this 所指对象 )销毁或状态改变时,可能影响 MyButton 对象的生命周期或行为。:调用的是无参构造函数。
2025-04-01 20:58:11
311
原创 void OSTimeDly (INT32U ticks), 函数的详细解读?
if OS_CRITICAL_METHOD == 3u:这是一个条件编译指令,若 OS_CRITICAL_METHOD 的值为 3,则会定义一个 OS_CPU_SR 类型的变量 cpu_sr 并初始化为 0。:OSTCBCur 指向当前正在运行的任务的任务控制块,OSTCBY 是任务控制块中的一个成员,代表任务在就绪表中的 Y 坐标。综上所述,这段代码实现了任务的延时功能,并且在执行延时操作前会进行必要的检查,以确保操作的安全性和正确性。:调用调度函数 OS_Sched(),重新选择下一个要运行的任务。
2025-04-01 14:59:49
494
原创 uint8_t TxBuffer[8]={0}; memset(TxBuffer,0,sizeof(TxBuffer)) 初始化数组 哪个方式比较好?
此外,它可以把内存块设置为除 0 以外的其他值(尽管对于非字符类型的数组,设置非 0 值可能会产生意想不到的结果)。若在数组定义之后的某个时刻才需要初始化:使用 memset(TxBuffer, 0, sizeof(TxBuffer));,它代码简洁,并且在编译阶段完成初始化,没有运行时开销。该操作在程序运行时执行。适用场景:适用于在数组定义之后的某个时刻进行初始化,或者需要对已经存在的内存块进行重置操作的情况。性能:由于是运行时函数调用,会有一定的函数调用开销,不过在现代处理器上,这种开销通常较小。
2025-04-01 11:09:56
368
原创 use of undeclared identifier ‘arg‘,
在上述修改后的代码中,tr(“获取的值是:%1”) 先获取待翻译的字符串,其中%1 是占位符,然后通过arg(value) 函数将value 的值替换到占位符%1 所在位置,这样就能正确设置label 显示的文本内容了。ui->label->setText(tr(“获取的值是:%l”,arg(value)));ui->label->setText(tr(“获取的值是:%1”).arg(value));ui->label->setText(tr(“获取的值是:%1”).arg(value));
2025-04-01 08:50:51
351
原创 共享位图 是什么?如 static vu32 shareBitMap[4] = {0,0,0,0};
共享位图 */ 是一个注释,其作用是对后续代码进行解释说明,表明 shareBitMap 数组的用途是作为共享位图。内部链接属性:若该代码处于源文件(.c 文件)里,static 会让 shareBitMap 具有内部链接属性,这意味着该数组仅能在定义它的源文件内部使用,其他源文件无法通过外部链接来访问它。对数组进行初始化,让数组的 4 个元素都初始化为 0。在这个示例里,shareBitMap 数组被当作共享位图使用,通过 set_bit 函数设置某一位,通过 check_bit 函数检查某一位的状态。
2025-03-29 16:58:41
369
原创 宏定义 放在 一个结构体中 合适吗?
违背设计意图:宏定义的目的是为了提供全局或局部的常量、代码片段替换等功能,而结构体的目的是组织数据。结构体:结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个新的数据单元。作用域混淆:宏定义的作用域是文件范围,而结构体成员的作用域是结构体内部。将宏定义放在结构体中会导致作用域概念的混淆,使得代码的逻辑难以理解。如果宏定义与结构体相关,可以将宏定义放在结构体定义之前或者包含该结构体定义的头文件中。综上所述,不建议把宏定义放在结构体中,应根据宏定义的使用范围和目的,将其放在合适的位置。
2025-03-29 16:40:14
421
原创 宏定义一般是放在什么位置 ?
这样,不同的源文件只需包含该头文件,就可以使用其中定义的宏,提高了代码的复用性和可维护性。适用场景:如果宏定义仅在某个源文件内部使用,不希望被其他文件访问,那么将其放在该源文件的开头部分是合适的。适用场景:对于一些大型项目,通常会有专门的配置文件来管理项目的各种配置信息,宏定义也可以放在这里。头文件:适用于需要在多个源文件中共享的宏定义。源文件:适用于仅在单个源文件中使用的宏定义。配置文件:适用于管理项目的配置信息的宏定义。// 仅在 main.c 中使用的宏。// 定义一个通用的常量宏。
2025-03-29 16:31:33
467
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人