最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

STM32野火教程學(xué)習(xí)筆記

2023-06-13 11:55 作者:是晃晃叔叔  | 我要投稿

up豬在C站(CSDN俗稱糞坑)的ID叫飛天大司馬,鑒于C站雖然閱讀量大,但是本人反饋無(wú)法及時(shí),因此在B站同步更新創(chuàng)作內(nèi)容,歡迎各位新老粉絲前來(lái)批評(píng)指正一起學(xué)習(xí)。

TIPS:

學(xué)習(xí)閱讀此文章需要儲(chǔ)備基礎(chǔ)的C語(yǔ)言知識(shí)和51單片機(jī)的一點(diǎn)點(diǎn)基礎(chǔ),當(dāng)然理解力超強(qiáng)的大佬除外。

歡迎使用STM32

雖然經(jīng)歷了疫情期間的價(jià)格起飛,但是STM32系列的單片機(jī)仍然是各個(gè)控制領(lǐng)域內(nèi)主流的微控制器。它是控制人的必修課之一。


STM32的編程方法

我們?cè)趯W(xué)習(xí)51單片機(jī)的時(shí)候,通常是通過(guò)編寫程序直接對(duì)其輸入輸出(i/o)口進(jìn)行操作。而STM32單片機(jī)更加高級(jí),它有更復(fù)雜的底層。因此我們對(duì)STM32單片機(jī)的編程方法有兩種。一個(gè)是類似于51單片機(jī)的直接控制片內(nèi)寄存器和i/o口的寄存器編程,一個(gè)是為了降低開(kāi)發(fā)難度給開(kāi)發(fā)者提供了巨大幫助的固件庫(kù)編程。今天所學(xué)習(xí)的是更加底層的寄存器編程。盡管在開(kāi)發(fā)的時(shí)候,我們用的基本上都是固件庫(kù)編程,但是學(xué)習(xí)寄存器編程有利于我們了解STM32的底層,學(xué)一門技術(shù)只有掌握了牢固的底層才是打了一個(gè)好的基礎(chǔ)。

前言

本人使用板子是野火STM32103指南者,型號(hào)是STM32VET6,兼容野火STM32f103霸道,型號(hào)是STM32ZET6。本筆記是在學(xué)習(xí)了野火官方教程的第11節(jié)課之后寫下的。如何安裝keilMDK,使用燒錄器,如何新建工程模板,請(qǐng)觀看野火stm32f103教程入門篇的前9節(jié)課。十分簡(jiǎn)單這里不再贅述。

野火教程B站鏈接

https://www.bilibili.com/video/BV1yW411Y7Gw/?p=6&;spm_id_from=333.880.my_history.page.click&vd_source=16419a44923b86308e680f95ec76193a

用寄存器編程點(diǎn)亮第一個(gè)LED燈以及LED燈的地址定義

單片機(jī)的點(diǎn)燈是所有微控制器的入門標(biāo)志,就好比C語(yǔ)言的Hello World!。這里我們類比一下51單片機(jī)的點(diǎn)燈方式。如圖


可以看到我們直接對(duì)LED連接的P2.0口進(jìn)行位操作拉低電平使其點(diǎn)亮。為何如此簡(jiǎn)單,奧妙就在于圖中第一行REG52.H當(dāng)中。這是一個(gè)C語(yǔ)言中叫做頭文件的東西,它用來(lái)存放一些已經(jīng)定義好的東西,比如在經(jīng)典的stdio.h中有各種數(shù)學(xué)運(yùn)算,REG52.H中就有定義每一個(gè)寄存器控制的i/o口也叫外設(shè)。

我們只要對(duì)這些定義好的東西操作,就可以通過(guò)單片機(jī)來(lái)控制各種電子器件了。

????????現(xiàn)在我們把目光轉(zhuǎn)移到stm32上來(lái),想要學(xué)會(huì)寄存器編程就要自己寫頭文件。先給頭文件起個(gè)名,非常好起就叫它stm32f103.h好了。在里面我們開(kāi)始寫定義寄存器,從而方便我們控制STM32的i/o口即GPIO口(外設(shè))的代碼,這種方法叫寄存器映射。

????????既然要控制寄存器,那么我們要知道寄存器的在單片機(jī)內(nèi)的地址,就如同警察叔叔找人要知道他的身份證號(hào)碼知道他住哪一樣。根據(jù)STM32官方給出的技術(shù)手冊(cè),外設(shè)的基地址(第一個(gè)地址,也叫起始位)是0x40000000,用C語(yǔ)言的unsigned int關(guān)鍵字將0x40000000轉(zhuǎn)化為地址位(16進(jìn)制數(shù))。其名稱根據(jù)外設(shè)的英語(yǔ)單詞periphral定義為PERIPH_BASE(如上圖代碼的第一行#define PERIPH_BASE ((unsigned int)0X40000000),這里用到了C語(yǔ)言里的宏定義知識(shí))。注意到這里我們還只是知道了寄存器的地址位還未對(duì)寄存器操作。

????????現(xiàn)在我們看第二行代碼,“#define APB1PERIPH_BASE PERIPH_BASE” 它的意思是定義在APB1上面的外設(shè)基地址,就是整個(gè)單片機(jī)的外設(shè)的基地址:0x40000000。至于APB1是什么,野火教程前面的課程有講解,簡(jiǎn)單點(diǎn)說(shuō)就是一塊放置外設(shè)的地方。

????????STM32的外設(shè)就分別放在APB1和APB2上,因此第三行是定義APB2上的外設(shè)地址,它的地址在APB1基地址上增加0x10000(16進(jìn)制數(shù))。

????????

第四行定義AHB的基地址,AHB在之前的野火課程中也有講解,這里簡(jiǎn)單說(shuō)一下它是橋接控制單片機(jī)外設(shè),時(shí)鐘和單片機(jī)內(nèi)核的部分,單片機(jī)想要工作必須打開(kāi)它從而打開(kāi)單片機(jī)的時(shí)鐘。因此第四行代碼“#define AHBPERIPH_BASE (PERIPH_BASE + 0X20000)”就是對(duì)AHB的地址定義了。

????????

定義完外設(shè)地址以后,我們還不能著急去定義寄存器實(shí)現(xiàn)寄存器映射。還有兩個(gè)重要的東西需要準(zhǔn)備。第一個(gè)東西:時(shí)鐘。單片機(jī)的時(shí)鐘就好像一個(gè)人的心臟,時(shí)鐘打開(kāi),單片機(jī)的心臟才開(kāi)始跳動(dòng),所以時(shí)鐘的地址就是AHB的初始地址上+0x1000。如第五行代碼所示。第二個(gè)東西:我們要控制的GPIO口。野火stm32單片機(jī)的LED燈在B號(hào)GPIO上,所以我們要控制GPIOB。GPIO就屬于單片機(jī)上的外設(shè)了,它的基地址就是APB2的基地址上+0x0C00。到這里點(diǎn)燈所有所需的地址位已經(jīng)準(zhǔn)備好了,我們要開(kāi)始通過(guò)這些地址位訪問(wèn)內(nèi)存來(lái)控制寄存器點(diǎn)燈了。

用寄存器編程點(diǎn)亮第一個(gè)LED燈的寄存器操作

代碼如下


????????首先我們要打開(kāi)時(shí)鐘,那么就要啟動(dòng)時(shí)鐘使能位,時(shí)鐘使能寄存器我們把它的名字叫做RCC_APB2ENR,它的地址是時(shí)鐘基地址上+0x18。

????????

? ? ????這里有一個(gè)難理解的點(diǎn),我們?yōu)槭裁匆M(jìn)行一個(gè)指針強(qiáng)制類型轉(zhuǎn)換這個(gè)操作?原因很簡(jiǎn)單,目前定義的那些地址例如APB1PERIPH_BASE,它還只是反映地址的立即數(shù)。打個(gè)比方,警察要找你,知道了你的身份證號(hào)。但是這不代表找到你了,只是知道了你的一個(gè)代號(hào),要找到你還得去線下你的住址找你。這樣的行為就像指針強(qiáng)制類型轉(zhuǎn)換的作用了,把代表寄存器地址的立即數(shù),強(qiáng)制轉(zhuǎn)化位指針,這樣它就是一個(gè)真正的地址了。真正的地址就可以訪問(wèn)寄存器來(lái)控制外設(shè)GPIO了。(指針不懂的去補(bǔ)補(bǔ)C語(yǔ)言指針,其實(shí)指針就是一個(gè)地址)

????????回到寄存器控制上來(lái),我們配置完時(shí)鐘后,下一步就是配置控制GPIO(外設(shè))的寄存器。點(diǎn)燈操作我們需要至少控制3個(gè)。端口配置低寄存器(CRL)、端口配置高寄存器(CRH)、端口輸出數(shù)據(jù)寄存器(ODR)最后3行就是這些寄存器的位和強(qiáng)制類型轉(zhuǎn)換的操作。

用寄存器編程點(diǎn)亮第一個(gè)LED燈

#include “stm32f10x.h”

int main(void)
{

//打開(kāi)GPIOB的時(shí)鐘


RCC_APB2ENR |=((1)<<3);

//清空控制PB0的端口位

??

GPIOB_CRL &= ~( (0x0F)<< (4*0));


// 配置IO口為輸出


GPIOB_CRL |=((1)<<(4*0)


// 控制ODR寄存器


GPIOB_ODR &= ~(1<<0);

//GPIOB_ODR |= (1<<0);關(guān)閉

}


void SystemInit(void)
{
//函數(shù)體為空,目的是為了騙過(guò)編譯器不報(bào)錯(cuò)

}

????????這里我們看到我們可以類似操作51單片機(jī)那樣直接對(duì)外設(shè)地址操作從而打開(kāi)時(shí)鐘,拉低GPIO口的電平點(diǎn)亮LED燈了。最后面那個(gè)紅色的騙過(guò)編譯器不報(bào)錯(cuò)是前面幾節(jié)課的內(nèi)容,打上就行,不用太深入了解,以后用不到。

????????

我們發(fā)現(xiàn)stm32對(duì)寄存器的操作不像51單片機(jī)可以直接賦值0或1,而是采用C語(yǔ)言里特殊的|=和&=~。|=是用于置1某一位而不改變其他位(一個(gè)寄存器上有好幾位,stm32單片機(jī)的一個(gè)寄存器有32位),比如這里的打開(kāi)時(shí)鐘是GPIOB的時(shí)鐘(main函數(shù)的第一行藍(lán)色代碼)。根據(jù)數(shù)據(jù)手冊(cè)GPIOB的時(shí)鐘在RCC_APB2ENR寄存器的第三位,把他第三位置1就單獨(dú)打開(kāi)了GPIOB的時(shí)鐘,這里我把數(shù)據(jù)手冊(cè)的截圖給大家看一下

????????另一個(gè)&=~,C語(yǔ)言讀法叫或等于取反,先是或等于再取反。其作用置0寄存器某一位而不改變其他位的值(狀態(tài))注意它后面永遠(yuǎn)是兩位16進(jìn)制數(shù),搭配左移右移符號(hào),后面再跟著想要置0的位數(shù)。例如主程序的第二行程序GPIOB_CRL &= ~( (0x0F)<< (4*0)),它的操作是將端口配置低寄存器初始4位(CNF0[0:1],MOOE0[0:1])全部置0,而不改變其他位的值(狀態(tài))。見(jiàn)下圖(0x0F這個(gè)16進(jìn)制數(shù)化為二進(jìn)制是00001111低四位是1111)

????????第三行代碼是控制GPIO口位為10MHz通用推挽輸出模式。將1左移4*0位變成0001(此寄存器每4位控制一個(gè)GPIO位的輸出模式)。

????????第四行就是將野火stm32指南者的LED綠燈(根據(jù)單片機(jī)開(kāi)發(fā)板原理圖GPIOB寄存器的第一位控制綠燈)點(diǎn)亮的操作,將ODR寄存器第1位置0(1左移0位)拉低電平。這樣我們就完成了點(diǎn)燈,入門成功!

————————————————

版權(quán)聲明:本文為CSDN博主「飛天大司馬」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/m0_51019960/article/details/129092570


STM32野火教程學(xué)習(xí)筆記的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
河曲县| 盖州市| 邢台市| 洪雅县| 屏边| 信阳市| 内乡县| 调兵山市| 广州市| 丹凤县| 铁岭市| 上栗县| 永年县| 白朗县| 正宁县| 顺昌县| 剑河县| 二手房| 富宁县| 雷州市| 南通市| 元氏县| 华亭县| 罗田县| 嵊州市| 托克逊县| 芮城县| 新蔡县| 玉林市| 响水县| 江口县| 四会市| 莆田市| 西乌珠穆沁旗| 垫江县| 谷城县| 安阳市| 静海县| 万山特区| 仙游县| 安仁县|