C语言
文章平均质量分 57
C语言知识和踩坑合集
董董灿是个攻城狮
阿里云社区专家博主,AI算法工程师
展开
-
判断是否为BCD码
BCD码的判断。先看什么是BCD码: BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。通俗点,BCD码就是对于8位数字来说,高4为和低4为原创 2018-01-18 18:19:03 · 4974 阅读 · 0 评论 -
软键盘设计的实现与代码分享(TP900掌机)
一个项目需要。需要在2天时间里在振中掌机上添加一个软键盘,用于输入掌机本身不支持的字符。接到这个任务后,便开始构思怎么实现,毕竟软键盘的显示与切换没有一个好的算法,用起来会有很多的问题。思来想去,最后确定了方案,开始着手实现。关于代码的实现思想其实实现起来不是很难,字符的输入与显示便是ASCII码,只要把ASCII码按照自己想要排列的键盘样式编好数组,然后通过上下左右键实现不同AS原创 2017-12-21 13:50:19 · 1330 阅读 · 1 评论 -
嵌入式C小程序合集(持续更新)
嵌入式C语言小程序合集本人在学习及开发嵌入式相关的过程中,经常会遇到一些程序的小问题,需要一些简单的小程序实现相应的功能,比如实现数组拷贝、数组交换等等。下面汇总了一些我经常用到且已得到验证功能良好的小程序,有需要的同学可按需取用,有任何问题可文章下留言或加好友交流。(本文会持续更新)内存、数组相关:数组逆序排列数组向数组拷贝数值向数组拷贝数组与数组比较数组与数值比较计原创 2018-01-18 13:43:06 · 2058 阅读 · 0 评论 -
数组与数比较函数(字符串与固定值对比)
将字符串与固定值DATA比较。U8 memcmpD(U8 *tPtr, U8 DATA, U16 Len){ for (; Len > 0; Len--, tPtr++) { if (*tPtr != DATA) { if(*tPtr > DATA)原创 2018-01-18 18:32:04 · 2755 阅读 · 0 评论 -
数组头尾交换
实现一个数组的逆序交换 e.g. 12 34 56 78 —>>> 78 56 34 12 // 说明: dst--目的地址 src -- 源地址 len -- 数组长度void HeadToTail(U8 *dst, U8 *src, U8 len){ U8 i; for(i=0;ilen;i++) { *(dst + i) = *原创 2018-01-18 13:38:19 · 1752 阅读 · 0 评论 -
大端小端以及判别方式
大端和小端是指数据在内存中的存储模式,它由 CPU 决定:1) 大端模式(Big-endian)是指将数据的低位(比如 1234 中的 34 就是低位)放在内存的高地址上,而数据的高位(比如 1234 中的 12 就是高位)放在内存的低地址上。这种存储模式有点儿类似于把数据当作字符串顺序处理,地址由小到大增加,而数据从高位往低位存放。2) 小端模式(Little-endian)是指将数据的转载 2018-01-16 14:06:36 · 6433 阅读 · 2 评论 -
计算数组长度
计算一个数组的长度:按数组占用内存地址计算。源代码: U16 strlen(const char *s){ /* find length of s[] */ const char *sc; for (sc = s; *sc != '\0'; ++sc); return (sc - s);}原创 2018-01-19 19:20:02 · 527 阅读 · 0 评论 -
8位机如何显示超过255的16位的数字?
背景今天写代码,需要显示数据发送次数,次数递增,最大有可能有几万次。但是测试时发现数字到了255之后便从零开始显示。显然是数据越界了。 其实这个问题很好解决,主要是数据类型转换就可以。但是如果遇到一个8位机,而且设备提供的接口函数中,数据的类型只有8位整形,该怎么办?就像我今天遇到的。解决设备提供一个现实数据的接口函数: void _putstr(U8 *p); 其输入只能是8...原创 2018-01-17 18:46:47 · 1893 阅读 · 0 评论 -
软键盘输入设计(C语言)
之前写过一篇关于软键盘输入设计的文章点击这里查看,用的是掌机自支持的zzdbase语言,花了半天时间,将原来的代码改为了c预言实现。原创 2018-01-16 09:29:56 · 1640 阅读 · 0 评论 -
16位帧校验 (pppfcs)
帧校验需要一个校验表,然后传入参数为需要校验的数组的首地址以及长度,返回16位校验值。U16 fcstab[256]={ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,原创 2018-01-18 18:38:24 · 3277 阅读 · 3 评论 -
固定值拷贝
将一个特定的数值拷贝到指定内存中。如定义数组> U8 A[3];希望A中元素全部为0x11,则memset(A,0x11,3);函数源代码:void *memset(void *s, U8 c, U16 n){ U8 *ss = s; while (n--) *ss++ = c; return s;}原创 2018-01-18 14:01:41 · 257 阅读 · 0 评论 -
数据比较函数(内存比较)
比较两个数或两个数组是否一致。 s1 s2 为数或数组首地址,n为需要比较的长度S8 memcmp(U8 *s1, U8 *s2, U8 n){ U8 *src1 = s1; U8 *src2 = s2; for( ; n>0 ; ++src1, ++src2, n--) { if(*src1 != *src2) {原创 2018-01-18 18:30:33 · 6623 阅读 · 0 评论 -
累加和校验算法
计算一串数据的累加和,即数据相加后的模255的值。U8 CheckSum(U8 *buf, U8 len){ U8 i, ret = 0; for(i=0; ilen; i++) { ret += buf[i]; } return ret;}原创 2018-01-18 18:34:21 · 11738 阅读 · 0 评论 -
16进制转ASCii码
数据转ASCII码函数。。关于ASCII码的定义请参看度娘。/* 转ASCII码函数 */unsigned char CharToHex(unsigned char bHex) { if((bHex >= 0)&&(bHex 9)) { bHex += 0x30; } else if((bHex>=10)&&(bHe原创 2018-01-19 19:23:36 · 7945 阅读 · 0 评论 -
如何做bin文件升级以及数据定位——文件操作函数簇!
写在前面之前自己一直在做芯片上应用程序的升级功能,也就是所谓的Bootloader程序,当然,是Secondery Bootloader程序。在做芯片升级的BootLoader程序时,我的做法计较简单:一般是接收上位机下发的数据,判断数据协议是否正确,判断正确后将数据写入flash。可是,上位机是如何把数据打包发来的,如何按协议组数据帧,如何在一个bin文件中准确定位数据,自己却一致没有机原创 2018-01-08 18:56:34 · 2781 阅读 · 0 评论 -
16位CRC校验算法
CRC校验比较常用,本例校验算法异或0x1021.U16 u16CRCVerify (const U8 *pu8Data, U32 u32Len, U16 u16CRCInit){ U8 u8i; U32 u16CRC = u16CRCInit;原创 2018-01-18 18:46:21 · 3248 阅读 · 4 评论 -
数组拷贝
将一个数组的值拷贝到指定内存中。如已知数组A[3] = {0X01,0X02,0X03};现有数组B[3],希望B中元素与A中元素相同。则memcpy(B,A,sizeof(B));源代码:void *memcpy(void *d, void *s, U16 n){ U16 i; U8 *src = s; U8 *dest = d;原创 2018-01-18 14:09:38 · 309 阅读 · 0 评论 -
串口数据交换,实现串口合二为一
两个串口数据互相转发原创 2018-01-10 19:17:47 · 4740 阅读 · 0 评论 -
你真的了解栈溢出么?
记得之前看过一篇文章说,最好查的bug是语法错误,因为编译器会告诉你,最不好查的bug是栈溢出,因为啥,因为不仅编译器不会告诉你,连你自己有可能都找不到原因出在哪。经过了一段时间的摸索,算是基本搞清楚了栈溢出的原理,写下来以防日后出现问题无从下手。前言开发过单片机的同学应该不陌生这个名词,一般我们也说堆栈,其实这里有两个意思:一般我们说堆栈其实指的就是帧本身,而说堆指的就是堆。这是两个原创 2018-01-23 19:05:55 · 11609 阅读 · 1 评论 -
UCOSii 函数集
UCOSII 是一个可以基于 ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。为了提供最好的移植性能, UCOSII 最大程度上使用 ANSI C 语言进行开发,并且已经移植到近 40 多种处理器体系上,涵盖了从 8 位到 64 位各种 CPU(包括 DSP)。 UCOSII 是专门为...转载 2018-02-08 09:05:50 · 1001 阅读 · 0 评论 -
链表与内存--头节点的登场和链表分割
上篇写到了链表,后来发现自己对链表的理解还有些偏差,重新做了下链表测试,优化了相关代码。具体可参看前一篇文章链表与内存块。 主要改动的地方是:之前理解的链表为一个节点一个节点串联起来,后来查看资料,发现如果给链表增加一个空节点,使用起来会更加方便。也就是说,链表表头的第一个节点只有地址,没有实际数据,当然我们也可以给他填充上一些数据比如链表长度等。从第二个节点开始节点有了地址和数据,我们称第二个...原创 2018-04-02 18:22:07 · 333 阅读 · 2 评论 -
ucos任务栈大小计算,如何高效定义栈空间大小!
在使用ucos时,首先需要创建任务,但是如果单片机RAM空间有限的情况下,如何能确保创建的任务栈既能满足任务需求,又避免任务栈浪费呢?其实ucos在设计的时候,考虑到了这一点。ucos自带两个任务,其优先级分别为最低和次低,分别为IDLE任务和STATISTICS任务,其中STATISTICS任务便是可以统计各任务的CPU使用率,也就是任务栈使用情况,因此,我们可以借用该统计任务的函数来统计各...原创 2018-02-24 14:24:16 · 12085 阅读 · 7 评论 -
红外发送调制38K
首先需要知道,单片机通过串口输出红外信号的同时需要输出一个调制信号,一般为38K占空比为1:3的方波。 至于为什么是38k以及占空比为1:3可以百度更多资料。对于单片机使用SCTimer计数器输出38KPWM的时,需要注意几点限值:也就是清楚counter的时的值。触发电平变化的值,一般指在上升沿或者下降沿触发。下面以单片机主频30MHz,说一下这几个值的计算:限值原创 2018-01-24 19:19:38 · 8292 阅读 · 1 评论 -
红外发射(NEC)资料
概念和NEC协议:基本概念:GPIO:General Purpose Input Output (通用输入/输出) NEC:一种红外遥控器传输协议,由NEC开发. 从网上找到的概念图,很形象,借用一下。红外遥控通常是由发送端和接收端两个部分组成。发送端将要发送的二进制信号编码成一系列的脉冲信号,然后通过红外发射管发射红外信号。 接收端完成对红外信号的接收,放大,整形,并解调出转载 2018-01-24 19:27:37 · 3242 阅读 · 0 评论 -
ASCII码转16进制
ASCII码转16进制void Ascll2Hex(U8 *s1, U8 *s2, U16 len){ U8 Hex[] = {"0123456789ABCDEF"}; U8 DataL,DataH; U16 i; for(i = 0; i len; i++) { DataL = s2[i] &0x0F; DataH =原创 2018-01-19 19:25:21 · 6589 阅读 · 0 评论 -
uCOS信号量的等待机制
刚开始接触 uCOS 的同学有可能不了解信号量的意思,云里雾绕。其实说白了,信号量就是操作系统提供的一种数据通信方式,他相当于一把钥匙,可以在不同任务之间进行通信,告诉其他任务是否可以执行了。比如任务 A 满足一定的条件需要执行任务 B , 那么任务 A 可以在自己的任务函数中释放一个信号量,任务 B 等到这个信号量之后,便觉得有信号了,好,我可以运行了。 uCOS提供了以下几个信号量相关的...原创 2018-02-10 19:23:06 · 2030 阅读 · 0 评论 -
BCD转换成bin格式
BCD码BCD码在报文中传输时,可以理解为样子是16进制,但实质为BCD(二—十进制数)。例如一帧数据传输日期时,报文格式为 20 18 04 04 代表2018年04月04日,并不是16进制的(0x20 0x18 0x04 0x04),但是我们知道报文中的数据一般为16进制,在有些时候需要我们把这个BCD码转换成十六进制。关于如何判断是否为BCD码请参看之前的文章如何判断BCD码。转...原创 2018-04-04 18:33:57 · 5823 阅读 · 0 评论 -
什么是嵌入式
什么是嵌入式?关于这个问题,在自己刚找到第一份嵌入式软件工程师的工作之后,有一次在学校和师弟师妹们聊天,谈到自己的工作规划,有了以下的对话。 “师兄,你找的工作是什么方面的啊?” “嵌入式软件工程师” “啊?这么高端,是干什么的啊” “就是写写程序啥的” “哦”原创 2017-09-23 18:53:58 · 7835 阅读 · 1 评论 -
[教你警告消除]Warning[Pe1072]: a declaration cannot have a label!
在使用switch时在case 后面申请变量会出现 error: a declaration cannot have a label 的提示原因:Case statements are only ‘labels’. This means the compiler will interpret this as a jump directly to the label.The problem here原创 2017-10-18 16:00:14 · 4752 阅读 · 0 评论 -
从零学习嵌入式
从零学习嵌入式作为一个非科班出身,目前从事嵌入式软件编程的小菜鸟,本博客(专栏)将记录并分享自己从零开始学习嵌入式的经历。包括但不限于技术分享类博文、代码分享类博文、编程感悟类博文以及学习性博文。 也许有人问了,你写的东西有什么价值呢?我会说,有没有价值不知道,但是如果能够记录自己在学习以及工作中针对嵌入式编程所遇到的问题,并且能够给出一个系统的解决方案,我相信对自己还是有用的。 从零学习...原创 2017-09-23 15:44:57 · 731 阅读 · 2 评论 -
Cortex-M0的BOD中断及重启-掉电检测的可利用性+BOD汇编启动
Cortex-M0的BOD中断及重启-掉电检测的可利用性+BOD汇编启动原创 2017-10-12 09:35:24 · 2027 阅读 · 0 评论 -
基于ARM Cortex-M0+内核的bootloader程序升级原理及代码解析
本文主要讲述BootLoader程序升级原理及一些代码的解析,力图用通俗易懂的语言描述清楚BootLoader升级的主要关键点。BootLoader 升级原理概述首次接触这一块时,有一个概念叫IAP(在应用编程),通俗一点讲便是通过一段已有的程序(我们称之为BootLoader程序)去升级另外的一段程序(用户程序)。升级的方式多种多样,可以通过串口、USB、SPI等等多种接口去升级。实...原创 2017-10-29 14:02:26 · 13565 阅读 · 6 评论 -
IAR编译器如何节省代码占用的flash空间?
IAR编译器如何节省代码占用的flash空间最近一直在做一个项目,用的IAR的开发环境,芯片的空间flash大小是32kB。在做项目之前评估代码量感觉够用,因此切换平台时选用了32kB的M0+核芯片。可是代码不是你想多大就多大。 所以问题就来了,当芯片的flash空间不足以支撑你的代码量时,如何通过编译优化等等各种手段缩小代码的占用空间呢?常用的手段有以下几种: - 优化代码 - 尝...原创 2017-09-24 12:56:51 · 4934 阅读 · 2 评论 -
链表与内存块
项目原因从来没有接触过链表,今天花了半天的时间研究了下链表,发现用的是二级指针,又研究了下二级指针,编写了几个链表小程序,将收获整理如下。链表与内存块链表实际上就是把一块块的内存通过指针连接起来。这些内存有可能是在物理地址上连续的,也有可能是不连续的,不过这不重要,因为在链表中有指针把这些地址连接起来。所以我们可以把链表看成是多个内存块的连接,就如同一根绳上栓了好多蚂蚱,虽然蚂蚱本身没...原创 2018-03-29 18:48:54 · 1233 阅读 · 1 评论 -
结构体位域定义与#Pragam pack()
位域定义结构体时,有时会使用位域来定义变量,这样能够最大限度的节省内存空间。我们知道,一个字节占8位。如不使用位域定义,我们一般定义变量为: U8 addr; 这个变量占8位字节。取值范围为0-255,可如果我们定义的变量,取值范围达不到255的级别,那么8位的字节中许多bit位就浪费掉了。不要小看这几个bit位,在嵌入式系统中,尤其是硬件资源紧张的情况下,每一个bit都应该能发挥自己的作...原创 2018-03-13 18:43:59 · 1163 阅读 · 0 评论 -
通俗易懂的函数指针及函数指针数组
函数指针指针我们知道实际上是一个变量或者数组等的地址。如我们定义: void *Ptr; 该指针变量可以指向我们希望指向的地址,如我们有数组为a[2] = {0,1},那么我们可以通过给指针变量赋值,使其指向该数组Ptr = a;。 函数指针实际上和这种指针类似,只不过其变量类型是一个函数类型而已。如果觉得搞不明白,可以把函数类型理解为和int一样的数据类型。 如我们可以这样定义一个函...原创 2018-03-20 19:10:39 · 1859 阅读 · 3 评论 -
简单实用的数据加密方法
异或异或算法的好处便是数A和数B异或后,把结果再和数A异或便可得到B,或者和数B异或可重新得到数据A。利用异或的这个特性可简单实现数据的加密和解密算法。构建加密机加密加密机实际上便是异或中的其中一个数,可以根据自己的需要随意构建。例如我可以构建如下加密机: const int EncodeMachine[10] = {0x01,0x02,0x03,0x04,0x05,0x06,0...原创 2018-03-15 18:42:35 · 4414 阅读 · 0 评论 -
memmove和memcpy的区别
memmove和memcpy一样都是C语言自带的函数,可实现内存数据的移动,不同的是,memcpy在使用时有可能会出现内存重叠现象,导致数据移动错误,而memmove就是为了解决内存重叠而存在的。void *memcpy(void *dst, const void *src, size_t count); void *memmove(void *dst, const void *src, s...原创 2018-03-28 12:47:11 · 3679 阅读 · 3 评论 -
C语言反斜杠的用法
反斜杠 \在c语言中,反斜杠\一般用在语句换行或者宏定义中。 但是需要注意的是,语句换行的\加或者不加影响不大。 但是在宏定义时,如果多条语句,则必须加反斜杠,如 #define aa if (a>1) f = 0;\ else f=1; 则必须加反斜杠!...原创 2018-03-27 18:46:34 · 17347 阅读 · 0 评论 -
[教你警告消除]Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined。
在利用IAR进行编译的时候,经常会出现 Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement C:\Users\Administrator\Desktop\IAP_BootLoader\UART\UART.c 38 这种报警。其实这种报警很简单消除。他的原创 2017-09-26 17:31:12 · 13598 阅读 · 0 评论