本文仅仅简单介绍了sbit、bit、sfr的使用。
sbit 用于定义 特殊功能寄存器(SFR) 中的某一位。SFR 是 8051 单片机中用于控制硬件资源的寄存器,例如 GPIO 端口、定时器、串口等。
sbit 变量名 = SFR地址^位号;
变量名:为某一位定义的别名。
SFR地址:特殊功能寄存器的地址。
位号:寄存器中的位编号(0 到 7)
作用范围:仅限于 SFR 的位可寻址部分。
存储位置:映射到 SFR 的某一位。
用途:用于控制 GPIO 引脚、访问 SFR 的某一位等。
#include
sbit LED = P1^0; // 定义 P1.0 为 LED
sbit KEY = P3^2; // 定义 P3.2 为按键
void main() {
while (1) {
if (KEY == 0) { // 检测按键是否按下(假设低电平有效)
LED = 0; // 点亮 LED
} else {
LED = 1; // 熄灭 LED
}
}
}
bit 用于定义普通的位变量。这些变量存储在 8051 单片机的 位寻址区(Bit-Addressable Area) 中。
bit 变量名;
变量名:位变量的名称。
作用范围:可以定义任意位变量。
存储位置:存储在 RAM 的位寻址区(地址范围为 0x20 到 0x2F,共 16 字节,128 位)。
用途:用于标志位、状态位等。
#include
bit flag = 0; // 定义一个位变量 flag
void main() {
while (1) {
if (P3^2 == 0) { // 检测按键是否按下
flag = 1; // 设置标志位
} else {
flag = 0; // 清除标志位
}
if (flag) { // 根据标志位控制 LED
P1^0 = 0; // 点亮 LED
} else {
P1^0 = 1; // 熄灭 LED
}
}
}
特性 sbit bit
用途 定义 SFR 中的某一位 定义普通的位变量
作用范围 仅限于 SFR 的位可寻址部分 可以定义任意位变量
存储位置 映射到 SFR 的某一位 存储在 RAM 的位寻址区
示例 sbit LED = P1^0; bit flag = 0;
以下是一个综合示例,展示 sbit 和 bit 的使用。
示例:按键控制 LED 状态
#include
sbit LED = P1^0; // 定义 P1.0 为 LED
sbit KEY = P3^2; // 定义 P3.2 为按键
bit keyPressed = 0; // 定义一个位变量,用于记录按键状态
void main() {
while (1) {
if (KEY == 0) { // 检测按键是否按下
if (!keyPressed) { // 如果按键之前未按下
LED = ~LED; // 切换 LED 状态
keyPressed = 1; // 设置按键状态为按下
}
} else {
keyPressed = 0; // 清除按键状态
}
}
}
仅适用于 SFR 的位可寻址部分(如 P0、P1、P2、P3、TCON 等)。
不是所有的 SFR 都支持位寻址。
8051 单片机的位寻址区只有 128 位(16 字节),因此 bit 变量的数量有限。
sbit 和 bit 是 Keil C51 编译器的扩展关键字,其他编译器可能不支持。
用于定义 SFR 中的某一位,适合控制 GPIO 引脚或访问 SFR 的某一位。
示例:sbit LED = P1^0;
用于定义普通的位变量,适合用作标志位或状态位。
示例:bit flag = 0;
通过合理使用 sbit 和 bit,可以更方便地操作 8051 单片机的硬件资源和实现逻辑控制。
sfr 寄存器名 = 地址;
寄存器名:为 SFR 定义的别名。
地址:SFR 的固定地址(0x80 到 0xFF)。
示例:
sfr P0 = 0x80; // 定义 P0 端口寄存器
sfr P1 = 0x90; // 定义 P1 端口寄存器
通过 sfr 可以直接访问 8051 单片机的硬件资源,如 GPIO 端口、定时器、串口等。
使用 sfr 定义的寄存器名比直接使用地址更直观,代码更易于理解和维护。
通过 sfr 可以直接操作寄存器,而不需要手动计算地址。
以下是一些常见的 SFR (特殊功能寄存器)及其地址:
寄存器名 地址 功能
P0 0x80 P0 端口寄存器
P1 0x90 P1 端口寄存器
P2 0xA0 P2 端口寄存器
P3 0xB0 P3 端口寄存器
TCON 0x88 定时器控制寄存器
TMOD 0x89 定时器模式寄存器
TH0 0x8C 定时器 0 高字节寄存器
TL0 0x8A 定时器 0 低字节寄存器
SCON 0x98 串口控制寄存器
SBUF 0x99 串口数据缓冲寄存器
#include
sfr P1 = 0x90; // 定义 P1 端口寄存器
void main() {
while (1) {
P1 = 0x55; // P1 端口输出 0x55(01010101)
Delay(50000); // 延时
P1 = 0xAA; // P1 端口输出 0xAA(10101010)
Delay(50000); // 延时
}
}
void Delay(uint ms) {
uint i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
#include
sfr TMOD = 0x89; // 定义定时器模式寄存器
sfr TH0 = 0x8C; // 定义定时器 0 高字节寄存器
sfr TL0 = 0x8A; // 定义定时器 0 低字节寄存器
sfr TCON = 0x88; // 定义定时器控制寄存器
void Timer0_Init() {
TMOD = 0x01; // 定时器 0 模式 1(16 位定时器)
TH0 = 0xFC; // 定时器初值高字节
TL0 = 0x18; // 定时器初值低字节
TCON = 0x10; // 启动定时器 0
}
void main() {
Timer0_Init();
while (1) {
if (TCON & 0x20) { // 检测定时器 0 溢出标志
TCON &= ~0x20; // 清除溢出标志
// 执行定时任务
}
}
}
#include
sfr SCON = 0x98; // 定义串口控制寄存器
sfr SBUF = 0x99; // 定义串口数据缓冲寄存器
void UART_Init() {
SCON = 0x50; // 串口模式 1,8 位数据,1 位停止位
TMOD = 0x20; // 定时器 1 模式 2(8 位自动重装)
TH1 = 0xFD; // 波特率 9600
TL1 = 0xFD;
TR1 = 1; // 启动定时器 1
ES = 1; // 使能串口中断
EA = 1; // 使能全局中断
}
void UART_SendByte(uchar byte) {
SBUF = byte; // 发送数据
while (!TI); // 等待发送完成
TI = 0; // 清除发送标志
}
void main() {
UART_Init();
UART_SendByte('A'); // 发送字符 'A'
while (1);
}
sfr 用于定义整个寄存器,而 sbit 用于定义寄存器中的某一位。两者可以结合使用。
示例:控制 GPIO 端口的某一位
#include
sfr P1 = 0x90; // 定义 P1 端口寄存器
sbit LED = P1^0; // 定义 P1.0 为 LED
void main() {
while (1) {
LED = 0; // 点亮 LED(假设低电平点亮)
Delay(50000); // 延时
LED = 1; // 熄灭 LED
Delay(50000); // 延时
}
}
void Delay(uint ms) {
uint i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
sfr 的地址必须在 0x80 到 0xFF 之间。
在 Keil C51 中,常用的 SFR 已经定义在头文件 reg52.h 中,无需手动定义。
sfr 是 Keil C51 编译器的扩展关键字,其他编译器可能不支持。
以上就是今天要讲的内容,本文仅仅简单介绍了sbit、bit、sfr的使用。