【STM32】GPIO_InitTypeDef GPIO_InitStructure;语句的理解

这句话声明一个结构体名字是GPIO_InitStructure,结构体原型由GPIO_InitTypeDef 确定,在stm32中用来初始化GPIO。设置完GPIO_InitStructure里面的内容后然后在GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct)里面调用。

但为什么GPIOx不需要取地址,但是GPIO_InitStructure为什么要用“&”取地址呢?

GPIO.c源文件:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{
  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
  uint32_t tmpreg = 0x00, pinmask = 0x00;
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
  assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  

后面省略

根据头文件,形参1 定义GPIOx为GPIO_TypeDef* 型为指针变量,只能是有效的指针和地址,形参2 定义GPIO_InitStruct为GPIO_InitTypeDef* 型也为指针变量,也只能是有效的指针和地址.

但当初始化设定GPIO口时,在STM32103x.h头文件中,已经定义了输入形参1的定义,所以形参1在初始化函数里不需要取地址符号,因为操作GPIOA等就是指针。

#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE

而当定义GPIO的初始化设置类型时,形参2 比如定义为 GPIO_InitTypeDef  GPIO_InitStructure,定义GPIO_InitStructure为GPIO_InitTypeDef 结构体类型,而不是GPIO_InitTypeDef* 。形参是指针类型,只能是指针和地址,而实参是GPIO_InitTypeDef 结构体类型,所以需要对实参进行取地址操作。所以要写成GPIO_Init(GPIOx, &GPIO_InitStructure)。

  • 12
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
工程是基于STM32F207的ADC_DMA的整体程序 #define ADC1_DR_Address ((u32)0x4001204C) //ADC1数据寄存器地址=ADC1基准地址(0x40012000)+数据寄存器偏移地址(0x4c) GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// 使能 GPIO 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);// 开启ADC时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // 开启DMA时钟 DMA_DeInit(DMA2_Stream0); DMA_InitStructure.DMA_Channel=DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;// 外设基址为:ADC 数据寄存器地址 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ad;_start;// 存储器地址,实际上就是一个内部SRAM的变量 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;// 数据传输方向为外设到存储器 DMA_InitStructure.DMA_BufferSize = 1;// 缓冲区大小为,指一次传输的数据量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设寄存器只有一个,地址不用递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 存储器地址 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// 外设数据大小为半字,即两个字节 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 存储器数据大小也为半字,跟外设数据大小相同 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 循环传输模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High;// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; // 禁止DMA FIFO ,使用直连模式 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
#include "i2c.h" #include "stm32f10x.h" #include <math.h> //Keil library // ¶¨ÒåMPU6050ÄÚ²¿µØÖ· //**************************************** #define SMPLRT_DIV 0x19 //ÍÓÂÝÒDzÉÑùÂÊ£¬µäÐÍÖµ£º0x07(125Hz) #define CONFIG 0x1A //µÍͨÂ˲¨ÆµÂÊ£¬µäÐÍÖµ£º0x06(5Hz) #define GYRO_CONFIG 0x1b //ÍÓÂÝÒÇ×Լ켰²âÁ¿·¶Î§£¬µäÐÍÖµ£º0x18(²»×Լ죬2000deg/s) #define ACCEL_CONFIG 0x1c //¼ÓËÙ¼Æ×Լ졢²âÁ¿·¶Î§¼°¸ßͨÂ˲¨ÆµÂÊ£¬µäÐÍÖµ£º0x01(²»×Լ죬2G£¬5Hz) #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B //µçÔ´¹ÜÀí£¬µäÐÍÖµ£º0x00(Õý³£ÆôÓÃ) #define WHO_AM_I 0x75 //IICµØÖ·¼Ä´æÆ÷(ĬÈÏÊýÖµ0x68£¬Ö»¶Á) #define MPU6050_Addr 0xd0 //¶¨ÒåÆ÷¼þÔÚIIC×ÜÏßÖеĴӵØÖ·,¸ù¾ÝALT ADDRESSµØÖ·Òý½Å²»Í¬ÐÞ¸Ä #define SCL_H GPIOB->BSRR = GPIO_Pin_6 #define SCL_L GPIOB->BRR = GPIO_Pin_6 #define SDA_H GPIOB->BSRR = GPIO_Pin_7 #define SDA_L GPIOB->BRR = GPIO_Pin_7 #define SCL_read GPIOB->IDR & GPIO_Pin_6 #define SDA_read GPIOB->IDR & GPIO_Pin_7 void SDA_IOIN(void); void SDA_IOOUT(void); void I2C_delay(void); void delay5ms(void); u8 I2C_Start(void); void I2C_Stop(void); void I2C_Ack(void); void I2C_NoAck(void); u8 I2C_WaitAck(void); void I2C_SendByte(u8 SendByte) ; unsigned char I2C_RadeByte(void); void READ_MPU6050(void); u8 Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data); void GPIO_Configuration(void); void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); } unsigned char BUF[15]; //½ÓÊÕÊý¾Ý»º´æÇø char TX_DATA[4]; //ÏÔʾ¾Ý»º´æÇø short T_X,A_X,T_Y,A_Y,T_Z,A_Z,T_T; void SDA_IOOUT(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // ¿ªÂ©Êä³ö GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // ×î¸ßÊä³öËÙÂÊ50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); // Ñ¡ÔñC¶Ë¿Ú } void SDA_IOIN(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // ¸¡¿ÕÊäÈë GPIO_Init(GPIOB, &GPIO_InitStructure); // Ñ¡ÔñC¶Ë¿Ú } void Init_MPU6050() { // Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x80); // delay5ms(); Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x00); delay5ms(); //½â³ýÐÝÃß״̬ Single_Write(MPU6050_Addr,SMPLRT_DIV, 0x07); delay5ms();//²ÉÑùËÙÂÊΪ Single_Write(MPU6050_Addr,CONFIG, 0x06); delay5ms(); Single_Write(MPU6050_Addr,GYRO_CONFIG, 0x18); delay5ms(); //ÍÓÂÝÒǼì²â·¶Î§500¶È/Ãë Single_Write(MPU6050_Addr,ACCEL_CONFIG, 0x01); delay5ms(); //¼ÓËÙÆ÷¼ì²â·¶Î§4G GPIO_Configuration(); }; unsigned char Single_Write(unsigned char SlaveAddress, unsigned char REG_Address, unsigned char REG_data) //void { if(!I2C_Start())return 0; I2C_SendByte(SlaveAddress); //·¢ËÍÉ豸µØÖ·+дÐźÅ//I2C_SendByte(((REG_Address & 0x0700) >>7) | SlaveAddress & 0xFFFE);//ÉèÖøßÆðʼµØÖ·+Æ÷¼þµØÖ· // if(!I2C_WaitAck()){I2C_Stop(); return 0;} I2C_WaitAck(); I2C_SendByte(REG_Address); //ÉèÖõÍÆðʼµØÖ· I2C_WaitAck(); I2C_SendByte(REG_data); I2C_WaitAck(); I2C_Stop(); delay5ms(); return 1; } unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address) { unsigned char REG_data; I2C_Start(); I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//ÉèÖøßÆðʼµØÖ·+Æ÷¼þµØÖ· I2C_WaitAck(); I2C_SendByte((u8) REG_Address); //ÉèÖõÍÆðʼµØÖ· I2C_WaitAck(); I2C_Start(); I2C_SendByte(SlaveAddress+1); I2C_WaitAck(); REG_data= I2C_RadeByte(); I2C_NoAck(); I2C_Stop(); //return 1; return REG_data; } /******************************************************************************* * Function Name : I2C_delay * Description : Simulation IIC Timing series delay * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_delay(void) { u8 i=30; //ÕâÀï¿ÉÒÔÓÅ»¯ËÙ¶È £¬¾­²âÊÔ×îµÍµ½5»¹ÄÜдÈë while(i) { i--; } } void delay5ms(void) { int i=5000; while(i) { i--; } } /******************************************************************************* * Function Name : I2C_Start * Description : Master Start Simulation IIC Communication * Input : None * Output : None * Return : Wheather Start ****************************************************************************** */ u8 I2C_Start(void) { SDA_IOOUT(); SDA_H; SCL_H; I2C_delay(); if(!SDA_read)return 0; //SDAÏßΪµÍµçƽÔò×ÜÏßæ,Í˳ö SDA_L; I2C_delay(); if(SDA_read) return 0; //SDAÏßΪ¸ßµçƽÔò×ÜÏß³ö´í,Í˳ö SDA_L; I2C_delay(); SCL_L; return 1; } /******************************************************************************* * Function Name : I2C_Stop * Description : Master Stop Simulation IIC Communication * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Stop(void) { SDA_IOOUT(); SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SDA_H; I2C_delay(); } /******************************************************************************* * Function Name : I2C_Ack * Description : Master Send Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Ack(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } /******************************************************************************* * Function Name : I2C_NoAck * Description : Master Send No Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_NoAck(void) { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); } /******************************************************************************* * Function Name : I2C_WaitAck * Description : Master Reserive Slave Acknowledge Single * Input : None * Output : None * Return : Wheather Reserive Slave Acknowledge Single ****************************************************************************** */ u8 I2C_WaitAck(void) //·µ»ØΪ:=1ÓÐACK,=0ÎÞACK { SDA_IOIN(); SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { SCL_L; SDA_IOOUT(); I2C_delay(); return 0; } SCL_L; SDA_IOOUT(); I2C_delay(); return 1; } /******************************************************************************* * Function Name : I2C_SendByte * Description : Master Send a Byte to Slave * Input : Will Send Date * Output : None * Return : None ****************************************************************************** */ void I2C_SendByte( unsigned char SendByte) //Êý¾Ý´Ó¸ßλµ½µÍλ// { u8 i=8; while(i--) { SCL_L; I2C_delay(); if(SendByte&0x80) SDA_H; else SDA_L; SendByte<<=1; I2C_delay(); SCL_H; I2C_delay(); } SCL_L; } /******************************************************************************* * Function Name : I2C_RadeByte * Description : Master Reserive a Byte From Slave * Input : None * Output : None * Return : Date From Slave ****************************************************************************** */ unsigned char I2C_RadeByte(void) //Êý¾Ý´Ó¸ßλµ½µÍλ// { u8 i=8; u8 ReceiveByte=0; SDA_IOIN(); while(i--) { ReceiveByte<<=1; SCL_L; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { ReceiveByte|=0x01; } } SCL_L; return ReceiveByte; } void READ_MPU6050(void) { BUF[0]=Single_Read(MPU6050_Addr,GYRO_XOUT_L); BUF[1]=Single_Read(MPU6050_Addr,GYRO_XOUT_H); T_X= (BUF[1]<<8)|BUF[0]; // T_X/=16.4; //¶ÁÈ¡¼ÆËãXÖá½ÇËÙ¶È BUF[2]=Single_Read(MPU6050_Addr,GYRO_YOUT_L); BUF[3]=Single_Read(MPU6050_Addr,GYRO_YOUT_H); T_Y= (BUF[3]<<8)|BUF[2]; // T_Y/=16.4; //¶ÁÈ¡¼ÆËãYÖá½ÇËÙ¶È BUF[4]=Single_Read(MPU6050_Addr,GYRO_ZOUT_L); BUF[5]=Single_Read(MPU6050_Addr,GYRO_ZOUT_H); T_Z= (BUF[5]<<8)|BUF[4]; // T_Z/=16.4; //¶ÁÈ¡¼ÆËãZÖá½ÇËÙ¶È BUF[6]=Single_Read(MPU6050_Addr,ACCEL_XOUT_L); BUF[7]=Single_Read(MPU6050_Addr,ACCEL_XOUT_H); A_X= (BUF[7]<<8)|BUF[6]; // A_X/=8192.0; //¶ÁÈ¡¼ÆËãXÖá¼ÓËÙ¶È BUF[8]=Single_Read(MPU6050_Addr,ACCEL_YOUT_L); BUF[9]=Single_Read(MPU6050_Addr,ACCEL_YOUT_H); A_Y= (BUF[9]<<8)|BUF[8]; // A_Y/=8192.0; //¶ÁÈ¡¼ÆËãYÖá¼ÓËÙ¶È BUF[10]=Single_Read(MPU6050_Addr,ACCEL_ZOUT_L); BUF[11]=Single_Read(MPU6050_Addr,ACCEL_ZOUT_H); A_Z= (BUF[11]<<8)|BUF[10]; // A_Z/=8192.0; //¶ÁÈ¡¼ÆËãZÖá¼ÓËÙ¶È BUF[12]=Single_Read(MPU6050_Addr,TEMP_OUT_L); BUF[13]=Single_Read(MPU6050_Addr,TEMP_OUT_H); T_T=(BUF[13]<<8)|BUF[12]; T_T = 35+ ((double) (T_T + 13200)) / 280;// ¶ÁÈ¡¼ÆËã³öÎÂ¶È }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值