原來(lái)LL庫(kù)是在1.1.0版本才加上的,大概意思就是:
1. LL APIs是寄存器級(jí)的編程,嗯,也就是我們常說(shuō)的直接操作寄存器吧。
2. LL APIs適用于xxx等一大堆外設(shè)
3. LL APIs函數(shù)全部定義為staticinline函數(shù),放在對(duì)應(yīng)的頭文件中,用戶使用需要包含相關(guān)頭文件
4. 參考這兩個(gè)文檔
看看LL庫(kù)文件在Cube庫(kù)中的位置,有20多個(gè)文件,全部以stm32l4xx_ll_xxx.h命名:
STM32Cube_FW_L4_V1.1.0DriversSTM32L4xx_HAL_DriverInc
就是講LL庫(kù)由5部分組成:每個(gè)外設(shè)對(duì)應(yīng)一個(gè)頭文件組成一部分,以及系統(tǒng)相關(guān)的bus,cortex,utils,system四個(gè)部分。
三、 開發(fā)環(huán)境搭建—— 新建STM32LL庫(kù)工程模板要開發(fā)首先要搭建開發(fā)環(huán)境,也就是簡(jiǎn)歷所謂的工程模板。由于獨(dú)立使用LL庫(kù)的情況下不能使用Cube來(lái)建立工程,所以需要手動(dòng)建立,這里的建工程方法和以前使用標(biāo)準(zhǔn)庫(kù)建工程模板比較類似:
1. 準(zhǔn)備相關(guān)文件:
新建一個(gè)文件夾用來(lái)放所有的文件
把需要用到的相關(guān)文件全部復(fù)制過(guò)來(lái):
首先是上一節(jié)說(shuō)到的幾個(gè)必不可少的文件
stm32l4xx.h,stm32l476xx.h,
system_stm32l4xx.h,system_stm32l4xx.c,
startup_stm32l476xx.s
這些文件都在STM32Cube_FW_L4_V1.1.0DriversCMSISDeviceSTSTM32L4xx文件夾下,為了方便查找,我保持了和庫(kù)文件中相同的文件夾結(jié)構(gòu)。如果閑麻煩,可以把STM32Cube_FW_L4_V1.1.0DriversCMSIS整個(gè)文件夾復(fù)制過(guò)來(lái),該文件夾下的其他文件如Include文件夾里面的也需要用到。
然后把所有LL庫(kù)的文件復(fù)制過(guò)來(lái),
STM32Cube_FW_L4_V1.1.0DriversSTM32L4xx_HAL_DriverInc文件夾下面所有stm32l4xx_ll_xxx.h命名的文件,也可以整個(gè)文件夾復(fù)制。
125005b8ank8aag2ag6kyl.png (35.33 KB, 下載次數(shù): 140)
下載附件
2016-6-17 16:13 上傳
其實(shí)主要就是這兩個(gè)文件夾下面相關(guān)的一些文件復(fù)制過(guò)來(lái)就好。當(dāng)然一股腦全部粘貼過(guò)去也沒什么影響,就是工程大一點(diǎn)(henduo)。
最后建立Inc,Src,MDK-ARM文件夾放頭文件、源文件和工程文件,,stm32l4xx_it.h/.c這兩個(gè)文件其實(shí)也可以不要,因?yàn)槲覀兛梢园阎袛嗪瘮?shù)處理函數(shù)放在任何地方都可以,main.c/main.h自己新建或者復(fù)制個(gè)模板。
所有文件,文件夾名字都可以隨便取,這里只是為了保持和庫(kù)、Cube建立的工程文件結(jié)構(gòu)保持一致,所以取這些名字。
125006f7grrhgqhsprjz5k.png (16.24 KB, 下載次數(shù): 115)
下載附件
2016-6-17 16:13 上傳
2. 好了,準(zhǔn)備工作做好了,開始建工程
打開Keil MDK,新建一個(gè)工程選擇型號(hào)STM32L4RG,在此之前需要確保已經(jīng)安裝了Keil STM32L4的Pack,不然新建工程的時(shí)候找不到對(duì)應(yīng)的型號(hào)。
125007m5sammzzx1svpekn.png (1.7 KB, 下載次數(shù): 143)
下載附件
2016-6-17 16:13 上傳
然后往工程里添加剛剛準(zhǔn)備好的相關(guān)文件:
125009lemmlqbr1nz0rz50.png (46.15 KB, 下載次數(shù): 121)
下載附件
2016-6-17 16:13 上傳
只需添加*.c和*.s文件,*.h文件設(shè)置頭文件包含路徑就行,也可以加到工程中方便查看。
接下來(lái)就是最重要的部分,工程設(shè)置:
有幾個(gè)主要地方需要設(shè)置,
1. 定義使用的芯片型號(hào) STM32L4xx
125009w8mc6nn0959fnv5w.png (46.96 KB, 下載次數(shù): 121)
下載附件
2016-6-17 16:13 上傳
2. 設(shè)置文件包含路徑
..Inc //自己寫的頭文件路徑
..DriversCMSISInclude //關(guān)于Cortex的一些頭文件
..DriversCMSISDeviceSTSTM32L4xxInclude // stm32l4xx.h,stm32l476xx.h等文件
..DriversSTM32L4xx_HAL_DriverInc //LL庫(kù)文件的路徑
125010goz4zocz2ttbafzx.png (23.1 KB, 下載次數(shù): 138)
下載附件
2016-6-17 16:13 上傳
3. 設(shè)置所用調(diào)試仿真器,使用Nucleo板載ST-Link
4.
125015h0yklfeyy40ffy8l.png (61.13 KB, 下載次數(shù): 134)
下載附件
2016-6-17 16:13 上傳
差不多就這些了,如果芯片型號(hào)選擇正確,pack安裝正確,其他的工程已經(jīng)默認(rèn)設(shè)置好,編譯一下無(wú)錯(cuò)誤無(wú)警告,下面就是真正的開發(fā),寫代碼了。
趁中午休息把開發(fā)環(huán)境搭建好,晚上回去寫兩個(gè)簡(jiǎn)單例子,這篇帖子就算是完結(jié)了!
四、 LL庫(kù) 第一個(gè)程序——點(diǎn)亮LED
首先點(diǎn)亮LED來(lái)驗(yàn)證下工程設(shè)置,代碼編寫是否正確。
1. 包含頭文件
在main.c中
#include "main.h"
在main.h中
- #include "stm32l4xx_ll_bus.h"
- #include "stm32l4xx_ll_rcc.h"
- #include "stm32l4xx_ll_system.h"
- #include "stm32l4xx_ll_utils.h"
- #include "stm32l4xx_ll_gpio.h"
- #include "stm32l4xx_ll_exti.h"
復(fù)制代碼
包含需要使用的相關(guān)模塊,要用那些就包含哪些,不知道用哪幾個(gè)就全部包含進(jìn)去。
2. 配置時(shí)鐘
用這個(gè)LL庫(kù)開發(fā)STM32跟用標(biāo)準(zhǔn)外設(shè)庫(kù)很像,很類似,只不過(guò)封裝層次更低。首先第一步要配置時(shí)鐘,因?yàn)閱?dòng)文件里沒有默認(rèn)配置,這和STM32F1早期的標(biāo)準(zhǔn)外設(shè)庫(kù)一樣,不過(guò)較高版本和后來(lái)的系列就可以不用了(如果使用默認(rèn)配置的話),啟動(dòng)文件里默認(rèn)配置了時(shí)鐘。怎么配置這里就不細(xì)說(shuō)了,看代碼應(yīng)該都能懂。
- __STATIC_INLINE void SystemClock_Config(void)
- {
- LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
-
- LL_RCC_HSI_Enable();
- while(LL_RCC_HSI_IsReady() != 1)
- {
- };
- LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_1, 10, LL_RCC_PLLR_DIV_2);
- LL_RCC_PLL_Enable();
- LL_RCC_PLL_EnableDomain_SYS();
- while(LL_RCC_PLL_IsReady() != 1) ;
- LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
- LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
- while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) ;
-
- LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
- LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
- LL_Init1msTick(80000000);
- LL_SetSystemCoreClock(80000000);
- }
復(fù)制代碼
函數(shù)聲明為__STATIC_INLINE(即staticinline)是因?yàn)樵搸?kù)所有函數(shù)都是__STATIC_INLINE,前面提到這樣做不需要額外的內(nèi)存,因此這樣最是為了保持這一點(diǎn)。
3. 將LED對(duì)應(yīng)引腳PA5配置為推挽輸出模式
- __STATIC_INLINE void Configure_GPIO(void)
- {
- LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
- LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_5, LL_GPIO_MODE_OUTPUT);
- LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_5, LL_GPIO_OUTPUT_PUSHPULL);
- LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_5, LL_GPIO_SPEED_LOW);
- LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_5, LL_GPIO_PULL_NO);
- }
復(fù)制代碼
4. PA5輸出高電平,點(diǎn)亮LED
LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5);
5. 最后需要在主函數(shù)中依次調(diào)用上訴函數(shù),編譯下載運(yùn)行即可看到Nulceo上的綠色LED被成功點(diǎn)亮了。
- int main(void)
- {
- SystemClock_Config();
- Configure_GPIO();
- LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5);
- while (1)
- { ;
- }
- }
復(fù)制代碼
/*碎碎念:雖然已經(jīng)不知道這是第幾百還是第幾千次做點(diǎn)燈實(shí)驗(yàn),依然還是不厭其煩啊,LED不愧是被稱為單片機(jī)屆的”Hello World!”*/
五、 添加其他程序功能
會(huì)了第一個(gè)程序,其他的就按照手冊(cè)講的寫就行了,再舉個(gè)簡(jiǎn)單的例子,利用按鍵中斷模式來(lái)控制LED的閃爍頻率。
只說(shuō)下大概步奏,不詳細(xì)說(shuō)明:將按鍵連接的引腳配置為中斷輸入模式,開啟中斷,配置中斷線,寫中斷服務(wù)函數(shù)來(lái)處理中斷。
- __STATIC_INLINE void Configure_EXTI(void)
- {
- LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
- LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
- LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_13, LL_GPIO_MODE_INPUT);
- LL_GPIO_SetPinPull(GPIOC, LL_GPIO_PIN_13, LL_GPIO_PULL_NO);
- NVIC_EnableIRQ(EXTI15_10_IRQn);
- NVIC_SetPriority(EXTI15_10_IRQn, 0);
- LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTC, LL_SYSCFG_EXTI_LINE13 );
- LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_13);
- LL_EXTI_EnableFallingTrig_0_31(LL_EXTI_LINE_13);
- }
復(fù)制代碼
在主函數(shù)調(diào)用Configure_EXTI()并添加代碼:
- while (1)
- {
- LL_GPIO_TogglePin(GPIOA, LL_GPIO_PIN_5);
- if(i == 0)
- {
- LL_mDelay(100);
- }
- else if(i == 1)
- {
- LL_mDelay(500);
- }
- else
- {
- LL_mDelay(1000);
- }
- }
復(fù)制代碼
實(shí)現(xiàn)功能:每按一次按鍵,LED改變一次閃爍頻率,間隔0.1s,0.5s,1s三種不同頻率循環(huán)閃爍。
最后,這個(gè)LL庫(kù)總體給人感覺是使用方法跟標(biāo)準(zhǔn)外設(shè)庫(kù)很像,但也有不同,前面也有提到,它全是直接操作寄存器,程序效率一定程度上會(huì)比較高,但使用起來(lái)有時(shí)候不一定那么方便,可移植性也不好,所以把它和HAL庫(kù)結(jié)合起來(lái)使用是最好的方式,在程序要求效率的地方就可以使用這些函數(shù),而其他地方使用HAL庫(kù),這也是我們常常使用的方法,只不過(guò)以前是使用HAL庫(kù),需要的地方我們自己直接寫操作寄存器,而現(xiàn)在可以換成使用這個(gè)【LL庫(kù)】了。
上個(gè)IAR工程模板:
stm32L476.7z
(2.24 MB, 下載次數(shù): 27)
2021-8-12 16:58 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5