C语言知识
文章平均质量分 65
天问XUiRH
叶子的离去是风的追求还是树的不挽留
展开
-
单片机固件中加入“版本信息”的方法
平时我们写程序,通常都会备注软件版本,那么,怎么在单片机中保存版本信息呢?方法其实有很多,但基本原理都是在指定存储区域(Flash)中写入软件版本信息。实现方法下面就分享一个最常用,也是最基础的小技巧:在Keil MDK环境下,通过软件代码,直接映射到并存储到Flash指定地址。包含:软件版本、编译日期、编译时间,代码如下:#define VERINFO_ADDR_BASE (0x0800FF00) //存放FLASH的地址const char Software_Ver[] __attrib原创 2022-04-06 21:07:49 · 1755 阅读 · 2 评论 -
转载:malloc()详解
侯捷C++内存分配课程总结六:malloc()详解: 文章内容参照于侯捷 C++内存分配系列教程 文章目录 侯捷C++内存分配课程总结六:malloc()详解:前言一、malloc()分配出的内存空间二、内存分配1.内存管理所用到的结构层次2.内存页的划分3.内存分配...转载 2021-12-08 08:49:32 · 2250 阅读 · 0 评论 -
C语言的宏定义技巧
1.防止头文件重复包含#ifndef COMDEF_H#define COMDEF_H //头文件内容#endif2.重定义类型,可以用宏或者typedef,推荐后者#ifndef BYTE #define BYTE unsigned char#endif#ifndef CHAR #define CHAR char#endif#ifndef WORD #define WORD unsigned short int#endif#ifndef INT16 #defin原创 2021-07-12 16:22:51 · 683 阅读 · 0 评论 -
基于双向链表的窗口消息管理框架
Manager.h#ifndef __MANAGER_H#define __MANAGER_H#include "rtdef.h"//Manager所需的参数#ifdef MAIN#define VAR_RANGE#else#define VAR_RANGE extern #endif#define configUSE_OPENWINDOW_LOG 0 //0 打开窗口不打印日志 1打开窗口打印日志#define configUSE_CLOSEWINDOW_LOG 0原创 2021-06-02 23:15:58 · 290 阅读 · 3 评论 -
支持标准Modbus的下位机程序
上位机如触摸屏采用ModbusRTU或ModbusTCP通讯协议与下位机如单片机通过串口或网络通信时,需要解析上位机报文Modbus寄存器读写的单位是字Word,读写Map表元素长度必须为字的整数倍,同时注意使用内存下标对齐时务必注意使用内存按字对齐支持功能码03/06/100x03 读保持寄存器 设备地址 功能码 起始地址 寄存器数...原创 2020-11-25 17:38:56 · 573 阅读 · 0 评论 -
一次关于定时Tick的调试经历
如何使用定时触发某一时间1.先看一个简单的例子,实现LED定时1ms翻转void RefreshLED(void){ HAL_Delay(1000); /*< Do something */ HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);}void RefreshLED(void){ static uint32_t TickBase=0; if( HAL_GetTick() - TickBase >= 1000){ Tick原创 2020-07-08 23:55:31 · 2111 阅读 · 0 评论 -
STM32 CAN配置
STM32 CAN 配置使用工具:CubeMX硬件:STM32F105RBT61.概述STM32F105x双can,CAN1为主,CAN2为从,使用CAN2必须使能CAN1的时钟,CAN1/CAN2使用共同的筛选器,总计28组。CAN2作为CAN1的从站,CAN1复位是否会影响CAN2?CAN总线关闭之后一定要自主恢复,自动脱离Bus-off状态,重复启动CAN总线错误...原创 2020-04-07 21:19:56 · 5206 阅读 · 0 评论 -
指针常量与常量指针
指针常量 :本质是常量 指针类型的常量指针类型的常量(int *const p)该指针是一个常量,不可改变,必须初始化,指向某个地址之后就不能改变了,指向的地址一定但所指向的内容是可以修改的int a=10,b=20;int *const p = &a;//必须初始化*p = 15;//Rightp = &b;//Errora = 15;//Right常...原创 2020-01-01 17:00:40 · 184 阅读 · 0 评论 -
动态打印字符串数组-printf和LCD显示
#include "stdarg.h"void LcdSSD1306_PosString(u16 x, u16 y, u8 font, char *string){ }#define LCD_PRINT(X,Y,FONT,fmt,arg...) \do{ \ char string[1024]; \...原创 2019-12-13 08:48:11 · 1077 阅读 · 0 评论 -
32位单片机周期性计时的问题
周期性闪烁LED的方式有一下两种,但第二种方式有问题由此引发C语言在32位机中计算时间间隔时的问题,此现象在PIC32和STM32中都有且一致u32 TickCounter_32;u16 TickCounter_16; void SysTickHandler(void){ TickCounter_32++; TickCounter_16++;} /** * @br...原创 2019-12-22 19:18:50 · 430 阅读 · 1 评论 -
STM32 重构printf函数
Printf函数采用阻塞式发送,不建议使用DMA方式发送,日志不能丢失,且DMA会刷新发送区域造成丢帧的问题,且如果串口和DMA共同使用则DMA发送的数据包会将日志数据冲掉.调试输出慢点没有关系问题:在使用STM32F105printf数据时如果在ADC初始化前使用printf输出日志(勾选MicroLib)时则出现不能进入ADCDMA采样中断的情况解决办法:重定义Sprintf函数...原创 2019-12-22 19:20:33 · 976 阅读 · 1 评论 -
STM32使用DMA方式Printf
使用库函数调试printf时需要占用系统资源所以采用DMA方式来printf数据两种实现方式@pre 已经有DMA发送管理函数#include "stdio.h"#include "stdarg.h"/** * @brief Modbus发送管理 */void StartModbusTranst(UART_HandleTypeDef* huart, u16 uLen){...原创 2019-07-19 10:31:02 · 4127 阅读 · 4 评论 -
C语言一级指针和二级指针
指针应该是C语言最核心的知识,也是难点,二级指针是如何操作又是如何使用的?int a = 12;int *b = &a;int **c = &b;int d = 100;int *p;void fun1(int *p1, int *p2){ p1 = p2;}void fun2(int **p1, int *p2){ *p1 = ...原创 2019-07-30 18:23:50 · 231 阅读 · 0 评论 -
Hardfault处理方法
keil仿真对HardFault_Handler的处理: STM32出现硬件错误可能有以下原因:(1)数组越界操作;(2)内存溢出,访问越界;(3)堆栈溢出,程序跑飞;(4)中断处理错误;在while(1)打断点 1.提取SP值,SP指向当前使用的栈顶...原创 2019-12-06 14:11:00 · 593 阅读 · 0 评论 -
ASSERT断言使用优化
Assert.h#ifndef __ASSERT_H#define __ASSERT_H#define ASSERT_ENABLE 1U //使能断言检查#define ERROR 0U#if (ASSERT_ENABLE != 0U) #define ASSERT(expr) ((expr) ? (void)0 : _Assert((uint8_t *)__FI...原创 2019-12-22 19:21:28 · 104 阅读 · 0 评论 -
PRINTF函数优化
printf函数主要用于数据输出和调试信息输出在DEBUG需要调试数据时使能PRINTF_ENABLE 1U,RELEASE版本则失能PRINTF_ENABLE 0U,编译器高等级优化选项会将宏定义((void)0)优化,不会影响程序效率Printf.h#ifndef __PRINTF_H#define __PRINTF_H#define PRINTF_ENABLE 1U ...原创 2019-12-22 19:19:18 · 240 阅读 · 0 评论 -
STM32Flash读取/擦除/编程
STM32Flash编程,在STM32Bootloader 在线编程,利用Flash扇区Sector Page存储数据 IAP应用编程:用户程序运行时对闪存微控制器中存储器重新编程。 写在前面: Flash在编程过程中,总线被占用不能取指和取值,能够触发systick中断,但是不能执行代码,如果串口接收数据则会丢失数据。 Flash在写...原创 2019-12-22 19:19:35 · 974 阅读 · 0 评论 -
Keil常见错误 last line of file ends without a newline原因
换行符无需添加空间,只需移动到文件等最后一行的末尾即可,然后按enter键并保存。出现警告是因为某些工具只处理以换行符结尾的文本,因此如果最后一个文本后面没有换行符,则该文本将被忽略几乎所有工具都真正处理文件数据到最后一个字符,而不是最后一个换行符,编译器警告只是为了确保在不同工具移动代码时不会受到伤害。...原创 2019-12-22 19:19:00 · 1355 阅读 · 0 评论 -
#和##的用法
#和##在C语言中宏定义使用很多,简单写下#和##的用法“#”运算符运算符#的名字是Stringizing Operator,它将函数宏的实际参数转换为对应的字符串常量。 ”#“的功能是对参数执行字符串化,如果没有特殊情况,这就意味着直接用""将参数包裹起来做替换。 如果实际参数中包含在字符串中使用时需要转义的字符(比如"和),那么这些字符就会被转义。 被字符串化...原创 2019-12-22 19:18:27 · 9805 阅读 · 0 评论 -
记一次STM32调试经历
先说结论,工程配置注意两点:1."Options for Target"-> "C/C++"->"Optimization:" 工程优化级别是不是太高,调试默认Level 0(-O0)不优化,<default>的优化等级为Level 2(-O2)2."Options for Target"-> "Target"->"IROM1:Start Size"在...原创 2019-12-22 19:20:48 · 92 阅读 · 0 评论 -
关于STM32串口使用DMA接收时发生ORE(过载错误)的原因分析
当使用串口接收到一帧数据,超时完成,关闭接收DMA,此时串口还是激活的,若此时串口来数据,无法触发DMA传输,此时产生上溢错误(ORE),由于串口数据寄存器里的数据不能及时转移走,后面来的数据就进不来。一旦出现这种错误后,就不会再触发DMA请求,即使再开启DMA也不行。要恢复正常的话就只有Deinit后再重新初始化串口,或者使用read接口直接将数据寄存器中的数据读走后,后面的数据...原创 2019-12-22 19:20:17 · 4629 阅读 · 2 评论 -
关于窗口消息用法的笔记
1.窗口延时现象描述:如果需要在某个窗口执行完任务后延时,不要在当前窗口建立定时器延时,在当前窗口建立定时器时当前窗口仍为活动窗口,WM_REFRESH如果有任务仍在刷新,要注意,问题的根源很有可能出现在这里,如果WM_REFRESH没有任务则一切正常,如果有则很有可能出现问题。解决方案:新建一个窗口winDelay处理延时,避免当前窗口刷新为动作窗口刷新任务引发不必要的问题2....原创 2019-07-02 16:20:03 · 106 阅读 · 0 评论