近日来一直在调试 AT91SAM9G45 开发板例程,遇到很多宏定义,归纳起来也基本就是如下几种:
#ifndef __ASSEMBLY__
typedef volatile unsigned int AT91_REG;// Hardware register definition
#define AT91_CAST(a) (a)
#else
#define AT91_CAST(a)
#endif
// 用实例说明 AT91_CAST(a) 的功能
// 例如:#define PMC_SCER (AT91_CAST(AT91_REG *) 0x00000000)
// 在C语言中,上述语言会变成 :
// #define PMC_SCER ( (volatile unsigned int *) 0x00000000)
// 在汇编中,上述语句会变成
// #define PMC_SCER ( 0x00000000)
// *****************************************************************************
// SOFTWARE API DEFINITION FOR Power Management Controller V610
// *****************************************************************************
#ifndef __ASSEMBLY__
typedef struct _AT91S_PMC {
AT91_REG PMC_SCER; // System Clock Enable Register
AT91_REG PMC_SCDR; // System Clock Disable Register
AT91_REG PMC_SCSR; // System Clock Status Register
AT91_REG Reserved0[1]; //
AT91_REG PMC_PCER; // Peripheral Clock Enable Register
AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
。。。
} AT91S_PMC, *AT91PS_PMC;
#else
#define PMC_SCER (AT91_CAST(AT91_REG *) 0x00000000) // (PMC_SCER) System Clock Enable Register
#define PMC_SCDR (AT91_CAST(AT91_REG *) 0x00000004) // (PMC_SCDR) System Clock Disable Register
#define PMC_SCSR (AT91_CAST(AT91_REG *) 0x00000008) // (PMC_SCSR) System Clock Status Register
#define PMC_PCER (AT91_CAST(AT91_REG *) 0x00000010) // (PMC_PCER) Peripheral Clock Enable Register
#define PMC_PCDR (AT91_CAST(AT91_REG *) 0x00000014) // (PMC_PCDR) Peripheral Clock Disable Register
。。。
#endif
// 上面宏定义定义了寄存器的偏移量,分别提供了两种不同的访问寄存器的方法:
// C程序中,可以通过结构体成员的方法访问相应端口寄存器:
// 首先定义端口基址:#define AT91C_BASE_PMC (AT91_CAST(AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
// 相当于:#define AT91C_BASE_PMC ( (struct _AT91S_PMC *) 0xFFFFFC00 )
// 然后就可以通过结构体成员设置寄存器:AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TWI;
// 汇编程序中,可以按如下方法访问寄存器:
// LDR r14, =AT91C_BASE_PMC
// LDR r0, [r14, #PMC_PCER ]
// -------- PMC_SCER : (PMC Offset: 0x0) System Clock Enable Register --------
#define AT91C_PMC_DDR (0x1 << 2) // (PMC) DDR controller Clock2x
#define AT91C_PMC_UHP (0x1 << 6) // (PMC) USB Host Port Clock
#define AT91C_PMC_UDP (0x1 << 7) // (PMC) USB Device Port Clock
#define AT91C_PMC_PCK0 (0x1 << 8) // (PMC) Programmable Clock Output
#define AT91C_PMC_PCK1 (0x1 << 9) // (PMC) Programmable Clock Output
。。。
// 上面的宏定义是对寄存器位的定义,有了这些宏定义就可以对寄存器AT91C_PMC_DDR进行如下设置:
// AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_DDR | AT91C_PMC_UHP,表示使能 DDR 和 USB Host 时钟。
由于芯片上端口很多,端口寄存器也很多,采用类似上述的宏定义,可以大大方面我们编程。
没有评论:
发表评论