完整函数
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
user5166922:
楼主知道什么原因了吗?
完整函数
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
Aoshuang Li:
回复 user5166922:
请问pinMask = 1UL << pin32;这句话什么意思?
完整函数
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
Susan Yang:
回复 Aoshuang Li:
首先请您有其他问题重新发帖,不要跟踪旧帖,谢谢
0UL——–无符号长整型0
1UL——–无符号长整型1
如果没有UL后缀,则系统默认为 int类型,即,有符号整形
将无符号长整型1左移pin32