STM32Hal庫學習筆記


STM32之旅

學習了51單片機后,就要接觸到更高級一點的單片機了,比如STM32,ST也有很多款單片機,現在用比較基礎的學習——STM32F103RCT6。

一、LED驅動

hal庫的使用比較簡單,可以直接在STM32CubeMX中分配好IO之后一鍵生成工程,為了提高程序的可讀性,自己寫一個頭文件,在調用過程中會比較簡單。

drv_led.h:

#ifndef __DRV_LED_H
#define __DRV_LED_H


#define LED1_PIN 			GPIO_PIN_8
#define LED1_PORT 			GPIOA

#define LED2_PIN 			GPIO_PIN_2
#define LED2_PORT 			GPIOD

#define LED1_ON				HAL_GPIO_WritePin(LED1_PORT, LED1_PIN, GPIO_PIN_RESET)
#define LED1_OFF			HAL_GPIO_WritePin(LED1_PORT, LED1_PIN, GPIO_PIN_SET)

#define LED2_ON				HAL_GPIO_WritePin(LED2_PORT, LED2_PIN, GPIO_PIN_RESET)
#define LED2_OFF			HAL_GPIO_WritePin(LED2_PORT, LED2_PIN, GPIO_PIN_SET)


#endif


二、按鍵驅動

幾乎每個項目都有用到按鍵,為了避免以后在做大項目的時候還在琢磨按鍵怎么寫,現在寫一個,方便以后使用。

drv_key.h:

#ifndef __DRV_KEY_H
#define __DRV_KEY_H

#define RESET 					0
#define SET 					1

#define WK_UP_PIN 				GPIO_PIN_0
#define WK_UP_PORT 				GPIOA

#define KEY1_PIN 				GPIO_PIN_5
#define KEY1_PORT 				GPIOC
	
#define KEY2_PIN 				GPIO_PIN_15
#define KEY2_PORT 				GPIOA

#define WK_UP					HAL_GPIO_ReadPin(WK_UP_PORT,WK_UP_PIN)
#define KEY1					HAL_GPIO_ReadPin(KEY1_PORT,KEY1_PIN)
#define KEY2					HAL_GPIO_ReadPin(KEY2_PORT,KEY2_PIN)

void key_scan(void);

#endif

drv_key.c:

#include "stm32f1xx.h"
#include "drv_led.h"
#include "drv_key.h"

void key_scan(void)
{
    if(RESET == KEY1)
    {
          HAL_Delay(10);				//消抖
          if(RESET == KEY1)
          {
                /********事件區***********/
                ED1_ON;	
                /********事件區***********/
                while(RESET == KEY1);	//松手反應
          }
    }

    if(RESET == KEY2)
    {
          HAL_Delay(10);				//消抖
          if(RESET == KEY2)
          {
                /********事件區***********/
                LED2_ON;
                /********事件區***********/
                while(RESET == KEY2);	//松手反應
          }
    }
}

三、時鍾樹

STM32F1是M3內核,它的時鍾數很龐大,讓一個初學者去看,估計會很吃力,和我們入門的8051單片機的時鍾不同,這里又倍頻、又分頻,而且還分成好多個時鍾,不同的外設時鍾不一樣。

總感覺不都明了,后來在STM32CubeMX中看到了時鍾配置,這個看起來就明了多了

四、USART

串口也是用的比較多的,在STM32CubeMX中生成代碼后,需要添加一些代碼才可以用。

drv_usart.h:

#ifndef __DRV_USART_H
#define __DRV_USART_H

#define USART1_MAX_LEN 64						//接收區長度
#define USART1_BUFF_CACHE_LEN 1					//接收緩沖區長度

extern uint16_t g_usart1_sta;					//接收狀態[1:15],最高位為接收完成標志
extern uint8_t g_usart1_buff[USART1_MAX_LEN];						//接收buff
extern uint8_t g_usart1_buff_cache[USART1_BUFF_CACHE_LEN];			//接收緩存

#endif

使用printf()發送的時候需要重定向,沒有fputc()是不行的;使用中斷接收的時候,並不是在USART1_IRQHandler()里面添加代碼,而是在回調函數HAL_UART_RxCpltCallback()中寫,接收完成時要在后面加上HAL_UART_Receive_IT(),串口初始化時也要加上HAL_UART_Receive_IT(),否則不能進中斷。

drv_usart.c:

#include "stm32f1xx.h"
#include "drv_usart.h"
#include "stdio.h"
#include "usart.h"

uint16_t g_usart1_sta;//接收狀態[1:15],最高位為接收完成標志
uint8_t g_usart1_buff[USART1_MAX_LEN];
uint8_t g_usart1_buff_cache[USART1_BUFF_CACHE_LEN];

/***********printf函數重寫,有了這個函數就可以使用printf()發送串口數據了**********/
int fputc(int ch,FILE *f)
{
    uint8_t temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,2);

    return 0;
}
/****************************串口中斷回調函數*************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(USART1 == huart->Instance)
    {
          if(0 == (g_usart1_sta & 0x8000))//接收未完成
          {
                g_usart1_buff[g_usart1_sta++] = g_usart1_buff_cache[0];

                if(0x0A == g_usart1_buff_cache[0])//如果接收到回車,就接收完成
                {
		    g_usart1_sta |= 0x8000;
                }
          }
          HAL_UART_Receive_IT(&huart1,(uint8_t *)g_usart1_buff_cache,USART1_BUFF_CACHE_LEN);
    }
}

這里沒加HAL_UART_Receive_IT()是不會進進中斷的。


usart.c:
void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
          Error_Handler();
    }
    HAL_UART_Receive_IT(&huart1,g_usart1_buff_cache,USART1_BUFF_CACHE_LEN);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM