- 博客(31)
- 收藏
- 关注
原创 C语言认识
人与计算机交流是计算机语言,C语言,C++,java等;买了台电脑,电脑是硬件,只有装操作系统,才能操作它之间有驱动层,调佣驱动层来驱动。操作系统,windows。linux.mac.在系统上你可以装软件,比如QQ,微信。应用软件及之上是上层,操作系统及之下是下层(底层)
2025-03-23 19:25:45
213
原创 【初始C语言】转义字符
转义字符转变字符的意思,n加\后他的意思就变了,就会变成换行符加了\和没加\的区别\n有换行的作用,转义字符\0是字符串的结束标志,所以\0是转义字符C语言规定的转义的字符。
2025-03-18 21:39:07
326
原创 SysTicK定时器
前面的delay我们是通过while来占用CPU的执行时间来达到一个延时的功能·,但是这个延时是不准确的这个定时器也叫滴答定时器systick是一个24位的向下递减的定时器他的时间是我们系统时钟的 倒数,比如我们的时钟是168mhz,那么我们的计数(每进入一次定时器)那么就是168/1ms滴答定时器计数,首先知道自己的时钟频率168mhz,168再/8得到21然后进入cortex系统那么他的计数就是1/21ms这个时间要使用定时器你必须打开这个使能位当定时器数到了0这个位就会置一。
2024-09-26 17:09:33
481
原创 使用库函数点亮一个LED灯
接着我们就要使能Gpio的时钟,使能之后对GPIO相关的参数,比如说工作模式,管脚输出方向,输出的速度怎么样,最后点亮LED灯。这样写便于移植,这些东西都是放在LED文件下的,如果你到时候换个版,你在这里修改引脚,到时候全部就可以用了,就不用改那么多了。在我们的主函数那里有很多初始化定义时钟的配置,还在关键字的重定义,这样子的主函数就会特别多东西。输出引脚高低电平的函数,第一个参数是他引脚的端口,第二个是他的引脚,第三个是高低电平。是想看看这个有没有被定义,没有的话就执行了下面的程序,
2024-09-22 11:35:14
666
原创 库函数模块创建
创建这个文件,这个文件是用来存放我们编译生成的一些中间文件,C,汇编,链接的一些列表清单,调试信息,以及需要我们下载到单片机的hex文件。在我们的固件库里面他会识别你的宏有没有定义,来决定你的这些文件有没有编译。这个存放我们stm32的一些库,以及我们CMSIS标准的一些文件。创建这个工程模版,是为了我们后面免去我们后面创建工程模版的步骤。给你的文件夹改名字,然后存放·他的一些文件,这些就会好辨认。比如main.c,stm32的头文件和配置文件,中断文件。hal_driver是存放HAL的一些驱动文件。
2024-09-21 20:42:49
844
原创 STM32固件库介绍
早期的标准库叫STD不管是hal库还是标准库都是封好库然后给我们使用的标准库可能兼容不了F1 F4 F7但是用HAL库就能够兼容那么多我们可以用cubex来配置一个工程固件库文件夹介绍CMSIS的启动文件,RTOS实时操作系统文件外设驱动文件Inc外设的头文件头文件对应的.C文件芯片厂商相关的文件DSP存放着DSP函数的原文件,以及ST提供的一些规范的代码include文件夹里面是一些内核相关的文件这个lib的DSP的函数库文件,已经是打包好的这个实时系统的一些头文件。
2024-09-20 13:58:18
418
原创 存储器与寄存器
我们把每个单元的功能作为名,给这个内存取个别名,这个别名就是我们·所说的寄存器,然后我们通过C语言指针操作这些寄存器即可,什么是寄存器映射呢,就是给已经分配好地址的特定的内存单元再去一个名字的过程就叫寄存器映射我们的内存单元大小固定是4个字节我们想要对内存区单元进行操作,其实就是对这个地址进行操作,你每次都要操作的话那么就要写一个很长的地址,所以我们要对这个内存取一个别名,这个别名就是寄存器,有了这个寄存器,那我们就可以用C语言的指针进行操作,寄存器映射就是对这个寄存器取别名的过程就是寄存器映射。
2024-09-16 18:12:19
516
原创 IAR常见的快捷键
Ctrl+Shift+K 去除所选区域的注释,所选区域必须是全被注释掉的.Ctrl+B 智能选择光标所在括弧内的区域,多次使用可选更大的区域。CTRL+SHIFT+K 取消快注释,取消屏蔽选中的代码;*Ctrl+Shift+V 列出剪切板中所有的字符串供选择粘贴。Ctrl+Shift+F 在文件中搜索。*Ctrl+Shift+4 关闭除当前激活外的所有文件。*Ctrl+F 向下寻找光标所在处的单词。
2024-08-21 09:08:47
880
原创 变量和常量(局部变量和全局变量)
常变的值叫变量,不变的值叫常量变量分为局部变量和全局变量在同一范围内,变量只能定义一次,否则就会报错全部变量和局部变量是可以同时存在的,不过使用的时候是局部优先变量如果你不给他初始化,那么他放得就是一个随机值,到时候你给他加加减减,你自己都不知道会变成什么而且你不初始化,编译器就会出警告如果想继续用scanf,需要在头文件前面加上报错警告要求你添加的头文件以后想彻底解决这种问题。
2024-07-11 10:38:32
416
原创 操作符详解(2)
如果你想得到整数,那么两边必须是整数,如果你想得到浮点数,那么你的操作数的两端必须有一个是浮点数。按位与,与的是他们的补码, 与的规则是两个都为真,才输出真(1),否则输出假(0)111111111111111111111111111111111011 (补码)111111111111111111111111111111111011 (补码)111111111111111111111111111111111011 (补码)%d打印的是原码,所以我们要把补码换算成原码。
2024-06-15 13:38:09
1056
原创 操作符详解(1)
0000 0000 0000 0000 0000 0000 0000 0011 移位移成这样,不管采用逻辑移位还是算术移位都是补0。0000 0000 0000 0000 0000 0000 0000 0111(补码)0000 0000 0000 0000 0000 0000 0000 0111 原码。0000 0000 0000 0000 0000 0000 0000 0111 反码。0000 0000 0000 0000 0000 0000 0000 0111 补码。
2024-06-15 11:04:35
780
原创 预处理(下)
注意宏是要替换的,传过去的5+1相当于5+1*5+1(宏的话是要和括号靠在一起的,就是SQUARE后面不能有个括号,宏里面的参数是到时候是会替换宏体的)在调用宏时,首先要对参数进行检查,看看是否包含#define定义的符号,如果是,那么首先将他们替换。宏体内的参数是可以出现其他宏定义的符号的,但是宏是不能递归的,不可能做到自己调用自己。第二种是带副作用的,a的话在赋值的时候是会改变值的,所以这就是有带有副作用的参数。宏的话是没办法调试的,宏的话在预编译的时候就已经是替换完了,你根本看不到他调试。
2024-06-12 22:48:04
2020
原创 指针和指针类型
在32位的机器上,地址是32个0或1组成二进制序列,那地址就得用4个字节来存储,所以一个指针变量是4个字节,那如果是在64位的机器上,有64根地址线,那一个指针变量是8个字节,才能存放1个地址。总结:指针就是地址,口头中说的指针其实说的是指针变量,指针变量是变量,指针变量是用来存放地址的一个变量,内存单元的地址是不需要存起来的,都是系统的硬件自动生成的。地址是怎么产生的,通过32位的机器,这个机器有32根地址线,每根地址都会在通电产生电信号,而他们产生的电信号,二进制序列就是我们通过物理的电信所转换的。
2024-06-10 08:55:50
490
原创 指针和数组
有3个指针,中间是一个数组arr,有个指针指向中间,其他两个指向两边,一个指向前面,一个人指向后面。虽然简化好,但是我们C语言要求是不允许这样写的,虽然大部分编译器是可以允许我这样写的。下面那个用数组名也是可以用的,因为他也表示一个地址,加1就会找后面那个元素的地址。我们C语言编译器中说指针允许往后比较大小,但不允许往前比面的指针比较大小。地址向后移,指针相比较,指针减减就是减去一个整数。同一指针相减的绝对值得到的是之间元素的个数。数组和指针的地址是一样的,说明是可以的。地址加地址,指针加指针没有意义。
2024-06-10 08:52:12
500
原创 结构体作业讲解
如果用unsigned 然后你的数字是负数的话,你那个负数就会被编译器变成补码,负数的补码是32个·1。b=++a是一个表达式,c++是一个表达式 ,++a是一个表达式, a++是一个表达式。C语言scanf返回值读成功就返回数的个数,不成功呢就返回EOF。两个数,一个是有符号,另一个无符号,那么有符号就会转换成无符号。局部变量,放在栈区,不初始化,默认值是随机值。逗号表达式的优先级是最低的,先赋值。全局变量,静态变量都是放在静态区的。&&和||是真就为1 假的话为0。输出二进位偶数和奇数。
2024-06-10 08:50:59
419
原创 结构体(上)
printe2的我们的aa是实参传给了pp形参,形参pp是实参的一份内存拷贝。结构是一些指的集合,这些值称为成员变量,结构的每个成员可以是不同的成员变量。这里我们拿到的是结构体的对象(变量)所以用点.如果是地址就要用到箭头了。我们把结构体的地址传过去 pp是指向结构体的指针,箭头可以找到他的成员。当然下面的结构体是依赖上面的结构体的,如果没有上面的结构体是不能过的。struct是结构的关键字,tag是结构体的标签。右边是我们的房子,图纸创建了,才能盖我们的·房子。像人的话身高对象,书的话作者出版社书号。
2024-06-09 21:45:03
353
原创 结构体内存对齐
然后我们就要找对齐数了,对齐数就是本身的字节数和编译器默认的对齐数,因为vs对应得对齐数是8,但是我们对齐数取最小的,所以对齐数就是4了。因为我们还有个规则,3个对齐数中对齐数最大就是4了,我们结构体的内存是最大对齐数的整数倍,但是我们才9,所以我们就加到12个。按照上面内存要是成员的对齐数的整数倍,我不是算了吗,为什么答案是12。为什么存在内存对齐,因为你如果不按照对齐数来对齐,那么就会取不出数据。对齐数是4那么就要在偏移量是4的倍数的值才能开始算值。因为我们的结构体内存是最大对齐数的整数倍、
2024-06-09 21:35:22
402
原创 数据存储(浮点数)
无符号数减去无符号就会得到一个很大的数,所以输出大于,当一个有符号数和无符号数在相加相减时,有符号数会向无符号数转换。为什么我这里的i定义成无符号整形后,i--到-1就是个很大的数了,就一直循环下去。右边圆环从0开始,加到128,因为char 是7个字节,2的7次方就是128值,第4行因为有符号数,是char,,所以截8位,然后有符号数就前面就补0。站在i的角度他是不承人符号数的,就是认为符号数等于1。strlen遇到\0之前的长度,-1到-128,如果是-128你再-1,他就是0。
2024-06-08 13:03:53
288
原创 数据存储(整形存储)
放32个bit位,,所以就成了上面的第一个,然后,我们要变成补码,才能放到内存里面,然后因为我们要存到char里面,所以直接截断前面8个,因为我们打印要%d,所以我们要整形提升,所以全加1,变成32位的bit位,因为刚才已经放的补码,我们打印出来是原码,所以我们取反加1,就得到-1。求取值范围,就要原码,因正数原反补相同,所以直接算,负数的话(符号位不变)然后取反加1.得出原码,如果负数的补码是10000000,没有原码,直接规定·就是128。首先-1是一个整形类型的,所以在内存中。
2024-06-08 13:02:34
210
原创 预处理(2)
刚才讲了text.c预编译成了text.i,然后编译成立text.o,然后汇编编译成立.o文件链接有两个步骤1.合并段表2.符号表的合并和重定位我们汇编生成add.o文件和test.o文件(都是二进制格式)我们刚才用的viscode是Linux格式一种文件都有自己的特殊格式前方纺放啥,后面放啥都有自己的格式上面汇编生成的文件,是Linux elf格式他会把add,o文件的数据分成几种段每一个段放他对应的属性的数据我们接下来要把这几个文件add.otest.o链接库。
2024-06-06 10:13:44
2325
原创 程序环境和预处理(1)
链接库是什么东西 比如我们写了printf你这时候就得包含别人的头文件把,你的头文件涉及到的那些依赖的库,也得是一个库文件提供给你的,你把他编译到我们的程序才能运行,否则是运行不了的,我们库函数所需要的东西,就会在我们的链接库所提供,然后链接到我们的可执行的程序里面,总之就是除了我们自己的实现的东西之外,我们编译器提供的一些东西。这说明了我们在预处理的时候会别人的头文件里面的东西,包含到我们的代码里面,才能使用那些库函数。2.注释的删除,编译器是不管注释的,直接删除,注释是给程序员看的。
2024-06-05 20:19:17
603
原创 offsetof宏的讲解
C2默认对齐数是8,本身是1个字节,取一个较小值为对齐数就是1,1要放在内存中,我们的C2必须要是1的倍数才能放在内存中。ww的大小是4,默认对齐数是8,取一个较小值为对齐数就是4,4要放在内存中,我们的ww必须要是4的倍数才能放在内存中。这个函数可以用来计算偏移位置就是偏移量,偏移量就是这个变量的内存空间起始位置相当于结构体开辟的位置的距离的大小。我们结构体的总大小,是总大对齐数的整数倍,我们对齐数最大就是4,所以我们就浪费了3个字节到12个字节。我们的计算i相较于起始位置的偏移量是4。
2024-06-05 16:49:09
363
原创 CC2530工程文件打不开问题
这时候就差这个错误,注意看到是.c的文件就要先remove他在工程的文件,然后就开一个新的。看到我的蓝色的区域没,把他复制粘贴然后放在路径区。下面这个就是添加路径的地方,需要添加正确的路径。c的文件到新的文件,然后添加进去工程。比如我们这个,现在我添加他的路径。h的文件,然后点击属性。这时候我们需要改路径才能不报错。
2024-06-05 15:33:03
369
原创 关键字的学习
而我们刚才前面讲到static用来修饰a,出了作用域是没有销毁的,其实这个a是被static修饰后,是放在了静态区,变成了静态变量,放在静态区的变量,出了作用域是不销毁的,那么什么时候销毁,是这个程序结束了,程序的生命周期结束了,他才销毁。在程序编译的时候,这条初始化的代码是不参与执行的,在编译时就创建好了,static int a=1,没有对应的汇编代码,当他汇编编译时会跳过那条初始化的语句,也就是说他永远只使用第一次创建好的a,再++;
2024-06-05 15:30:56
1597
原创 枚举的学习
我们给枚举里面先把星期的未来可能都列出来,而未来我要给枚举变量赋值的时候就可以直接引用他里面的常量。当你写好test.c 要经过编译经过链接,然后生成exe的文件,编译之前会进行预处理,预处理时。枚举常量是不能修改的,我们在这里只是给他赋值了个初始值。枚举有类型,枚举本身是一种类型,而宏定义是没有类型的。结构体里面的是有类型的变量,枚举里面的是枚举的常量。警号#define 是怎么工作的,是要完成替换的。是类型是图纸是模版是不会占任何空间的。枚举有类型检查,但在C语言体现的不深。stu是结构体的标签。
2024-06-04 18:42:11
241
原创 动态内存管理
当我们要开辟多少个字节时,就往malloc里面写多少个字节,比如我们要开辟40个·字节的空间,就直接写40,开辟好了空间之后,就要返回这个空间的起始地址,哎呀但是为什么返回的地址是无符号的呢,因为你开辟这个空间,你可能想好了这个空间以后是用来干什么的,但是这个函数是不知道你想干什么的,所以他返回的无符号,并且如果你想用来开辟char和int都可以。有时候我们申请的空间太小了,不够用,有时候我们申请的空间太大了,浪费了,为了合理的使用的内存,所以我们出现了这个函数。
2024-06-04 16:11:43
791
原创 字符串的学习
然后我们创建一个while循环,把src赋值给dest,然后把dest和src强转为char的指针类型,这样子后,然后用星号取他的地址对应的值,一个个取,然后dest等于他本身的地址加1,src也是,这样子就可以,一个字符一个字符的值慢慢拷贝就不会有什么多余的bug了。地址被覆盖,因为你在3时,你拷贝1过去,这时候3的地址就变成1的,就是说你从原本的3那里往后数3个数,这时候你取的第3个数的地址已经变成1的了。他们比较的时候是一个一个字符比较的,一个一个比较ASCII码值的,比的是谁的值大。
2024-06-04 07:30:47
844
原创 联合(共用体)
取地址,把他变成char类型的指针,就可以一个一个字节,然后用*号取他第一个地址对应的值,如果是1就是小端和0的话就是大端。返回的是第一个字节,u.i是4个字节往整形放1个1,因为char c 和int i是同用1个空间返回1个字节。这里并不是说是等价,只是让我们更好的去理解,把arr【5】想成5个char字符的变量去对待他们的对齐数都是1。因为char是5但其实char 就是1个字节,他的对齐数是1,int i 他的对齐数是4个字节。这些c1到c5都是i的第一个字节,他们都是1个1个的成员。
2024-06-03 21:39:59
306
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人