【问题标题】:Reading Single Bit from a Char从字符中读取单个位
【发布时间】:2013-04-20 19:53:42
【问题描述】:

这是我在这里的第一篇文章,所以请原谅我做错了什么:) 这是我的情况。我正在使用 MPLAB 和 HI-Tech C 编译器为 PIC16F876 编写一个简单的数据传输操作。

我有一个名为 data 的字符,我想访问 data 中的位并将它们发送到 portB0,从 MSB 开始。

在汇编中我会简单地做:

PORTB,0 = data,7 // 获取 MSB 并将其放在端口 B0 上,然后我将对所有位执行此操作。

但是在 C 中这似乎更复杂。我做了一些研究,发现了一个有效的功能:

getBit(char data, int bitNumber)
{
     return (data & (1 << bitNumber-1)) != 0;
}

那我就用:

PORTBbits.RB0 = getBit(data,7);

这没关系,但是很乱而且似乎需要更长的时间,我不知道为什么我需要一个额外的功能......所以我的问题是:没有简单的方法来访问寄存器中的位吗?喜欢:

PORTBbits.RB0 = data,7

我不明白为什么编译器无论如何都不会将其转换为汇编??!!!!

提前致谢。 问候,蒂姆。

【问题讨论】:

  • 你可以在结构体中使用位域。但这可能会更糟。
  • 您好,感谢您的快速回复,Elazar,我确实尝试过,但是看到我想要的,最后,为数据发送编写一个循环这行不通,因为我不能循环一个名字。 Amigable:我看过那些(和其他)主题,我读到的那些似乎是针对 C 语言的。此外,问题的一部分是为什么没有一个简单的解决方案,因为该语言基于 ASM。
  • 大多数 C 编译器都允许您使用内联汇编。对于您的多位操作,您可能需要重复移位,并从 MSB 或 LSB 获取输出(取决于您想要的顺序)。

标签: c embedded pic


【解决方案1】:

另一种完成您所寻找的方法是这样的:

PORTBbits.RB0 = (data >> 7) & 1;

或更笼统地说:

#define BIT(x,n) (((x) >> (n)) & 1)
PORTBbits.RB0 = BIT(data, 7);

【讨论】:

  • 这个看起来不错,我试试,谢谢。仍然不知道为什么没有一个简单的选项可以直接访问寄存器中的元素,我认为 PIC 的 C 旨在简化事情......
  • 工作就像一个魅力,我想数据,7 Vs。 (data >> 7) & 1 在打字方面是相当接近的匹配。我仍然不明白为什么需要它...非常感谢您的帮助,我没有被允许投票,因为我没有代表,但这是我选择的答案:)。
【解决方案2】:

请记住,当您使用诸如此类的函数时,这意味着您要将两个值压入堆栈、执行跳转、执行操作、弹出堆栈并返回一个值。

您可以通过内联代码的 MACRO 绕过它

#define GETBIT(x,n) ((x >> (n-1)) & 1)

选项 #2 是使用内联 ASM,如果您喜欢自虐和尖叫以节省周期。 ~微笑~

【讨论】:

    【解决方案3】:

    如果您只需要这个位,您可以通过( data &amp; (1 &lt;&lt; (bitNumber-1)) ) != 0 获得。或者您可以定义一个宏以使其更具可读性

    #define getBit(x,y) ((x) & (1 << ((y)-1))) != 0
    

    并通过getBit(data,bitNumber)调用它

    宏将移除函数开销。但是没有运算符可以按照您想要的方式为您提供位值。

    【讨论】:

      【解决方案4】:

      一些(大多数?)微控制器有几个用于引脚的寄存器 - 如果您知道您将要做什么,那么(例如)写入 SET 或 CLEAR 引脚寄存器可以保存整个读取-modify-write/masking kerfuffle.

      您可能知道,但是为了清楚起见 - SET/CLEAR 寄存器仅通过在写入的位为 1 时设置或清除引脚来工作,如果写入 0,则引脚状态不会改变,这意味着硬件正在执行为你工作。要设置端口的引脚 3,您只需将 0x04 写入 port_SET 寄存器。要清除它,请将 0x04 写入 port_CLEAR 寄存器。

      并非总是可以使用这些,但如果可以的话,它会减少大量 CPU 周期。

      【讨论】:

        猜你喜欢
        • 2012-02-28
        • 1970-01-01
        • 2012-03-03
        • 1970-01-01
        • 2017-04-01
        • 2013-01-03
        • 2014-04-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多