可變我有三個電機驅動器,我想和我的控制器接口連接的結構中的一員。我的問題涉及如何編寫代碼以使函數更新這些驅動程序的值。參考使用存儲在結構用C
我用結構來表示的驅動器和控制器具有用於訪問所述控制器的不同的寄存器一組內置結構。
我想使一個函數,它的結構爲特定的電動機驅動器作爲輸入參數,並且改變各種的GPIO的值用於該特定電機驅動器。
比方說,我的控制器上的引腳與下面的代碼訪問(這是由控制器製造商提供的結構):
GpioCtrlRegs.GPAMUX1.bit.GPIO01 = 0;
爲了方便更新在多個位置的銷我使用下面的宏:
#define MOTOR1_nSLEEP GPIO01
#define MOTOR1_nSLEEP_MUX GPAMUX1
GpioCtrlRegs.MOTOR1_nSLEEP_MUX.bit.MOTOR1_nSLEEP = 1;
現在,這裏是棘手的地方。我想定義下面的函數。
void Initialize (struct motor_driver MOTOR1) {
GpioCtrlRegs.MOTOR1_nSLEEP_MUX.bit.MOTOR1_nSLEEP = 1;
}
但問題是,我需要能夠根據輸入參數更改宏。據我所知,這是不可能的。所以我認爲我會使用指針指向內存中的GPIO特定位置,然後將該指針添加到「struct motor_driver」中,以便它也傳遞到函數中。所以像這樣:
MOTOR1.pointers.nSLEEP_MUX = &(GpioCtrlRegs.MOTOR1_nSLEEP_MUX.bit.MOTOR1_nSLEEP);
然後在函數中,我可以使用這個指針來直接調整GPIO寄存器的值。不幸的是,由於指針必須在字節級別工作,所以不允許指針取值爲位域。
所以我將不得不使用指針的第一個#define值「MOTOR1_nSLEEP_MUX」,然後手動訪問「.bit.MOTOR1_nSLEEP」(可能通過使用結構指針)。
現在的問題是,我不知道如何在一個靈活的,宏觀獨立的方式在宏「MOTOR1_nSLEEP」的工作,因爲它等於「GPIO01」。如何將「GPIO01」傳遞給必要的結構指針,以便我可以訪問正確的位域?你有什麼建議?我首先以一種愚蠢的方式接近這一點?
這裏是GpioCtrlRegs一些額外的信息:
struct GPIO_CTRL_REGS {
union GPACTRL_REG GPACTRL; // GPIO A Control Register (GPIO0 to 31)
union GPA1_REG GPAQSEL1; // GPIO A Qualifier Select 1 Register (GPIO0 to 15)
union GPA2_REG GPAQSEL2; // GPIO A Qualifier Select 2 Register (GPIO16 to 31)
union GPA1_REG GPAMUX1; // GPIO A Mux 1 Register (GPIO0 to 15)
union GPA2_REG GPAMUX2; // GPIO A Mux 2 Register (GPIO16 to 31)
union GPADAT_REG GPADIR; // GPIO A Direction Register (GPIO0 to 31))
union GPADAT_REG GPAPUD; // GPIO A Pull-Up Disable Register
Uint16 rsvd1[2]; // Reserved
union GPBCTRL_REG GPBCTRL; // GPIO B Control Register (GPIO32 to 63)
union GPB1_REG GPBQSEL1; // GPIO B Qualifier Select 1 Register (GPIO32 to 47)
union GPB2_REG GPBQSEL2; // GPIO B Qualifier Select 2 Register (GPIO48 to 63)
union GPB1_REG GPBMUX1; // GPIO B Mux 1 Register (GPIO32 to 47)
union GPB2_REG GPBMUX2; // GPIO B Mux 2 Register (GPIO48 to 63)
union GPBDAT_REG GPBDIR; // GPIO B Direction Register (GPIO32 to 63)
union GPBDAT_REG GPBPUD; // GPIO B Pull-Up Disable Register
Uint16 rsvd2[24]; // Reserved
union AIO_REG AIOMUX1; // Analog IO Mux 1 Register
Uint16 rsvd3[2]; // Reserved
union AIODAT_REG AIODIR; // Analog IO Direction Register
Uint16 rsvd4[4]; // Reserved
};
union GPA1_REG {
Uint32 all;
struct GPA1_BITS bit;
};
struct GPA1_BITS { // bits description
Uint16 GPIO0:2; // 1:0 GPIO0
Uint16 GPIO1:2; // 3:2 GPIO1
Uint16 GPIO2:2; // 5:4 GPIO2
Uint16 GPIO3:2; // 7:6 GPIO3
Uint16 GPIO4:2; // 9:8 GPIO4
Uint16 GPIO5:2; // 11:10 GPIO5
Uint16 GPIO6:2; // 13:12 GPIO6
Uint16 GPIO7:2; // 15:14 GPIO7
Uint16 GPIO8:2; // 17:16 GPIO8
Uint16 GPIO9:2; // 19:18 GPIO9
Uint16 GPIO10:2; // 21:20 GPIO10
Uint16 GPIO11:2; // 23:22 GPIO11
Uint16 GPIO12:2; // 25:24 GPIO12
Uint16 GPIO13:2; // 27:26 GPIO13
Uint16 GPIO14:2; // 29:28 GPIO14
Uint16 GPIO15:2; // 31:30 GPIO15
};
而在另一個文件:
#ifdef __cplusplus
#pragma DATA_SECTION("GpioCtrlRegsFile")
#else
#pragma DATA_SECTION(GpioCtrlRegs,"GpioCtrlRegsFile");
#endif
volatile struct GPIO_CTRL_REGS GpioCtrlRegs;
您可能會對這裏的宏太過幻想。你有沒有考慮用一系列電機制造你自己的結構?只要你的結構域與其結構覆蓋相同的內存,它就可以工作。請記住使用所有相同的額外參數進行定義,例如volatile,打包,字節順序,其他可能附加的其他內容。 –
你爲什麼不創建一個條件來決定什麼寄存器將被初始化 – KS7X
它可能做一個條件,但考慮到將會有多少個函數以及我需要做多少次(添加到代碼長度和開銷時間),我寧願提出一個更優雅的解決方案。 –