我正在为微控制器编写自己的库(头文件)。我想访问以下示例中的元素。我该如何实现?
myLibrary.h:
#include <stdint.h>
struct PWR_CR_tag {
union {
uint32_t R;
struct {
uint32_t VOS:1;
uint32_t FPDS:1;
uint32_t DBP:1;
uint32_t PLS:3;
uint32_t PVDE:1;
uint32_t CSBF:1;
uint32_t CWUF:1;
uint32_t PDDS:1;
uint32_t LPDS:1;
} B;
} PWR_CR;
};
#define PWR_CR (*(volatile struct PWR_CR_tag *) 0x40007004)
然后在 main.c 中(给出 ERROR ):
#include <stdio.h>
#include <myLibrary.h>
int main() {
PWR_CR test; // this gives ERROR expected ‘;’ before ‘test’
test.R = // write to address 0x40007004
test.B.VOS = // write to address 0x40007004 with offset 0xE (=0x40007012)
return 0;
}
如何实现PWR_CR test;
不会失败并且能够访问test.R
,test.B.VOS
,...
因此,我正在尝试实现以下目标:
// led struct
GPIO_InitTypeDef GPIO_LedInitStructure;
// configure led
GPIO_LedInitStructure.GPIO_Pin = ...;
GPIO_LedInitStructure.GPIO_Mode = ...;
GPIO_LedInitStructure.GPIO_Speed = ...; // for example GPIO_Speed_2Mhz
GPIO_LedInitStructure.GPIO_OType = ...;
GPIO_LedInitStructure.GPIO_PuPd = ...;
答案 0 :(得分:2)
首先,您声明了一个名为PWR_CR
的联合和一个名为PWR_CR
的宏,这将发生冲突。别那样
我们可以通过删除结构PWR_CR_tag并将其声明为并集PWR_CR_tag来修复您的某些代码,从而从PWR_CR_tag结构中删除PWR_CR成员。
另外,我们可以将变量声明移至宏,并在当前代码中使用variable.R = smth;
:
union PWR_CR_tag {
uint32_t R;
struct {
uint32_t VOS:1;
uint32_t FPDS:1;
uint32_t DBP:1;
uint32_t PLS:3;
uint32_t PVDE:1;
uint32_t CSBF:1;
uint32_t CWUF:1;
uint32_t PDDS:1;
uint32_t LPDS:1;
} B;
};
#define test (*(volatile union PWR_CR_tag *)0x40007004)
int main() {
test.R = 0x00; // write to address 0x40007004
test.B.VOS = 0x01 // write to address 0x40007004 with offset (at least) 0xE (=0x40007012) (or offset WORD_SIZE-(at least) 0xE depending on machine endianess and padding bytes)
return 0;
}
充当全局变量。但是,我肯定会删除宏,并为易失性对象声明一个全局const指针变量,以使代码更简洁,并通知程序员他正在取消引用指针:
static volatile union PWR_CR_tag * const PWR_CR = (void*)0x40007004;
int main() {
PWR_CR->R = 0; // write to address 0x40007004
PWR_CR->B.VOS = 1; // write to address 0x40007004 with offset 0xE (=0x40007012)
return 0;
}
PS。但是您提到了GPIO_InitTypeDef
,它是在stm32 hal库中声明的类型。正如您似乎知道STM32和hal标头一样,为什么不像hal一样使用PWR->CR
,例如here?您将减少错误,将程序轻松移至另一stm32行,从而使编程速度更快?
#include "stm32l0xx.h"
int main() {
PWR->CR = 0x00;
MODIFY_REG(PWR->CR, PWR_CR_VOS, 0b10);
// or better:
LL_PWR_SetRegulVoltageScaling(0b10);
return 0;
}
说到错误,我想VOS是2位而不是1位(至少在stm32l1和l0上),如果是stm32,我认为您的结构需要从结构开始就填充位,希望您知道目标的内在性平台并考虑到这一点,编译器可以在位字段之间插入任意数量的填充字节,因此您只能希望它不会这样做,因为声明uint32_t类型的位字段不符合标准,除非uint32_t是“实现定义的类型”平台上的位域”,我希望您在该结构的gcc编译器上使用__attribute__((__packed__))
。
答案 1 :(得分:0)
这取决于您的控制器体系结构。 在16位计算机上的地址:
#include <stdint.h>
struct PWR_CR_tag {
union {
uint32_t R; //Addr. 0x40007004
struct {
uint32_t VOS; //Addr. 0x40007014
uint32_t FPDS; //Addr. 0x40007012
uint32_t DBP; //Addr. 0x40007010
uint32_t PLS; //Addr. 0x4000700E
uint32_t PVDE; //Addr. 0x4000700C
uint32_t CSBF; //Addr. 0x4000700A
uint32_t CWUF; //Addr. 0x40007008
uint32_t PDDS; //Addr. 0x40007006
uint32_t LPDS; //Addr. 0x40007004
} B;
} PWR_CR;
};
#define PWR_CR (*(volatile struct PWR_CR_tag *) 0x40007004)
答案 2 :(得分:0)
不确定define
试图实现什么(注意,它的名称与您试图在main
中声明的变量类型相同(难怪它不会编译)为它扩展为:
//PWR_CR test;
//expanded to:
(*(volatile struct PWR_CR_tag *) 0x40007004) test;
但是,如果您更改define的名称,则可以将其用作:
#define PWR_test (*(volatile struct PWR_CR_tag *) 0x40007004)
//no need to declare a variable
PWR_test.PWR_CR.R = 2;
PWR_test.PWR_CR.B.VOS = 1;
我希望那是你想要的。