Keil MDK网站上下载的Keil.STM32F1xx_DFP.2.2.0.pack包中的stm32f10x.h头文件里面没有USB_TypeDef的定义,只有寄存器位的定义,是不完整的头文件。没有USB的数据结构就会给访问USB寄存器带来一定的困难。虽然可以参照STM32参考手册中的USB register map自己编写出USB_TypeDef结构体,但是这样比较麻烦。
不过,STM32CubeMX工具生成的STM32F103工程中的头文件stm32f103xe.h中就有完整的USB数据结构,该头文件的版本是V4.2.0,日期为31-March-2017,作者仍然是Keil里面的MCD Application Team,这比Keil中的V3.5.0(11-March-2011)版本新得多,里面还额外增加了各寄存器位的具体位置的定义:***_Pos。
有了Pos定义,我们就可以直接指定多位选项的值。例如:
SDIO->CLKCR = SDIO_CLKCR_CLKEN | (70 << SDIO_CLKCR_CLKDIV_Pos); // 72MHz/(70+2)=1MHz
SDIO->CMD = SDIO_CMD_CPSMEN | (15 << SDIO_CMD_CMDINDEX_Pos); // 发送15号命令
ADC1->SQR1 = (3 << ADC_SQR1_L_Pos); // L=3, 3+1 conversions
ADC1->SQR3 = (4 << ADC_SQR3_SQ1_Pos) | (9 << ADC_SQR3_SQ2_Pos) | (0 << ADC_SQR3_SQ3_Pos) | (11 << ADC_SQR3_SQ4_Pos);
而不用一位一位的或起来,这样可读性比较差:
ADC1->SQR1 = ADC_SQR1_L_1 | ADC_SQR1_L_0; // L=3, 3+1 conversions
我们可以把其中常用的USB有关的内容复制出来,单独存放为一个stm32f10x_usb.h文件,或者索性直接就使用较新版本的头文件。
【stm32f10x_usb.h】
#define USB_BASE (APB1PERIPH_BASE + 0x00005C00U) /*!< USB_IP Peripheral Registers base address */
#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000U) /*!< USB_IP Packet Memory Area base address */
#define USB ((USB_TypeDef *)USB_BASE)
/**
* @brief Universal Serial Bus Full Speed Device
*/
typedef struct
{
__IO uint16_t EP0R; /*!< USB Endpoint 0 register, Address offset: 0x00 */
__IO uint16_t RESERVED0; /*!< Reserved */
__IO uint16_t EP1R; /*!< USB Endpoint 1 register, Address offset: 0x04 */
__IO uint16_t RESERVED1; /*!< Reserved */
__IO uint16_t EP2R; /*!< USB Endpoint 2 register, Address offset: 0x08 */
__IO uint16_t RESERVED2; /*!< Reserved */
__IO uint16_t EP3R; /*!< USB Endpoint 3 register, Address offset: 0x0C */
__IO uint16_t RESERVED3; /*!< Reserved */
__IO uint16_t EP4R; /*!< USB Endpoint 4 register, Address offset: 0x10 */
__IO uint16_t RESERVED4; /*!< Reserved */
__IO uint16_t EP5R; /*!< USB Endpoint 5 register, Address offset: 0x14 */
__IO uint16_t RESERVED5; /*!< Reserved */
__IO uint16_t EP6R; /*!< USB Endpoint 6 register, Address offset: 0x18 */
__IO uint16_t RESERVED6; /*!< Reserved */
__IO uint16_t EP7R; /*!< USB Endpoint 7 register, Address offset: 0x1C */
__IO uint16_t RESERVED7[17]; /*!< Reserved */
__IO uint16_t CNTR; /*!< Control register, Address offset: 0x40 */
__IO uint16_t RESERVED8; /*!< Reserved */
__IO uint16_t ISTR; /*!< Interrupt status register, Address offset: 0x44 */
__IO uint16_t RESERVED9; /*!< Reserved */
__IO uint16_t FNR; /*!< Frame number register, Address offset: 0x48 */
__IO uint16_t RESERVEDA; /*!< Reserved */
__IO uint16_t DADDR; /*!< Device address register, Address offset: 0x4C */
__IO uint16_t RESERVEDB; /*!< Reserved */
__IO uint16_t BTABLE; /*!< Buffer Table address register, Address offset: 0x50 */
__IO uint16_t RESERVEDC; /*!< Reserved */
} USB_TypeDef;