在 C 中重新定义寄存器位域的技巧
我正在努力想出一种干净的方法来重新定义一些寄存器位字段,以便在我正在使用的芯片上使用。
例如,CAN 配置寄存器之一的定义如下:
extern volatile near unsigned char BRGCON1;
extern volatile near struct {
unsigned BRP0:1;
unsigned BRP1:1;
unsigned BRP2:1;
unsigned BRP3:1;
unsigned BRP4:1;
unsigned BRP5:1;
unsigned SJW0:1;
unsigned SJW1:1;
} BRGCON1bits;
这些定义都没有多大帮助,因为我需要如下所示分配 BRP 和 SJW:
struct
{
unsigned BRP:6;
unsigned SJW:2;
} GoodBRGbits;
以下是我所做的两次尝试:
尝试 #1 :
union
{
byte Value;
struct
{
unsigned Prescaler:6;
unsigned SynchronizedJumpWidth:2;
};
} BaudRateConfig1 = {NULL};
BaudRateConfig1.Prescaler = 5;
BRGCON1 = BaudRateConfig1.Value;
尝试#2:
static volatile near struct
{
unsigned Prescaler:6;
unsigned SynchronizedJumpWidth:2;
} *BaudRateConfig1 = (volatile near void*)&BRGCON1;
BaudRateConfig1->Prescaler = 5;
是否有任何“更干净”的方法来完成我想做的事情?另外,我对尝试 #2 中铸造附近的不稳定感到有点恼火。是否有必要指定一个变量是near?
I am struggling trying to come up with a clean way to redefine some register bitfields to be usable on a chip I am working with.
For example, this is what one of the CAN configuration registers is defined as:
extern volatile near unsigned char BRGCON1;
extern volatile near struct {
unsigned BRP0:1;
unsigned BRP1:1;
unsigned BRP2:1;
unsigned BRP3:1;
unsigned BRP4:1;
unsigned BRP5:1;
unsigned SJW0:1;
unsigned SJW1:1;
} BRGCON1bits;
Neither of these definitions is all that helpful, as I need to assign the BRP and SJW like the following:
struct
{
unsigned BRP:6;
unsigned SJW:2;
} GoodBRGbits;
Here are two attempts that I have made:
Attempt #1:
union
{
byte Value;
struct
{
unsigned Prescaler:6;
unsigned SynchronizedJumpWidth:2;
};
} BaudRateConfig1 = {NULL};
BaudRateConfig1.Prescaler = 5;
BRGCON1 = BaudRateConfig1.Value;
Attempt #2:
static volatile near struct
{
unsigned Prescaler:6;
unsigned SynchronizedJumpWidth:2;
} *BaudRateConfig1 = (volatile near void*)&BRGCON1;
BaudRateConfig1->Prescaler = 5;
Are there any "cleaner" ways to accomplish what I am trying to do? Also I am slightly annoyed about the volatile near casting in Attempt #2. Is it necessary to specify a variable is near?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
就我个人而言,出于可移植性的原因,我尽量避免使用位字段。相反,我倾向于使用位掩码,以便我可以明确控制使用哪些位。
例如(假设位顺序正确)...
然后可以适当地生成掩码并分配或读取或测试值。您可以为宏选择更好的名称。
希望这有帮助。
Personally, I try to avoid using using bit fields for portability reasons. Instead, I tend to use bit masks so that I can explicitly control which bits are used.
For example (assuming the bit order is correct) ...
Masks can then be generated as appropriate and values assigned or read or tested. Better names for the macros can be picked by you.
Hope this helps.
我建议您不要将位域声明与硬件寄存器的寻址混淆。
您的联合/结构声明了位域的排列方式,然后在声明指向此类结构的指针时指定寻址和访问限制。
关于近/远,我假设默认值为近,除非指定远,除非您可以使用编译器开关将默认指针大小设置为远。
I suggest that you dont mix up the bitfield declaration with the adressing of the hardware register.
Your union/struct declares how the bitfields are arranged, then you specify addressing and access restrictions when declaring a pointer to such a structure.
Regarding near/far I assume that the default is near unless far is specified, unless you can set the default pointer size to far using compiler switches.