前言
在嵌入式系統(tǒng)開發(fā)中,HAL(Hardware Abstraction Layer)庫是一個重要的概念,它提供了一個抽象層,使開發(fā)者可以更容易地編寫可移植的代碼,而不必擔心底層硬件的細節(jié)。STM32CubeMX是一款由STMicroelectronics提供的工具,用于生成STM32微控制器的初始化代碼,其中包括了HAL庫的使用。
HAL庫的本質(zhì)與HAL庫源碼分析
HAL庫的本質(zhì)是一個由供應商提供的軟件庫,旨在提供一系列抽象接口,用于訪問底層硬件資源,如GPIO、USART、I2C等。這些接口隱藏了底層硬件的細節(jié),使得開發(fā)者能夠以統(tǒng)一的方式進行開發(fā),而不必擔心不同型號或者不同系列的微控制器的差異。
HAL庫的源碼分析可以揭示其內(nèi)部的工作原理和實現(xiàn)細節(jié)。通過分析源碼,我們可以了解到每個函數(shù)的具體功能、調(diào)用關系以及與底層硬件交互的細節(jié)。HAL庫通常包括了對不同硬件模塊的驅(qū)動程序,這些驅(qū)動程序是與特定型號的微控制器兼容的。
一、HAL庫的本質(zhì)
1.1 HAL庫的本質(zhì)是操作寄存器
其實點燈就是操作下面的output data register
比如我們之前點燈寫的HAL_GPIO_WritePin()
他的源碼如下:
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
}
}
他去設置某個寄存器等于某個值,這叫是HAL庫的本質(zhì)
1.2 自己實現(xiàn)HAL_GPIO_WritePin
寄存器
CPU可以發(fā)出地址,然后訪問比如Flash、RAM、GPIOC
我們可以通過訪問某一個地址區(qū)間去訪問Flash
訪問其他地址訪問GPIOC等等等等
我們可以訪問ram,寫入val,讀出仍是val
我們可以訪問flash,使用讀出指令,不能直接寫
在GPIOC里面有很多的寄存器,但我們不能像操作ram和flash一樣,這些寄存器的功能各有不同
比如說以我這個F103ZE為例子:
比如Port configuration配置寄存器,一個低位,一個高位
比如輸入寄存器:Port input data,通過讀他,可以得到引腳的狀態(tài)/數(shù)據(jù)
比如輸出寄存器:Port output data,我們可以通過寫這個寄存器,讓這個引腳輸出高低電平
還有一些其他的
通過寄存器的操作點燈
我們可以在芯片手冊中找到GPIOC的基地址,在看GPIOC的輸出寄存器偏移地址可以得出,要訪問輸出寄存器就要訪問0x400110C這個地址的寄存器
比如說,舉個例子:我們可以通過一個C語言的指針指向這個要操作的寄存器
然后把里面的值給改變了是不是就操作了寄存器的值
他的每一個寄存器的大小都是2bytes
首先我們使用指針指向寄存器的位子
unsigned int *p;
p = (unsigned int*)0x40010C0C;
接下來我們需要操作第十三個寄存器,即可點亮我們的燈
比如我們可以這樣設置他為1:
unsigned int val = *p;
val = val | (1<<5);
*p = val;
我們可以這樣設置他為0:
val = *p;
val = val & ~(1<<5);
*p = val;
這樣我們就通過寄存器輸出高低電平了
要注意的是,比如你要操作GPIOC里面的13,你就要移13,像下面這樣,其他的也是一樣
要操作哪個引腳就偏移他的引腳名稱,我這里的燈是PB5,所以就把他的地址里面的值偏移5即可
代碼概況
/* 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 */
unsigned int *p;
p = (unsigned int*)0x40010C0C;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
unsigned int val = *p;
val = val | (1<<5);
*p = val;
HAL_Delay(500);
val = *p;
val = val & ~(1<<5);
*p = val;
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
Port bit set/reset register寄存器
像我們上面,我們需要把寄存器的內(nèi)容拿出來,然后通過控制某一位的0/1來操作高低電平,這樣稍微有點麻煩,那么我們可以使用下面這個寄存器Port bit set/reset register,他只需要寫入1到某一位就可以輸出高電平/低電平
他是一個32位的寄存器
比如BRy
他寫入1就把指定的GPIO reset
0就是沒有任何作用
比如BSy
他寫入1就是指定GPIO set
0就是沒有任何作用
那么我們就可以把代碼變成這樣:
unsigned int *p;
p = (unsigned int*)(0x40010C00 + 0x10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
unsigned int val = *p;
*p = (1 << 21);
HAL_Delay(500);
*p = (1 << 5);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
通過寫21位,把他變成reset狀態(tài)
通過寫5位,把他變成set狀態(tài),這樣就實現(xiàn)了閃爍燈文章來源:http://www.zghlxwxcb.cn/news/detail-828585.html
總結
HAL庫作為嵌入式系統(tǒng)開發(fā)中的重要工具,提供了一種方便、快捷的方式來訪問STM32微控制器的硬件資源。通過使用HAL庫,開發(fā)者可以更加專注于應用程序的開發(fā),而不必花費大量時間去編寫底層的驅(qū)動程序。通過深入分析HAL庫的源碼,我們可以更好地理解其內(nèi)部實現(xiàn)細節(jié),從而更好地利用這一工具來開發(fā)高效、可靠的嵌入式應用程序。文章來源地址http://www.zghlxwxcb.cn/news/detail-828585.html
到了這里,關于【STM32 CubeMX】HAL庫的本質(zhì)讀寫寄存器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!