公众号文章同步阅读网址:www.netor0x86.com
闲话:没有眼光就是只盯着自己眼前的这点东西,连头都懒得抬一下,连听都懒得听进去一句话。渐渐成为了不是瞎子的瞎子,不是聋子的聋子,不是傻子的傻子……不!是傻子中的傻子!
关于定时器/计数器的内容已经算是了解了一些了,不过这里梳理一个关于 C 语言位运算的内容。对于接触过汇编、C 语言、以及系统底层的内容的话,其实对位运算不会陌生的。
0x01:回顾 STC-ISP 生成的初始化代码
在前面我们使用 STC-ISP 生成了一段初始化定时器/计时器相关的代码,代码如下:
代码语言:javascript复制void Timer0Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
上面的这段代码,和我们写的初始化的代码略有不同,看下我们的代码:
代码语言:javascript复制TMOD = 1;
TL0 = 0;
TH0 = 0xDC;
TR0 = 1;
从两段代码可以看出 TMOD 寄存器的赋值是有差别的。STC-ISP 生成的使用了 按位与 和 按位或 操作对 TMOD 进行了赋值;而我们的代码则直接使用的是赋值操作。
0x02:按位操作的意义
对于我们写的代码和 STC-ISP 生成的代码有何区别呢?对于我们的代码而言,没有啥区别。但是,对于 STC-ISP 生成的代码应该算是更标准化和工程化吧(这话说得很油腻啊!)。
按位与操作(就是 & 这个符号),很多语言都有这个运算符,意义也都一样。& 操作的特性是对指定位进行清 0,其他位保持不变。那 TMOD &= 0xF0 来说,这条语句是把 TMOD 的低 4 位清 0,高 4 位则保持不变。因为我们要使用 T0 定时器/计数器,使用 T0 需要设置 TMOD 的低 4 位,所以先给低 4 位清 0,然后再对低 4 位进行设置。而高 4 位是用来设置 T1 的,我们不使用 T1 ,所以让 T1 的设置保持不变。
按位或操作(就是 | 这个符号),很多语言也都有这个运算符。| 操作的特性是对指定位进行置位操作,而其余位保持不变。对于 TMOD |= 0x01 来说,这条语句是让 TMOD 的高 4 位保持不变,然后把最低位设置为 1。
很多时候一个字节是拆成很多个位来使用的,比如 TMOD 就是这样。在操作这些位的时候,就要尽可能地只操作我们需要操作的位,而其他我们不操作的位要保持不变。甚至在有些情况下要把整个字节或者标志位都保存了,操作后再进行恢复,以保持上下文环境不被我们的操作所破坏。
我是一个程序员,了解 C、PHP、Java、ASM、Python,有 信安、CISP 证书,写小白也能看得懂的文章,感谢关注!!!