i2creg = I2C_FLAG >> 28作用

右移 28 位的操作用于确定标志位属于 SR1 寄存器还是 SR2 寄存器。这个技巧的背景是寄存器标志位的掩码值在位掩码定义中已经进行了编码,其中高 4 位(即右移 28 位后的结果)指示了标志位属于哪个寄存器。下面是详细解释:

标志位和寄存器的映射
在你提供的寄存器标志定义中,标志位被分配到两个不同的寄存器:

SR1 寄存器:包含如 I2C_FLAG_SMBALERT、I2C_FLAG_TIMEOUT 等标志。
SR2 寄存器:包含如 I2C_FLAG_DUALF、I2C_FLAG_SMBHOST 等标志。
在这些定义中,标志位的掩码值通常具有不同的位位置,这些位位置能够指示标志位是来自 SR1 还是 SR2。例如:

/* SR1 register flags */
#define I2C_FLAG_SMBALERT                                    ((uint32_t)0x10008000)
#define I2C_FLAG_TIMEOUT                                     ((uint32_t)0x10004000)
#define I2C_FLAG_PECERR                                      ((uint32_t)0x10001000)
#define I2C_FLAG_OVR                                         ((uint32_t)0x10000800)
#define I2C_FLAG_AF                                          ((uint32_t)0x10000400)
#define I2C_FLAG_ARLO                                        ((uint32_t)0x10000200)
#define I2C_FLAG_BERR                                        ((uint32_t)0x10000100)
#define I2C_FLAG_TXE                                         ((uint32_t)0x10000080)
#define I2C_FLAG_RXNE                                        ((uint32_t)0x10000040)
#define I2C_FLAG_STOPF                                       ((uint32_t)0x10000010)
#define I2C_FLAG_ADD10                                       ((uint32_t)0x10000008)
#define I2C_FLAG_BTF                                         ((uint32_t)0x10000004)
#define I2C_FLAG_ADDR                                        ((uint32_t)0x10000002)
#define I2C_FLAG_SB                                          ((uint32_t)0x10000001)

/* SR2 register flags */
#define I2C_FLAG_DUALF                                       ((uint32_t)0x00800000)
#define I2C_FLAG_SMBHOST                                     ((uint32_t)0x00400000)
#define I2C_FLAG_SMBDEFAULT                                  ((uint32_t)0x00200000)
#define I2C_FLAG_GENCALL                                     ((uint32_t)0x00100000)
#define I2C_FLAG_TRA                                         ((uint32_t)0x00040000)
#define I2C_FLAG_BUSY                                        ((uint32_t)0x00020000)
#define I2C_FLAG_MSL                                         ((uint32_t)0x00010000)

右移 28 位的原理

通过右移 28 位,你可以确定一个标志位的高 4 位。这些高 4 位用于区分标志位所属的寄存器。例如: • 如果高 4 位是 `0x1`,标志位属于 `SR1`。 • 如果高 4 位是 `0x0`,标志位属于 `SR2`。  这个逻辑是基于以下几个假设: 1. 标志位掩码 在 `SR1` 和 `SR2` 寄存器的位定义中具有不同的高位模式。 2. 寄存器偏移:`SR1` 和 `SR2` 寄存器的地址偏移量不同,这使得你可以通过计算寄存器地址来确定标志位的寄存器。  

示例

假设 `I2C_FLAG` 是 `0x10000040`,这意味着标志位属于 `SR1` 寄存器。

uint32_t i2creg = I2C_FLAG >> 28; // 右移 28 位
// i2creg = 0x1,表明标志位属于 SR1 寄存器

反之,假设 I2C_FLAG0x00800000,这意味着标志位属于 SR2 寄存器。

uint32_t i2creg = I2C_FLAG >> 28; // 右移 28 位
// i2creg = 0x0,表明标志位属于 SR2 寄存器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值