標準庫占絕大多數(shù),自己買的板子跟的資料也一般是標準庫,HAL庫很少,不過要是使用STM32CubeMx配置,那么就是使用的HAL庫了,而參考資料是標準庫的,就沒有辦法用。
注意:
1. 標準庫與HAL庫不兼容,不要想著直接拿來用了,比如標準庫使用#include "stm32f10x.h",HAL庫使用#include "stm32f1xx_hal.h"
要讓標準庫程序使用HAL庫時也可以正常運行得到想要的結(jié)果,有以下幾種方法:
一、 將標準庫程序中的每個函數(shù)內(nèi)的代碼修改為使用HAL庫且同樣效果的代碼,
比如標準庫中配置GPIO的代碼直接就可以用STM32CubeMx配置為相同效果
二、根據(jù)標準庫程序整個程序運行的原理使用HAL庫中提供的函數(shù)實現(xiàn),
比如使用IIC寫入內(nèi)存的代碼可以使用HAL庫中提供的函數(shù)HAL_I2C_Mem_Write
實現(xiàn)
先舉例介紹第一種方法:
1. 外部中斷
標準庫:中斷入口函數(shù)在stm32f10x_it.c中,修改void EXTI&_IRQHandler()
使用if(EXTI_GetITStatus(EXTI_Line2)==SET)判斷是否產(chǎn)生中斷
處理中斷時,要清除中斷線路掛起位(EXTI_ClearITPendingBit),以便下次使用
HAL庫:在stm32f1xx_it.c中依然有中斷入口函數(shù)void EXTI2_IRQHandler(void)
該函數(shù)調(diào)用了HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);,當該引腳產(chǎn)生中斷事件時會調(diào)用該函數(shù)
最后會由HAL_GPIO_EXTI_Callback(GPIO_Pin);回調(diào)函數(shù)執(zhí)行中斷,該函數(shù)是可以被重定義的,復制該函數(shù)添加到main.c中就可以進行特定引腳的中斷事件處理
在HAL庫的回調(diào)函數(shù)和標準庫的中斷入口函數(shù)中的中斷事件執(zhí)行是差不多的
2. 引腳操作
51、STM32的標準庫和HAL庫對引腳都有基本的讀取引腳狀態(tài)和設置引腳的操作
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可以實現(xiàn)直接將八位二進制直接傳遞給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)讀取引腳狀態(tài)
HAL庫:所有GPIO的操作函數(shù)在stm32f1xx_hal_gpio.h中,也定義了一些GPIO設置用到的參數(shù)
具體函數(shù)見stm32f1xx_hal_gpio.h,功能和標準庫大致相同,有一個引腳反轉(zhuǎn)函數(shù)HAL_GPIO_TogglePin
問題:如何使用HAL庫實現(xiàn)向多個引腳寫入八位十六進制數(shù)據(jù)?
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);
}
這個方法比較笨,是使用與運算直接判斷八位二進制數(shù)據(jù)的各位是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結(jié)構(gòu)體中的屬性,結(jié)構(gòu)體為:
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結(jié)構(gòu)體的屬性也是在該文件中定義的,具體結(jié)構(gòu)體為:
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結(jié)構(gòu)體定義相同。
評論
查看更多