2

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

我有一个称为数据的字符,我想访问数据中的位并将它们发送到端口 B0,从 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

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

提前致谢。问候,蒂姆。

4

4 回答 4

12

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

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

或更笼统地说:

#define BIT(x,n) (((x) >> (n)) & 1)
PORTBbits.RB0 = BIT(data, 7);
于 2013-04-26T15:24:21.250 回答
3

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

你可以通过一个内联代码的 MACRO 来解决它

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

选项 #2 是使用内联 ASM,如果你被给予受虐狂和尖叫以节省周期。~微笑~

于 2013-04-26T15:21:26.307 回答
2

如果您只需要该位,则可以通过( data & (1 << (bitNumber-1)) ) != 0. 或者您可以定义一个宏以使其更具可读性

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

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

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

于 2013-04-26T15:23:04.943 回答
0

一些(大多数?)微控制器有几个用于引脚的寄存器——如果你知道你要做什么,那么(例如)写入 SET 或 CLEAR 引脚寄存器可以节省整个读取-修改-写入/屏蔽混乱。

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

并不总是可以使用这些,但如果可以的话,它会减少很多 CPU 周期。

于 2013-05-02T09:22:59.327 回答