欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: STM32深入淺出 [打印本頁(yè)]

作者: 51heisex    時(shí)間: 2016-1-23 03:15
標(biāo)題: STM32深入淺出
STM32學(xué)前班教程之一:為什么是它  
經(jīng)過(guò)幾天的學(xué)習(xí),基本掌握了STM32的調(diào)試環(huán)境和一些基本知識(shí)。想拿出來(lái)與大家共享,笨教程本著最大限度簡(jiǎn)化刪減STM32入門(mén)的過(guò)程的思想,會(huì)把我的整個(gè)入門(mén)前的工作推薦給大家。就算是給網(wǎng)上的眾多教程、筆記的一種補(bǔ)充吧,所以叫學(xué)前班教程。其中涉及產(chǎn)品一律隱去來(lái)源和品牌,以防廣告之嫌。全部漢字內(nèi)容為個(gè)人筆記。所有相關(guān)參考資料也全部列出。:lol  

教程會(huì)分幾篇,因?yàn)樘L(zhǎng)啦。今天先來(lái)說(shuō)說(shuō)為什么是它——我選擇STM32的原因。  

我對(duì)未來(lái)的規(guī)劃是以功能性為主的,在功能和面積之間做以平衡是我的首要選擇,而把運(yùn)算放在第二位,這根我的專(zhuān)業(yè)有關(guān)系。里面的運(yùn)算其實(shí)并不復(fù)雜,在入門(mén)階段想盡量減少所接觸的東西。

不過(guò)說(shuō)實(shí)話(huà),對(duì)DSP的外設(shè)并和開(kāi)發(fā)環(huán)境不滿(mǎn)意,這是為什么STM32一出就轉(zhuǎn)向的原因。下面是我自己做過(guò)的兩塊DSP28的全功能最小系統(tǒng)板,在做這兩塊板子的過(guò)程中發(fā)現(xiàn)要想盡力縮小DSP的面積實(shí)在不容易(目前只能達(dá)到50mm×45mm,這還是沒(méi)有其他器件的情況下),尤其是雙電源的供電方式和1.9V的電源讓人很頭疼。

后來(lái)因?yàn)橐粋(gè)項(xiàng)目,接觸了LPC2148并做了一塊板子,發(fā)現(xiàn)小型的ARM7在外設(shè)夠用的情況下其實(shí)很不錯(cuò),于是開(kāi)始搜集相關(guān)芯片資料,也同時(shí)對(duì)小面積的AVR和51都進(jìn)行了大致的比較,這個(gè)時(shí)候發(fā)現(xiàn)了CortexM3的STM32,比2148擁有更豐富和靈活的外設(shè),性能幾乎是2148兩倍(按照MIPS值計(jì)算)。正好2148我還沒(méi)上手,就直接轉(zhuǎn)了這款STM32F103。

與2811相比較(核心1.8V供電情況下),135MHz×1MIPS。現(xiàn)在用STM32F103,72MHz×1.25MIPS,性能是DSP的66%,STM32F103R型(64管腳)芯片面積只有2811的51%,STM32F103C型(48管腳)面積是2811的25%,最大功耗是DSP的20%,單片價(jià)格是DSP的30%。且有更多的串口,CAP和PWM,這是有用的。高端型號(hào)有SDIO,理論上比SPI速度快。

    由以上比較,準(zhǔn)備將未來(lái)的擁有操作系統(tǒng)的高端應(yīng)用交給DSP的新型浮點(diǎn)型單片機(jī)28335,而將所有緊湊型小型、微型應(yīng)用交給STM32。


STM32學(xué)前班教程:怎么開(kāi)發(fā)  



sw笨笨的STM32學(xué)前班教程之二:怎么開(kāi)發(fā)目前手頭的入門(mén)階段使用的開(kāi)發(fā)器概述

該產(chǎn)品為簡(jiǎn)易STM32調(diào)試器和DEMO板一體化的調(diào)試學(xué)習(xí)設(shè)備,價(jià)格在一百多塊。

2、硬件配置

仿真部分:USB口,reset,指示燈,JTAG

DEMO部分:4按鍵(IO),4LED(IO),一個(gè)串口,啟動(dòng)方式跳線(xiàn),所有引腳的焊盤(pán)(可自行焊接插針進(jìn)行擴(kuò)展)

DEMO芯片:STM32F103C8T6(程序空間64K)

參數(shù)和擴(kuò)展:

注:學(xué)習(xí)的目標(biāo)芯片是STM32F103CBT6(7×7mm,128K flash,16K RAM)以及STM32F103RET6(10×10mm,512K flash,64K RAM)。

STM32-SK的硬件連接方法(用板載調(diào)試器調(diào)試板載DEMO):

JP3、JP5 須全部短接

USB通過(guò)電纜連接至PC的USB

串口連接至PC的串口或者通過(guò)USB轉(zhuǎn)串口電纜連接(力特Z-TEC,USB2.0與RS232轉(zhuǎn)接電纜)

WindowsXP自動(dòng)安裝驅(qū)動(dòng)

安裝完成后如果DEMO板里面有程序就會(huì)自動(dòng)運(yùn)行了。這是ST-Link-II的通用連接方法

以上是學(xué)習(xí)階段比較方便的仿真器,進(jìn)入工程階段后準(zhǔn)備換J-Link V7的仿真器進(jìn)行開(kāi)發(fā)。目前比較滿(mǎn)意的產(chǎn)品:JLink v7+USB轉(zhuǎn)串口:

  購(gòu)買(mǎi)后所需的改造:打開(kāi)殼體,將USB的+5V供電跟JTAG20針的第二腳Vsupply飛線(xiàn),提供目標(biāo)板5V500mA的供電。看中的特點(diǎn):集成串口,擁有20針JTAG可以改造Vspply為供電接口,小巧好帶,便宜。

常見(jiàn)的用于STM32單片機(jī)的仿真器分類(lèi)

a) Ulink2:之前常用的仿真器。Keil公司產(chǎn)品,之前專(zhuān)用于ARM7,現(xiàn)擴(kuò)展到CortexM3,調(diào)試接口支持JTAG和SWD,連接到PC主機(jī)的USB。現(xiàn)在這種調(diào)試器已經(jīng)用的越來(lái)越少了。

b) ST-Link-II:ST公司的仿真接口,支持IAR EWARM,USB 1.1全速,USB電源供電,自適應(yīng)目標(biāo)系統(tǒng)JTAG電平3.3V-5V,可向目標(biāo)系統(tǒng)提供不大于5V/200mA電源。這種調(diào)試器不多見(jiàn),但是許多調(diào)試器與目標(biāo)板一體設(shè)計(jì)的學(xué)習(xí)板上常見(jiàn)。

c) J-Link V6/V7:SEGGER公司產(chǎn)品,調(diào)試接口支持JTAG和SWV(V7速度是V6的12倍),USB 2.0接口,通過(guò)USB供電,下載速度達(dá)到720k byte/s, 與IAR WEARM無(wú)縫集成,寬目標(biāo)板電壓范圍:1.2V-3.3V(V7支持5V),多核調(diào)試,給目標(biāo)板提供3.3V50mA電源。這種調(diào)試器現(xiàn)在出現(xiàn)的越來(lái)越多,兼容性比較好(主要是指能夠與IAR WEARM無(wú)縫集成這點(diǎn)),國(guó)內(nèi)山寨貨和各種變種也很多。

6、目標(biāo)板主要分為一體化設(shè)計(jì)(與調(diào)試器、供電整合)和單獨(dú)設(shè)計(jì)兩類(lèi),詳細(xì)產(chǎn)品比較見(jiàn)豆皮的《如何選擇STM32開(kāi)發(fā)板》。


                                               STM32學(xué)前班教程之三:讓PC工作  



開(kāi)發(fā)軟件的選擇

1、 軟件與版本的選擇

需求:支持STLink2或未來(lái)的Jlink V7調(diào)試接口(因?yàn)镾TM32-SK使用這個(gè)接口),能夠找到去除軟件限制的方法,最好具有中文版幫助和界面,最好帶有純軟件仿真

選擇:RealView MDK 3.23RPC或者IAR EWARM 4.42A(5版本觀望一下)。

2、 RealView MDK 3.23RPC(中國(guó)版)安裝與去除限制

第一步:執(zhí)行安裝程序完成基本安裝,最后選項(xiàng)選擇加入虛擬硬件,便于純軟件調(diào)試。

第二步:執(zhí)行軟件,點(diǎn)擊File-->Licence Manager,復(fù)制CID的數(shù)據(jù)到破解器的CID,其他選項(xiàng)如下圖,然后點(diǎn)擊Generate。

第三步:復(fù)制LIC0的數(shù)據(jù)到軟件的LIC框里面,點(diǎn)擊Add LIC。注意添加序列號(hào)后Licence Manager會(huì)算出這個(gè)號(hào)對(duì)應(yīng)的有效期,如果到期會(huì)顯示為紅色,需要重新點(diǎn)擊破解軟件的Generate,再算一個(gè)填進(jìn)去就行了。

第四步:將ST-LINKII-KEIL Driver所需的文件(兩個(gè)DLL)拷貝到\Keil\ARM\BIN下,替換原有文件。

第五步:打開(kāi)Keil安裝目錄下的TOOLS.INI文件,在[ARM]、[ARMADS]、[KARM]項(xiàng)目下添加TDRV7=BIN\ST-LINKII-KEIL.dll("ST LinkII Debugger")行,并保存修改。

第六步:打開(kāi)MDK,在項(xiàng)目的options設(shè)置的Debug選項(xiàng)中選擇ST LINKII Debugger,同時(shí)在Utilities的選項(xiàng)中選擇ST LINKII Debugger。

完成以上步驟,就完成了ST-LINKII的相關(guān)配置,可以作為調(diào)試器開(kāi)始使用。注意:目前ST-LINKII不支持Flash菜單中的Download和Erase命令,程序在使用Start/Stop Debug Session時(shí)自動(dòng)載入flash中供調(diào)試。

3、 IAR EWARM 4.42A安裝與破解

第一步:開(kāi)始/運(yùn)行…/CMD顯示DOS界面,執(zhí)行iarid.exe>>ID.TXT得到本機(jī)ID碼,復(fù)制這個(gè)ID碼,再執(zhí)行iarkg.exe ID碼>>Lic422A.TXT,得到一組注冊(cè)碼。

第二步:使用EWARM-EV-WEB-442A.exe(30天限制版,其他版本無(wú)法使用第一步中的注冊(cè)碼),執(zhí)行安裝程序完成基本安裝,過(guò)程中需要添入第一步里面算出來(lái)的注冊(cè)碼,可以取消時(shí)間限制,但是那一組當(dāng)中只有一個(gè)有效,需要實(shí)驗(yàn)。

4、 鏈接硬件調(diào)試程序

RealView MDK:找到一個(gè)STM32-SK的基礎(chǔ)程序,最好是只關(guān)于IO的且與當(dāng)前板子程序不同,這樣在板上就可以看到結(jié)果,點(diǎn)擊Project/open project。例如GPIO、TIMER(另兩個(gè)例程是關(guān)于串口的,需要連接串口才能夠看到運(yùn)行結(jié)果)。

使用“Open Project”打開(kāi),然后設(shè)置Option里面的linker和Utilities里面的項(xiàng)目為“ST LinkII Debuger”。

編譯程序,再使用“Start/Stop Debug Session”來(lái)寫(xiě)入程序。

IAR EWARM:與以上相同,找到一個(gè)符合條件的例程。打開(kāi)一個(gè)eww工程文件,右鍵選取Option,在Debuger里面選擇“Third-Party Driver”,在“Third-Party Driver”里面添上“$PROJ_DIR$\..\ddl\STM32Driver.dll”。

使用“Make”或“Rebuild All”來(lái)編譯程序,點(diǎn)“Debug”就燒寫(xiě)進(jìn)Flash。使用調(diào)試欄里面的“go”等等運(yùn)行程序。

注:由于目前版本MDK與我手頭的ST-LINK-II編程器不兼容,所以后面的所有工作均改用IAR。





                           STM32學(xué)前班教程之四:打好基礎(chǔ)建立模板  


1、 新建目錄Project_IAR4,按照自己的順序重新組織dll(驅(qū)動(dòng));inc、src函數(shù)庫(kù);settings,其他所有文件全部放這個(gè)新建的目錄下。  

2、 雙擊打開(kāi)Project.eww,繼續(xù)更改內(nèi)部設(shè)置。  

3、 需更改的內(nèi)容列表:  

位置和項(xiàng)目 目標(biāo) 說(shuō)明  

Project\Edir confignations 新建基于STM3210B的配置 編譯目標(biāo)和過(guò)程文件存放  

Project\Option\General Option\Target ST STM32F10x 選擇芯片類(lèi)型  

Project\Option\ C/C++ Compiler\Preprocessor\Additional include directories $PROJ_DIR$\  

$PROJ_DIR$\inc 頭文件相對(duì)位置,需要包括“map/lib/type”的位置  

Project\Option\ C/C++ Compiler\Preprocessor\Defined symbols  空 空白是在Flash里面調(diào)試程序,VECT_TAB_RAM是在RAM里調(diào)試程序  

Project\Option\ C/C++ Compiler\Optimizations\Size 最終編譯一般選擇High  

調(diào)試可選None None,Low,Medium,High是不同的代碼優(yōu)化等級(jí)  

Project\Option\ Linker\Output 去掉Overrride default 輸出格式使用默認(rèn)  

Project\Option\ Linker\Extra Output 打開(kāi)General Extra Output去掉Overrride default 廠家要求  

Project\Option\ Linker\Config 打開(kāi)Overrride default  

$PROJ_DIR$\lnkarm_flash.xcl 使用Flash調(diào)試程序,如果需要使用RAM調(diào)試則改為lnkarm_RAM.xcl  

Project\Option\ Debugger\Setup\Driver  Third-Party Driver 使用第三方驅(qū)動(dòng)連接單片機(jī)  

Project\Option\ Debugger\ Download Use flash loader 下載到flash所需的設(shè)置  

Project\Option\ Debugger\ Third-Party Driver\ Third-Party Driver\IAR debugger driver $PROJ_DIR$\ddl\STM32Driver.dll 驅(qū)動(dòng)文件路徑  

注1:所有跟路徑相關(guān)的設(shè)置需要根據(jù)實(shí)際情況編寫(xiě),相對(duì)路徑的編寫(xiě)——“$PROJ_DIR$”代表eww文件所在文件夾,“..”代表向上一層。  

注2:其他設(shè)置使用庫(kù)函數(shù)里面的工程文件的默認(rèn)選項(xiàng)即可,初學(xué)不用了解太多。  

4、 需要重新刪除并重新添加Project下“FWLib”和“User”的所有文件,為了刪減外設(shè)模塊方便需要在“USER”額外添加“stm32f10x_conf.h”(不添加也可以,需要展開(kāi)main.c找到它)。然后執(zhí)行Project\Rebuid All,通過(guò)則設(shè)置完畢。  

5、 完成以上步驟,第一個(gè)自己習(xí)慣的程序庫(kù)就建立完畢了,以后可以從“stm32f10x_conf.h”中刪減各種庫(kù)文件,從“stm32f10x_it.c”編輯中斷,從“main.c”編寫(xiě)得到自己的程序。最后需要將這個(gè)庫(kù)打包封存,每次解壓縮并修改主目錄名稱(chēng)即可。  

6、 我的程序庫(kù)特點(diǎn):  

a) 默認(rèn)兼容ST-LINK-II,IAR EWARM 4.42A,F(xiàn)lash調(diào)試,其他有可能需要更改設(shè)置  

b) 為操作方便減少了目錄的層次  

c) 為學(xué)習(xí)方便使用網(wǎng)友漢化版2.0.2固件,主要是庫(kù)函數(shù)中c代碼的注釋。  

后面隨著學(xué)習(xí)深入將在我的模板里面加入如下內(nèi)容:  

d) 加入必用的flash(讀取優(yōu)化),lib(debug),nvic(中斷位置判斷、開(kāi)中斷模板),rcc(時(shí)鐘管理模板,開(kāi)啟外設(shè)時(shí)鐘模板),gpio(管腳定義模板)的初始化代碼,所有模板代碼用到的時(shí)候只要去掉前面的注釋“//”,根據(jù)需求填入相應(yīng)值就可以了。  

e) 因?yàn)樽约河浶圆缓茫詍ain函數(shù)中的代碼做到每行注釋?zhuān)阌谧约阂院笫褂谩?nbsp; 

f) 集成Print_U函數(shù)簡(jiǎn)單串口收發(fā)函數(shù)代碼,便于調(diào)試,改變使用Printf函數(shù)的調(diào)試習(xí)慣。  

g) 集成使用systick的精確延時(shí)函數(shù)delay。  

h) 集成時(shí)鐘故障處理代碼。  

i) 集成電壓監(jiān)控代碼。  

j) 集成片上溫度檢測(cè)代碼。  

k) 逐步加入所有外設(shè)的初始化模塊  

一、編寫(xiě)程序所需的步驟

1、解壓縮,改目錄名稱(chēng),和eww文件名,以便跟其他程序區(qū)分。

2、更改設(shè)置:在“stm32f10x_conf.h”關(guān)閉不用的外設(shè)(在其聲明函數(shù)前面加注釋符號(hào)“//”)。并根據(jù)外部晶振速度更改其中“HSE_Value”的數(shù)值,其單位是Hz。

3、完成各種頭文件的包含(#include "xxx.h";),公共變量的聲明(static 數(shù)據(jù)類(lèi)型 變量名稱(chēng);),子程序聲明(void 函數(shù)名稱(chēng)(參數(shù));)……C語(yǔ)言必須的前置工作。

4、改寫(xiě)我的程序庫(kù)里面所預(yù)設(shè)的模板,再進(jìn)行其他模塊的初始化子程序代碼的編寫(xiě),并在程序代碼的開(kāi)始部分調(diào)用。注意:必須記住所有外設(shè)的使用需要考慮4個(gè)問(wèn)題:

a)     開(kāi)時(shí)鐘RCC(在RCC初始化中);

b)     自身初始化;

c)     相關(guān)管腳配置(在GPIO初始化中);

d)     是否使用中斷(在NVIC初始化中)

5、編寫(xiě)main.c中的主要代碼和各種子函數(shù)。

6、在“stm32f10x_it.c”填寫(xiě)各種中斷所需的執(zhí)行代碼,如果用不到中斷的簡(jiǎn)單程序則不用編寫(xiě)此文件。

7、編譯生成 “bin”的方法:Project\Option\ Linker\Output\Format,里面選擇“Other”,在下面的“Output”選 “raw-binary”生成bin。

8、編譯生成“hex”的方法:Project\Option\ Linker\Output\Format,里面選擇“Other”,在下面的“Output”選“intel-extended”,生成a79直接改名成為hex或者選中上面的“Output Flie”在“Overrride default”項(xiàng)目里面改擴(kuò)展名為hex。

使用軟件界面的Debug燒寫(xiě)并按鈕調(diào)試程序。注意,ST-Link-II是直接將程序燒寫(xiě)進(jìn)Flash進(jìn)行調(diào)試,而不是使用RAM的方式。  



                             STM32學(xué)前班教程之五:給等待入門(mén)的人一點(diǎn)點(diǎn)建議  



入門(mén)必須閱讀的相關(guān)文檔

1、 幾個(gè)重要官方文檔的功能:

a) Datasheet——芯片基本數(shù)據(jù),功能參數(shù)封裝管腳定義和性能規(guī)范。

b) 固件函數(shù)庫(kù)用戶(hù)手冊(cè)——函數(shù)庫(kù)功能,庫(kù)函數(shù)的定義、功能和用法。

c) 參考手冊(cè)——各種功能的具體描述,使用方法,原理,相關(guān)寄存器。

d) STM32F10xxx硬件開(kāi)發(fā):使用入門(mén)——相關(guān)基礎(chǔ)硬件設(shè)計(jì)

e) STM32F10XXX的使用限制:芯片內(nèi)部未解決的硬件設(shè)計(jì)bug,開(kāi)發(fā)需要注意繞開(kāi)。

f) 一本簡(jiǎn)單的C語(yǔ)言書(shū),相信我,不用太復(fù)雜。

2、 其他的有用文檔,對(duì)初學(xué)幫助很大

a) 如何使用STM32的軟件庫(kù)在IAR的EWARM下進(jìn)行應(yīng)用開(kāi)發(fā)——IAR基礎(chǔ)設(shè)置。

b) 輕松進(jìn)入STM32+Cortex-M3世界.ppt——開(kāi)發(fā)板和最小系統(tǒng)設(shè)計(jì)需求。

c) 如何選擇STM32開(kāi)發(fā)板.pdf——各種開(kāi)發(fā)板介紹和功能比較。

d) MXCHIP的系列視頻教程——全部芯片基礎(chǔ)及其外設(shè)的教程,使用函數(shù)庫(kù)編程的話(huà)就不用看每個(gè)視頻后半段的關(guān)于寄存器的介紹了。

e) STM32_Technical_Slide(常見(jiàn)問(wèn)題)——一些優(yōu)化設(shè)計(jì)方案。

3、 關(guān)于參考書(shū),買(mǎi)了兩本但是基本對(duì)學(xué)習(xí)沒(méi)什么幫助,如果湊齊以上資料,建議慎重買(mǎi)書(shū),不如留著那n個(gè)幾十塊錢(qián),攢到一起買(mǎi)開(kāi)發(fā)板。

我自己的學(xué)習(xí)過(guò)程

1、 一共24個(gè)庫(kù),不可能都學(xué),都學(xué)也沒(méi)用。按照我的工作需求必須學(xué)的有16個(gè),這16個(gè)也不是全學(xué)。主要學(xué)習(xí)來(lái)源是各種例程代碼、“固件函數(shù)庫(kù)用戶(hù)手冊(cè)”和“參考手冊(cè)”。

具體學(xué)習(xí)方法是通讀不同來(lái)源的程序,在程序中找到相關(guān)的函數(shù)庫(kù)的應(yīng)用,然后再閱讀相關(guān)文檔,有條件的實(shí)驗(yàn)。對(duì)于內(nèi)容的選擇方面,根據(jù)入門(mén)內(nèi)容和未來(lái)應(yīng)用,將所涉及的范圍精簡(jiǎn)到最低,但是對(duì)所選擇的部分的學(xué)習(xí)則力求明確。以下是我按照自己的需求對(duì)程序庫(kù)函數(shù)排列的學(xué)習(xí)順序:

a) 絕大部分程序都要涉及到的庫(kù)——flash,lib,nvic,rcc,只學(xué)基礎(chǔ)的跟最簡(jiǎn)單應(yīng)用相關(guān)必用的部分,其他部分后期再返回頭學(xué)。

b) 各種程序通用但不必用的庫(kù)——exti,MDA,systic,只通讀理解其作用。

c) DEMO板擁有的外設(shè)庫(kù)——gpio,usart,編寫(xiě)代碼實(shí)驗(yàn)。

d) 未來(lái)需要用到的外設(shè)的庫(kù)——tim,tim1,adc,i2c,spi,先理解等待有條件后實(shí)驗(yàn)。

e) 開(kāi)發(fā)可靠性相關(guān)庫(kù)——bkp,iwdg,wwdg,pwr,參考其他例程的做法。

f) 其他,根據(jù)興趣來(lái)學(xué)。





                                      STM32學(xué)前班教程之六:這些代碼大家都用得到  


2、 閱讀flash: 芯片內(nèi)部存儲(chǔ)器flash操作函數(shù)

我的理解——對(duì)芯片內(nèi)部flash進(jìn)行操作的函數(shù),包括讀取,狀態(tài),擦除,寫(xiě)入等等,可以允許程序去操作flash上的數(shù)據(jù)。

基礎(chǔ)應(yīng)用1,F(xiàn)LASH時(shí)序延遲幾個(gè)周期,等待總線(xiàn)同步操作。推薦按照單片機(jī)系統(tǒng)運(yùn)行頻率,0—24MHz時(shí),取Latency=0;24—48MHz時(shí),取Latency=1;48~72MHz時(shí),取Latency=2。所有程序中必須的

用法:FLASH_SetLatency(FLASH_Latency_2);

位置:RCC初始化子函數(shù)里面,時(shí)鐘起振之后。

基礎(chǔ)應(yīng)用2,開(kāi)啟FLASH預(yù)讀緩沖功能,加速FLASH的讀取。所有程序中必須的

用法:FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

位置:RCC初始化子函數(shù)里面,時(shí)鐘起振之后。

3、 閱讀lib:調(diào)試所有外設(shè)初始化的函數(shù)。

我的理解——不理解,也不需要理解。只要知道所有外設(shè)在調(diào)試的時(shí)候,EWRAM需要從這個(gè)函數(shù)里面獲得調(diào)試所需信息的地址或者指針之類(lèi)的信息。

基礎(chǔ)應(yīng)用1,只有一個(gè)函數(shù)debug。所有程序中必須的。

用法: #ifdef DEBUG

    debug();

#endif

位置:main函數(shù)開(kāi)頭,聲明變量之后。

4、 閱讀nvic:系統(tǒng)中斷管理。

我的理解——管理系統(tǒng)內(nèi)部的中斷,負(fù)責(zé)打開(kāi)和關(guān)閉中斷。

基礎(chǔ)應(yīng)用1,中斷的初始化函數(shù),包括設(shè)置中斷向量表位置,和開(kāi)啟所需的中斷兩部分。所有程序中必須的。

用法: void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;//中斷管理恢復(fù)默認(rèn)參數(shù)

#ifdef  VECT_TAB_RAM   

//如果C/C++ Compiler\Preprocessor\Defined symbols中的定義了VECT_TAB_RAM(見(jiàn)程序庫(kù)更改內(nèi)容的表格)

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //則在RAM調(diào)試

#else        //如果沒(méi)有定義VECT_TAB_RAM

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//則在Flash里調(diào)試

#endif        //結(jié)束判斷語(yǔ)句

//以下為中斷的開(kāi)啟過(guò)程,不是所有程序必須的。

//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  

//設(shè)置NVIC優(yōu)先級(jí)分組,方式。

//注:一共16個(gè)優(yōu)先級(jí),分為搶占式和響應(yīng)式。兩種優(yōu)先級(jí)所占的數(shù)量由此代碼確定,NVIC_PriorityGroup_x可以是0、1、2、3、4,分別代表?yè)屨純?yōu)先級(jí)有1、2、4、8、16個(gè)和響應(yīng)優(yōu)先級(jí)有16、8、4、2、1個(gè)。規(guī)定兩種優(yōu)先級(jí)的數(shù)量后,所有的中斷級(jí)別必須在其中選擇,搶占級(jí)別高的會(huì)打斷其他中斷優(yōu)先執(zhí)行,而響應(yīng)級(jí)別高的會(huì)在其他中斷執(zhí)行完優(yōu)先執(zhí)行。

//NVIC_InitStructure.NVIC_IRQChannel = 中斷通道名;

//開(kāi)中斷,中斷名稱(chēng)見(jiàn)函數(shù)庫(kù)

//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

//搶占優(yōu)先級(jí)

//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  

//響應(yīng)優(yōu)先級(jí)

//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//啟動(dòng)此通道的中斷

//NVIC_Init(&NVIC_InitStructure);     //中斷初始化

}

5、 閱讀rcc:?jiǎn)纹瑱C(jī)時(shí)鐘管理。

我的理解——管理外部、內(nèi)部和外設(shè)的時(shí)鐘,設(shè)置、打開(kāi)和關(guān)閉這些時(shí)鐘。

基礎(chǔ)應(yīng)用1:時(shí)鐘的初始化函數(shù)過(guò)程——

用法:void RCC_Configuration(void)    //時(shí)鐘初始化函數(shù)

{

  ErrorStatus HSEStartUpStatus;     //等待時(shí)鐘的穩(wěn)定

  RCC_DeInit();         //時(shí)鐘管理重置

  RCC_HSEConfig(RCC_HSE_ON);      //打開(kāi)外部晶振

  HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部晶振就緒

  if (HSEStartUpStatus == SUCCESS)

  {

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//flash讀取緩沖,加速

    FLASH_SetLatency(FLASH_Latency_2); //flash操作的延時(shí)

    RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB使用系統(tǒng)時(shí)鐘

    RCC_PCLK2Config(RCC_HCLK_Div2);  //APB2(高速)為HCLK的一半

    RCC_PCLK1Config(RCC_HCLK_Div2);  //APB1(低速)為HCLK的一半

//注:AHB主要負(fù)責(zé)外部存儲(chǔ)器時(shí)鐘。PB2負(fù)責(zé)AD,I/O,高級(jí)TIM,串口1。APB1負(fù)責(zé)DA,USB,SPI,I2C,CAN,串口2345,普通TIM。



    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

//PLLCLK = 8MHz * 9 = 72 MHz

    RCC_PLLCmd(ENABLE);     //啟動(dòng)PLL

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}

//等待PLL啟動(dòng)

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//將PLL設(shè)置為系統(tǒng)時(shí)鐘源

while (RCC_GetSYSCLKSource() != 0x08){}

          //等待系統(tǒng)時(shí)鐘源的啟動(dòng)

  }

  //RCC_AHBPeriphClockCmd(ABP2設(shè)備1 | ABP2設(shè)備2 |, ENABLE);

  //啟動(dòng)AHP設(shè)備

  //RCC_APB2PeriphClockCmd(ABP2設(shè)備1 | ABP2設(shè)備2 |, ENABLE);

  //啟動(dòng)ABP2設(shè)備

  //RCC_APB1PeriphClockCmd(ABP2設(shè)備1 | ABP2設(shè)備2 |, ENABLE);

  //啟動(dòng)ABP1設(shè)備

}

1、閱讀exti:外部設(shè)備中斷函數(shù)

我的理解——外部設(shè)備通過(guò)引腳給出的硬件中斷,也可以產(chǎn)生軟件中斷,19個(gè)上升、下降或都觸發(fā)。EXTI0~EXTI15連接到管腳,EXTI線(xiàn)16連接到PVD(VDD監(jiān)視),EXTI線(xiàn)17連接到RTC(鬧鐘),EXTI線(xiàn)18連接到USB(喚醒)。

    基礎(chǔ)應(yīng)用1,設(shè)定外部中斷初始化函數(shù)。按需求,不是必須代碼。

    用法: void EXTI_Configuration(void)

{

EXTI_InitTypeDef EXTI_InitStructure; //外部設(shè)備中斷恢復(fù)默認(rèn)參數(shù)

EXTI_InitStructure.EXTI_Line = 通道1|通道2;  

//設(shè)定所需產(chǎn)生外部中斷的通道,一共19個(gè)。

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //產(chǎn)生中斷

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

//上升下降沿都觸發(fā)  

EXTI_InitStructure.EXTI_LineCmd = ENABLE; //啟動(dòng)中斷的接收  

EXTI_Init(&EXTI_InitStructure);           //外部設(shè)備中斷啟動(dòng)

}



2、閱讀dma:通過(guò)總線(xiàn)而越過(guò)CPU讀取外設(shè)數(shù)據(jù)

我的理解——通過(guò)DMA應(yīng)用可以加速單片機(jī)外設(shè)、存儲(chǔ)器之間的數(shù)據(jù)傳輸,并在傳輸期間不影響CPU進(jìn)行其他事情。這對(duì)于入門(mén)開(kāi)發(fā)基本功能來(lái)說(shuō)沒(méi)有太大必要,這個(gè)內(nèi)容先行跳過(guò)。

3、閱讀systic:系統(tǒng)定時(shí)器

我的理解——可以輸出和利用系統(tǒng)時(shí)鐘的計(jì)數(shù)、狀態(tài)。

基礎(chǔ)應(yīng)用1,精確計(jì)時(shí)的延時(shí)子函數(shù)。推薦使用的代碼。

    用法:

static vu32 TimingDelay;//全局變量聲明

void SysTick_Config(void)//systick初始化函數(shù)

{

    SysTick_CounterCmd(SysTick_Counter_Disable);//停止系統(tǒng)定時(shí)器

    SysTick_ITConfig(DISABLE);                //停止systick中斷

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);

    //systick使用HCLK作為時(shí)鐘源,頻率值除以8。

    SysTick_SetReload(9000);//重置時(shí)間1毫秒(以72MHz為基礎(chǔ)計(jì)算)

    SysTick_ITConfig(ENABLE);//開(kāi)啟systic中斷

}

void Delay (u32 nTime) //延遲一毫秒的函數(shù)

{

    SysTick_CounterCmd(SysTick_Counter_Enable);   //systic開(kāi)始計(jì)時(shí)



    TimingDelay = nTime;               //計(jì)時(shí)長(zhǎng)度賦值給遞減變量

    while(TimingDelay != 0);           //檢測(cè)是否計(jì)時(shí)完成



SysTick_CounterCmd(SysTick_Counter_Disable);  //關(guān)閉計(jì)數(shù)器

    SysTick_CounterCmd(SysTick_Counter_Clear);    //清除計(jì)數(shù)值

}

void TimingDelay_Decrement(void)

//遞減變量函數(shù),函數(shù)名由“stm32f10x_it.c”中的中斷響應(yīng)函數(shù)定義好了。

{

    if (TimingDelay != 0x00)               //檢測(cè)計(jì)數(shù)變量是否達(dá)到0

       {  

      TimingDelay--;                     //計(jì)數(shù)變量遞減

       }

}

注:建議熟練后使用,所涉及知識(shí)和設(shè)備太多,新手出錯(cuò)的可能性比較大。新手可用簡(jiǎn)化的延時(shí)函數(shù)代替:

void Delay(vu32 nCount)//簡(jiǎn)單延時(shí)函數(shù)

{

  for(; nCount != 0; nCount--);(循環(huán)變量遞減計(jì)數(shù))

}

當(dāng)延時(shí)較長(zhǎng),又不需要精確計(jì)時(shí)的時(shí)候可以使用嵌套循環(huán):

void Delay(vu32 nCount)        //簡(jiǎn)單的長(zhǎng)時(shí)間延時(shí)函數(shù)

{int i;                         //聲明內(nèi)部遞減變量

  for(; nCount != 0; nCount--)  //遞減變量計(jì)數(shù)

{for (i=0; i<0xffff; i++)}  //內(nèi)部循環(huán)遞減變量計(jì)數(shù)

}

4、閱讀gpio:I/O設(shè)置函數(shù)

我的理解——所有輸入輸出管腳模式設(shè)置,可以是上下拉、浮空、開(kāi)漏、模擬、推挽模式,頻率特性為2M,10M,50M。也可以向該管腳直接寫(xiě)入數(shù)據(jù)和讀取數(shù)據(jù)。

    基礎(chǔ)應(yīng)用1,gpio初始化函數(shù)。所有程序必須。

    用法:void GPIO_Configuration(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;   //GPIO狀態(tài)恢復(fù)默認(rèn)參數(shù)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_標(biāo)號(hào) | GPIO_Pin_標(biāo)號(hào) ;

//管腳位置定義,標(biāo)號(hào)可以是NONE、ALL、0至15。

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//輸出速度2MHz

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入模式

    GPIO_Init(GPIOC, &GPIO_InitStructure);        //C組GPIO初始化

//注:以上四行代碼為一組,每組GPIO屬性必須相同,默認(rèn)的GPIO參數(shù)為:ALL,2MHz,F(xiàn)LATING。如果其中任意一行與前一組相應(yīng)設(shè)置相同,那么那一行可以省略,由此推論如果前面已經(jīng)將此行參數(shù)設(shè)定為默認(rèn)參數(shù)(包括使用GPIO_InitTypeDef GPIO_InitStructure代碼),本組應(yīng)用也是默認(rèn)參數(shù)的話(huà),那么也可以省略。以下重復(fù)這個(gè)過(guò)程直到所有應(yīng)用的管腳全部被定義完畢。

……

}

    基礎(chǔ)應(yīng)用2,向管腳寫(xiě)入0或1

    用法:GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//寫(xiě)入1



                                       STM32筆記之七:讓它跑起來(lái),基本硬件功能的建立  




0、        實(shí)驗(yàn)之前的準(zhǔn)備

a)        接通串口轉(zhuǎn)接器

b)        下載IO與串口的原廠程序,編譯通過(guò)保證調(diào)試所需硬件正常。

1、        flash,lib,nvic,rcc和GPIO,基礎(chǔ)程序庫(kù)編寫(xiě)

a)        這幾個(gè)庫(kù)函數(shù)中有一些函數(shù)是關(guān)于芯片的初始化的,每個(gè)程序中必用。為保障程序品質(zhì),初學(xué)階段要求嚴(yán)格遵守官方習(xí)慣。注意,官方程序庫(kù)例程中有個(gè)platform_config.h文件,是專(zhuān)門(mén)用來(lái)指定同類(lèi)外設(shè)中第幾號(hào)外設(shè)被使用,就是說(shuō)在main.c里面所有外設(shè)序號(hào)用x代替,比如USARTx,程序會(huì)到這個(gè)頭文件中去查找到底是用那些外設(shè),初學(xué)的時(shí)候參考例程別被這個(gè)所迷惑住。

b)        全部必用代碼取自庫(kù)函數(shù)所帶例程,并增加逐句注釋。

c)        習(xí)慣順序——Lib(debug),RCC(包括Flash優(yōu)化),NVIC,GPIO

d)        必用模塊初始化函數(shù)的定義:

void RCC_Configuration(void);        //定義時(shí)鐘初始化函數(shù)

void GPIO_Configuration(void);        //定義管腳初始化函數(shù)

void NVIC_Configuration(void);        //定義中斷管理初始化函數(shù)

void Delay(vu32 nCount);                        //定義延遲函數(shù)

e)        Main中的初始化函數(shù)調(diào)用:

RCC_Configuration();                //時(shí)鐘初始化函數(shù)調(diào)用

NVIC_Configuration();        //中斷初始化函數(shù)調(diào)用

GPIO_Configuration();        //管腳初始化函數(shù)調(diào)用

f)        Lib注意事項(xiàng):

屬于Lib的Debug函數(shù)的調(diào)用,應(yīng)該放在main函數(shù)最開(kāi)始,不要改變其位置。

g)        RCC注意事項(xiàng):

Flash優(yōu)化處理可以不做,但是兩句也不難也不用改參數(shù)……

根據(jù)需要開(kāi)啟設(shè)備時(shí)鐘可以節(jié)省電能

時(shí)鐘頻率需要根據(jù)實(shí)際情況設(shè)置參數(shù)

h)        NVIC注意事項(xiàng)

注意理解占先優(yōu)先級(jí)和響應(yīng)優(yōu)先級(jí)的分組的概念

i)        GPIO注意事項(xiàng)

注意以后的過(guò)程中收集不同管腳應(yīng)用對(duì)應(yīng)的頻率和模式的設(shè)置。

作為高低電平的I/O,所需設(shè)置:RCC初始化里面打開(kāi)RCC_APB2

PeriphClockCmd(RCC_APB2Periph_GPIOA);GPIO里面管腳設(shè)定:IO輸出(50MHz,Out_PP);IO輸入(50MHz,IPU);

j)        GPIO應(yīng)用

GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_RESET);//重置

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//寫(xiě)入1

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x00);//寫(xiě)入0

GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) ;//讀入IO

k)        簡(jiǎn)單Delay函數(shù)

void Delay(vu32 nCount)//簡(jiǎn)單延時(shí)函數(shù)

{for(; nCount != 0; nCount--);}

實(shí)驗(yàn)步驟:

RCC初始化函數(shù)里添加:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);

不用其他中斷,NVIC初始化函數(shù)不用改

GPIO初始化代碼:

//IO輸入,GPIOB的2、10、11腳輸出

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;//管腳號(hào)

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //輸出速度

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //輸入輸出模式

     GPIO_Init(GPIOB, &GPIO_InitStructure);              //初始化

簡(jiǎn)單的延遲函數(shù):

void Delay(vu32 nCount)                     //簡(jiǎn)單延時(shí)函數(shù)

{ for (; nCount != 0; nCount--);}           //循環(huán)計(jì)數(shù)延時(shí)

完成之后再在main.c的while里面寫(xiě)一段:

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//寫(xiě)入1

Delay(0xffff);

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x00);//寫(xiě)入0

Delay(0xffff);

就可以看到連接在PB2腳上的LED閃爍了,單片機(jī)就跑起來(lái)了。  





                                         STM32筆記之八:來(lái)跟PC打個(gè)招呼,基本串口通訊  

a)        目的:在基礎(chǔ)實(shí)驗(yàn)成功的基礎(chǔ)上,對(duì)串口的調(diào)試方法進(jìn)行實(shí)踐。硬件代碼順利完成之后,對(duì)日后調(diào)試需要用到的printf重定義進(jìn)行調(diào)試,固定在自己的庫(kù)函數(shù)中。

b)        初始化函數(shù)定義:

void USART_Configuration(void);        //定義串口初始化函數(shù)

c)        初始化函數(shù)調(diào)用:

void UART_Configuration(void);        //串口初始化函數(shù)調(diào)用

初始化代碼:

void USART_Configuration(void)                        //串口初始化函數(shù)

{

//串口參數(shù)初始化   

  USART_InitTypeDef USART_InitStructure;              //串口設(shè)置恢復(fù)默認(rèn)參數(shù)

//初始化參數(shù)設(shè)置

  USART_InitStructure.USART_BaudRate = 9600;                                     //波特率9600

   USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //字長(zhǎng)8位

  USART_InitStructure.USART_StopBits = USART_StopBits_1;                 //1位停止字節(jié)

  USART_InitStructure.USART_Parity = USART_Parity_No;                      //無(wú)奇偶校驗(yàn)

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無(wú)流控制

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打開(kāi)Rx接收和Tx發(fā)送功能

    USART_Init(USART1, &USART_InitStructure);                                         //初始化

  USART_Cmd(USART1, ENABLE);                                                          //啟動(dòng)串口

}

RCC中打開(kāi)相應(yīng)串口

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);

GPIO里面設(shè)定相應(yīng)串口管腳模式

//串口1的管腳初始化   

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                        //管腳9

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       //復(fù)用推挽輸出

  GPIO_Init(GPIOA, &GPIO_InitStructure);                               //TX初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                    //管腳10

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入

  GPIO_Init(GPIOA, &GPIO_InitStructure);                             //RX初始化

d)        簡(jiǎn)單應(yīng)用:

發(fā)送一位字符

USART_SendData(USART1, 數(shù)據(jù));                //發(fā)送一位數(shù)據(jù)

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}                                                                                        //等待發(fā)送完畢

接收一位字符

while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}                                                                                        //等待接收完畢

變量= (USART_ReceiveData(USART1));        //接受一個(gè)字節(jié)

發(fā)送一個(gè)字符串

    先定義字符串:char rx_data[250];

      然后在需要發(fā)送的地方添加如下代碼
int i;                                                                     //定義循環(huán)變量

    while(rx_data!='\0')                                           //循環(huán)逐字輸出,到結(jié)束字'\0'

    {USART_SendData(USART1, rx_data);            //發(fā)送字符

     while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待字符發(fā)送完畢

     i++;}  

e)        USART注意事項(xiàng):

發(fā)動(dòng)和接受都需要配合標(biāo)志等待。

只能對(duì)一個(gè)字節(jié)操作,對(duì)字符串等大量數(shù)據(jù)操作需要寫(xiě)函數(shù)

使用串口所需設(shè)置:RCC初始化里面打開(kāi)RCC_APB2PeriphClockCmd

(RCC_APB2Periph_USARTx);GPIO里面管腳設(shè)定:串口RX(50Hz,IN_FLOATING);串口TX(50Hz,AF_PP);  

f)        printf函數(shù)重定義(不必理解,調(diào)試通過(guò)以備后用)

(1)        需要c標(biāo)準(zhǔn)函數(shù):

#include "stdio.h"

(2)        粘貼函數(shù)定義代碼

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)  //定義為putchar應(yīng)用

(3)        RCC中打開(kāi)相應(yīng)串口

(4)        GPIO里面設(shè)定相應(yīng)串口管腳模式

(6)        增加為putchar函數(shù)。

int putchar(int c)                                              //putchar函數(shù)

{

  if (c == '\n'){putchar('\r');}                                //將printf的\n變成\r

  USART_SendData(USART1, c);                                    //發(fā)送字符

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待發(fā)送結(jié)束

  return c;                                                     //返回值

}

(8)        通過(guò),試驗(yàn)成功。printf使用變量輸出:%c字符,%d整數(shù),%f浮點(diǎn)數(shù),%s字符串,/n或/r為換行。注意:只能用于main.c中。

3、        NVIC串口中斷的應(yīng)用

a)        目的:利用前面調(diào)通的硬件基礎(chǔ),和幾個(gè)函數(shù)的代碼,進(jìn)行串口的中斷輸入練習(xí)。因?yàn)樵趯?shí)際應(yīng)用中,不使用中斷進(jìn)行的輸入是效率非常低的,這種用法很少見(jiàn),大部分串口的輸入都離不開(kāi)中斷。

b)        初始化函數(shù)定義及函數(shù)調(diào)用:不用添加和調(diào)用初始化函數(shù),在指定調(diào)試地址的時(shí)候已經(jīng)調(diào)用過(guò),在那個(gè)NVIC_Configuration里面添加相應(yīng)開(kāi)中斷代碼就行了。

c)        過(guò)程:

i.        在串口初始化中USART_Cmd之前加入中斷設(shè)置:

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//TXE發(fā)送中斷,TC傳輸完成中斷,RXNE接收中斷,PE奇偶錯(cuò)誤中斷,可以是多個(gè)。

ii.        RCC、GPIO里面打開(kāi)串口相應(yīng)的基本時(shí)鐘、管腳設(shè)置

iii.        NVIC里面加入串口中斷打開(kāi)代碼:

NVIC_InitTypeDef NVIC_InitStructure;//中斷默認(rèn)參數(shù)

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;//通道設(shè)置為串口1中斷

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   //中斷占先等級(jí)0

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;              //中斷響應(yīng)優(yōu)先級(jí)0

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //打開(kāi)中斷

NVIC_Init(&NVIC_InitStructure);                                                //初始化

iv.        在stm32f10x_it.c文件中找到void USART1_IRQHandler函數(shù),在其中添入執(zhí)行代碼。一般最少三個(gè)步驟:先使用if語(yǔ)句判斷是發(fā)生那個(gè)中斷,然后清除中斷標(biāo)志位,最后給字符串賦值,或做其他事情。

void USART1_IRQHandler(void)                              //串口1中斷

{

char RX_dat;                                                          //定義字符變量



  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //判斷發(fā)生接收中斷

  {USART_ClearITPendingBit(USART1,  USART_IT_RXNE);          //清除中斷標(biāo)志



   GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)0x01);             //開(kāi)始傳輸

   RX_dat=USART_ReceiveData(USART1) & 0x7F;                       //接收數(shù)據(jù),整理除去前兩位

   USART_SendData(USART1, RX_dat);                                       //發(fā)送數(shù)據(jù)

   while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//等待發(fā)送結(jié)束

  }

}

d)        中斷注意事項(xiàng):

可以隨時(shí)在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);來(lái)關(guān)閉中斷響應(yīng)。

NVIC_InitTypeDef NVIC_InitStructure定義一定要加在NVIC初始化模塊的第一句。

全局變量與函數(shù)的定義:在任意.c文件中定義的變量或函數(shù),在其它.c文件中使用extern+定義代碼再次定義就可以直接調(diào)用了。



                                 STM32筆記之九:打斷它來(lái)為我辦事,EXIT (外部I/O中斷)應(yīng)用


a)        目的:跟串口輸入類(lèi)似,不使用中斷進(jìn)行的IO輸入效率也很低,而且可以通過(guò)EXTI插入按鈕事件,本節(jié)聯(lián)系EXTI中斷。

b)        初始化函數(shù)定義:

void EXTI_Configuration(void); //定義IO中斷初始化函數(shù)

c)        初始化函數(shù)調(diào)用:

EXTI_Configuration();//IO中斷初始化函數(shù)調(diào)用簡(jiǎn)單應(yīng)用:

d)        初始化函數(shù):

void EXTI_Configuration(void)

{

  EXTI_InitTypeDef EXTI_InitStructure;        //EXTI初始化結(jié)構(gòu)定義



EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中斷標(biāo)志

   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管腳選擇

   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);



    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件選擇

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//觸發(fā)模式

  EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //線(xiàn)路選擇

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//啟動(dòng)中斷

  EXTI_Init(&EXTI_InitStructure);//初始化

}



e)        RCC初始化函數(shù)中開(kāi)啟I/O時(shí)鐘

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);



GPIO初始化函數(shù)中定義輸入I/O管腳。

//IO輸入,GPIOA的4腳輸入

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉輸入

  GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化

f)        在NVIC的初始化函數(shù)里面增加以下代碼打開(kāi)相關(guān)中斷:

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;        //通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先級(jí)

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                        //響應(yīng)級(jí)

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //啟動(dòng)

  NVIC_Init(&NVIC_InitStructure);                                                                //初始化



g)        在stm32f10x_it.c文件中找到void USART1_IRQHandler函數(shù),在其中添入執(zhí)行代碼。一般最少三個(gè)步驟:先使用if語(yǔ)句判斷是發(fā)生那個(gè)中斷,然后清除中斷標(biāo)志位,最后給字符串賦值,或做其他事情。

  if(EXTI_GetITStatus(EXTI_Line3) != RESET)                                  //判斷中斷發(fā)生來(lái)源

   { EXTI_ClearITPendingBit(EXTI_Line3);                                          //清除中斷標(biāo)志

    USART_SendData(USART1, 0x41);                                              //發(fā)送字符“a”

    GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED發(fā)生明暗交替

}

h)        中斷注意事項(xiàng):

中斷發(fā)生后必須清除中斷位,否則會(huì)出現(xiàn)死循環(huán)不斷發(fā)生這個(gè)中斷。然后需要對(duì)中斷類(lèi)型進(jìn)行判斷再執(zhí)行代碼。

使用EXTI的I/O中斷,在完成RCC與GPIO硬件設(shè)置之后需要做三件事:初始化EXTI、NVIC開(kāi)中斷、編寫(xiě)中斷執(zhí)行代碼。  



                                        STM32筆記之十:工作工作,PWM輸出


a)        目的:基礎(chǔ)PWM輸出,以及中斷配合應(yīng)用。輸出選用PB1,配置為T(mén)IM3_CH4,是目標(biāo)板的LED6控制腳。

b)        對(duì)于簡(jiǎn)單的PWM輸出應(yīng)用,暫時(shí)無(wú)需考慮TIM1的高級(jí)功能之區(qū)別。

c)        初始化函數(shù)定義:

void TIM_Configuration(void);  //定義TIM初始化函數(shù)

d)        初始化函數(shù)調(diào)用:

TIM_Configuration();  //TIM初始化函數(shù)調(diào)用

e)        初始化函數(shù),不同于前面模塊,TIM的初始化分為兩部分——基本初始化和通道初始化:

void TIM_Configuration(void)//TIM初始化函數(shù)

{  

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定時(shí)器初始化結(jié)構(gòu)

  TIM_OCInitTypeDef  TIM_OCInitStructure;//通道輸出初始化結(jié)構(gòu)



//TIM3初始化

  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;        //周期0~FFFF

  TIM_TimeBaseStructure.TIM_Prescaler = 5;          //時(shí)鐘分頻

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;      //時(shí)鐘分割

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);   //基本初始化

  TIM_ITConfig(TIM3, TIM_IT_CC4, ENABLE);//打開(kāi)中斷,中斷需要這行代碼



//TIM3通道初始化

  TIM_OCStructInit(& TIM_OCInitStructure);                                                //默認(rèn)參數(shù)

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                    //工作狀態(tài)

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //設(shè)定為輸出,需要PWM輸出才需要這行代碼

  TIM_OCInitStructure.TIM_Pulse = 0x2000;                                 //占空長(zhǎng)度

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                 //高電平

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);                                 //通道初始化



  TIM_Cmd(TIM3, ENABLE);                                                                        //啟動(dòng)TIM3

}



f)        RCC初始化函數(shù)中加入TIM時(shí)鐘開(kāi)啟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM3, ENABLE);

g)        GPIO里面將輸入和輸出管腳模式進(jìn)行設(shè)置。信號(hào):AF_PP,50MHz。

h)        使用中斷的話(huà)在NVIC里添加如下代碼:



//打開(kāi)TIM2中斷

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;  //通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//占先級(jí)

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;           //響應(yīng)級(jí)

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //啟動(dòng)

  NVIC_Init(&NVIC_InitStructure);                                            //初始化



中斷代碼:

void TIM2_IRQHandler(void)

{

  if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)       //判斷中斷來(lái)源

  {

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);            //清除中斷標(biāo)志

    GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_11)));//變換LED色彩

    IC4value = TIM_GetCapture4(TIM2);                   //獲取捕捉數(shù)值

  }   

}



i)        簡(jiǎn)單應(yīng)用:

//改變占空比

TIM_SetCompare4(TIM3, 變量);



j)        注意事項(xiàng):

管腳的IO輸出模式是根據(jù)應(yīng)用來(lái)定,比如如果用PWM輸出驅(qū)動(dòng)LED則應(yīng)該將相應(yīng)管腳設(shè)為AF_PP,否則單片機(jī)沒(méi)有輸出。   



                                  STM32筆記之十一:捕捉精彩瞬間,脈沖方波長(zhǎng)度捕獲

a)        目的:基礎(chǔ)PWM輸入也叫捕獲,以及中斷配合應(yīng)用。使用前一章的輸出管腳PB1(19腳),直接使用跳線(xiàn)連接輸入的PA3(13腳),配置為T(mén)IM2_CH4,進(jìn)行實(shí)驗(yàn)。

b)        對(duì)于簡(jiǎn)單的PWM輸入應(yīng)用,暫時(shí)無(wú)需考慮TIM1的高級(jí)功能之區(qū)別,按照目前我的應(yīng)用目標(biāo)其實(shí)只需要采集高電平寬度,而不必知道周期,所以并不采用PWM輸入模式,而是普通脈寬捕獲模式。

c)        初始化函數(shù)定義:

void TIM_Configuration(void);  //定義TIM初始化函數(shù)

d)        初始化函數(shù)調(diào)用:

TIM_Configuration();  //TIM初始化函數(shù)調(diào)用

e)        初始化函數(shù),不同于前面模塊,TIM的CAP初始化分為三部分——計(jì)時(shí)器基本初始化、通道初始化和時(shí)鐘啟動(dòng)初始化:

void TIM_Configuration(void)//TIM2的CAP初始化函數(shù)

{  

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定時(shí)器初始化結(jié)構(gòu)

  TIM_ICInitTypeDef TIM_ICInitStructure;         //通道輸入初始化結(jié)構(gòu)



//TIM2輸出初始化

  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;     //周期0~FFFF

  TIM_TimeBaseStructure.TIM_Prescaler = 5;       //時(shí)鐘分頻

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //時(shí)鐘分割

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化



//TIM2通道的捕捉初始化   

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;//通道選擇

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;//下降沿

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//管腳與寄存器對(duì)應(yīng)關(guān)系

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分頻器

  TIM_ICInitStructure.TIM_ICFilter = 0x4;        //濾波設(shè)置,經(jīng)歷幾個(gè)周期跳變認(rèn)定波形穩(wěn)定0x0~0xF

  TIM_ICInit(TIM2, &TIM_ICInitStructure);        //初始化



  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);   //選擇時(shí)鐘觸發(fā)源

  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//觸發(fā)方式

  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //啟動(dòng)定時(shí)器的被動(dòng)觸發(fā)

  TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);        //打開(kāi)中斷



  TIM_Cmd(TIM2, ENABLE);                         //啟動(dòng)TIM2

}



f)        RCC初始化函數(shù)中加入TIM時(shí)鐘開(kāi)啟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM3, ENABLE);

g)        GPIO里面將輸入和輸出管腳模式進(jìn)行設(shè)置。IN_FLOATING,50MHz。

h)        使用中斷的話(huà)在NVIC里添加如下代碼:



//打開(kāi)TIM中斷(與前一章相同)

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;



i)        簡(jiǎn)單應(yīng)用:

變量 = TIM_GetCapture4(TIM2);



j)        注意事項(xiàng):

i.        由于我的需求只跟高電平寬度有關(guān),所以避免了使用PWM輸入模式,這樣可以每個(gè)管腳捕捉一路信號(hào)。如果使用PWM模式,每一路需要占用兩個(gè)寄存器,所以一個(gè)定時(shí)器只能同時(shí)使用兩路PWM輸入。

ii.        由于捕捉需要觸發(fā)啟動(dòng)定時(shí)器,所以PWM輸出與捕捉不容易在同一個(gè)TIM通道上實(shí)現(xiàn)。如果必須的話(huà)只能增加計(jì)數(shù)溢出的相關(guān)代碼。

iii.        有些程序省略了捕捉通道的初始化代碼,這是不對(duì)的

iv.        在基本計(jì)時(shí)器初始化代碼里面注意選擇適當(dāng)?shù)挠?jì)數(shù)器長(zhǎng)度,最好讓波形長(zhǎng)度不要長(zhǎng)于一個(gè)計(jì)數(shù)周期,否則需要增加溢出代碼很麻煩。一個(gè)計(jì)數(shù)周期的長(zhǎng)度計(jì)算跟如下幾個(gè)參數(shù)有關(guān):

(1)        RCC初始化代碼里面的RCC_PCLKxConfig,這是TIM的基礎(chǔ)時(shí)鐘源與系統(tǒng)時(shí)鐘的關(guān)系。

(2)        TIM初始化的TIM_Period,這是計(jì)數(shù)周期的值

(3)        TIM初始化的TIM_Prescaler,這是計(jì)數(shù)周期的倍頻計(jì)數(shù)器,相當(dāng)于調(diào)節(jié)計(jì)數(shù)周期,可以使TIM_Period盡量大,提高計(jì)數(shù)精度。   





                                    STM32筆記之十二:時(shí)鐘不息工作不止,systic時(shí)鐘應(yīng)用

a)        目的:使用系統(tǒng)時(shí)鐘來(lái)進(jìn)行兩項(xiàng)實(shí)驗(yàn)——周期執(zhí)行代碼與精確定時(shí)延遲。

b)        初始化函數(shù)定義:

void SysTick_Configuration(void);

c)        初始化函數(shù)調(diào)用:

SysTick_Configuration();

d)        初始化函數(shù):

void SysTick_Configuration(void)

{

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//時(shí)鐘除8

  SysTick_SetReload(250000);                                                    //計(jì)數(shù)周期長(zhǎng)度

  SysTick_CounterCmd(SysTick_Counter_Enable);                   //啟動(dòng)計(jì)時(shí)器

  SysTick_ITConfig(ENABLE);                                                     //打開(kāi)中斷

}

e)        在NVIC的初始化函數(shù)里面增加以下代碼打開(kāi)相關(guān)中斷:

NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 1, 0);//中斷等級(jí)設(shè)置,一般設(shè)置的高一些會(huì)少受其他影響

f)        在stm32f10x_it.c文件中找到void SysTickHandler 函數(shù)

void SysTickHandler(void)

{

執(zhí)行代碼

}

g)        簡(jiǎn)單應(yīng)用:精確延遲函數(shù),因?yàn)閟ystic中斷往往被用來(lái)執(zhí)行周期循環(huán)代碼,所以一些例程中使用其中斷的啟動(dòng)和禁止來(lái)編寫(xiě)的精確延時(shí)函數(shù)實(shí)際上不實(shí)用,我自己編寫(xiě)了精確計(jì)時(shí)函數(shù)反而代碼更精簡(jiǎn),思路更簡(jiǎn)單。思路是調(diào)用后,變量清零,然后使用時(shí)鐘來(lái)的曾變量,不斷比較變量與延遲的數(shù)值,相等則退出函數(shù)。代碼和步驟如下:

i.        定義通用變量:u16 Tic_Val=0; //變量用于精確計(jì)時(shí)

ii.        在stm32f10x_it.c文件中相應(yīng)定義:

extern u16 Tic_Val;//在本文件引用MAIN.c定義的精確計(jì)時(shí)變量

iii.        定義函數(shù)名稱(chēng):void Tic_Delay(u16 Tic_Count);//精確延遲函數(shù)

iv.        精確延時(shí)函數(shù):

void Tic_Delay(u16 Tic_Count)               //精確延時(shí)函數(shù)

{         Tic_Val=0;                           //變量清零

  while(Tic_Val != Tic_Count){printf("");}//計(jì)時(shí)

}

v.        在stm32f10x_it.c文件中void SysTickHandler 函數(shù)里面添加

     Tic_Val++;//變量遞增

vi.        調(diào)用代碼:Tic_Delay(10);   //精確延時(shí)

vii.                            疑問(wèn):如果去掉計(jì)時(shí)行那個(gè)沒(méi)用的printf("");函數(shù)將停止工作,這個(gè)現(xiàn)象很奇怪

                                              STM32筆記之十三:惡搞,兩只看門(mén)狗

a)        目的:

了解兩種看門(mén)狗(我叫它:系統(tǒng)運(yùn)行故障探測(cè)器和獨(dú)立系統(tǒng)故障探測(cè)器,新手往往被這個(gè)并不形象的象形名稱(chēng)搞糊涂)之間的區(qū)別和基本用法。

b)        相同:

都是用來(lái)探測(cè)系統(tǒng)故障,通過(guò)編寫(xiě)代碼定時(shí)發(fā)送故障清零信號(hào)(高手們都管這個(gè)代碼叫做“喂狗”),告訴它系統(tǒng)運(yùn)行正常。一旦系統(tǒng)故障,程序清零代碼(“喂狗”)無(wú)法執(zhí)行,其計(jì)數(shù)器就會(huì)計(jì)數(shù)不止,直到記到零并發(fā)生故障中斷(狗餓了開(kāi)始叫喚),控制CPU重啟整個(gè)系統(tǒng)(不行啦,開(kāi)始咬人了,快跑……)。

c)        區(qū)別:

獨(dú)立看門(mén)狗Iwdg——我的理解是獨(dú)立于系統(tǒng)之外,因?yàn)橛歇?dú)立時(shí)鐘,所以不受系統(tǒng)影響的系統(tǒng)故障探測(cè)器。(這條狗是借來(lái)的,見(jiàn)誰(shuí)偷懶它都咬!)主要用于監(jiān)視硬件錯(cuò)誤。

窗口看門(mén)狗wwdg——我的理解是系統(tǒng)內(nèi)部的故障探測(cè)器,時(shí)鐘與系統(tǒng)相同。如果系統(tǒng)時(shí)鐘不走了,這個(gè)狗也就失去作用了。(這條狗是老板娘養(yǎng)的,老板不干活兒他不管!)主要用于監(jiān)視軟件錯(cuò)誤。

d)        初始化函數(shù)定義:鑒于兩只狗作用差不多,使用過(guò)程也差不多初始化函數(shù)栓一起了,用的時(shí)候根據(jù)情況刪減。

void WDG_Configuration(void);

e)        初始化函數(shù)調(diào)用:

WDG_Configuration();

f)        初始化函數(shù)

void WDG_Configuration()                //看門(mén)狗初始化

{

//軟件看門(mén)狗初始化

  WWDG_SetPrescaler(WWDG_Prescaler_8); //時(shí)鐘8分頻4ms

// (PCLK1/4096)/8= 244 Hz (~4 ms)

   WWDG_SetWindowValue(65);                    //計(jì)數(shù)器數(shù)值

  WWDG_Enable(127);                   //啟動(dòng)計(jì)數(shù)器,設(shè)置喂狗時(shí)間

// WWDG timeout = ~4 ms * 64 = 262 ms

   WWDG_ClearFlag();                   //清除標(biāo)志位

  WWDG_EnableIT();                    //啟動(dòng)中斷

//獨(dú)立看門(mén)狗初始化

  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//啟動(dòng)寄存器讀寫(xiě)

  IWDG_SetPrescaler(IWDG_Prescaler_32);//40K時(shí)鐘32分頻

  IWDG_SetReload(349);                 //計(jì)數(shù)器數(shù)值

  IWDG_ReloadCounter();                //重啟計(jì)數(shù)器

  IWDG_Enable();                       //啟動(dòng)看門(mén)狗

}

g)        RCC初始化:只有軟件看門(mén)狗需要時(shí)鐘初始化,獨(dú)立看門(mén)狗有自己的時(shí)鐘不需要但是需要systic工作相關(guān)設(shè)置。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

h)        獨(dú)立看門(mén)狗使用systic的中斷來(lái)喂狗,所以添加systic的中斷打開(kāi)代碼就行了。軟件看門(mén)狗需要在NVIC打開(kāi)中斷添加如下代碼:

  NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel; //通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //占先中斷等級(jí)

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;      //響應(yīng)中斷優(yōu)先級(jí)

  NVIC_Init(&NVIC_InitStructure);                        //打開(kāi)中斷

i)        中斷程序,軟件看門(mén)狗在自己的中斷中喂狗,獨(dú)立看門(mén)狗需要使用systic的定時(shí)中斷來(lái)喂狗。以下兩個(gè)程序都在stm32f10x_it.c文件中。

void WWDG_IRQHandler(void)

{

  WWDG_SetCounter(0x7F);          //更新計(jì)數(shù)值

WWDG_ClearFlag();               //清除標(biāo)志位

}

void SysTickHandler(void)

{  IWDG_ReloadCounter();         //重啟計(jì)數(shù)器(喂狗)

}

j)        注意事項(xiàng):

i.        有狗平常沒(méi)事情可以不理,但是千萬(wàn)別忘了喂它,否則死都不知道怎么死的!

ii.        初始化程序的調(diào)用一定要在systic的初始化之后。

iii.        獨(dú)立看門(mén)狗需要systic中斷來(lái)喂,但是systic做別的用處不能只做這件事,所以我寫(xiě)了如下幾句代碼,可以不影響systic的其他應(yīng)用,其他systic周期代碼也可參考:

第一步:在stm32f10x_it.c中定義變量

int Tic_IWDG;           //喂狗循環(huán)程序的頻率判斷變量

第二步:將SysTickHandler中喂狗代碼改為下面:

Tic_IWDG++;             //變量遞增

if(Tic_IWDG>=100)       //每100個(gè)systic周期喂狗

{  IWDG_ReloadCounter();//重啟計(jì)數(shù)器(喂狗)

  Tic_IWDG=0;          //變量清零

}  

                            STM32筆記之十四:基本問(wèn)題,來(lái)討論一下軟件架構(gòu)

網(wǎng)上大家都在討論和學(xué)習(xí),但是對(duì)于架構(gòu)這個(gè)基本問(wèn)題卻沒(méi)幾個(gè)人討論。個(gè)人認(rèn)為有個(gè)好的架構(gòu)是寫(xiě)好代碼的基礎(chǔ),可以使后期的調(diào)式工作事半功倍!!

1、        架構(gòu)組成:我的程序代碼分為四種結(jié)構(gòu)

a)        順序執(zhí)行代碼

定義:按照順序逐行執(zhí)行的代碼

優(yōu)點(diǎn):是思路簡(jiǎn)單,代碼可靠不易被干擾。

缺點(diǎn):占用資源

用途:只用來(lái)各種變量、函數(shù)的定義,硬件的初始化程序

位置:main.c的開(kāi)始一直到main函數(shù)的while函數(shù)之前

b)        空閑執(zhí)行代碼

定義:在CPU空閑的時(shí)候才執(zhí)行的代碼

        優(yōu)點(diǎn):不占用資源

        缺點(diǎn):執(zhí)行的實(shí)時(shí)性不能保證

        用途:非實(shí)時(shí)任務(wù),調(diào)試信息輸出,不重要的狀態(tài)指示

        位置:main.c的main函數(shù)的while函數(shù)內(nèi)部

c)        中斷執(zhí)行代碼

定義:由軟硬件事件打斷整個(gè)程序而執(zhí)行的代碼

優(yōu)點(diǎn):可以保證實(shí)時(shí)性,各種中斷可以安排優(yōu)先順序

缺點(diǎn):關(guān)系相對(duì)復(fù)雜,互相之間容易干擾

用途:觸發(fā)性的代碼,比如接收數(shù)據(jù),響應(yīng)外部設(shè)備,按鈕的相應(yīng)

位置:stm32f10x_it.c內(nèi)部

d)        循環(huán)執(zhí)行代碼

定義:按照時(shí)間周期執(zhí)行的代碼

優(yōu)點(diǎn):定期自動(dòng)執(zhí)行

缺點(diǎn):實(shí)時(shí)性不好

用途:需要周期執(zhí)行的任務(wù),狀態(tài)檢查及相關(guān)信息輸出,數(shù)據(jù)記錄

位置:stm32f10x_it.c的SysTickHandler內(nèi)部

e)        DMA自動(dòng)代碼

定義:不需要主程序干預(yù),外設(shè)自動(dòng)執(zhí)行

優(yōu)點(diǎn):自動(dòng)刷新數(shù)據(jù),不占用CPU資源

缺點(diǎn):不能控制

用途:數(shù)據(jù)通信存儲(chǔ),AD轉(zhuǎn)換

位置:不需要

2、架構(gòu)執(zhí)行順序圖

下載 (51.33 KB)

2009-4-22 15:39





                   STM32學(xué)習(xí)筆記之十五——IAR4的最后瘋狂,笨笨的開(kāi)發(fā)模板下載

準(zhǔn)備大換血了,包括開(kāi)發(fā)環(huán)境升級(jí)和固件升級(jí),那個(gè)需要一定過(guò)程,吧之前完成的模板跟大家共享一下。

我的程序庫(kù)特點(diǎn):

a)        默認(rèn)兼容ST-LINK-II,IAR EWARM 4.42A,F(xiàn)lash調(diào)試,使用串口1,GPIOA的3、4、

    5、6腳輸入,GPIOB的1、2、10、11腳輸出,其他有可能需要更改設(shè)置

b)        為操作方便減少了目錄的層次

c)        為學(xué)習(xí)方便使用網(wǎng)友漢化版2.0.2固件,主要是庫(kù)函數(shù)中c代碼的注釋。

d)        加入必用的flash(讀取優(yōu)化),nvic(RAM與Flash調(diào)試選擇),rcc(時(shí)鐘管理模

    板,開(kāi)啟外設(shè)時(shí)鐘模板),gpio(管腳定義模板)的初始化代碼,所有模板代碼用到的

    時(shí)候只要去掉前面的注釋"//",根據(jù)需求填入相應(yīng)值就可以了。

e)        因?yàn)樽约河浶圆缓茫詍ain函數(shù)中的代碼做到每行注釋?zhuān)阌谧约阂院笫褂谩?

f)        列出常見(jiàn)應(yīng)用代碼模板與ASCII常用列表。

g)        集成putchar字符輸出和Printf的重定義到串口的代碼,便于調(diào)試。

h)        集成NVIC中斷管理模板,EXTI外部I/O中斷模板

i)      針對(duì)自己情況集成PWM輸出模板和CAP脈寬捕捉模板,并全部注釋。

j)      集成系統(tǒng)循環(huán)時(shí)鐘的初始化函數(shù)模板

k)      集成自己編寫(xiě)精確延時(shí)代碼,不會(huì)影響systic的周期代碼的執(zhí)行。

l)      集成兩種看門(mén)狗的使用代碼,小心使用

M)      集成hex生成設(shè)置命令,位置在編譯目錄(STM32F103C8)的Exe下,集成ISP軟件便

    于脫離仿真器的串口調(diào)試STMISP.exe。

由于注釋寫(xiě)的太多,還加入自己編程以來(lái)的許多格式習(xí)慣,所以許多人會(huì)覺(jué)得混亂不堪,在

此聲明,此程序庫(kù)僅僅為個(gè)人學(xué)習(xí)之用!



                                  STM32學(xué)習(xí)筆記之十六——題外話(huà),自己做塊工程板

一、我的學(xué)習(xí)計(jì)劃將STM32單片機(jī)的硬件設(shè)計(jì)工作:

第一步——用STM32F103CBT6的48腳芯片,為光電平臺(tái)的簡(jiǎn)單控制為目標(biāo),實(shí)現(xiàn)基本外圍硬件、PWM、串口、I/O。將SPI、I2C留插針。

第二步——為集成傳感器應(yīng)用為目標(biāo),在第一步硬件基礎(chǔ)上制作功能性的套版,兩板連接實(shí)現(xiàn)AD、SPI、I2C、RTC等等功能。

二、硬件規(guī)劃

選用STM32F103CBT6,面積7×7mm,128K flash,16K RAM,4個(gè)16bit PWM,12個(gè)12bit PWM或CAP,2個(gè)SPI,2個(gè)I2C,3個(gè)串口,1個(gè)CAN,1個(gè)USB,),12ADC。

管腳分配目標(biāo)1如圖,之后的功能包括:4個(gè)AD,3個(gè)串口(1個(gè)與I2C復(fù)用),1個(gè)SPI,8個(gè)(兩組)PWM輸入輸出,1個(gè)USB,1個(gè)I/O,1個(gè)MCO。

三、管腳分配:

下載 (32.83 KB)

2009-4-26 16:14



四、ALTIUM DESIGNER 6(Protel的第六個(gè)版本)操作筆記

之所以選擇這個(gè)軟件三個(gè)理由:1、界面習(xí)慣兼容Protel。2、操作習(xí)慣于Windows類(lèi)似方便。3、可輸出igs用于結(jié)構(gòu)設(shè)計(jì)。

軟件使用筆記如下:

a)        流程:新建工程,添加原理圖,添加SCH庫(kù),畫(huà)原理圖,添加PCB庫(kù),設(shè)定封裝,添加PCB,布線(xiàn),檢查,導(dǎo)出生產(chǎn)文件。

b)        新建工程:最好使用自己以前的同版本文檔設(shè)置,會(huì)包含各種庫(kù)省去大量工作

c)        添加器件到SCH,可使用復(fù)制粘貼的辦法,注意管腳,有些需要外殼接地的器件把外殼的焊點(diǎn)畫(huà)出來(lái)。完成后點(diǎn)擊放置,改動(dòng)后再器件名稱(chēng)點(diǎn)擊右鍵更改。

d)        畫(huà)原理圖:操作類(lèi)似其他windows軟件,會(huì)自動(dòng)檢查錯(cuò)誤連接和重復(fù)硬件。

e)        添加器件到PCB庫(kù),最好使用拷貝粘貼的辦法,最好有官方的焊點(diǎn)圖。沒(méi)有的話(huà)可以按照封裝的型號(hào)直接去http://www.***search.com/搜索封裝型號(hào)(不是器件型號(hào)),也有封裝的相關(guān)尺寸和焊點(diǎn)圖。

f)        雙擊原理圖的器件,在右下角改封裝名稱(chēng)。

g)        添加新的PCB到工程:

“設(shè)計(jì)/規(guī)則”改線(xiàn)寬、線(xiàn)距、器件距離……;

“設(shè)計(jì)/板子形狀/重新定義板子形狀”改工作區(qū)域大小,然后左鍵點(diǎn)擊前置Keepout層,畫(huà)電路板外形;

“設(shè)計(jì)/板參數(shù)選項(xiàng)”改網(wǎng)格大小,器件和走線(xiàn)中鼠標(biāo)捕捉的間隔大小……;

“設(shè)計(jì)/Import changes From……”引入原理圖的器件和連接方式,包括改動(dòng)(出現(xiàn)對(duì)match提示選擇繼續(xù)就可以了);

“查看/切換單位”改公制和英制;

“工具/取消布線(xiàn)”取消已經(jīng)布好的線(xiàn);

“自動(dòng)布線(xiàn)”計(jì)算機(jī)自動(dòng)布線(xiàn),功能比Protel增強(qiáng)不少;

“報(bào)告/測(cè)量距離”測(cè)量實(shí)際距離;

在層標(biāo)簽單擊,前置這個(gè)層。右鍵有隱藏層和顯示層比較常用。

屏幕中點(diǎn)擊右鍵菜單中“設(shè)計(jì)/規(guī)則”、“選項(xiàng)/板參數(shù)選項(xiàng)”、 “選項(xiàng)/層疊管理”(添加和刪除層)、“選項(xiàng)/顯示掩藏”(針對(duì)各種類(lèi)型進(jìn)行顯示和隱藏,查找未布的線(xiàn)就使用此功能后在操作框中點(diǎn)擊“所有最終”然后點(diǎn)擊“Apply”,再手工點(diǎn)擊所有的選項(xiàng)為“隱藏的”再點(diǎn)“Apply”就能看到未布線(xiàn)的連線(xiàn)了)

快捷鍵:空格鍵旋轉(zhuǎn)器件,TAB鍵切換線(xiàn)寬和放置過(guò)孔。左鍵單擊選擇,左鍵按住移動(dòng)器件(多個(gè)重疊會(huì)有列表選擇,未松開(kāi)時(shí)右鍵取消操作),左鍵雙擊改器件屬性(所在層、位置……),右鍵按住移動(dòng)鼠標(biāo)平移視野,滾輪上下移動(dòng),滾輪按住移動(dòng)鼠標(biāo)放大縮小

五、基本電路原理設(shè)計(jì)

拋棄復(fù)雜設(shè)計(jì),專(zhuān)注于可獨(dú)立調(diào)式的CPU板設(shè)計(jì)。計(jì)劃設(shè)計(jì)模塊包括:供電、JTAG、晶振、RTC(電池引出)。

注:未使用標(biāo)準(zhǔn)JTAG設(shè)計(jì),原因有三:

1、原設(shè)計(jì)太占管腳,這個(gè)尺寸實(shí)在難實(shí)現(xiàn)

2、這只是CPU板具體應(yīng)用會(huì)再做功能套版,上面可以連接標(biāo)準(zhǔn)JTAG

3、有可能向USB燒寫(xiě)和SW雙線(xiàn)調(diào)式方向轉(zhuǎn)變,所以以后不一定會(huì)使用標(biāo)準(zhǔn)JTAG


作者: changfeng4hao    時(shí)間: 2016-1-25 10:53
點(diǎn)贊,            




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1