標準庫占絕大多數,自己買的板子跟的資料也一般是標準庫,HAL庫很少,不過要是使用STM32CubeMx配置,那么就是使用的HAL庫了,而參考資料是標準庫的,就沒有辦法用。
注意:
1. 標準庫與HAL庫不兼容,不要想著直接拿來用了,比如標準庫使用#include "stm32f10x.h",HAL庫使用#include "stm32f1xx_hal.h"
要讓標準庫程序使用HAL庫時也可以正常運行得到想要的結果,有以下幾種方法:
一、 將標準庫程序中的每個函數內的代碼修改為使用HAL庫且同樣效果的代碼,
比如標準庫中配置GPIO的代碼直接就可以用STM32CubeMx配置為相同效果
二、根據標準庫程序整個程序運行的原理使用HAL庫中提供的函數實現,
比如使用IIC寫入內存的代碼可以使用HAL庫中提供的函數HAL_I2C_Mem_Write
實現
先舉例介紹第一種方法:
1. 外部中斷
標準庫:中斷入口函數在stm32f10x_it.c中,修改void EXTI&_IRQHandler()
使用if(EXTI_GetITStatus(EXTI_Line2)==SET)判斷是否產生中斷
處理中斷時,要清除中斷線路掛起位(EXTI_ClearITPendingBit),以便下次使用
HAL庫:在stm32f1xx_it.c中依然有中斷入口函數void EXTI2_IRQHandler(void)
該函數調用了HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);,當該引腳產生中斷事件時會調用該函數
最后會由HAL_GPIO_EXTI_Callback(GPIO_Pin);回調函數執行中斷,該函數是可以被重定義的,復制該函數添加到main.c中就可以進行特定引腳的中斷事件處理
在HAL庫的回調函數和標準庫的中斷入口函數中的中斷事件執行是差不多的
2. 引腳操作
51、STM32的標準庫和HAL庫對引腳都有基本的讀取引腳狀態和設置引腳的操作
51:P0? = 0x00; //置P0口為低電平,P08個IO口全為低電平
P0? = 0xff; //置P0口為高電平
注意P0有8個IO口,即從P0.0到P0.7,而0x00二進制就是0000 0000,效果就是P0.0到P0.7都是0,即低電平。
P0 = 0xC8;
51可以實現直接將八位二進制直接傳遞給8個IO口,只需一次傳值;也可以單獨對某個IO口設置,但HAL庫只能一次對一個引腳操作
標準庫:GPIO_SetBits(GPIOC,GPIO_Pin_All);將引腳置1,可以將多個引腳一起設置使用GPIOx->BSRR = GPIO_Pin;
GPIO_ResetBits(GPIOC,GPIO_Pin_All);將引腳置0,使用GPIOx->BRR = GPIO_Pin;
GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)讀取引腳狀態
HAL庫:所有GPIO的操作函數在stm32f1xx_hal_gpio.h中,也定義了一些GPIO設置用到的參數
具體函數見stm32f1xx_hal_gpio.h,功能和標準庫大致相同,有一個引腳反轉函數HAL_GPIO_TogglePin
問題:如何使用HAL庫實現向多個引腳寫入八位十六進制數據?
51:cmd = 0xc8;
PC = cmd;
HAL庫:cmd = 0xc8;
if(cmd&0x01)
{
HAL_GPIO_WritePin(GPIOC,D0_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D0_Pin,GPIO_PIN_RESET);
}
if(cmd&0x02)
{
HAL_GPIO_WritePin(GPIOC,D1_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D1_Pin,GPIO_PIN_RESET);
}
if(cmd&0x04)
{
HAL_GPIO_WritePin(GPIOC,D2_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D2_Pin,GPIO_PIN_RESET);
}
if(cmd&0x08)
{
HAL_GPIO_WritePin(GPIOC,D3_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D3_Pin,GPIO_PIN_RESET);
}
if(cmd&0x10)
{
HAL_GPIO_WritePin(GPIOC,D4_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D4_Pin,GPIO_PIN_RESET);
}
if(cmd&0x20)
{
HAL_GPIO_WritePin(GPIOC,D5_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D5_Pin,GPIO_PIN_RESET);
}
if(cmd&0x40)
{
HAL_GPIO_WritePin(GPIOC,D6_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D6_Pin,GPIO_PIN_RESET);
}
if(cmd&0x80)
{
HAL_GPIO_WritePin(GPIOC,D7_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOC,D7_Pin,GPIO_PIN_RESET);
}
這個方法比較笨,是使用與運算直接判斷八位二進制數據的各位是0還是1,然后設置相應引腳即可。
3. 直接操作寄存器
這個在標準庫和HAL庫中的使用是一樣的,
標準庫:例如 #define IIC_SDA_IN()? {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 8 << 12;GPIOB->BSRR = 1 << 11;}
其中GPIOB是在stm32f10x.h中定義的,其中BSRR、CRH等是GPIO結構體中的屬性,結構體為:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
HAL庫:例如? #define LCD_RST_CLR GPIOC->BRR=1<<5
其中GPIOC是在stm32f103xe.h中定義的,BSRR,BRR等GPIO結構體的屬性也是在該文件中定義的,具體結構體為:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
與標準庫的GPIO結構體定義相同。
評論
查看更多