学习STC51单片机11(芯片为STC89C52RC)
越来越难了兄弟们,我们的脑子都扛起刺刀向前冲锋了!!
难就对了,舒服是留给死人的
按位操作
四个2进制数表示一位16进制数 0000 1111B(2进制) -> 0x0F(16进制)
8421法进制的转换(方便人类来看,对于计算机的底层来说,不关心机制010101010101)
配置寄存器推荐用按位操作,清零的时候,对应的需要清零的位与上0,不需要清0的位与上1
置1的时候,需要置1的位置或1,不需要置1的位置或0
1. 单片机底层确实只 "认识" 二进制
- 硬件实现:单片机的寄存器(如 TMOD)由触发器组成,每个触发器只能存储 0 或 1(即二进制)。
- 代码中的进制只是书写形式:
当你写 TMOD = 0x01; 时,编译器会将 0x01(十六进制)自动转换为 00000001(二进制),再写入寄存器。
例如:- 0x01(十六进制) = 1(十进制) = 00000001(二进制)
- 0x53(十六进制) = 83(十进制) = 01010011(二进制)
2. TMOD 寄存器的结构
- 高 4 位(D7~D4)控制定时器 T1:
GATE1 | C/T1 | M1_1 | M0_1
- 低 4 位(D3~D0)控制定时器 T0:
GATE0 | C/T0 | M1_0 | M0_0
3. 赋值过程的正确理解
当执行 TMOD = 0x01;(即二进制 00000001)时:
- 整体赋值:TMOD 的 8 位被一次性设置为 00000001。
- 高 4 位(T1 相关位):全部被清 0 → T1 的配置被重置。
- 低 4 位(T0 相关位):0001 → M1=0, M0=1 → T0 工作在 16 位模式。
注意:这种赋值方式会覆盖 T1 的原有配置,因此通常需要结合按位操作(如 TMOD |= 0x01;)来避免影响其他位。
4. 对比示例
- 错误写法(覆盖原有配置):
TMOD = 0x01; // 直接赋值,高4位(T1)被清0!
- 正确写法(仅修改 T0,保留 T1):
TMOD &= 0xF0; // 先清低4位(T0),保留高4位(T1)
TMOD |= 0x01; // 再设置低4位为 0001
5. 为什么用十六进制而不是二进制?
虽然单片机最终处理的是二进制,但代码中使用十六进制有两个原因:
- 书写简洁:
- 16 位二进制 1101110101001010 → 只需写成 0xDD4A(4 个字符)。
- 直观对应寄存器位:
- 十六进制的 1 位 = 二进制的 4 位,因此 0x53 可直接拆分为:
- 5(高 4 位) → 0101(对应 T1 的配置)
- 3(低 4 位) → 0011(对应 T0 的配置)
- 十六进制的 1 位 = 二进制的 4 位,因此 0x53 可直接拆分为:
总结
- 二进制是硬件的基础,但代码中使用十六进制是为了提高可读性和编程效率。
- 对 TMOD 的赋值是整体覆盖的,因此需谨慎使用按位操作来保护不需要修改的位。
- 十六进制与二进制的转换规则:
0xAB → 高4位 A(二进制 4位) + 低4位 B(二进制 4位)
例如:0x53 → 0101(高 4 位) + 0011(低 4 位)。
AUXR寄存器
这边提一下AUXR寄存器,这个寄存器的话主要就是对于一个电磁辐射对于时钟的影响,那么如果后期项目越做越大的话 发现单片机的时钟有点收到电磁辐射的影响,那么我们要记住有个寄存器可以进行管理减少电磁辐射的影响提高性能,目前我们小项目可以先不用加。
定时器控制LED启用中断版本
我们一般定时这边也要去封装一个函数,要保持好的习惯,所以我们的main函数里面就会那么简洁,main函数里面的while是不能去掉的,即使没有led2在里面也不能去掉,目的是为了程序的持续执行
中断的话我们这边TF0是 定时器0的中断控制位也是溢出标志位,当TF0为1的时候就是爆表了,爆表了就会去向cpu申请中断,然后就执行中断函数里面的代码。
硬件调用中断 中断的寄存器IE
之前用的定时器用的是查询法没有中断前 ,而且要手动清零