This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

希望有人能帮我解答F28377s中void GPIO_SetupPinOptions(Uint16 pin, Uint16 output, Uint16 flags)中的疑惑

完整函数

void GPIO_SetupPinOptions(Uint16 pin, Uint16 output, Uint16 flags)
{
volatile Uint32 *gpioBaseAddr;
volatile Uint32 *dir, *pud, *inv, *odr, *qsel;
Uint32 pin32, pin16, pinMask, qual;

pin32 = pin % 32;
pin16 = pin % 16;
pinMask = 1UL << pin32;
gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (pin/32)*GPY_CTRL_OFFSET;

//Create pointers to the appropriate registers. This is a workaround
//for the way GPIO registers are defined. The standard definition
//in the header file makes it very easy to do named accesses of one
//register or bit, but hard to do arbitrary numerical accesses. It's
//easier to have an array of GPIO modules with identical registers,
//including arrays for multi-register groups like GPyQSEL1-2. But
//the header file doesn't define anything we can turn into an array,
//so manual pointer arithmetic is used instead.
dir = gpioBaseAddr + GPYDIR;
pud = gpioBaseAddr + GPYPUD;
inv = gpioBaseAddr + GPYINV;
odr = gpioBaseAddr + GPYODR;
qsel = gpioBaseAddr + GPYQSEL + pin32/16;

EALLOW;

//Set the data direction
*dir &= ~pinMask;
if (output == 1)
{
//Output, with optional open drain mode and pull-up
*dir |= pinMask;

//Enable open drain if necessary
if (flags & GPIO_OPENDRAIN)
*odr |= pinMask;
else
*odr &= ~pinMask;

//Enable pull-up if necessary. Open drain mode must be active.
if (flags & (GPIO_OPENDRAIN | GPIO_PULLUP))
*pud &= ~pinMask;
else
*pud |= pinMask;
} else
{
//Input, with optional pull-up, qualification, and polarity inversion
*dir &= ~pinMask;

//Enable pull-up if necessary
if (flags & GPIO_PULLUP)
*pud &= ~pinMask;
else
*pud |= pinMask;

//Invert polarity if necessary
if (flags & GPIO_INVERT)
*inv |= pinMask;
else
*inv &= ~pinMask;
}

//Extract the qualification parameter and load it into the register. This is
//also needed for open drain outputs, so we might as well do it all the time.
qual = (flags & GPIO_ASYNC) / GPIO_QUAL3;
*qsel &= ~(0x3L << (2 * pin16));
if (qual != 0x0)
*qsel |= qual << (2 * pin16);

EDIS;
}

有一个疑惑,就是在gpioBaseAddr = (Uint32 *)&GpioCtrlRegs + (pin/32)*GPY_CTRL_OFFSET;中GPY_CTRL_OFFSET为“0x40/2”可是看了寄存器手册32脚的地址为正好为0x40,为什么要/2呢?

类似还有dir = gpioBaseAddr + GPYDIR;     //GPYDIR是0xA/2,寄存器地址是0xA
pud = gpioBaseAddr + GPYPUD;            //GPYDIR是0xC/2,寄存器地址是0xC
inv = gpioBaseAddr + GPYINV;
odr = gpioBaseAddr + GPYODR;
qsel = gpioBaseAddr + GPYQSEL + pin32/16;

头文件定义:

//Helpful constants for array-based access to GPIO registers
#define GPY_CTRL_OFFSET (0x40/2)
#define GPY_DATA_OFFSET (0x8/2)

#define GPYQSEL (0x2/2)
#define GPYMUX (0x6/2)
#define GPYDIR (0xA/2)
#define GPYPUD (0xC/2)
#define GPYINV (0x10/2)
#define GPYODR (0x12/2)
#define GPYGMUX (0x20/2)
#define GPYCSEL (0x28/2)
#define GPYLOCK (0x3C/2)
#define GPYCR (0x3E/2)

#define GPYDAT (0x0/2)
#define GPYSET (0x2/2)
#define GPYCLEAR (0x4/2)
#define GPYTOGGLE (0x6/2)

#endif // end of F2837xS_GPIO_DEFINES_H definition