我不明白你何时以及为什么要使用bitshift运算符进行微芯片编程:例如......
SWITCH_DDR &= ~SWITCH_BIT;
SWITCH_PORT |= SWITCH_BIT;
Run Code Online (Sandbox Code Playgroud)
为何使用这些运营商?
要么...
void SerialInit(void)
{
UBRRH = ((XTAL / (8 * 250000)) - 1)>>8; // 250kbps at 16Mhz
UBRRL = (XTAL / (8 * 250000)) - 1;
UCSRA = (1<<U2X);
UCSRB = (1<<TXEN);
UCSRC = (1<<URSEL) + (1<<UCSZ1) + (1<<UCSZ0);
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么???有人请用0和1来图解说明.或者这是另一个例子:
ulong MesureLC(void)
{
int i;
TCCR1B = 0;
CountHigh = 0;
TCNT1 = 0;
for (i=0;i<25000;i++)
{
TCCR1B = (1<<CS12) + (1<<CS11) + (1<<CS10); // WTF ???
UDR = 0x55;
while(!(UCSRA & (1<<UDRE)));
}
while(!(UCSRA & (1<<TXC)));
TCCR1B = 0;
CountLow = TCNT1;
Count = CountLow + (CountHigh << 16);
return Count;
}
Run Code Online (Sandbox Code Playgroud)
我需要了解这些东西.任何帮助表示赞赏.
pax*_*blo 17
我们会想到为什么要使用它们的原因有很多.
首先,有时微型控制器类型设备上的内存很紧,您可能希望尽可能少地存储.
此要求也可能是由于您与之交互的其他设备或软件具有相同的最小空间需求这一事实.他们可以使用子字节数据类型来完成工作,其中一个例子是TCP/IP头,其中字段的范围从单个位(例如DF字段)到更多(例如IP地址).
实际上,您提供的第二位代码SerialInit是为串行通信芯片(UART =通用异步接收器和发送器)设置属性.UCSRx通常代表UART控制/状态寄存器#x,因此您将信息写入相当低级别的设备以控制其行为.
另一个原因是您可能有内存映射I/O. 这意味着,虽然您认为自己正在写入内存,但您可能会将这些位直接发送到某种I/O设备.
一个典型的例子可能是使用存储器映射字节,其中七段LED被控制.
LED的结构可以是:
+---+---+---+---+---+---+---+---+
| d | e | g | f | a | b | c | p |
+---+---+---+---+---+---+---+---+
# # # # # # # #
# # # # # # # #===========#
# # # # # # # #
# # # # # # #===========# #
# # # # # # # #
# # # # # #===========# # #
# # # # # # # #
# # # # #=====# # # #
# # # # # # # #
# # # # +-------+ # # #
# # # # |aaaaaaa| # # #
# # # # +-+-------+-+ # # #
# # # # |f| |b| # # #
# # # #===|f| |b|===# # #
# # # |f| |b| # #
# # # +-+-------+-+ # #
# # #=========|ggggggg| # #
# # +-+-------+-+ # #
# # |e| |c| # #
# #===========|e| |c|=======# #
# |e| |c| #
# +-+-------+-+ +---+ #
#=================|ddddddd| |ppp|=====#
+-------+ +---+
其中七个段和点中的每一个都由不同的位控制.如果你想打开一个片段,同时保留其他片段,你可以使用像你的问题包含的位操作.
举例来说,打开g细分涉及以下操作:
mmap_byte |= 0x20; // binary 00100000
Run Code Online (Sandbox Code Playgroud)
关闭它涉及:
mmap_byte &= 0xdf; // binary 11011111
Run Code Online (Sandbox Code Playgroud)
您可能还会发现自己处于一个字节中的单个位或一组位控制完全不同的设备并且您不希望一个操作影响另一个的情况.
至于位运算符的作用,它们是处理多位值的运算符,但概念上一次一位:
暂时折扣这些变化,这些可以最好地描述为真值表.输入的可能性是在顶部和左,所得位是四个(两个不因为它仅具有一个输入的情况下),在两个输入的交点中示出的一个值.
AND | 0 1 OR | 0 1 XOR | 0 1 NOT | 0 1
----+----- ---+---- ----+---- ----+----
0 | 0 0 0 | 0 1 0 | 0 1 | 1 0
1 | 0 1 1 | 1 1 1 | 1 0
Run Code Online (Sandbox Code Playgroud)
一个例子是如果你只想要一个整数的低4位,你和它15(二进制1111),所以:
201: 1100 1001
AND 15: 0000 1111
------------------
IS 9 0000 1001
Run Code Online (Sandbox Code Playgroud)
另一个例子是,如果您要将两个4位值打包成8位值,则可以使用所有三个运算符(left-shift,and和or):
packed_val = ((val1 & 15) << 4) | (val2 & 15)
Run Code Online (Sandbox Code Playgroud)
& 15操作将确保两个值仅具有低4位.<< 4是一个4位移位,可以移动val1到8位值的前4位.|简单地结合了这两者结合起来.如果val1是7并且val2是4:
val1 val2
==== ====
& 15 (and) xxxx-0111 xxxx-0100 & 15
<< 4 (left) 0111-0000 |
| |
+-------+-------+
|
| (or) 0111-0100
Run Code Online (Sandbox Code Playgroud)
如果您具有可以启用或禁用的功能,则可以使用单个位来设置状态:1或0.这样,在1个字节中,您可以设置8个功能.
如果你需要存储值(比如从0到7),你只需要3位(二进制000,dec = 0,001 = 1,00 = 2,......,111 = 7).你还有8位中的5位免费.
这里发生了什么???有人请用0和1来图解说明
1 << 2 = 00000001 << 2 = 00000100 = 4
4 >> 2 = 00000100 >> 2 = 00000001 = 1
| 归档时间: |
|
| 查看次数: |
2296 次 |
| 最近记录: |