1. 程式人生 > >STM32學習---GPIO和RCC(流水燈學習)

STM32學習---GPIO和RCC(流水燈學習)

       因為實驗室課題的需要,需要學習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);
 }