当前位置:网站首页>初学ARM的个人心得
初学ARM的个人心得
2022-08-09 15:02:00 【翔在天上飞】
目录
1、判断寄存器某一位上的值是0还是1

UTRSTAT2是一个寄存器,寄存器往往要对位进行操作,这里就需要对该寄存器的第0位进行判断,判断是否这里的第0位为 1,如果是1,说明接收到了(其实UTRSTAT2这个寄存器的第0位是一个判断标志位)
while(!(UTRSTAT2&(1<<0)));
这句话我觉得设计的非常巧妙,借助这个while循环,既可以判断是否接收到了消息,又可以去阻塞地等待,直到接收到消息才跳出循环,进行后续的消息读取。
UTRSTAT2&(1<<0)
此处也可以通过改变偏移量,去检查其他的位。其检查原理如下:

通过移动1这个数,然后和原来的寄存器上的数据进行相与,可以确保其他的几个位置上都是0,由于和0相与都是0,所以不会影响到最终结果,其结果只与移动对应位置寄存器上的数据有关。
如果,这个位置上,寄存器的数据是1 ,则1与1是1,整体为真;
如果,这个位置上,寄存器的数据是0 ,则0与1是0,整体为假。
2、数据的移位操作
在操作硬件寄存器时,往往需要通过数值+一定的偏移量来对一个寄存器进行赋值,使用这种操作可以使得程序更加清晰,让他人知道当前操作的具体是寄存器的那一个位(通过移动的位数来判断)。
数据在硬件编程时,不管我们写的时候是以二进制、十进制还是十六进制,其最终都是以二进制补码的形式来的,所以,我们在进行移位操作时,移动多少位,移动的都是二进制数。
另,以右移为例,往右边移几位,就是在原二进制数后面补上几个0
3、volatile关键字
volatile关键字在设计到底层代码编程时,可以说是经常会被使用到
volatile是一个特征修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接通过所在的地址去读值,这样从事物的本源去取值,就不会出错。
volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
其实我们在编写程序时,所写的代码,编译器在执行的时候,不一定会按部就班的去执行,编译器会将一些步骤按照编译器的理解来优化,这种优化可能会导致某些步骤的缺失。
下面举个例子说明一下:
假设a、i均已经定义,且i是有值的。
这是我们所写的
while(1)
{
a = i;
}这是编译器优化后的
a = i;
while(1);编译器会认为,这里的值一直没有变化,不需要去一次次的赋值,赋值一次就够了。
当然,加上volatile就可避免编译器的这种优化。
4、一种调用寄存器极其方便的宏的写法
下面这种写法可以结合寄存器的初始化与赋值为一体,使程序更清晰,使用起来也更方便
#define reg_set(reg,h,l,val) (reg = reg & ~((1 << (h - l + 1) -1) << l) | (val << l))①reg是待操作的寄存器
②h是操作范围最高位
③l是操作范围最低位
④val是要写入的具体值
边栏推荐
猜你喜欢
随机推荐
ASCII码表
蒙特卡罗 Monte Carlo 模拟
【Postgraduate Work Weekly】(The third week)
聚集索引和非聚集索引
【Postgraduate Work Weekly】(Week 5)
数据拟合方法 MATLAB在数学建模中的应用(第二版)
Unity Shader零基础入门3:逐像素光照、Blinn-Phong、透明度
基于FTP协议的文件上传与下载
Janus介绍
GCC编译过程
使用libwebsockets搭建一个简单的websocket服务器
ACL配置
VRRP详解与配置实例
[Paper reading] LIME: Low-light Image Enhancement via Illumination Map Estimation (the most complete notes)
libev库解剖(1)
String的构造方法,其他方法
TOPSIS优劣解距离法
Heap series _0x04: Internal structure of heap (_HEAP=_HEAP_SEGMENT+_HEAP_ENTRY)
如何通过Photoshop根据纹理贴图轻松获得法线贴图
ping www.baidu.com虚拟机中ping百度









