版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1.1單片機與STM32
歡迎加入“學銀在線課程”《C語言及單片機控制技術(shù)》(徐亮老師主持),可使用“學習通”APP掃描下面二維碼加入課程,或者百度搜索“學銀在線”進入官網(wǎng)后搜索課程名稱進入課程主頁并加入課程。
本課程即將登陸“智慧職教”平臺,敬請期待……知識目標:
了解單片機的發(fā)展史及其主要應用領(lǐng)域、STM32的由來以及產(chǎn)品線簡介。1.1.1什么是單片機單片機是一種集成電路芯片,是采用超大規(guī)模集成電路技術(shù)把具有數(shù)據(jù)處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統(tǒng)、定時器/計數(shù)器等功能(可能還包括顯示驅(qū)動電路、脈寬調(diào)制電路、模擬多路轉(zhuǎn)換器、A/D轉(zhuǎn)換器等電路)集成到一塊硅片上構(gòu)成的一個小而完善的微型計算機系統(tǒng)。1.1.2單片機發(fā)展史單片機誕生于20世紀70年代末,經(jīng)歷了SCM、MCU、SoC三大階段。
1、SCM即單片微型計算機(SingleChipMicrocomputer)階段,這一階段單片機的主要特點是追求如何將計算機體系單片化,即將計算機的CPU、RAM、ROM、總線等部件集成在一片芯片上,便于嵌入到設備之中。這一階段的代表產(chǎn)品有Intel公司的MCS-48單片機。
2、MCU即微控制器(MicroControllerUnit)階段,由于在實際項目中,單片機往往需要與各種外設芯片協(xié)同工作才能完成特定的控制功能,為了進一步簡化單片機應用電路的設計,單片機芯片上集成了越來越多的外設,稱為“片內(nèi)外設”。這一階段單片機的特點就是單片機集成的片內(nèi)外設越來越多,單片機控制板卡的獨立外設芯片越來越少。在發(fā)展MCU方面,早期最著名的廠家當數(shù)Philips公司,本文介紹的STM32系列單片機也是MCU大家庭中的一員。
3、SoC單片機(SystemOnChip),與MCU相比,SoC單片機可以看做是一種專用型單片機。比如國產(chǎn)的樂鑫ESP8266單片機,內(nèi)核是一個32位的精簡指令集處理器,自帶一個WIFI模塊;再比如高通的驍龍?zhí)幚砥?,CPU只占整個芯片面積的15%,其余被GPU(GraphicsProcessingUnit,圖像處理器)、DSP(DigitalSignalProcessing,數(shù)字處理)單元、基帶/射頻前端、Modem(調(diào)制解調(diào)器)等模塊占據(jù)。1.1.3STM32的誕生與發(fā)展
STM32系列單片機是來自歐洲的意法半導體公司(STMicroelectronics,簡稱ST)旗下眾多半導體產(chǎn)品之一。2007年6月11日,STM32單片機誕生于北京,同年STM32單片機在全球通用MCU市場排第11名,此后一路高歌猛進,2015年上升到第3名,2018年繼續(xù)上升到第2名,2021年登頂?shù)?名。
與傳統(tǒng)單片機不同,STM32的內(nèi)核并非由ST自主研發(fā),而是采用了英國ARM公司授權(quán)的Cortex-M內(nèi)核,圍繞內(nèi)核增加了外設并進行封裝。除了STM32之外,目前市面上還有恩智浦(NXP)、新唐(Nuvoton)等知名半導體公司推出了屬于自己的基于Cortex-M內(nèi)核的單片機。1.1.4STM32豐富的產(chǎn)品線
截止2023年9月,STM32單片機提供4大類16個系列共計1291個型號,并且還在持續(xù)更新中。
STM32產(chǎn)品廣泛應用于工業(yè)控制、消費電子、物聯(lián)網(wǎng)、通訊設備、醫(yī)療服務、安防監(jiān)控等應用領(lǐng)域,其優(yōu)異的性能進一步推動了生活和產(chǎn)業(yè)智能化的發(fā)展。Tobecontinued...1.2STM32的引腳與封裝知識目標:
了解STM32的引腳結(jié)構(gòu),掌握簡單的單片機最小系統(tǒng)的設計。1.2.1引腳結(jié)構(gòu)本課程選擇的STM32的型號是STM32F103R6,該型號芯片基于ARMCortex-M3內(nèi)核,其主要特性為:⑴電源電壓直流2.0~3.6V;⑵封裝LQFP64(10×10mm);⑶輸入/輸出引腳數(shù)51個;⑷程序存儲器(FlashMemory)32KB,靜態(tài)隨機存儲器(SRAM)6KB;⑸最高主頻72MHz;⑹片內(nèi)外設有ADC、DMA、PWM、RTC、Timers;⑺通信接口有I2C、SPI、USART、CAN、USB2.0;⑻工作溫度-40~+85℃。⑼工業(yè)級芯片。a.引腳分布圖b.芯片實物圖芯片引腳的主要功能有:⑴電源引腳:VDD_x、VSS_x(x=1~4)、VDDA、VSSA、VBAT(電池正極);⑵時鐘源輸入輸出引腳:OSC_IN、OSC_OUT、OSC32_IN、OSC32_OUT;⑶復位引腳NRST;⑷輸入輸出引腳PAx、PBx、PCx、PDx(x=0~15),共計51個引腳;⑸大部分引腳具備多重功能,比如PA9、PA10分別為串口1(USART1)的數(shù)據(jù)發(fā)送引腳與數(shù)據(jù)接收引腳。具體后續(xù)章節(jié)將會介紹。1.2.2最小系統(tǒng)
所謂單片機最小系統(tǒng),即單片機運行所需最少的外部條件:⑴
電源●VDD_1、~VDD_4數(shù)字量電源正極,內(nèi)部連通,VSS_1~VSS_4數(shù)字量電源負極,內(nèi)部連通;●VDDA、VSSA,模擬量電源正負極,若不用ADC、DAC,或?qū)纫蟛桓邥r可以直接與數(shù)字量電源正負極相連;●VBAT作為電池正極輸入端,一般用于RTC供電,若不用RTC則直接與數(shù)字量電源正極相連。通常給定電源電壓為3.3V。⑵復位電路STM32的復位方式有系統(tǒng)復位、上電復位、備份區(qū)域復位三種,其中系統(tǒng)復位又分為外部復位、WWDG(窗口看門狗)復位、IWDG(獨立看門狗)復位、軟件復位、低功耗管理復位五種情況,這里僅介紹其中的外部復位。
外部復位電路的典型電路如下圖所示,當系統(tǒng)上電或在運行過程中按下圖中按鈕時,STM32可按BOOT模式的設定進行復位,關(guān)于BOOT模式的具體內(nèi)容將在1.3節(jié)中介紹。⑶時鐘電路STM32的時鐘源輸入引腳一共有四個,可劃分為兩組:●OSC_IN和OSC_OUT引腳用于連接外部高速晶振(4~16MHz,典型值8MHz);●OSC32_IN、OSC32_OUT引腳用于連接外部低速晶振(32.768kHz),如果不用RTC就不用接。無論高速晶振還是低速晶振,當設計方案對時鐘源精度要求不高時,都可以選擇內(nèi)部RC振蕩器來代替外部晶振。內(nèi)部高速RC振蕩器頻率為8MHz,內(nèi)部低速RC振蕩器頻率為40kHz。專業(yè)術(shù)語:HSI——內(nèi)部高速時鐘HSE——外部高速時鐘LSI——內(nèi)部低速時鐘LSE——外部低速時鐘幾種晶振外部高速晶振與外部低速晶振的電路分別如下兩圖所示。單片機最小系統(tǒng)典型電路如下圖所示,當然可根據(jù)實際需要對電路進行修改。Tobecontinued...1.3STM32的內(nèi)部構(gòu)造知識目標:
了解與程序開發(fā)相關(guān)的部分單片機內(nèi)部構(gòu)造,主要包括存儲結(jié)構(gòu)、啟動模式與時鐘樹三部分。1.3.1Cortex-M3的存儲結(jié)構(gòu)
Cortex-M3的存儲器(包括FlashROM、SRAM等)采用統(tǒng)一編址方式,尋址空間為4GB(32位尋址,,0x00000000~0xFFFFFFFF)。4GB尋址空間被分為8個主塊(Block0~Block7),每塊512MB。
FlashROM(用于存放程序)位于Block0中,地址范圍0x08000000~0x0801FFFF,STM32F103R6地址范圍0x08000000~0x08007FFF(共計32KB);SRAM(用于存放程序運行中產(chǎn)生的臨時數(shù)據(jù))位于Block1中,起始地址0x20000000,STM32F103R6地址范圍0x20000000~0x200017FF(共計6KB);Peripherals(片上外設映射地址)位于Block2中,起始地址0x40000000。
由于STM32使用C語言開發(fā)程序,因此程序與數(shù)據(jù)的存儲地址完全由編譯器自動分配,無需人為干預。定義變量,比如:
inta=12;
編譯器為變量a自動分配一個4字節(jié)的SRAM空間并賦予初值12。定義常量,比如:
constintb=23;
當變量b為常量時,編譯器為變量b自動分配一個4字節(jié)的ROM空間并賦予初值23。1.3.2STM32的啟動(BOOT)模式STM32F103系列單片機具有三種啟動方式,如下表所示,分別為從MainFlashmemory(主閃存)啟動、從Systemmemory(系統(tǒng)存儲器)啟動和從EmbeddedSRAM(內(nèi)置靜態(tài)隨機存儲器)啟動。
其中尤以前兩種啟動方式最為常見:①從主閃存啟動即正常運行用戶編寫的程序,②從系統(tǒng)存儲器啟動即進入ST公司預置的BootLoader(啟動加載程序),一般用于從串口1下載用戶程序(具體將在1.4部分介紹)。對于STM32F103R6而言,BOOT0引腳即60號引腳,BOOT1引腳即28號引腳(PB2)。1.3.3時鐘樹STM32片內(nèi)外設較多,為了實現(xiàn)低功耗設計,允許用戶對各種外設的時鐘信號進行配置,由此構(gòu)成了如右圖所示的時鐘樹。
STM32內(nèi)部采用了PLL(Phase-LockedLoop,鎖相環(huán))技術(shù),可以將總線頻率最高倍頻至72MHz。Tobecontinued...1.4STM32的程序開發(fā)方式知識目標:
了解STM32的程序開發(fā)流程,了解與STM32程序開發(fā)相關(guān)的軟件與硬件知識。1.4.1STM32程序開發(fā)流程概述利用STM32CubeIDE的圖形化配置工具生成工程目錄與初始化代碼利用STM32CubeIDE的代碼編輯工具編寫程序并生成HEX文件利用FlashLoaderDemonstrator將程序下載至單片機FlashROM利用Proteus仿真模擬硬件實物調(diào)試軟件仿真模擬1.4.2STM32CubeIDE簡介STM32CubeIDE是ST官方在2019年推出的STM32專用IDE。
STM32CubeIDE由原先兩個工具軟件整合而成:一個是ST公司在2016年推出的圖形化配置工具STM32CubeMX,;另一個是ST公司在2017年從Atollic收購的ARM編程工具TrueSTUDIO,其主要功能是用于編寫STM32程序代碼。1.4.3硬件實物調(diào)試簡介STM32可以通過ISP、ST-LINK、J-LINK三種途徑下載程序,本課程主要介紹第一種程序下載方式——ISP方式。該方式需要用到ST免費提供的FlashLoaderDemonstrator工具,并且需要在IDE中設定生成HEX文件(默認不生成HEX文件)。1.4.4軟件仿真模擬簡介STM32電路仿真軟件采用了來自英國Labcenter公司出品的EDA工具Proteus,2016年末Proteus8.6中開始增加對STM32的支持,推薦使用Proteus8.15及以上版本。Tobecontinued...2.1C語言入門與順序結(jié)構(gòu)能力目標:
理解并掌握C語言基本數(shù)據(jù)類型,以及算術(shù)運算符、逗號運算符、賦值運算符三類運算符的使用,能使用Dev-C++編寫簡單的順序結(jié)構(gòu)程序。任務要求:根據(jù)隨機輸入的半徑r,計算得到相應的圓周長、圓面積、球面面積、球體積。2.1.1計算機語言與C語言(1)計算機語言概述●機器語言機器碼是唯一能被計算機CPU直接識別的代碼,它由二進制編碼按一定規(guī)律構(gòu)成。但由于不同的CPU集成的指令集不盡相同,因此即便是完成相同的功能,機器碼的編寫方式也不一樣。●匯編語言本質(zhì)上匯編語言與機器語言沒有區(qū)別,只是將晦澀難懂的二進制編碼用英文助記符來代替,方便人們編寫代碼。匯編代碼與機器代碼逐條對應,工作量基本相同?!窀呒壵Z言如果說機器語言、匯編語言是完全站在計算機CPU的角度考慮問題,那么高級語言就是偏向于站在人類的角度考慮問題了。高級語言通過字母、符號、數(shù)字的組合,以一種簡單、優(yōu)雅的方式書寫代碼,程序更緊湊,結(jié)構(gòu)更清晰,可以有效的提高人們的工作效率。(2)C語言的產(chǎn)生與發(fā)展
●1972年,美國貝爾實驗室的DennisM.Ritchie在B語言的基礎(chǔ)上設計出了一種全新的計算機語言,這就是C語言。
●1978年,DennisM.Ritchie與BrianW.Kernighan合著了著名的《TheCProgrammingLanguage》,但此書并沒有給出一個完整的C語言的標準。C語言之父——DennisM.Ritchie(1941年9月9日-2011年10月12日)
●1983年,美國國家標準化協(xié)會(AmericanNationalStandardsInstitute,簡稱ANSI)在《TheCProgrammingLanguage》的基礎(chǔ)上制定了第一個C語言標準,并于1989年正式發(fā)布,稱為“C89”標準,這也是后來人們熟知的“ANSIC”標準。
●后來,國際標準化組織(InternationalOrganizationforStandardization,簡稱為ISO)接納了“C89”標準,并在此基礎(chǔ)上不斷修改,陸續(xù)推出了“C90”、“C99”、“C11”標準,這些也被人們稱為“ISOC”標準。(3)C語言的標識符與關(guān)鍵字標識符是構(gòu)成C語言代碼的重要元素之一,標識符由英文字母、數(shù)字和下劃線組成,而且開頭只能是字母或者下劃線,比如:a、Ab、Ba1、_1a,都是合法的標識符。值得注意的是,C語言區(qū)分大小寫字母。ANSIC保留了32個標識符作為C語言的關(guān)鍵字,不能重做其他定義。(表見下一頁)關(guān)鍵字功能關(guān)鍵字功能auto聲明自動變量short聲明短整型變量或函數(shù)int聲明整型變量或函數(shù)long聲明長整型變量或函數(shù)float聲明浮點型變量或函數(shù)double聲明雙精度變量或函數(shù)char聲明字符型變量或函數(shù)struct聲明結(jié)構(gòu)體變量或函數(shù)union聲明共用數(shù)據(jù)類型enum聲明枚舉類型typedef用以給數(shù)據(jù)類型取別名const聲明只讀變量unsigned聲明無符號類型變量或函數(shù)signed聲明有符號類型變量或函數(shù)extern聲明變量是在其他文件正聲明register聲明寄存器變量static聲明靜態(tài)變量volatile說明變量在程序執(zhí)行中可被隱含地改變關(guān)鍵字功能關(guān)鍵字功能void聲明函數(shù)無返回值或無參數(shù),聲明無類型指針if條件語句else條件語句否定分支(與if連用)switch用于開關(guān)語句case開關(guān)語句分支for一種循環(huán)語句do循環(huán)語句的循環(huán)體while循環(huán)語句的循環(huán)條件goto無條件跳轉(zhuǎn)語句continue結(jié)束當前循環(huán),開始下一輪循環(huán)break跳出當前循環(huán)default開關(guān)語句中的“其他”分支sizeof計算數(shù)據(jù)類型長度return子程序返回語句(可以帶參數(shù),也可不帶參數(shù))循環(huán)條件2.1.2使用Dev-C++編寫計算機C程序Dev-C++是一種免費的C/C++集成開發(fā)環(huán)境(IntegratedDevelopmentEnvironment,簡稱IDE),適合用來學習C/C++語言。在計算機桌面上找到Dev-C++的圖標并雙擊運行。選擇菜單欄“文件”→“新建”→“項目”新建項目。進入所示編程界面。
編寫程序并按下“編譯運行”按鈕,彈出運行窗口。2.1.3C語言的基本數(shù)據(jù)類型
本次課僅學習其中的基本數(shù)據(jù)類型:整型、浮點型、字符類型(1)整型
其中,int是一般整型,short是短整型,long是長整型,unsigned表示無符號,即類似于數(shù)學的正整數(shù)。
實際上,int型數(shù)據(jù)長度不定,與編譯器有很大關(guān)系,有可能長度為2個字節(jié),也有可能長度為4個字節(jié)。類別數(shù)據(jù)類型字節(jié)長度取值范圍一般整型int2-3,2768~3,2767短整型short2-3,2768~3,2767長整型long4-21,4748,3648~21,4748,3647無符號一般整型unsignedint20~6,5535無符號短整型unsignedshort20~6,5535無符號長整型unsignedlong40~42,9496,7295
C語言是強類型語言,所有變量必須先定義再使用。變量的定義格式:類型說明符變量名;變量的賦值格式:變量名=常量、變量或表達式;整型變量的定義與賦值:
這里的“=”不同于數(shù)學上等號的意義,屬于C語言的賦值運算符,表示將“=”右邊的常量、變量或表達式的值賦給左邊的變量。inta,b,c;a=12,b=014,c=0xC;
可以一次只定義一個變量,也可以一次定義多個變量,多個變量之間用逗號運算符“,”隔開。變量也可以在定義的同時進行初始化:以上,三個變量a、b、c實際上賦值的內(nèi)容是一樣的,只是分別采用十進制、八進制、十六進制進行了賦值,八進制前綴“0”,十六進制前綴“0x”或者“0X”,如果十六進制數(shù)據(jù)中出現(xiàn)了字母,大小寫皆可。inta=12,b=014,c=0xC;(2)浮點型
浮點型類似于數(shù)學的實數(shù)類型,有float、double兩種,float是一般浮點型,double是雙精度浮點型。浮點型變量的定義與賦值:以上,變量a、b分別采用了十進制小數(shù)形式、指數(shù)形式進行了賦值,其中指數(shù)形式“4.56e1”即為4.56×101的意思,這里“e”也可以寫成“E”。類別數(shù)據(jù)類型字節(jié)長度取值范圍有效位單精度浮點型float4±1.0e-37~±1.0e+387雙精度浮點型double8±1.0e-307~±1.0e+30816floata,b;a=12.3,b=4.56e1;(3)字符型字符型變量一般用來存放字符對應的ASCII碼,比如:以上,變量a、b實際上賦值的內(nèi)容是一樣的,變量a賦予字符7,變量b賦予字符7對應的ASCII碼。實際使用的時候,字符型變量往往也用來存放整數(shù)數(shù)據(jù)。類別數(shù)據(jù)類型字節(jié)長度取值范圍字符型char1-128~127無符號字符型unsignedchar10~255chara,b;a=’7’,b=55;ASCII碼表(引自百度百科)2.1.4格式輸入/輸出函數(shù)格式輸入函數(shù)用于從輸入設備(比如鍵盤)向計算機輸入數(shù)據(jù),格式輸出函數(shù)用于計算機向輸出設備(比如顯示器)輸出數(shù)據(jù)。格式輸入/輸出函數(shù)是由C標準庫函數(shù)提供,在使用它們的時候,必須使用預處理命令中的“包含”命令將標準輸入/輸出頭文件“stdio.h”包含到當前項目中來。#include<stdio.h>main(){……}……值得注意的是,預處理命令不是C語言語句。以包含命令為例,簡單的說就是在編譯器編譯之前,將頭文件中的內(nèi)容替換該包含命令,再進行編譯。
(1)格式輸出函數(shù)——printf()格式輸出函數(shù)的一般形式是:printf(“格式控制字符串”,輸出列表);
括號內(nèi)內(nèi)容由兩部分構(gòu)成:
①格式控制字符串作用是指定輸出格式,它又由三部分構(gòu)成:●顯示字符串,按原樣輸出?!窀袷交嘉环?,用于按照指定格式將數(shù)據(jù)輸出,由“%”和特定的字符組成,常用格式化占位符如表所示(后頁),輸出時自動按指定格式顯示變量或表達式的值?!褶D(zhuǎn)義字符,在輸出時會被自動轉(zhuǎn)換為對應的操作命令,常用的轉(zhuǎn)移字符如表所示(后頁)。
●格式占位符:占位符作用占位符作用%d以十進制整數(shù)形式輸出%s輸出字符串%x或%X以十六進制整數(shù)形式輸出%f以小數(shù)形式輸出實數(shù)%c輸出單個字符%e或%E以指數(shù)形式輸出實數(shù)轉(zhuǎn)義字符作用轉(zhuǎn)義字符作用\n換行符,將當前位置移到下一行開頭\\輸出一個反斜杠“\”\r回車符,將當前位置移到本行開頭\’輸出一個單引號“’”\t水平制表符\”輸出一個雙引號“””\v垂直制表符\0空字符,也是字符串結(jié)束標志
●轉(zhuǎn)義字符:
②輸出列表輸出變量或表達式的列表,用逗號運算符“,”隔開,輸出列表中變量或表達式的個數(shù)必須與格式控制字符串的個數(shù)一一對應。例如:運行結(jié)果:chara=’7’;printf("字符%c的ASCII碼是%d\n",a,a);(2)格式輸入函數(shù)——scanf()格式輸入函數(shù)的一般形式是:scanf(“格式控制字符串”,地址列表);變量的地址是由取地址運算符“&”后跟變量名構(gòu)成,比如“&a”表示變量a在計算機內(nèi)存中的地址。
比如:運行結(jié)果:inta,b,c;scanf("%d%d%d",&a,&b,&c);printf("變量a,b,c的值分別是:%d,%d,%d\n",a,b,c);2.1.5C語言的運算符(一)
(1)算術(shù)運算符首先演示整數(shù)的運算:運算符功能應用舉例+加法運算符x+y-減法運算符x-y*乘法運算符x*y/除法運算符x/y%取模(求余數(shù))運算符x%y++自增運算符x++或者++x--自減運算符x--或者--xinta=13,b=3;printf("和:%d差:%d積:%d商:%d余數(shù):%d\n",a+b,a-b,a*b,a/b,a%b);格式結(jié)果:值得注意的是,13/3的結(jié)果是整除的結(jié)果4,只有整數(shù)才能做整除與取模運算。C語言中,四則運算同樣遵循“先乘除后加減”的原則,如果需要改變運算次序,可以用小括號“()”來提升運算優(yōu)先等級,比如:floata=1,b=2,c=3,d=4,r;r=(a+b)/c+d;自增/減運算符屬于單目運算符,符號與變量的位置不同,程序運行的效果也截然不同。接著演示自增運算符的使用方法:運行結(jié)果:總結(jié):若++/--運算符在前是先自增/減再執(zhí)行語句,若++/--運算符在后則是先執(zhí)行語句再自增/減。inta=1,b=1;printf("a的值是%d,b的值是%d\n",++a,b++);printf("a的值是%d,b的值是%d\n",a,b);
(2)賦值運算符演示程序:運行結(jié)果:運算符功能舉例運算符功能舉例=賦值a=b;&=位與賦值a&=b等價于a=a&b+=加賦值a+=b等價于a=a+b^=位異或賦值a^=b等價于a=a^b-=減賦值a-=b等價于a=a-b|=位或賦值a|=b等價于a=a|b*=乘賦值a*=b等價于a=a*b<<=左移賦值a<<=n等價于a=a<<n/=除賦值a/=b等價于a=a/b>>=右移賦值a>>=n等價于a=a>>n%=取模賦值a%=b等價于a=a%b
inta=11,b=13,c=15,d=17,e=19;a+=1;b-=2;c*=3;d/=4;e%=5;printf("a:%d,b:%d,c:%d,d:%d,e:%d\n",a,b,c,d,e);
(3)逗號運算符逗號運算構(gòu)成的表達式一般形式是:
表達式1,表達式2,表達式3,…,表達式n以上表達式的功能是,從左往右依次求出每個表達式的值,表達式n的值即為整個逗號表達式的值。演示程序:運行結(jié)果:inta=2,b;b=(a++,a+3);printf("b:%d\n",b);2.1.6任務程序的編寫
(現(xiàn)場操作演示...)
圓周長:圓面積:球面面積:球體積:Tobecontinued...2.2C語言分支結(jié)構(gòu)能力目標:
理解、區(qū)分并掌握C語言的邏輯運算符與位運算符,理解并掌握C語言的比較運算符,能利用if語句與switch語句實現(xiàn)分支結(jié)構(gòu)程序。任務要求:
任務A:輸入年份,判斷該年份是否為閏年。
任務B:某商場舉辦優(yōu)惠購物活動,購物滿5000元打8折,購物滿2000元,不滿5000元打8.5折,購物滿1000元,不滿2000元打9折,其余不打折,輸入購物金額數(shù),自動計算折后價。2.2.1C語言的運算符(二)(1)邏輯運算符在邏輯關(guān)系中,用整型或字符型數(shù)字“0”代表“假”,用非零值代表“真”,但邏輯表達式的計算結(jié)果只有“0”或者“1”。演示程序://邏輯與運算printf("And:%d,%d,%d,%d\n",0&&0,0&&1,2&&0,3&&4);//邏輯或運算printf("Or:%d,%d,%d,%d\n",0||0,0||1,2||0,3||4);//邏輯非運算printf("Not:%d,%d\n",!0,!1);運算符功能表達式&&邏輯與a&&b||邏輯或a||b!邏輯非!a
運行結(jié)果:(2)位運算符運算符功能舉例運算符功能舉例&按位與a&b^按位異或a^b|按位或a|b<<左移a<<n~按位取反~a>>右移a>>n首先演示按位與、按位或、按位取反、按位異或運算符的使用:運行結(jié)果:下面是四個表達式的手工驗算過程:01000010B=42H,11111011B=FBH,10000101B=85H,10111001B=B9Hunsignedchara=0x7A,b=0xC3;printf("%x,%x,%x,%x\n",a&b,a|b,(unsignedchar)(~a),a^b);接著演示左移運算符:運行結(jié)果:
下面是手工驗算過程:55H=01010101Bunsignedchardat=0x55;dat=dat<<1;printf("左移一位:%x\n",dat);dat=dat<<3;printf("繼續(xù)左移三位:%x\n",dat);C語言的左移運算表達式在移動數(shù)據(jù)位的過程中左側(cè)移出位丟棄,右側(cè)補010101010B=AAH,01010000B=50H
右移運算與左移運算類似,不做演示。
(3)關(guān)系運算符關(guān)系運算符用來表達數(shù)值的大小,關(guān)系成立則運算結(jié)果為“真”(1),否則為“假”(0)。演示程序:運行結(jié)果:chara,b;a=(3>=2),b=(3==2);printf("%d,%d\n",a,b);運算符符號實例讀作大于>小于等于<=大于等于>=等于==小于<不等于!=
(4)運算優(yōu)先級
*C語言中的運算優(yōu)先級一共分為16級,數(shù)字越小,優(yōu)先級就越高。優(yōu)先級運算符結(jié)合方向優(yōu)先級運算符結(jié)合方向1后綴運算符:[]().->++(后置)--(后置)從左往右2一元運算符:++(前置)--(前置)!~+-*(指針)&從右往左3類型轉(zhuǎn)換運算符:()從右往左4乘除法運算符:*/%從左往右5加減法運算符:+-從左往右6移位運算符:<<>>從左往右7關(guān)系運算符:>>=<<=從左往右8關(guān)系運算符:==!=從左往右9位運算符:&從左往右10位運算符:^從左往右11位運算符:|從左往右12邏輯運算符:&&從左往右13邏輯運算符:||從左往右14條件三目運算符:?:從右往左15賦值運算符:=+=-=*=/=%=&=^=|=<<=>>=從右往左16逗號運算符:,從左往右2.2.2分支語句(1)if語句if分支語句的通用格式為:if語句的流程圖:
if(條件表達式1)分支語句1;elseif(條件表達式2)分支語句2;elseif(條件表達式3)分支語句3;……elseif(條件表達式n)分支語句n;else分支語句n+1;例如,隨機輸入數(shù)字0~9,輸出與其對應的英文翻譯:charnum;printf("輸入數(shù)字0~9:");scanf("%d",&num);If(num==0)printf("Zero\n");elseif(num==1)printf("One\n");elseif(num==2)printf("Two\n");elseif(num==3)printf("Three\n");elseif(num==4)printf("Four\n");elseif(num==5)printf("Five\n");elseif(num==6)printf("Six\n");elseif(num==7)printf("Seven\n");elseif(num==8)printf("Eight\n");elseif(num==9)printf("Nine\n");elseprintf("輸入數(shù)字超限!\n");
運行結(jié)果:C語言有一條“條件三目運算符(?:)”可以替代“if...else...”結(jié)構(gòu)語句,比如判斷隨機輸入整數(shù)是否為正數(shù):可以用條件三目運算符替代:intnum;printf("請輸入一個整數(shù):");scanf("%d",&num);if(num>0)printf("輸入的數(shù)字是正數(shù):-)\n");elseprintf("輸入的數(shù)字不是正數(shù):-(\n");intnum;printf("請輸入一個整數(shù):");scanf("%d",&num);num>0?printf("輸入的數(shù)字是正數(shù):-)\n"):printf("輸入的數(shù)字不是正數(shù):-(\n");(2)switch開關(guān)語句switch開關(guān)語句的通用格式為:switch語句的流程圖:switch(表達式){case常量表達式1:語句1;break;case常量表達式2:語句2;break;……case常量表達式n:語句n;break;default:語句n+1;}例如,隨機輸入數(shù)字0~9,輸出與其對應的英文翻譯:charnum;printf("輸入數(shù)字0~9:");scanf("%d",&num);switch(num){case0:printf("Zero\n");break;case1:printf("One\n");break;case2:printf("Two\n");break;case3:printf("Three\n");break;case4:printf("Four\n");break;case5:printf("Five\n");break;case6:printf("Six\n");break;case7:printf("Seven\n");break;case8:printf("Eight\n");break;case9:printf("Nine\n");break;default:printf("輸入數(shù)字超限!\n");}
運行結(jié)果:任務要求:
任務A:輸入年份,判斷該年份是否為閏年。
任務B:某商場舉辦優(yōu)惠購物活動,購物滿5000元打8折,購物滿2000元,不滿5000元打8.5折,購物滿1000元,不滿2000元打9折,其余不打折,輸入購物金額數(shù),自動計算折后價。2.2.3任務程序的編寫任務A:閏年是公歷中的概念,分為普通閏年和世紀閏年兩種,所謂普通閏年指的是年份數(shù)是4的倍數(shù)但不是100的倍數(shù)的年份,比如2020年,所謂世紀閏年指的是年份數(shù)是400的倍數(shù)的年份,比如2000年。(現(xiàn)場操作演示...)任務B:(現(xiàn)場操作演示...)Tobecontinued...2.3C語言循環(huán)結(jié)構(gòu)能力目標:
理解數(shù)組的概念,掌握一維數(shù)組的定義及使用方法,能利用while語句、do…while語句、for語句實現(xiàn)循環(huán)結(jié)構(gòu)程序。任務要求:任務A:隨機輸入5個正整數(shù),找出其中的最大值、最小值。任務B:隨機輸入2個正整數(shù),求出它們的最大公約數(shù)、最小公倍數(shù)。2.3.1數(shù)組數(shù)組是同類型數(shù)據(jù)的有序集合(1)一維整型數(shù)組一維數(shù)組的定義:類型說明符數(shù)組名[整型常量表達式];其中,類型說明符就是組成數(shù)組的各個元素的數(shù)據(jù)類型,數(shù)組名類似于變量名,即用于表達數(shù)組的標識符,方括號中的整型常量表達式表示數(shù)組元素的個數(shù),或者說數(shù)組的長度。一維數(shù)組定義之后即可使用其元素,元素格式為:數(shù)組名[下標]。
比如:注意:如果數(shù)組長度為N,則數(shù)組元素的下標取值范圍為0~N-1inta[5];a[0]=12,a[1]=23,a[2]=34,a[3]=45,a[4]=56;數(shù)組在定義的時候也可以同時直接初始化初值,比如:一維數(shù)組在初始化的時候,甚至可以不必指定數(shù)組長度,編譯器在編譯的時候,能根據(jù)初始化元素的個數(shù)自動判斷數(shù)組長度,比如:(2)一維浮點型數(shù)組浮點型數(shù)組的定義及使用與整型數(shù)組類似,可以先定義再賦值,比如:也可以定義的同時進行初始化初值,比如:inta[5]={12,23,34,45,56};inta[]={12,23,34,45,56};floata[5];a[0]=1.2,a[1]=2.3,a[2]=3.4,a[3]=4.5,a[4]=5.6;floata[5]={1.2,2.3,3.4,4.5,5.6};(3)一維字符型數(shù)組字符型數(shù)組的定義和使用除了與整型數(shù)組、浮點型數(shù)組類似之外,也有自己的特點??梢韵榷x再賦值,比如:以上程序定義了一個長度為6的字符型數(shù)組并賦值“Hello”字符串,注意最后一個字符“\0”是字符串結(jié)束標志。也可以定義的同時進行初始化初值,比如:
也可以在初始化的時候直接賦予字符串,比如:chara[6];a[0]=’H’,a[1]=’e’,a[2]=’l’,a[3]=’l’,a[4]=’o’,a[5]=’\0’;chara[6]={‘H’,’e’,’l’,’l’,’o’,’\0’};chara[6]=”Hello”;//尾部會自動添加“\0”2.3.2循環(huán)語句循環(huán)結(jié)構(gòu)又稱重復結(jié)構(gòu),可以完成重復性、規(guī)律性的操作,比如求若干數(shù)的和、迭代求根等等。(1)while語句通用格式:循環(huán)語句若由多條語句構(gòu)成,必須以大括號“{”、“}”括起來構(gòu)成復合語句。while(條件表達式)循環(huán)語句;例如,計算1+2+3+…+100=?運行結(jié)果:unsignedintsum=0,i=1;while(i<=100){ sum+=i; i++;}printf("1+2+3+...+100=%d\n",sum);(2)do…while語句
通用格式:同樣,1+2+3+…+100=?運行結(jié)果:do循環(huán)語句while(條件表達式);unsignedintsum=0,i=1;do{ sum+=i; i++;}while(i<=100);printf("1+2+3+...+100=%d\n",sum);(3)for語句
通用格式:for語句的執(zhí)行過程:for(表達式1;表達式2;表達式3)循環(huán)語句實際使用的時候,for語句的常用格式:同樣,1+2+3+…+100=?運行結(jié)果:for(循環(huán)變量賦初值;循環(huán)條件;循環(huán)變量增/減值)循環(huán)語句unsignedintsum=0,i;for(i=1;i<=100;i++)sum+=i;printf("1+2+3+...+100=%d\n",sum);
(4)continue語句與break語句
●continue語句的作用是提前結(jié)束當次循環(huán)進行下一次循環(huán)。舉例說明:運行結(jié)果:inti=1;while(i<10){ if(i==5) { i++; continue; } printf("第%d次循環(huán)\n",i); i++;}
●break語句的作用則是直接跳出循環(huán)
舉例說明:運行結(jié)果:inti=1;while(i<10){ if(i==5) { i++; break; } printf("第%d次循環(huán)\n",i); i++;}2.3.3任務程序的編寫
任務A:
以找出五個隨機正整數(shù)中的最大值為例,先假定第一個數(shù)就是最大值,然后跟第二個數(shù)比較,若假定的最大值比第二個數(shù)小,則將第二個數(shù)替換為假定的最大值,否則什么也不做。以此類推,接著將假定的最大值與第三個、第四個、第五個數(shù)比較,最后假定最大值必然為五個數(shù)中真實的最大值。找出五個隨機正整數(shù)中的最小值也是采用類似方法。(現(xiàn)場操作演示...)任務B:兩個正整數(shù)的最大公約數(shù)未必存在,比如兩個質(zhì)數(shù)就不存在最大公約數(shù),但最小公倍數(shù)是必然存在的,比如兩個質(zhì)數(shù)的乘積就是兩者的最小公倍數(shù)。以求解兩個隨機正整數(shù)的最大公約數(shù)為例,先假定較小的數(shù)字就是兩者的最大公約數(shù),將兩數(shù)同時除以假定最大公約數(shù),若能整除則假定最大公約數(shù)就是兩者實際的最大公約數(shù),結(jié)束求解過程,若不能整除,則將假定最大公約數(shù)遞減一次,再將兩數(shù)同時除以假定最大公約數(shù),依次類推,直到求得最大公約數(shù)。對于兩個質(zhì)數(shù)而言,依照此流程最后求得的結(jié)果是1,但顯然1不能作為兩個正整數(shù)的最大公約數(shù)。求解兩個隨機正整數(shù)的最小公倍數(shù)也是采用類似的方法,但假定的最小公倍數(shù)是較大的數(shù)字。(現(xiàn)場操作演示...)Tobecontinued...2.4模塊化程序的設計能力目標:
簡單了解結(jié)構(gòu)體、指針的相關(guān)基礎(chǔ)知識,重點理解并掌握C語言函數(shù)的概念及使用方法。任務要求:隨機輸入五個正整數(shù),將五個數(shù)字按從小到大的順序進行排列。2.4.1結(jié)構(gòu)體認知
●數(shù)組是同種類型數(shù)據(jù)的組合。
●結(jié)構(gòu)體是不同類型數(shù)據(jù)的組合。在STM32的HAL/LL庫中大量使用了結(jié)構(gòu)體,用于對片內(nèi)外設的一組不同的參數(shù)進行設定,但這部分主要是一些自動生成代碼,讀者僅僅需要了解即可。結(jié)構(gòu)體的使用可分為如下三步:構(gòu)造結(jié)構(gòu)體類型→定義結(jié)構(gòu)體變量→結(jié)構(gòu)體變量賦值。①首先是構(gòu)造結(jié)構(gòu)體類型的一般形式:struct結(jié)構(gòu)體名{ 類型名1成員名1; 類型名2成員名2; …… 類型名3成員名3;};比如構(gòu)造一個名為“Student”的結(jié)構(gòu)體,用來記錄學生的基本信息:②然后是定義結(jié)構(gòu)體變量的一般形式:比如定義一個“Student”型的結(jié)構(gòu)體變量“student1”:structStudent{ unsignedintNo;//學號 charName[10];//姓名 charSex;//性別};struct結(jié)構(gòu)名
變量名列表;structStudentstudent1;③最后是使用這個結(jié)構(gòu)體變量,包括賦值和讀取它的值??梢栽诙x的同時進行初始化,比如:也可以在定義完成后進行賦值,比如:structStudentstudent1={325,"張三",'M'};structStudentstudent1;student1.No=325;strcpy(student1.Name,"張三");//字符串賦值函數(shù),需要包含頭文件“string.h”student1.Sex='M';2.4.2指針認知指針就是用于指向變量內(nèi)存單元的變量,或者說在指針變量中存儲了其指向變量的內(nèi)存地址。
指針在STM32單片機程序的開發(fā)中,主要是調(diào)用HAL/LL庫API函數(shù)時進行實參的地址引用,這里僅對①指針指向基本變量、②指針指向一維數(shù)組的使用方法進行扼要介紹,在2.4.3中也會簡單介紹③指針變量作為函數(shù)參數(shù)的使用方法。(1)指針指向基本變量首先是指針變量的定義,定義格式為:類型說明符*變量名;這里,“*”表示這是一個指針變量,類型說明符指的是指針所指向變量的數(shù)據(jù)類型。比如:int*p;表示定義了一個指針變量p,他可以指向一個整型變量,但具體指向哪一個整型變量,需要對指針變量賦值,指針變量的賦值格式:變量1=&變量2;
這里,“&”是取地址運算符,表示獲取變量2的地址,注意到這是一個單目運算符,與位運算符中的位與運算符“&”不是一個功能,比如:
也可以定義的同時直接做初始化:利用指針引用變量,比如:
在利用指針引用變量時,“*p”表示指針變量“p”指向變量的值。運行結(jié)果:inta,*p;p=&a;inta,*p=&a;inta=56,*p=&a;printf("%d",*p);(2)指針指向一維數(shù)組數(shù)組在計算機內(nèi)存中的地址是連續(xù)的,一般我們可以將指針指向數(shù)組的第一個元素的地址,在遍歷數(shù)組中每一個元素時,只需要將指針不斷往后偏移即可。比如定義一個指針并指向整型一維數(shù)組的第一個元素:也可以:
即“&a[0]”和“a”都可以表示數(shù)組a的首地址。int*p,a[5]={12,23,34,45,56};p=&a[0];int*p,a[5]={12,23,34,45,56};p=a;利用指針遍歷一維數(shù)組,比如:
這里的“*p++”,“++”優(yōu)先級別比“*”高,等價于“*(p++)”。
運行結(jié)果:int*p,a[5]={12,23,34,45,56},i;p=a;for(i=0;i<5;i++){ printf("%d",*p++);}2.4.3函數(shù)與模塊化程序設計C語言程序一般是由一個主函數(shù)(即main函數(shù))加若干其他函數(shù)構(gòu)成,主函數(shù)是整個程序執(zhí)行的入口,不可或缺。將一段具有特定功能的代碼封裝成函數(shù),既方便程序員在后續(xù)的開發(fā)中直接調(diào)用,也提高了代碼的可維護性,可謂一舉兩得。由于每一個函數(shù)也是一個獨立的功能模塊,因此C語言也被稱為模塊化程序設計語言。函數(shù)的使用一般分三步進行:定義、聲明、調(diào)用。定義的一般形式:函數(shù)類型函數(shù)名(形式參數(shù)表){函數(shù)體語句}第一行構(gòu)成函數(shù)的首部,大括號中的內(nèi)容構(gòu)成函數(shù)的函數(shù)體。其中,形式參數(shù)簡稱“形參”,即函數(shù)的輸入值,函數(shù)的形參可以有多個,也可以只有一個,甚至于沒有形參;函數(shù)類型也叫函數(shù)的返回值類型,即函數(shù)的輸出值類型,函數(shù)的返回值最多只能有一個,當函數(shù)沒有返回值時,函數(shù)類型必須寫上“void”。聲明的一般形式:一般直接將函數(shù)的首部復制并粘貼到主函數(shù)之前,加上分號“;”即可。調(diào)用的一般形式:函數(shù)類型函數(shù)名(形式參數(shù)表);函數(shù)名(實際參數(shù)表);調(diào)用函數(shù)時,必須將形參全部替換為實際參數(shù)(簡稱“實參”)。函數(shù)的定義可以理解為是定義了一種運算關(guān)系,形參可以理解為自變量,返回值可以理解為因變量;函數(shù)的調(diào)用可以理解為將常量代入這種運算關(guān)系從而得出運算結(jié)果;函數(shù)的聲明,這與編譯器的編譯順序有關(guān),比如定義的函數(shù)在主函數(shù)之后,而主函數(shù)調(diào)用了該函數(shù),如果不提前聲明,編譯器會認為該函數(shù)不存在從而終止編譯。
比如,圓面積的計算:#include<stdio.h>constfloatpi=3.141592;//“const關(guān)鍵字說明“pi”是一個常量main(){ floatr,s; printf("請輸入半徑:"); scanf("%f",&r); s=pi*r*r; printf("圓面積:%f\n",s);}將圓面積的計算公式封裝成獨立函數(shù):#include<stdio.h>constfloatpi=3.141592;//“const”關(guān)鍵字說明“pi”是一個常量floatsquare(floatr);//函數(shù)的聲明main(){ floatr,s; printf("請輸入半徑:"); scanf("%f",&r); s=square(r);//函數(shù)的調(diào)用 printf("圓面積:%f\n",s);}//函數(shù)的定義floatsquare(floatr){ returnpi*r*r;//由“return”語句返回運算結(jié)果}
圓面積計算函數(shù)中,形參只有半徑“r”,返回值類型為浮點型,由于這不是一個void型函數(shù),因此調(diào)用時可以將函數(shù)返回值賦值給變量“s”。
運行結(jié)果:
值得注意的是,在main函數(shù)和square函數(shù)中都有變量“r”,但這兩個變量“r”沒有任何關(guān)系,他們分屬于兩個不同函數(shù)的“局部變量”,其作用域僅限于各自所在的函數(shù)內(nèi)部;變量“pi”定義的位置在所有函數(shù)之前,這屬于“全局變量”,其作用域可達整個程序的任何位置,如果當全局變量與局部變量同名時,局部變量會在其作用域內(nèi)自動屏蔽同名全局變量。接下來比較一下形參分別為變量和指針時的區(qū)別:#include<stdio.h>voidf1(inta);voidf2(int*p);main(){ inta=0; f1(a); printf("a=%d\n",a); f2(&a); printf("a=%d\n",a);}voidf1(inta){ a++;}voidf2(int*p){ (*p)++;}
運行結(jié)果:f1函數(shù)采用的是“值傳遞”的參數(shù)傳遞方式,函數(shù)執(zhí)行完畢后,不會影響到原變量的值,而f2函數(shù)采用的是“地址傳遞”的參數(shù)傳遞方式,函數(shù)在執(zhí)行過程中,直接改變了指針指向的變量值,所以函數(shù)執(zhí)行完畢后,原變量的值自然發(fā)生了變化。2.4.4任務程序的編寫顯然,本次任務必須借助于數(shù)組,在定義排序函數(shù)的時候,可以利用指針指向數(shù)組的首地址,在調(diào)用排序函數(shù)之后,數(shù)組中的元素即完成從小到大的排序。排序策略為:先將數(shù)組第一個元素依次與后面的四個比較,在比較過程中,只要發(fā)現(xiàn)第一個元素比某一個元素大,就交換兩個元素的位置,確保最小的元素排在數(shù)組的第一位,然后將數(shù)組的第二個元素與后面的三個比較……以此類推。
(現(xiàn)場操作演示...)Tobecontinued...3.1LED單燈閃爍之軟件延時能力目標:
理解單片機GPIO兩種主要的輸出類型,初步掌握使用STM32CubeIDE開發(fā)單片機應用程序的方法,掌握通過ISP下載程序并通過實物驗證的方法。任務要求:電路如圖所示,要求通過單片機PC0引腳控制LED0以1秒周期閃爍。3.1.1STM32的GPIO及其輸出類型STM32F103R6具有51個GPIO(General-purposeinput/output,通用輸入輸出)引腳,每個引腳都具備如圖所示結(jié)構(gòu)。GPIO的八種工作模式:
本次課著重講其中的⑴⑵兩種工作模式。⑴推挽輸出⑵開漏輸出⑶復用推挽輸出⑷復用開漏輸出⑸模擬量輸入⑹浮空輸入⑺下拉輸入⑻上拉輸入⑴推挽輸出
此時P-MOS管與N-MOS管發(fā)揮作用:
①當控制輸出1時,P-MOS管閉合、N-MOS管斷開,引腳輸出電源電壓(+3.3V);
②當控制輸出0時,P-MOS管斷開、N-MOS管閉合,引腳輸出GND。
推挽輸出模式一般應用在輸出電平為0和+3.3V而且需要高速切換開關(guān)狀態(tài)的場合。在STM32的應用中,除了必須用開漏模式的場合,我們都習慣使用推挽輸出模式。
值得注意的是,當引腳直接接地的時候,切不可推挽輸出高電平,否則電源將被直接短路?、崎_漏輸出此時P-MOS管始終斷開,僅N-MOS管發(fā)揮作用:
①當控制輸出1時,N-MOS管斷開,引腳懸空;
②當控制輸出0時,N-MOS管閉合,引腳輸出GND。
開漏輸出一般應用在①I2C、SMBUS通訊等需要“線與”功能的總線電路中。除此之外,②還用在電平不匹配的場合,如需要輸出5伏的高電平,就可以在外部接一個上拉電阻,上拉電源為5V,并且把引腳設置為開漏模式,當輸出高阻態(tài)時,由上拉電阻和電源向外輸出5V電平,如右圖所示。3.1.2STM32CubeIDE的使用STM32CubeMX的作用是通過圖形化配置完成STM32的工程目錄的建立與初始化代碼的生成。下面是操作步驟。
(1)在桌面上找到并雙擊程序圖標,打開程序主界面。
(2)點擊菜單“File=>NewProject”新建工程,在搜索欄中輸入單片機型號“STM32F103R6”,出現(xiàn)兩種封裝的搜索結(jié)果。
(3)在搜索結(jié)果中選擇LQFP64封裝,雙擊打開左圖配置界面。
(4)在右圖“Pinout&Configuration”界面上將引腳PC0修改為“GPIO_Output”模式。
(5)在左圖“ProjectManager”界面上對工程命名,制定工程目錄,指定集成開發(fā)環(huán)境為“TrueSTUDIO”后點擊“DeviceConfigurationToolCodeGeneration”按鈕
生成單片機程序工程目錄。
本案例沒有對時鐘樹進行設定,采用了默認的內(nèi)部RC振蕩源。
接下來就是繼續(xù)完成程序代碼的編寫。
本次任務需要用到兩個API函數(shù)(API函數(shù)來源于“UM1850_DescriptionofSTM32F1HALandLow-layerdrivers.PDF”文檔):①引腳輸出狀態(tài)翻轉(zhuǎn)函數(shù)HAL_GPIO_TogglePin
例程:HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//將PC0引腳輸出狀態(tài)取反②延時函數(shù)HAL_Delay
例程:下面是操作步驟。HAL_Delay(500);//延時500ms(即0.5s)
(1)在左側(cè)“Src”目錄中找到main.c文件,雙擊打開。(5)值得注意的是,由于STM32CubeIDE默認不生成HEX文件,需要人為設置:在IDE主界面菜單欄中選擇“Project(工程)”→“Properties(屬性)”打開如圖3-12所示屬性對話框,選擇“C/C++Build(C/C++生成)”→“Settings(設置)”→“ToolSettings(工具設置)”→“MCUPostbuildoutputs(單片機編譯后輸出)”,在“ConverttoIntelHexfile(-Oihex)(轉(zhuǎn)換為英特爾HEX文件)”項目打鉤并保存,回到IDE主界面后再按下生成按鈕,即可在源代碼編譯成功后輸出HEX文件。3.1.3使用ISP方式下載程序
程序編寫完畢,生成HEX文件以后,通過ISP工具下載到單片機電路運行驗證。特別注意的是,接線的時候請斷電。
步驟:
①將開發(fā)板上核心板的PC0引腳與LED模塊LED0的引出端用杜邦線連接;②將開發(fā)板USB通信口與計算機USB口通過USB線連接;③接通電源;④將核心板撥動開關(guān)撥到“ISP”位置,按下“RST”復位按鈕;⑤通過ISP工具“FlashLoaderDemonstrator”讀取工程目錄下“.../Debug/2.1.Hex”文檔中的機器碼,并將機器碼下載至單片機Flash,操作步驟請見后頁。
ISP工具桌面圖標是。⑥程序下載完畢后,將核心板撥動開關(guān)撥回到“Run”位置,再次按下復位按鈕“RST”,單片機將按照設定程序運行。具體的代碼另外給出。技能訓練(選做):
修改電路,改由PC1驅(qū)動LED1作單燈閃爍,閃爍周期改為2s。Tobecontinued...3.2按鈕輸入能力目標:
理解并掌握單片機GPIO三種主要的輸入類型,掌握使用Proteus仿真單片機電路的方法。任務要求:電路如圖所示,要求通過按鈕BTN0控制LED0的亮滅(LED0接PC0,BTN0接PC1)。3.2.1GPIO的輸入類型STM32F103R6具有51個GPIO(General-purposeinput/output,通用輸入輸出)引腳,每個引腳都具備如圖所示結(jié)構(gòu)。GPIO的八種工作模式:
本次課著重講其中的⑺⑻兩種工作模式。⑴推挽輸出⑵開漏輸出⑶復用推挽輸出⑷復用開漏輸出⑸模擬量輸入⑹浮空輸入⑺下拉輸入⑻上拉輸入⑴當圖中上拉電阻、下拉電阻均未接入時輸入模式為浮空輸入,此時若輸入信號斷開,則引腳輸入狀態(tài)不定(不常用);
⑵當圖中上拉電阻接入時輸入模式為上拉輸入,此時若輸入信號斷開,則引腳輸入為高電平;(常用)
⑶當圖中下拉電阻接入時輸入模式為下拉輸入,此時若輸入信號斷開,則引腳輸入為低電平。(常用)
典型按鈕電路如圖:
左圖引腳PC1配置為上拉輸入時,若松開按鈕,引腳默認輸入高電平,若按下按鈕,引腳輸入低電平;右圖引腳PC1配置為下拉輸入時,若松開按鈕,引腳默認輸入低電平,若按下按鈕,引腳輸入高電平;
如果選擇浮空輸入模式,則按鈕上拉或下拉電阻必須外接,比如本項目仿真電路。3.2.2電路仿真
電路仿真采用Proteus,操作步驟:
(1)在桌面上找到并雙擊程序圖標,打開左圖主界面,選擇“NewProject”新建工程(如右圖),過程中除了路徑之外,其余均采用缺省設定。(2)拾取元件。左圖中在左側(cè)工具欄中按下(ComponentMode)按鈕進入元器件拾取模塊,接著按下右側(cè)的(PickDevice)按鈕打開中圖元器件拾取對話框。在中圖“Keywords”搜索欄內(nèi)依次輸入本次課題所需元器件名稱,在右圖“Results”結(jié)果欄內(nèi)選中并雙擊所需元器件將其拾取到主界面元器件中,完成后關(guān)閉對話框。(3)放置元件并更改元器件參數(shù)。在主界面元件池中依次選擇所需元件將其擺放到主界面中心圖紙上。依次選中圖紙上的元件,在鼠標右鍵彈出的快捷菜單內(nèi)選擇“EditProperties”打開右圖所示編輯屬性對話框,修改參數(shù)后點“OK”按鈕保存退出。(4)電路連線。在左側(cè)工具欄中按下(TerminalsMode)終端模式按鈕,在終端列表中分別選擇電源終端POWER、接地終端GROUND并添加到圖紙中,完成電路連線。(5)設定電源正負極參數(shù)。在主界面中選擇菜單欄“Design=>ConfigurePowerRails...”打開電源軌配置對話框如左圖所示,需要設定的是:①將電源正極由5V改為3.3V;②將模擬量電源正負極VDDA與VSSA分別添加到VCC/VDD網(wǎng)絡與GND網(wǎng)絡,否則單片機將無法仿真,添加結(jié)果如中圖與右圖所示。(6)指定HEX文件路徑?;氐街鹘缑?,選擇原理圖中的單片機并在右鍵快捷菜單中選擇“EditProperties”打開如圖所示編輯屬性對話框,在對話框中點擊按鈕,選擇HEX文件并確認保存。(7)運行仿真。按下左下角運行按鈕即可開始仿真。注意:Proteus8.8和8.9仿真模型中上拉模式不可用,必須外接上拉電阻。3.2.3任務程序的編寫
本次內(nèi)容需要用到的新的API函數(shù)是:
引腳輸入函數(shù)HAL_GPIO_ReadPin
例程:
(現(xiàn)場操作演示...)GPIO_PinStatex=HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1);//讀取PC1輸入狀態(tài)技能訓練(選做):通過兩只按鈕控制一個LED的亮滅,要求兩個按鈕一個采用上拉輸入模式,另一個采用下拉輸入模式。參考電路如下圖所示。Tobecontinued...3.3流水燈之軟件延時能力目標:理解并掌握通過改進算法提高編程效率的方法。任務要求:
電路如圖所示,要求實現(xiàn)流水燈效果,即按LED0~LED7的順序依次點亮,每次僅限一只LED發(fā)光,周期4秒。3.3.1程序算法
算法(Algorithm)是指解決方案準確而完整的描述,是一系列解決問題的清晰指令,算法代表著用系統(tǒng)的方法描述解決問題的策略機制。首先人們自然會想到“位操作法”,但這種算法編程效率太低,下面介紹兩種比較好的算法:⑴查表法
即將8個狀態(tài),定義為8個字節(jié),每隔一段時間,按先后順序查表并將8個狀態(tài)量賦值給單片機的規(guī)定輸出口,狀態(tài)表如下。序號狀態(tài)字節(jié)(二進制)狀態(tài)字節(jié)(十六進制)序號狀態(tài)字節(jié)(二進制)狀態(tài)字節(jié)(十六進制)11111,1110FE51110,1111EF21111,1101FD61101,1111DF31111,1011FB71011,1111BF41111,0111F780111,11117F⑵移位法所謂移位法,就是利用C語言的移位運算符“<<”、“>>”實現(xiàn)狀態(tài)字節(jié)的循環(huán)移位。但由于C語言的移位運算符只能實現(xiàn)單向移位,因此必須通過一定的算法來間接實現(xiàn),具體的做法是:假設M位數(shù)據(jù)A需要循環(huán)左移N位(M>N),先將A左移N位得到B,再將A右移(M-N)位得到C,最后將A、B按位求或運算即可獲得最終結(jié)果。比如,8位二進制數(shù),各位均用字母表示為“ABCDEFGH”,需要循環(huán)左移3位,可先將原數(shù)左移3位,得到“DEFGH000”,再將原數(shù)右移5位,得到“00000ABC”,最后將兩數(shù)按位或即可得到循環(huán)左移3位的結(jié)果“DEFGHABC”,示意如下。①ABCDEFGH<<3→DEFGH000②ABCDEFGH>>5→00000ABC③DEFGH000|00000ABC
→DEFGHABC3.3.2任務程序的編寫
本次任務程序?qū)⒏鶕?jù)位操作法、查表法與移位法三種方法編寫,需要用到的新的API函數(shù):
①引腳輸出函數(shù)HAL_GPIO_WritePin
新版HAL庫改為:GPIO_PIN_RESETGPIO_PIN_SET
例程:今天我們要對若干個引腳一起輸出相同的電平值,比如
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET);//PC0輸出低電平HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_S
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度創(chuàng)業(yè)孵化器股份無償贈與及孵化服務合同
- 二零二五版成都房地產(chǎn)工程后期維護合同4篇
- 二零二五年電商連鎖店鋪租賃合同3篇
- 二零二五年度鲅魚圈區(qū)非物質(zhì)文化遺產(chǎn)保護與開發(fā)合同3篇
- 2025版不銹鋼水箱維修保養(yǎng)與更換服務合同樣本3篇
- 二零二五年全新資金過橋業(yè)務合同規(guī)范文本下載2篇
- 二零二五版沉井施工施工日志記錄合同范本下載4篇
- 二零二五年度智能家居系統(tǒng)定制開發(fā)及維護服務合同2篇
- 二零二五年度民辦幼兒園教師聘用標準合同范本
- 二零二四圖書版權(quán)代理與海外銷售合同3篇
- 2025年礦山開采承包合同實施細則4篇
- 2025-2030年中國雪茄市場運行現(xiàn)狀及投資發(fā)展前景預測報告
- 《水利工程安全管理》課件
- 三年級數(shù)學(上)計算題專項練習附答案
- 中外美術(shù)史試題及答案
- 《架空輸電線路導線舞動風偏故障告警系統(tǒng)技術(shù)導則》
- 2024年計算機二級WPS考試題庫
- 廣東省廣州黃埔區(qū)2023-2024學年八年級上學期期末數(shù)學試卷(含答案)
- 工會換屆公示文件模板
- 江蘇省南京市協(xié)同體七校2024-2025學年高三上學期期中聯(lián)合考試英語試題答案
- 青島版二年級下冊三位數(shù)加減三位數(shù)豎式計算題200道及答案
評論
0/150
提交評論