STM32学习---GPIO和RCC(流水灯学习)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/XUCHEN1230/article/details/84192662

       因为实验室课题的需要,需要学习stm32。之前本科时学过51单片机,虽然stm32本质上来说也是用C对底层寄存器进行操作,但是硬件架构和底层设计的不同两者还是有天壤之别。所以把自己当做新生,从0开始学习STM32。摆正心态,稳步前进!

       所采用的开发板:正点原子MINI(实验室直接拿,很方便);

      参考书籍:STM32库开发实战指南   刘火良   杨森著(图书馆借,很方便,外加学长推荐);

      其他资料:网络查找。

  ————————————————————————————————————————————————————————

关于 KEIL5 开发环境配置和另外找时间写。

————————————————————————————————————————————————————————

1.什么是GPIO?

通俗理解就是I/O引脚。输入输出端口。

2.GPIO分组?

GPIO分为:从GPIOA->GPIOG 等不同的组。

每一个GPIOX组又有0-15共16个不同的引脚。

这些引脚在通过软件操作时,不同0/1组合可以实现不同的功能。

3.我们需要对GPIO进行哪些操作?

(1)配置输入/输出;

(2)配置相应的模式;

(3)配置数据传输速度;

4.如何操作?

现在有三种操作方法:寄存器操作,库函数操作,HAL库操作。因为实际课题的需要,所以我需要学习的是标准库函数操作。

配置寄存器的具体操作,参考官方的技术手册。

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
//使用GPIO时,首先定义一个GPIO的结构体类型变量;

//然后选定需要操作的引脚,用GPIO结构体中的成员定义;
#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */

//然后设置传输速度和模式:
typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
typedef enum

  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

//控制I/O输出高、低电平
GPIO_SetBits()控制输出高电平;
GPIO_ResetBits()控制输出低电平;
//输入参数:
两个参数:GPIOx,GPIO_Pin;


//再运用初始化库函数---GPIO_Init()进行“激活”
/*
输入两个参数:GPIO——TypeDef 和 GPIO_InitTypeDef 型指针;
GPIOx用于选择A-G具体的端口;
GPIO_InitTypeDef 是上面定义的GPIO型结构体变量;
*/
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));  
  
/*---------------------------- GPIO Mode Configuration -----------------------*/
  currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
  if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
  { 
    /* Check the parameters */
    assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
    /* Output mode */
    currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
  }
/*---------------------------- GPIO CRL Configuration ------------------------*/
  /* Configure the eight low port pins */
  if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
  {
    tmpreg = GPIOx->CRL;
    for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    {
      pos = ((uint32_t)0x01) << pinpos;
      /* Get the port pins position */
      currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
      if (currentpin == pos)
      {
        pos = pinpos << 2;
        /* Clear the corresponding low control register bits */
        pinmask = ((uint32_t)0x0F) << pos;
        tmpreg &= ~pinmask;
        /* Write the mode configuration in the corresponding bits */
        tmpreg |= (currentmode << pos);
        /* Reset the corresponding ODR bit */
        if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
        {
          GPIOx->BRR = (((uint32_t)0x01) << pinpos);
        }
        else
        {
          /* Set the corresponding ODR bit */
          if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
          {
            GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
          }
        }
      }
    }
    GPIOx->CRL = tmpreg;
  }

  
 //和其他的MCU不同的是,STM32在设置好GPIO的寄存器之后,STM32还应该开启外设时钟。
 
 //调用RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx,ENABLE)函数;
 /*
    RCC_APB2Periph_GPIOx---->x表示从A->G的端口,需要激活哪个就把x改成哪个;
    打开挂载在外设总线APB2上的引脚(端口);
    挂载在其余总线的端口由其他函数调用打开,具体可参考文件: stm32f10x_rcc.c
 */
 
 

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

 void Delay(int count)
 {

  for(;count>0;count--);

 }
 int main(void)
 {	
	 
			GPIO_InitTypeDef GPIOx1,GPIOx2;	
			
		    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);	
	 
			GPIOx1.GPIO_Pin=GPIO_Pin_8;	
			GPIOx2.GPIO_Pin=GPIO_Pin_2;	

			GPIOx1.GPIO_Mode=GPIO_Mode_Out_PP;
			GPIOx2.GPIO_Mode=GPIO_Mode_Out_PP;
	 
			GPIOx1.GPIO_Speed=3;
			GPIOx2.GPIO_Speed=3;
	 
		    GPIO_Init(GPIOA,&GPIOx1);
		    GPIO_Init(GPIOD,&GPIOx2);
		 
		   //GPIO_SetBits(GPIOA,GPIO_Pin_8);
		   while(1){
		       Delay(10000000);
		 
		       GPIO_SetBits(GPIOA,GPIO_Pin_8);
		       GPIO_SetBits(GPIOD,GPIO_Pin_2);
		 
		 
			     Delay(10000000);
		         GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		       GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	 
	 }
	 return(1);
 }


 
 
 

猜你喜欢

转载自blog.csdn.net/XUCHEN1230/article/details/84192662