STM32F0xx的头文件,对芯片的外围作了定义,并且定义了C语言编程时使用的结构等。大家可能发现,ST的过程调用里的参数传递,一般使用结构体,这样的好处是节省寄存器,在子程序、包括中断函数中,就可以节省入栈出栈的时间。
1、在stm32f0xx.h头文件的开头,定义了常用的宏后,就定义IRQ向量的枚举类型:
typedef enum IRQn
{
……
} IRQn_Type;
而对于外围硬件(模块),则使用结构体,如:
typedef struct
{
__IO uint32_t ISR; /*!< ADC Interrupt andStatus register, Address offset:0x00 */
__IO uint32_t IER; /*!< ADC Interrupt Enable register,Address offset:0x04 */
__IO uint32_t CR; /*!< ADC Control register,Address offset:0x08 */
__IO uint32_t CFGR1; /*!< ADC Configura
tion register 1,Address offset:0x0C */
__IO uint32_t CFGR2; /*!< ADC Configuration register 2,Address offset:0x10 */
__IO uint32_t SMPR; /*!< ADC Sampling time register,Address offset:0x14 */
uint32_t RESERVED1; /*!< Reserved, 0x18 */
uint32_t RESERVED2; /*!< Reserved, 0x1C*/
__IO uint32_t TR; /*!< ADC watchdog thresholdregister, Address offset:0x20 */
uint32_t RESERVED3; /*!< Reserved, 0x24 */
__IO uint32_t CHSELR; /*!< ADC channel selection register,Address offset:0x28 */
uint32_t RESERVED4[5]; /*!< Reserved, 0x2C*/
__IO uint32_t DR; /*!< ADC data register, Address offset:0x40 */
} ADC_TypeDef;
以及寄存器的位定义,如:
#define ADC_CHSELR_CHSEL18 ((uint32_t)0x00040000) /*!
……
#define GPIO_MODER_MODER0 ((uint32_t)0x00000003)
2、各模块的头文件。
在各模块的头文件中,定义了各模块的对应寄存器,以及结构体等。如GPIO头文件中:
typedef struct
{
uint32_t GPIO_Pin;
GPIOMode_TypeDef GPIO_Mode;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOOType_TypeDefGPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;
}GPIO_InitTypeDef;
这些结构体的定义实际上是为了配合ST公司的例程对模块的使用方法问题。如对GPIO0的初始化。
/* Configure PA0 pin asinput floating */
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitStructure);
由上可见,首先初始化结构体,再调用初始化函数。
这种方法的优点是,程序可读性非常好,对于某一端口的设置一目了然。程序嵌入到操作系统时也很方便。但这种方法的执行效率却很差。如IO口的初始化函数,即是对某一个端口操作,也要执行这条语句:
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
{
……
if (currentpin == pos)
……
}