从字符中读取单个位

时间:2013-04-26 15:17:36

标签: c embedded pic

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

我有一个名为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

我无法理解为什么不会因为编译器将其转换为汇编而无论如何?!!!!

提前致谢。 此致,蒂姆。

4 个答案:

答案 0 :(得分:12)

完成你所寻找的东西的另一种方法是:

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

或者更一般地说:

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

答案 1 :(得分:3)

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

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

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

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

答案 2 :(得分:2)

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

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

并通过getBit(data,bitNumber)

进行调用

宏将删除函数开销。但是没有操作员可以按照你想要的方式给你比特值。

答案 3 :(得分:0)

有些(大多数?)微处理器有几个引脚寄存器 - 如果你知道你将要做什么,那么(例如)写入SET或CLEAR引脚寄存器会保存整个读取-modify-write / masking kerfuffle。

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

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