这是我在这里的第一篇文章所以请原谅我做错了:) 这是我的情况。我正在使用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
我无法理解为什么不会因为编译器将其转换为汇编而无论如何?!!!!
提前致谢。 此致,蒂姆。
答案 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周期。