网站开发一般用什么数据库推广文案怎么写吸引人
特别有意思,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次,总延时约1msnum--; // 控制总延时次数}
}/* 位反转函数@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 */}}
}
效果展示: