当前位置: 首页 > 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 */
        }
    }
}

 效果展示:

http://www.dtcms.com/a/71819.html

相关文章:

  • 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——计算机内存详解通俗理解
  • 文本数据处理——最佳文本切分策略
  • 【开源免费】基于SpringBoot+Vue.JS电商应用系统(JAVA毕业设计)
  • 编程题《牛牛的链表删除》的python可以用非链表的方式
  • 射频前端模块(FEM)中的功率放大器(PA):关键作用与优化方法
  • 掌阅iReader全球首款 7 英寸 Carta 1300 墨水屏阅读器即将发布
  • 【TI MSPM0】GPIO学习
  • 五大基础算法——递归算法
  • AI软件栈:推理框架(二)-Llama CPP1
  • 软件需求分类、需求获取(高软46)
  • 【专栏预告】《VR 360°全景视频开发:从GoPro到Unity VR眼镜应用实战》