1.1 GPIO流水燈硬件電路分析
發光二極管是屬于二極管的一種,具有二級管單向導電特性,即只有在正向電壓(二極管的正極接正,負極接負)下才能導通發光。PB0引腳接發光二極管(LED1)的正極,所以PB0引腳輸出高電平LED1亮,PB0引腳輸出低電平LED1熄滅,,LED2,LED3同理。
圖1 LED電路圖
在上一章,我們知道STM32的引腳有8中模式,我們要點亮LED,顯然是輸出模式,那么則要將PB0、PG6、PG7設置為普通輸出模式,那么是是開漏輸出,還是推挽輸出呢?或者都可以。為了使得LED點亮,我們只需要將PB0、PG6、PG7輸出為高電平,斌企鵝需要輸出電流,則需要將其設置為推挽輸出,因為如果是開漏輸出,則不會有電流,LED就不會點亮。好了,就到這里吧,我們使用STM32Cube新建工程。
1.2 STM32Cube新建工程
關于如何使用使用STM32Cube新建工程在前文已經講解過了,這里直說配置GPIO部分內容。本文要實現流水燈,其實輸出為初始化設置為高電平還是低電平都可以,因為流水燈需要不斷反轉。
1.首先進行系統配置
Debug模式選擇可以選擇其他模式,默認選擇No debug,Timebase Source選擇SysTick,關于Timebase Source在后文會詳細講解。
圖2系統配置
2.時鐘配置,外部高速時鐘
圖3
配置系統時鐘配置72MHz,APB1總線配置36MHz。默認高速時鐘是使用內部(HSI),而且CPU時鐘配置的比較低。以我選擇的STM32F103,外部8M晶振為例(如下圖)。
圖4
3.GPIO初始化配置
我們將PB0、PG6、PG7配置輸出模式(高電平、低電平均可)、輸出速率、上/下拉等,默認即可。
圖5 GPIO初始化
4.工程生成設置
圖6
其他默認即可。最后點擊“生成代碼”即可生成代碼。
圖7生成代碼
1.3 GPIO流水燈實現與代碼分析
1.3.1 流水燈實現
我們要實現流水燈,需要在主函數添加一下代碼。
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);HAL_Delay(500);HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);HAL_Delay(500);HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);HAL_Delay(500);HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
圖8
1.3.2流水燈代碼分析
在分析代碼前,先看看流水燈編程流程:
1>使能GPIO端口時鐘;
2>初始化GPIO引腳,即為GPIO初始化結構體賦值,并調用相應初始化函數完成初始化配置;
3>根據實際需求控制流水燈。
STM32采用固件庫開發,代碼比較多,因此,我們在看一個實際工程時,只需從主函數開始,好了,接下來,筆者就帶領大家一步一步看看流水燈是怎么實現的。筆者先貼出主函數代碼。
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
注釋部分不用管,我們只看代碼。
1.復位所有硬件
HAL_Init()函數為復位所有硬件,這個就不細說了。
HAL_StatusTypeDef HAL_Init(void)
{
/* Configure Flash prefetch */
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) ||
defined(STM32F102x6) || defined(STM32F102xB) ||
defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) ||
defined(STM32F105xC) || defined(STM32F107xC)
/* Prefetch buffer is not available on value line devices */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif
#endif /* PREFETCH_ENABLE */
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
HAL_InitTick(TICK_INT_PRIORITY);
/* Init the low level hardware */
HAL_MspInit();
/* Return function status */
return HAL_OK;
}
2.時鐘初始化函數
SystemClock_Config()函數用于時鐘初始化,也就是通過STM32Cube實現。
圖9時鐘配置
時鐘初始化函數如下:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
RCC_OscInitTypeDef結構體類型定義時鐘來源和系統時鐘生成配置,就是圖9中的配置,本例程使用外部8MHz晶振,通過PLL鎖相環9倍頻后得到72M系統時鐘。
RCC_ClkInitTypeDef結構體類型定義總線時鐘配置,一般選擇使能系統時鐘、AHB、APB1和APB2總線時鐘,其中只有APB1總線時鐘36MHz,其他都為72MHz。
HAL_RCC_ClockConfig函數就是HAL定義的一個系統滴答定時器初始化配置函數,通過這個函數得到延時效果。
2.GPIO初始化函數
MX_GPIO_Init()函數用于LED的GPIO初始化,代碼如下:
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
/*Configure GPIO pin : PB0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PG6 PG7 */
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
以上就是LED的初始化函數,初始化GPIO有個重要的結構體GPIO_InitTypeDef,先看看該結構體。
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIO_mode_define */
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
This parameter can be a value of @ref GPIO_pull_define */
uint32_t Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;
Pin:引腳編號選擇,一個GPIO有16個引腳可選,參數可選有:GPIO_PIN_0、….、GPIO_PIN_15和GPIO_PIN_ALL。很多時候我們可以使用或運算進行選擇:GPIO_PIN_0| GPIO_PIN_4。
Mode:引腳模式選擇,在前文筆者已經介紹了引腳有8中工作模式,根據外設選擇相應模式。
表1GPIO引腳工作模式
Pull:上下拉,用于輸入模式,可選:GPIO_NOPULL不上下拉;GPIO_PULLUP:使能下拉;GPIO_PULLDOWN使能下拉;
Speed:引腳速度,可選:GPIO_SPEED_FREQ_LOW:低速(2MHz);中速(10MHz);高速(50MHz)。
在初始化代碼中,還有一個重要的函數HAL_GPIO_WritePin()。HAL_GPIO_WritePin()函數為3個LED燈時鐘初始化狀態,這里設置為低電平,所以初始化狀態3個LED都是暗的。
4.流水燈實現
在前文已經貼出了流水燈的相應代碼。
while (1)
{
/* USER CODE END WHILE */
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_7);
/* USER CODE BEGIN 3 */
}
HAL_GPIO_TogglePin函數用于GPIO電平反轉,HAL_Delay用于延時,單位是毫秒,以此不斷將LED1、LED2、LED3關滅,這就是實現流水燈的效果。
1.4實驗現象
將編譯好的程序下載到板子中,可以看到三個LED燈不同地閃爍。
上一篇:STM32選型考量指標
下一篇:STM32與FPGA用FMC進行通訊
- 熱門資源推薦
- 熱門放大器推薦
設計資源 培訓 開發板 精華推薦
- arduino esp8266開發板
- 【航順訓練營】基于航順HKF030的學習板設計
- DC1299A-B,用于 LTC6421CUD-20 雙路匹配 1.3GHz 差分放大器/ADC 驅動器的演示板
- NCV7429V1GEVB:NCV7429 系統基礎芯片評估板
- 使用 Analog Devices 的 LT1184FCS 的參考設計
- NCV78M09BDTRKG 9V可調輸出穩壓器的典型應用
- 【吉醫iCAN大賽】燈光品質檢測
- AM6TW-2407DH35Z ±7.2V 6 瓦單輸出 DC-DC 轉換器的典型應用
- 555_BJT-1811571124
- RDR-648 - 使用 HiperPFS-4 和 HiperLCS 的 150 W 功率因數校正 LLC 電源