原创 C语言应用基础

2023-10-9 13:46 1803 7 4 分类: MCU/ 嵌入式 文集: C语言

1、程序和内存

程序:数据+算法

内存的本质就是存储代码和数据的

数据和代码的存储方式不同,可分为冯诺依曼结构和哈佛结构

冯诺依曼结构:程序和数据存储在同一个存储器,二者共用一条传输总线

哈佛结构:将程序和数据分开存储,指令和数据存取可同时进行

单片机中将变量数据等存放在SRAM中,将程序存储到Flash中,常量通常存储在Flash中

内存管理

系统角度

无OS时:程序直接操作内存,编程这自己计算和安排内存,属于静态内存分配

有OS时:

静态内存分配:通过一些操作系统提供的接口分配内存

动态内存分配:程序运行时,需要随时分配,不需要时随时释放

语言角度

汇编语言:没有内存管理,直接操作内存地址

C语言:编译器管理内存,操作系统下,通过API访问内存

C++:对内存封装,使用new创建对象分配内存,delete删除对象释放内存,若new了未delete,则造成内存泄漏

C#/Java:不直接操作内存,通过虚拟机来操作内存;若申请内存未释放,虚拟机会帮助释放内存

寄存器、缓存、内存的关系

寄存器离CPU最近,接下来是缓存,最后是内存

CPU只与寄存器中进行存取,寄存器从内存读取数据,但由于寄存器和内存读取速度相差太大,所以产生了缓存

缓存:一级缓存和二级缓存Cache

内存

ROM:PROM,EPROM,EEPROM

SRAM

SRAM:数据存入后,掉电才数据才消失

DRAM:必须在一定时间内刷新才能保持存储的数据,比SRAM慢,比ROM快,比SRAM

寄存器(Register)是 CPU 中用于存储数据的单元,而寄存器是位于 CPU 内部的单元。


位,字节,半字,字的概念和内存位宽

CPU32位系统一般指数据线位32位,数据线越多一次传输处理的数据越多,性能越好

若要向内存写入一个数据,向控制总线传输写指令,地址总线上面传输内存地址,数据总线传输要写入内存的数据。

内存单位:GB、MB、KB、B、bit

CPU和内存之间的数据传送单位通常是一个字长,32位的系统一个字为4byte

stm32是32bit处理器,所以它的字是32bit的(一次处理4字节长度的数据)。半字自然就是16bit(2字节);

内存编址以字节为单位,一个内存单元就是一个字节,无论多少位内存都以字节位单位进行内存编址

数据类型占用字节大小

占用的大小由编译器决定

数据类型+*是指针类型,是地址,地址线为32位,则所有的该类型占8个字节

int a = 5; 若为32位系统,占4个字节,若内存地址从0x30000000,代表一个字节长度,分配了4个连续的地址

数据总线,地址总线,存储容量的关系

地址总线AB

一个cpu的N根地址总线,则可以说这个CPU的地址总线宽度为N。这样cpu最多可以寻址2的N次方个内存单元。

数据总线DB

8根数据总线传送一个8位二进制,数据线数量相当于每单元的位数

存储容量

存储容量=单元数*每单元的位数,一般每单元位数都是8

例子:若256KB的SRAM具有8条数据线,则他具有多少条地址线,存储容量多少

256KB = 2^18B 地址线为18条,8位则数据线8条,存储容量256KB*8

管理内存---数组、结构体、栈、堆

数组

数组定义就是在内存开辟一块连续的内存空间,数组明就是开辟的内存空间的首地址

数组所有元素类型相同,数组大小在定义时给出,数组空间是连续的

结构体

解决数组中所有元素类型必须相同的问题

结构体变量名代表的是整个结构体变量,结构体定义后,编译器会为所有成员分配空间

结构体内嵌指针实现面向对象

保存局部变量(非静态局部变量)

只有一个口,先进后出

局部变量自动完成入栈,自动分配内存,出栈

函数退出的时候局部变量就会被释放,所以不能返回局部变量地址

栈保存在函数调用所需的所有维护信息

局部变量值未初始化时,值是随机的,因为栈内存是反复使用的

栈是有大小的,栈的大小是可以设置的,但定义局部变量时不能太大,避免栈的一处

容量不限,动态分配;申请和释放都需要手工进行

堆内存申请函数:malloc, calloc, realloc

堆内存申请需要给定大小,申请完成则空间大小不变

动态申请的数据存储在堆中

静态存储区

静态局部变量和全局变量存储在静态存储区

静态存储区的大小在编译时就确定了,随程序运行而分配空间,程序运行结束才释放内存空间


2、C语言位操作

常用操作符

按位与&,逻辑与 &&

位或 |,逻辑或 ||

位取反 ~ ,逻辑非!

位异或 ^

左移位

将一个数转为二进制,左移若干位,左移出的丢弃,右边补零

x >> n = x * 2^n;

右移位

将各二进制位全部右移若干位,左边二进制位补0或补1(若操作数是无符号数或有符号正数就补0,若为有符号负数就补1),右边的二进制位丢弃

对寄存器位操作

清零

&= 十六进制数,要清零的位设置为0,其他位设置为1

REG1 &= 0XFFFF00FF //将bit8~bit15清零,其他位不变

置一

|= 十六进制数,要置位的数设置为1,其他位设置为0

REG1 |= 0X0000FF00 //将bit8~bit15置1,其他位不变

位取反

^= 十六进制数,要取反的位设置为1,其他位设置为0

REG1 ^= 0x0000FF00 //将bit8~bit15置取反,其他位不变

若REG1 = 0xAAAAAAAA ,将bit8~bit15取反后,得到REG1 = 0xAAAA55AA

移位构建特定二进制数

移位来构造二进制

设置bit3~bit7和bit23~bit25位为1

结合位取反获取特定位位0的二进制数

宏定义完成位运算

宏定义来置位

定义一个32位二进制数x的第n位置1(右边算起,bit0算第一位)

宏定义清除某位

定义一个32位二进制数x的第n位清零(右边算起,bit0算第一位)

作者: light, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-4056283.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论1条评论)

登录后参与讨论

开发工匠 2023-10-12 08:49

写的好,参考和学 习
相关推荐阅读
light 2023-10-18 10:57
C语言--指针和函数
指针和函数   1、  用指针传递数据,函数可以修改数据 采用swap函数,指针传递数据,实现数据交换,传递指针,则数据能被修改   ...
light 2023-10-04 22:51
电路基础知识
《实例解读模拟电子技术》记录1、电源(power supply)是向电路提供电能的装置 电源的额定电压不可以随意选择 原电池(不能充电的电池)电压值为1.5的整数倍:1.5V 3V&nb...
light 2023-09-05 17:05
linux命令行
如果提示符的最后一个字符是“#”, 而不是“$”, 那么这个终端会话就有超级用户权限。 1、简单命令:     日期,时间:date  cal ...
light 2023-09-04 10:46
STM32通信
一、什么是同步/异步通信?   同步通信:一方发送,另一方应答,否则不进行下一次传输(带时钟同步信号传输)。   异步通信:一方发送,不考虑另一方是否收到,直接进行...
light 2023-09-01 15:35
STM32存储
存储器 1G=1024M     1M=1024K    1K(B)=1024Byte(字节)  &n...
我要评论
1
7
关闭 站长推荐上一条 /2 下一条