STM32CubeMX-HAL庫開發筆記
前言
這是自己撰寫的一個打地鼠的小游戲,串口顯示程式運行位置,右方小燈顯示分數,達到17分進入彩蛋程式,

Proteus 8 配置工程

使用Proteus 8可以仿真STM32F103系列T4、T6、C4、C6、R4、R6單片機,可以幫助專案前期少走一點彎路,學習者前期可以少花點錢去學習STM32,

使用STM32CubeMX配置基礎工程的部分不做講解,因為圖形化真的很簡單,本文章主要記錄在配置工程后,HAL庫函式的使用,
1、GPIO
讀取IO:

HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin);
寫入IO:

HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
HAL_GPIO_WritePin(GPIOA,LED0_Pin,GPIO_Pin_RESET) //置1;
HAL_GPIO_WritePin(GPIOA,LED0_Pin,GPIO_Pin_SET) //置0;
翻轉IO:
HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
HAL_GPIO_TogglePin(GPIOA, LED0_Pin);
按鍵例子:
if(HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin) == GPIO_Pin_SET);
{
while(HAL_GPIO_ReadPin(GPIOA,BUTTONO_Pin) == GPIO_Pin_SET);//等待按鍵抬起
HAL_GPIO_TogglePin(GPIOA, LED0_Pin); //翻轉
HAL_Delay(200); //延時200ms
HAL_GPIO_TogglePin(GPIOA, LED0_Pin); //翻轉
}
2、串口通信

串口通信模式:
Asynchronous:異步通信
發送、接收資料
//發送資料
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
uint8_t temp[] = "Hello World!\n\r";
HAL_UART_Transmit(&huart1,temp,12,50);
//接收資料
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
printf 重定向
在Private includes中引入
#include <stdio.h>
在USER CODE BEGIN 0 添加
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2); //h-uart1需要根據自己的配置修改
return ch;
}
然后就可以在任意地方使用printf陳述句方便的輸出你想要的內容,
printf("Hello World!\n\r");
HAL_Delay(200);

LOG資訊列印
主流嵌入式輸出格式:[日志級別] 檔案名: 日志資訊
"[info] main.c : init ok!"
"[debug] adc.c : adc_getvalue -> 3.3V"
printf("[info] main.c : HAL_Init ok! \r\n");
條件編譯
在單片機開發程序中,需要大量的LOG資訊;但是開發結束后,不需要一直列印(拖慢單片機速度),
所以在main.h頭檔案添加:
#define Log 1 //列印Log資訊,不想列印時改為0即可
再把.c檔案中所有printf陳述句包裹上#id Log 與 #endif:
#if Log
printf("[info] main.c : HAL_Init ok! \r\n");
# endif
個性化串口輸出
字符轉ASCII碼網站: 個性化
#define Log 1 //列印Log資訊,不想列印時改為0即可
#if Log
printf(" _____ ______ _______ _ _ _____ _ _ \r\n");
printf(" | __ )| ____|__ __| | | | __ )( ) | |\r\n");
printf(" | |__) | |__ | | | | | | |__) | )| |\r\n");
printf(" | _ /| __| | | | | | | _ /| . ` |\r\n");
printf(" | | ) )| |____ | | | |__| | | ) (| |( |\r\n");
printf(" |_| )_)______| |_| (_____/|_| )_(_| (_|\r\n");
# endif

可變引數宏
在Private includes中引入
#include <stdio.h>
在USER CODE BEGIN 0 添加
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2); //h-uart1需要根據自己的配置修改
return ch;
}
在USER CODE BEGIN 0 添加
#define USER_LOG //注釋此行,不列印
#ifdef USER_LOG
#define user_main_printf(format,...) printf(format "\r\n",##__VA_ARGS__)
#define user_main_info(format,...) printf("[main]info:" format "\r\n",##__VA_ARGS__)
#define user_main_debug(format,...) printf("[main]debug:" format "\r\n",##__VA_ARGS__)
#define user_main_error(format,...) printf("[main]error:" format "\r\n",##__VA_ARGS__)
#else
#define user_main_printf(format,...)
#define user_main_info(format,...)
#define user_main_debug(format,...)
#define user_main_error(format,...)
#endif
在while()中添加
user_main_info("Hello World!");
HAL_Delay(200);
自動添加報頭和報尾

發送、接收中斷
//發送中斷
HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//接收中斷
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
DMA
//使用DMA發送
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//使用DMA接收
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
//DMA暫停
HAL_UART_DMAPause(UART_HandleTypeDef *huart);
//DMA恢復
HAL_UART_DMAResume(UART_HandleTypeDef *huart);
//DMA停止
HAL_UART_DMAStop(UART_HandleTypeDef *huart);
3、外部中斷
回呼函式
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == BUTTON0_Pin); //多個外部中斷,需要進一步判斷
}
4、定時器


使能
HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
HAL_TIM_Base_Start_IT(&htim1); //定時器1使能
回呼函式
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim1.Instance)
{
//定時器1中斷業務
}
}
//讀取定時器1的數值
int time_num = __HAL_TIM_GET_COUNTER(&htim1); //讀取定時器1的數值
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/286692.html
標籤:其他
上一篇:簡單實作掌控板搶答器實驗
