【问题标题】:8051 Controller port bit reading / writing8051 控制器端口位读/写
【发布时间】:2025-12-31 00:00:07
【问题描述】:

这个想法是从端口读取任何位。 无论如何访问一个已知位很简单,例如

P0_0 <-- gets bit 0 from port 0

但是如果我需要通过函数访问位 y?

read_bit(__bit y){
    return P0_y; // <-- just an idea but its not right becouse of syntax.
}

使用 SDCC 编程和 8051 标头。

【问题讨论】:

  • 在 c 中使用位检查。例如 return (P0&(1>chk_bit)&1)

标签: c port bit 8051 sdcc


【解决方案1】:

如果是字面常量,可以使用宏技巧:

#define READ_P0_BIT(BIT) (P0_ ## BIT)
unsigned x = READ_P0_BIT(1);

如果不是字面常量,你可以这样做:

int readP0bit(int bitNo)
{
    switch (bitNo)
    {
    case 0: return P0_0;
    case 1: return P0_1;
    // ...
    case 7: return P0_7;
    default: return 0;
    }
}

【讨论】:

    【解决方案2】:

    您可以创建一个包含函数中位的局部数组变量,并使用“位”作为该数组的索引。

    类似:

    __bit read_bit(const int b)
    {
        __bit all_bits[8] = {
            P0_0,
            P0_1,
            /* etc. */
            P0_7
        };
    
        return (b < 8 ? all_bits[b] : 0);
    }
    

    【讨论】:

    • 最有可能的是,P0_something 是一种特殊类型的硬接线标识符和一个硬编码位置,编译器知道如何访问它。您的代码很可能无法编译,但如果编译,它将读取硬件端口的所有位,这通常不是一件好事,因为读取硬件端口可能会产生副作用。您通常也不能指向此类端口位。
    • @AlexeyFrunze 是的,你是对的。这就是为什么我对你的答案投票。 :)
    【解决方案3】:

    看看这个函数

    char chek_bit_p0(unsigned char chk_bit){
     if((P0>>chk_bit) & 1)
        return 1;
     else 
        return 0;
    }
    

    或简单地通过如下宏(首选方式)

    #define chek_bit_p0(x) (((P0>>x)&1)&&1)
    

    【讨论】: