当前位置: 首页 > news >正文

硬件地址反序?用位操作为LED灯序“纠偏”。反转二进制数即可解决

特别有意思,LED的灯序与其硬件地址刚好相反,没办法直接通过加1实现二进制进位的亮灯操作,查了一些资料说用数组和switch实现,觉得太麻烦了,思索良久,就想到了反转二进制数解决这个问题。

reverse_bits( )是实现反转二进制数:

/* 位反转函数
   @param num 待反转的8位数据
   @return 返回位顺序反转后的数值 */
unsigned char reverse_bits(unsigned char num) {
    unsigned char reversed = 0;
    int i;
    for (i = 0; i < 8; i++) {               // 遍历每一位
        reversed |= ((num >> i) & 1) << (7 - i); // 将第i位移至对称位置
    }
    return reversed; // 例如:0b00000001 -> 0b10000000
}

 说明:

>>        将操作数的所有位向右移动指定的位数。       
<<        将操作数的所有位向左移动指定的位数。
&         对两个操作数的每一位执行逻辑与操作,如果两个相应的位都为 1,则结果为 1,否则为 0。(全1则1)
|          对两个操作数的每一位执行逻辑或操作,如果两个相应的位都为 0,则结果为0 ,否则为 1。(有1则1)

 以下代码是通过按键实现二进制进位的亮灯操作(STC89C52RC):

#include <REGX52.H>       // 包含8052单片机寄存器定义头文件
#include <INTRINS.H>      // 包含内联函数库(如_nop_())

/* 延时函数
   @param num 延时次数,次数越多总延时越长
   @11.0592MHz晶振下,每次循环约1ms */
void Delay(int num)        //@11.0592MHz
{
    while(num){
        unsigned char i, j;
        _nop_();          // 插入一个空指令周期(1.085us)
        i = 2;
        j = 199;
        do {               // 双重循环实现精确延时
            while (--j);   // 内层循环约0.5ms
        } while (--i);     // 外层循环2次,总延时约1ms
        num--;             // 控制总延时次数
    }
}

/* 位反转函数
   @param num 待反转的8位数据
   @return 返回位顺序反转后的数值 */
unsigned char reverse_bits(unsigned char num) {
    unsigned char reversed = 0;
    int i;
    for (i = 0; i < 8; i++) {               // 遍历每一位
        reversed |= ((num >> i) & 1) << (7 - i); // 将第i位移至对称位置
    }
    return reversed; // 例如:0b00000001 -> 0b10000000
}

/* 主函数:检测按键控制LED显示 */
void main() {
    //8051/52 系列单片机的寄存器是 8 位
    // 代码中 P2 端口驱动 8 个 LED,每个引脚对应 1 个 LED
    //通过 char 类型的位操作可以直接控制每个 LED 的状态:
    unsigned char num=0;          
    while(1) {                    // 主循环
        if (P3_1 == 0) {          // 检测P3.1引脚(如按键)是否按下(低电平)
            Delay(20);            // 延时20ms消抖
            while (P3_1 == 0);    // 等待按键释放(保持阻塞直到松开)
            Delay(20);            // 再次消抖
            num++;                
            P2=~(reverse_bits(num)); // 数值取反后发送到P2口驱动LED
            /* 执行流程:
               1. reverse_bits(num):将数值位反转
               2. ~:按位取反(因LED通常低电平点亮)
               示例:num=1(0x01) 
                     → 反转后0x80 
                     → 取反0x7F → P2.7引脚低电平点亮LED */
        }
    }
}

 效果展示:

相关文章:

  • TCP/IP协议中三次握手(Three-way Handshake)与四次挥手(Four-way Wave)
  • 2025年跨网文件交换系统推荐:安全的内外网文件传输系统Top10
  • 01-1 音视频知识学习(音频)
  • 【Java代码审计 | 第十四篇】MVC模型、项目结构、依赖管理及配置文件概念详解
  • 九、Prometheus 监控windows(外部)主机
  • How To Change Windows VPS Password
  • 【k8s001】K8s架构浅析
  • 网页制作16-Javascipt时间特效の设置D-DAY倒计时
  • 基于KL-ISODATA算法的电力负荷数据场景聚类matlab仿真
  • ElasticSearch组合查询及实际应用
  • 交换机控制软件的实现步骤猜测
  • 安装教程整理 docker linux 虚拟机
  • Podman 1panel中容器管理docker替换为Podman
  • Linux shell 进度条
  • Nerf较真系列
  • Mybatis3 批量执行操作
  • 豆包API的部署和实战|基于 Selenium 的抖音自动化评论系统开发实践
  • 算法题刷题方法记录(蓝桥杯、Leetcode)
  • 算法练习(链表)
  • linux——计算机内存详解通俗理解
  • 阿根廷发生5.6级地震,震源深度30公里
  • 《一鸣惊人》五一特别节目:以戏曲为桥梁,展现劳动者的坚守
  • 海警巡航时海豚围舰艇嬉戏,专家:证明海域生态环境持续向好
  • 神十九都带回了哪些实验样品?果蝇等生命类样品已交付科学家
  • 海南机场拟超23亿元收购美兰空港控股权,进一步聚焦机场主业
  • 武汉楼市新政:二孩、三孩家庭购买新房可分别享受6万元、12万元购房补贴