第3章-stm32單片機C語言程序設計基礎匯總課件_第1頁
第3章-stm32單片機C語言程序設計基礎匯總課件_第2頁
第3章-stm32單片機C語言程序設計基礎匯總課件_第3頁
第3章-stm32單片機C語言程序設計基礎匯總課件_第4頁
第3章-stm32單片機C語言程序設計基礎匯總課件_第5頁
已閱讀5頁,還剩149頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、退出嵌入式單片機原理及應用燕山大學電氣工程學院自動化系 1 ARM嵌入式系統(tǒng)概述2 STM32單片機結構和最小系統(tǒng) 3 基于標準外設庫的C語言程序設計基礎 4 STM32通用輸入輸出GPIO5 STM32外部中斷6 STM32通用定時器7 STM32通用同步/異步收發(fā)器USART8 直接存儲器存取DMA9 STM32的模數(shù)轉換器ADC10 STM32的集成電路總線I2C11 STM32的串行外設接口SPI第3章 基于標準外設庫的C語言程序設計基礎3.1 嵌入式C語言基礎文件結構、程序板式、C語言知識精編3.2 CMSISCortex-M3微控制器軟件接口標準CMSIS概述、STM32F10 x

2、標準外設庫3.3 基于MDK的STM32開發(fā)退出C語言的特點1、語言簡單、緊湊、靈活。(32個關鍵字,9種控制語句)2、運算符豐富(34種表達式)3、數(shù)據(jù)結構豐富4、具有結構化的控制語句5、目標代碼質量高,程序執(zhí)行效率高。6、可移值性好7、兼有低級語言和高級語言的特點3.1 嵌入式C語言基礎 3.1 嵌入式C語言基礎 每個C程序通常分為兩個文件,一個文件用于保存程序的聲明,稱為頭文件,以“.h”為后綴。另一個文件用于保存程序的實現(xiàn),稱為源文件,以“.c”為后綴。如果一個工程中頭文件數(shù)目較多,通常將頭文件和源文件分別保存在不同的目錄以便于維護。例如可以將頭文件保存于inc目錄,源文件保存于src

3、目錄。退出版權和版本聲明/* Copyright (c) 2014,燕山大學電氣工程學院* All rights reserved.* 文件名稱:filename.h* 摘 要:簡要描述本文件的內容* 當前版本:1.1* 作 者:輸入作者(或修改者)名字* 完成日期:2014年7月20日* 取代版本:1.0 * 原作者 :輸入原作者(或修改者)名字* 完成日期:2014年1月10日*/頭文件結構頭文件版權和版本聲明、預處理塊和函數(shù)聲明/ 版權和版本聲明#ifndef_GRAPHICS_H_#define_GRAPHICS_H_#include #include “myheader.h” / 引

4、用非標準庫的頭文件void Function1();/ 全局函數(shù)聲明#endif源文件結構源文件版權和版本聲明、頭文件的引用和程序的實現(xiàn)體/ 版權和版本聲明#include “graphics.h”/ 全局函數(shù)的實現(xiàn)體void Function1()簡單的C程序介紹例1:最簡單的程序#include /包含頭文件 int main(void)/*主函數(shù)*/printf(“this is a c program!n”); /*輸出了一句話*/例2 求兩個數(shù)之和#include /包含頭文件 int main(void)/*主函數(shù)*/ int a,b,sum;/*定義變量*/a=100;b=200

5、; /*給變量賦值*/sum=a+b/*求a與b的和*/printf(“sum=%dn”,sum);/*輸出結果*/ scanf(“%d%d”,&a,&b);例3 求兩個數(shù)中的最大數(shù)#include /包含頭文件int max(int x,int y); /*定義max函數(shù),函數(shù)值為整型,x,y為型參,整型*/ int z; /*函數(shù)內用到內部變量z,也要加以定義*/ if(xy) z=x; /*比較x,y的大小,如果x大于y,則執(zhí)行z=x*/else z=y; /*否則執(zhí)行z=y*/return(z); /*將z的值返回,通過max帶回調用處*/ int main(void)/*主函數(shù)*/i

6、nt a,b,c; /*定義變量*/ scanf(“%d%d”,&a,&b); /*輸入變量a,b的值*/ c=max(a,b); /*調用函數(shù),將得到的值賦給c*/ printf(“max=%dn”,c); /*輸出c的值*/C程序的結構特點和書寫格式1、函數(shù)是組成C程序的基本結構2、一個函數(shù)由兩部分組成:函數(shù)說明部分函數(shù)體函數(shù)體:說明部分 執(zhí)行部分 3、一個程序總是從main函數(shù)開始執(zhí)行4、語句以分號;結束5、書寫格式自由6、用/*/做注釋字符集什么是字符集在C語言程序中允許出現(xiàn)的所有基本字符的組合稱為C語言的字符集。字符集分類(1) 大小寫英文字母(52個)(2) 數(shù)字符號(10個)(3

7、) 鍵盤符號(33個)(4) 轉義字符C語言的基本元素1、符號集(字符集)C語言使用的基本符號共有如下5種:(1)大寫字母:A-Z(2)小寫字母:a-z(3)阿拉伯數(shù)字:0-9(4)下劃線:_(5)標點符號和運算符標識符什么是標識符標識符是用戶自定義的一種字符序列,通常用來表示程序中需要辨認的對象名稱。標識符的命名規(guī)則標識符是由字符或下劃線開頭的字母、數(shù)字、下劃線組成的一串符號;保留字不能作為標識符?!癬”可以作為標識符的第一個字母,但是往往用于庫代碼正確標識符:sum i a2 a_2 _a2 _a_2錯誤的標識符:2a a? c.g a-2 if whileC語言的數(shù)據(jù)類型數(shù)據(jù)是操作的對象

8、,數(shù)據(jù)類型是指數(shù)據(jù)的內在表現(xiàn)形式(代碼、存儲、運算)C語言程序的數(shù)據(jù)類型如下:空類型數(shù)據(jù)類型基本類型數(shù)據(jù)類型指針類型整型int實型(浮點型)字符型char單精度flaot雙精度double數(shù)組結構體共用體枚舉型派生類型退出關鍵字意義char聲明字符型變量或函數(shù)數(shù)double聲明雙精度變量或函數(shù)據(jù)enum聲明枚舉類型類float聲明浮點型變量或函數(shù)型int聲明整型變量或函數(shù)long聲明長整型變量或函數(shù)short聲明短整型變量或函數(shù)signed聲明有符號類型變量或函數(shù)struct聲明結構體變量或函數(shù)union聲明共用體(聯(lián)合)數(shù)據(jù)類型unsigned聲明無符號類型變量或函數(shù)void聲明函數(shù)無返回值

9、或無參數(shù),聲明空類型指針C語言的數(shù)據(jù)類型常量什么是常量又稱為字面量,表述常數(shù)常量類型整型常量實型常量字符常量字符串常量常量和變量一、常量和符號常量1、常量:在程序運行過程中, 其值不能被改變的量常量區(qū)分為不同類型(表現(xiàn)形式)如:12、3.2、a二、變量1、變量:其值是可以改變的量,它用標識符(變量名)來表示,在內存中占據(jù)一定的存儲單元。2、變量的定義方法類型符標識符3、注意:1.見字知意2.先定義后使用3.習慣:符號常量大寫,變量名小寫如:int a,b,max; char c1,c2,s; float x,y,z; double i,j;變量變量數(shù)據(jù)類型數(shù)據(jù)類型類型符號占用字節(jié)數(shù)數(shù)據(jù)類型類型

10、符號占用字節(jié)數(shù)整型int4無符號長整型unsigned long4短整型short2單精度實型float4長整型long4雙精度實型double8無符號整型unsigned int4字符型char1無符號短整型unsigned short2變量存儲類型存儲類型存儲類型符存儲地點自動型auto內存堆棧區(qū)寄存器型registerCPU的通用寄存器靜態(tài)型static內存數(shù)據(jù)區(qū)外部參照型extern變量的定義和初始化變量的初始化變量在定義時就要初始化變量賦初值的語句格式存儲類型符 數(shù)據(jù)類型符 變量名=初值;結構型的定義定義語句struct 結構名稱 數(shù)據(jù)類型1 成員1名; 數(shù)據(jù)類型2 成員2名; .

11、. 數(shù)據(jù)類型n 成員n名;結構的本質是不同類型元素的集合結構型變量的定義和引用結構型變量的定義方法:先定義結構型、后定義變量struct student int id; char name20; int age;struct student x , y;結構型變量成員的引用引用方法結構型變量成員的引用方法引用格式:結構型變量名.成員名結構型變量成員地址的引用方法引用格式:&結構型變量名.成員名結構型變量地址的引用方法引用格式:&結構型變量名指向結構型數(shù)據(jù)的指針變量的定義和引用指向結構型變量的指針定義方法:同結構型變量的定義方法,區(qū)別在于定義時變量名前面加*。引用方法方法1: (指針變量).成員

12、名方法2: 指針變量成員名基礎練習:輸入3個學生信息,并輸出!(使用兩種引用方式,結構體變量和結構體指針)學生結構體定義如下:struct student int id; char name20; int age;編程練習學生管理系統(tǒng):學生管理系統(tǒng)可以實現(xiàn)學生信息的錄入,查詢,注銷等功能。定義學生的結構體(以后可以按照具體情況增加個人信息內容)struct student int id; char name20; int age;C語言中的運算符運算符什么是運算符用來表示各種運算的符號稱為運算符。運算符特點運算符必須有運算對象,運算對象都有規(guī)定的數(shù)據(jù)類型,同時運算結果也有確定的數(shù)據(jù)類型。每個運

13、算符都有自己特定的運算規(guī)則。當表達式中出現(xiàn)多個運算符時則必須考慮運算符的優(yōu)先級。同級別的運算符還規(guī)定了結合性。算術運算符運算符名稱優(yōu)先級結合性+、-取正、取負2自右向左*、/、%乘、除、取余數(shù)3自左向右+、-加、減4自左向右增1、減1運算符有哪些運算符號j = i+; 相當于 j = I; i= i+1;j = +i; 相當于 i = i +1; j = i; 運算符名稱優(yōu)先級結合性+增12自右向左- -減1關系運算符運算符名稱優(yōu)先級結合性=、 、= 、大于等于、大于、小于等于、小于6自左向右=、!=等于、不等于7自左向右關系運算符要點關系運算符可以用來比較兩個數(shù)值型數(shù)據(jù)的大小,也可以比較兩個

14、字符型數(shù)據(jù)的大小。關系運算符的運算結果是邏輯值,若為“真”用整數(shù)1表示,若為“假”用整數(shù)0表示。邏輯運算符運算符名稱優(yōu)先級結合性!邏輯非2自右向左&邏輯與11自左向右|邏輯或12自左向右邏輯運算符的特點邏輯運算符運算對象是數(shù)值型或字符型等;如果是非0表示邏輯真,0表示邏輯假。運算結果是邏輯值,如運算結果為真用1表示,若為假則用0表示。邏輯運算用“&”對兩個表達式進行計算時,若第1個表達式的值為“假”,則與第2個表達式的值無關,結果肯定為“假”,所以C語言規(guī)定此時第2個表達式不再計算用“| ”對兩個表達式進行計算時,若第1個表達式的值為“真”,則與第2個表達式的值無關,結果肯定為“真”,所以C語

15、言規(guī)定此時第2個表達式不再計算賦值運算符和賦值表達式一、賦值運算符“=”用法:變量=表達式作用:將表達式的值賦給變量如:a=5;ave=(a+b)/10;二、賦值結果和類型轉換1、實型數(shù)據(jù)(包括單、雙精度)賦給整型變量時,舍棄實數(shù)的小數(shù)部分。2、整型數(shù)據(jù)賦給單、雙精度變量時,數(shù)值不變,但以浮點數(shù)形式存儲到變量中#include “stdio.h” void main() int i; float f; i=1.23; f=45; printf(“%d %fn”,i,f);結果:i=1f=45.000000逗號運算符和逗號表達式形式:表達式1,表達式2,表達式n作用:用于連接表達式 如:3+5,

16、6-5計算過程:1、求解表達式12、再求解表達式2,表達式n3、整個逗號表達式的值是表達式n的值.一個逗號表達式又可以與另一個表達式組成一個新的逗號表達式。如;(a=3*5,a*4),a+5 x=a=3,6*a注意:并不是任何地方出現(xiàn)的 逗號都是逗號運算符 如:printf(“%d,%dn”,a,b)條件運算符該運算符是三目運算符,其三個運算對象是表達式(e1?e2:e3);運算規(guī)則是如果e1表達式為“真”,取e2表達式的值,否則取e3表達式的值。位運算符什么是位運算是一種對運算對象按二進制位進行操作的運算。位運算的特點位運算不允許只操作其中的某一位,而是對整個數(shù)據(jù)按二進制位進行運算;位運算的

17、對象只能是整型數(shù)據(jù)(包括字符型),運算結果仍是整型數(shù)據(jù)位運算符分為位邏輯運算符、位移位運算符、位自反賦值運算符三種位運算符運算符名稱優(yōu)先級結合性位非2自右向左&位與8自左向右異或9自左向右|位或10自左向右位移位運算符運算符名稱優(yōu)先級結合性右移自左向右位運算符按位與 & 0&0=0; 0&1=0; 1&0=0; 1&1=1 按位或 | 0|0=0; 0|1=1; 1|0=1; 1|1=1 按位異或 00=0; 01=1; 10=1; 11=0按位取反 0=1; 1=0;表達式什么是表達式用運算符將運算對象連接形成的式子就是表達式。表達式的特點每個表達式都可以按照其中運算符的優(yōu)先級和運算規(guī)則依次

18、對運算對象進行運算,最終獲得一個數(shù)據(jù),該數(shù)據(jù)稱為表達式的值。表達式值的數(shù)據(jù)類型就稱為表達式的數(shù)據(jù)類型。表達式的分類主要有六種:算術表達式、關系表達式、邏輯表達式、條件表達式、賦值表達式和逗號表達式。表達式類型轉換方法表達式計算中數(shù)據(jù)類型的自動轉換原則特點:參加運算的各個數(shù)據(jù)都轉換成數(shù)據(jù)長度最長的數(shù)據(jù)類型,然后計算。計算結果值當然就是數(shù)據(jù)長度最長的數(shù)據(jù)類型例如:設i為int,f為float,d為double,e為long則10+a+i*f-d/e的結果是double。運算結果存入變量時數(shù)據(jù)類型的自動轉換原則特點:先將運算結果的數(shù)據(jù)類型自動轉換成變量的數(shù)據(jù)類型,然后再賦予該變量不同類型數(shù)據(jù)間的混合

19、運算整型、實型(包括單、雙精度)、字符型數(shù)據(jù)間可以混合運算。如:10+a+12.3-4.56*x是合法的運算時,不同類型的數(shù)據(jù)要先轉換成同一類型,然后進行運算。轉換規(guī)則如下:floatdoublelongunsignedintchar,short高低float型數(shù)據(jù)在運算時一律先轉換成double型不同類型進行混合運算時,按照類型級別由低到高的順序轉換字符型和short型在運算時一律轉換成int型分支結構程序設計退出關鍵字意義for循環(huán)語句控do循環(huán)語句的循環(huán)體制while循環(huán)語句的循環(huán)條件語break跳出當前循環(huán)句 continue結束當前循環(huán),開始下一輪循環(huán)if條件語句else條件語句否定

20、分支(與if連用)goto無條件跳轉語句switch開關語句case開關語句分支default開關語句中的其它分支return返回語句在C語言中,分支結構主要是利用if語句來實現(xiàn)的,if語句是對給定的條件進行判斷,然后決定執(zhí)行某個分支。C語言的if語句有3種形式:if語句if else語句else if語句If語句條件執(zhí)行一般形式為:If(表達式)語句含義:如果表達式的值為真,則執(zhí)行其后的語句;否則不執(zhí)行該語句。語句表達式真(非0)假(0)If(x0)printf(“hello!”);例:輸入兩個數(shù),輸出其中較大的數(shù)main()int a,b,max;printf(“n input two n

21、umbers:”);scanf(“%d%d”,&a,&b);max=a;if(maxb)max=a;min=b;elsemax=b;min=a;if(maxc)min=c;printf(“max=%dt min=%dn”,max,min);else-if語句前面兩種形式的if語句一般都用于兩個分支情況。在實際程序設計時經常需要進行多分支處理,C語言中進行多分支處理時,可采用else-if語句實現(xiàn)。階梯式的if語句一般形式 if(表達式1)語句1; elseif(表達式2)語句2; elseif(表達式3)語句3; elseif(表達式m)語句m; else語句m+1;含義:依次判斷各個表達式的

22、值,當出現(xiàn)某個值為真時,則執(zhí)行其對應的語句,然后跳出else-if結構。如果所有的表達式的值均為假,則執(zhí)行語句m+1,然后執(zhí)行后續(xù)程序。表達式1語句1真真真真表達式2表達式3表達式4語句2語句3語句2語句2假假假假例:根據(jù)鍵盤輸入字符的類型并輸出相應的信息#include main()char c;printf(input a character:);c=getchar(); if(c=0&c=a&c=A&cb)printf(“ABn”);elseprintf(“Ab)max=a; elsemax=b;可以采用條件運算符實現(xiàn): max=(ab)?a:b;條件運算符是一個3目運算符,即有3個參與

23、運算的量。由條件運算符組成的表達式稱為條件表達式:表達式1?表達式2:表達式3使用條件表達式時,還應注意以下幾點:(1)條件運算符的運算優(yōu)先級低于關系運算符和算術運算符,但高于賦值運算符。(2)條件運算符?和:是一對運算符,不能分開單獨使用。(3)條件運算符的結合方向是自右至左。如:ab?a:cd?c:d例:比較兩個數(shù)的大小并輸出較大值 main( ) int a,b;printf(“n input two numbers:”);scanf(“%d%d”,&a,&b);printf(“max=%d”,ab?a:b); switch-case語句在實際中經常需要處理多分支問題,如統(tǒng)計學生成績分布

24、等,雖然可以用else-if和嵌套if語句來實現(xiàn)多分支程序設計,但是當分支較多時,程序變得冗長且可讀性低。在C語言中提供了直接處理多分支的方法:switch-case語句。一、格式: switch(表達式)case常量表達式1:語句1;case常量表達式2:語句2;case常量表達式n:語句n;default :語句n+1;二、執(zhí)行過程1.計算表達式的值2.若與常量表達式n值一致,則從該語句開始執(zhí)行;直到遇到break語句或switch語句的3、若與任何常量表達式值均不一致時,則執(zhí)行default語句或執(zhí)行后續(xù)語句其中:表達式可以是整型、字符型、枚舉型常量表達式必須與表達式類型一致(整型與字符

25、型通用)常量表達式中的數(shù)據(jù)僅起語句標號作用,不作求值判斷常量表達式的值必須是唯一的,沒有先后順序多個case語句可以共用一組執(zhí)行語句循環(huán)結構程序設計內容提要:循環(huán)就是在滿足一定條件時重復執(zhí)行一段程序概述構成循環(huán)的語句while、do-while、for、if-goto循環(huán)結構的比較break語句和continue語句While語句用while語句實現(xiàn)循環(huán)while語句的一般形式:while (表達式) 語句;表達式語句下一語句假(0)真(非0)表達式語句 當表達式的值為真(非0)時,執(zhí)行其中的內嵌語句(循環(huán)體),然后回過頭來再判斷表達式的值,如此重復;當表達式為假(0)時結束循環(huán)。while語

26、句的一般形式:while (表達式) 語句;如:k=1;while(k=100)s+=k;k+;循環(huán)控制表達式循環(huán)控制變量循環(huán)體注意: 若循環(huán)體包含一條以上的語句,應以復合語句形式出現(xiàn) 循環(huán)體,必須給循環(huán)控制變量賦值 循環(huán)體中,必須有改變循環(huán)控制變量值的語句(使循環(huán)趨向結束的語句) 循環(huán)體可以為空如:while(c=getchar()!=A); 等價:c=getchar(); while(c!=A)c=getchar();編程練習:打印100以內所有的奇數(shù)(不包括100)打印100以內所有的偶數(shù)(不包括100)打印100以內所有3的倍數(shù),并統(tǒng)計個數(shù)。輸入一個數(shù),判斷是幾位數(shù)?(使用循環(huán)實現(xiàn)?。?/p>

27、do-while循環(huán)do-while語句用來實現(xiàn)“直到型”循環(huán),它的一般形式為:do語句While(表達式);不可以省略切記切記!語句表達式下一語句假真NS圖注意點與while相同for循環(huán)for循環(huán)的一般形式:for(表達式1;表達式2;表達式3)語句求解表達式1表達式2語句求解表達式3下一語句假真求解表達式1表達式2語句求解表達式3表達式1在進入循環(huán)之前求解(循環(huán)變量賦初值)表達式3是循環(huán)體的一部分for循環(huán)的其他形式:for( ;表達式2; )語句表達式3;表達式1表達式1;表達式3表達式2為空值永遠為真成為死循環(huán)變量賦初值這個分號不能移走相當于循環(huán)體的一部分可以移到語句后面來說明1、表

28、達式1省略時,應在for前給循環(huán)變量賦初值。如:k=1;for(;k=3;k+) s+=k;2、表達式2省略時,不判斷循環(huán)條件,將成為“死循環(huán)”,需要在循環(huán)體內引入break語句以退出循環(huán)3、表達式3省略時,循環(huán)體內應有使循環(huán)條件改變的語句如:for(k=1;k=3; )s+=k;k+;4、同時省略表達式1和表達式3,只有表達式2,此時相當于while語句。如:k=1;k=1;for(;k=3;)while(k=3)s+=k;k+s+=k;k+5、表達式2一般是關系表達式或邏輯表達式,但也可以是數(shù)值表達式或字符表達式,只要其值不等于0就執(zhí)行循體如: for(k=1;k-4;k+)s+=k;僅當

29、k的值等于4的時候終止循環(huán)。k-4是數(shù)值表達式。求100以內的奇數(shù)、偶數(shù)之和循環(huán)的嵌套一個循環(huán)體內包含著另一個完整的循環(huán)結構,就稱為循環(huán)嵌套內嵌的循環(huán)中又可以嵌套循環(huán),從而構成多重循環(huán)。三種循環(huán)可以互相嵌套下面給出幾種合法的嵌套形式:(1)while嵌套while(2)do-while嵌套do-whilewhile()dowhile()dowhile();while();(3)for嵌套for(4)while嵌套do-whilefor(;)while()for(;)dowhile();(5)for嵌套while(6)do-while嵌套forfor(;)dowhile()for; while(

30、);循環(huán)嵌套的說明嵌套的循環(huán)控制變量不能相同內循環(huán)變化快,快循環(huán)變化慢正確確定循環(huán)體循環(huán)控制變量常與求解的問題掛鉤有1、2、3、4個數(shù)字,能組成多少個互不相同且無重復數(shù)字的三位數(shù)?都是多少?main()int i,j,k;printf(n);for(i=1;i5;i+)*以下為三重循環(huán)*/ for(j=1;j5;j+) for (k=1;k5;k+) if (i!=k&i!=j&j!=k) /*確保i、j、k三位互不相同*/ printf(%d,%d,%dn,i,j,k); 幾種循環(huán)的比較一、關于循環(huán)的控制循環(huán)控制條件修改循環(huán)條件循環(huán)條件初始化break語句和continue語句一、break

31、語句用break語句可以結束switch結構和三種循環(huán)、for(n=1;n1000) break; printf(“%f”,n);二、continue語句用continue語句可以結束本次循環(huán),既忽略循環(huán)體中剩余語句。如:把100200之間不能被3整除的數(shù)輸出本次循環(huán)結束循環(huán)體的剩余語句被忽略執(zhí)行表達式3,進下一循環(huán)continue總是作if的內嵌語句通用轉移語句goto語句Goto語句隨意跳轉到任意位置Goto語句一般配合標號語句使用Goto語句容易導致代碼混亂精心設計的goto語句可以帶來代碼的高效Goto語句在嵌入式編程中用的很多3.1.3 C語言知識精編 關鍵詞退出關鍵字意義存auto

32、聲明自動變量,缺省時一般為“auto”儲extern聲明變量是在其它文件中聲明(也可以看做是引用變量)類register聲明寄存器變量型static聲明靜態(tài)變量const聲明只讀變量sizeof計算對象所占內存空間大小其typedef給數(shù)據(jù)類型取別名它volatile說明變量在程序執(zhí)行中switch開關語句case開關語句分支default開關語句中的其它分支return返回語句3.1.3 C語言知識精編 預處理退出預處理命令意義#define宏定義#undef撤銷已定義過的宏名#include使編譯程序將另一源文件嵌入到帶有#include的源文件中#if#if 的一般含義是:如果#if 后

33、面的常量表達式為true,則編譯它與#endif 之間的代碼,否則跳過這些代碼。#else#endif 標識一個#if 塊的結束。#elif#else 在# if 失敗的情況下建立另一選擇。#endif#elif 命令意義與else if 相同,它形成一個if else-if 階梯狀語句,可進行多種編譯選擇。#ifdef#ifndef用#ifdef 與#ifndef 命令分別表示“如果有定義”及“如果無定義”,是條件編譯的另一種方法#line改變當前行數(shù)和文件名稱,它們是在編譯程序中預先定義的標識符,命令的基本形式為:#line numberfilename#error編譯程序時,#error

34、 就會生成一個編譯錯誤提示消息,并停止編譯#pragma它允許向編譯程序傳送各種指令,當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本打印出來?!邦A處理”是指在對C語言源程序進行編譯之前,要先對程序中的“宏定義、文件包含、條件編譯”等特殊命令進行預先處理。宏定義:定義一個標識符來表示一個字符串,稱為“宏定義”,該標識符稱為“宏名”。在編譯預處理時,對程序中所有出現(xiàn)的“宏名”的地方都用字符串去代換。宏定義分類:分為有參數(shù)宏定義和無參數(shù)宏定義兩種。宏的定義不帶參數(shù)的宏定義宏定義的一般格式為:#define 文本串 /*#define就是宏定義命令*/功能:將宏名的值定義為指定的文本串。在預處理時

35、凡出現(xiàn)宏名的地方,都用指定的文本串替換。在預處理時將宏名替換成指定的文本串的過程稱為“宏展開”,或稱為“宏替換”。【例】 求圓周長、面積和相同半徑圓球體積。#define PI 3.14159void main() float r,l,s,v; printf(“input radius:”); scanf(“%f”,&r); l=2.0*PI*r; s=PI*r*r; v=3.0/4*PI*r*r*r; printf(“l(fā)=%6.2fns=%6.2fnv=%6.2fn”,l,s,v); 程序運行結果:input radius:6l= 37.70s=113.10v=508.94注意:(1) 宏名

36、為了與變量名區(qū)別一般用大寫字母表示。(2) 宏展開時只用文本串替換宏名,不作正確性檢查。(3) 宏定義行末尾不能加分號。加分號,宏展時會當作文 本串字符一同代入。 (4) 宏名的有效范圍是:從定義位置開始到本文件結束(5) 可以用#undef命令終止宏定義的作用域。(6) 在宏定義時,可以引用已定義的宏名?!纠吭诤甓x時引用已定義的宏名#define R 4.0#define PI 3.14159#define L 2*PI*R#define S PI*R*Rvoid main() printf(“L=%6.2fnS=%6.2fn”,L,S);運行結果如下:L= 25.13S= 50.27【

37、例】分析下列程序#define OK 100void main() printf(OK); printf(n);運行結果為:OK為什么不是100?帶參數(shù)的宏定義帶參數(shù)的宏定義格式如下:#define (參數(shù)表) 文本串功能:定義一個帶參數(shù)的宏。例如:#define S(x,y) 3*x+2*yarea=S(3,2);宏展開:用實參從左到右逐個字符進行替換文本串中的形參字符。如圖8.1所示。執(zhí)行:area=S(3,2) 宏展開后變成:area=3*3+2*2; 【例】 求圓的面積。 #define PI 3.14159 #define S(r) PI*r*r void main() float

38、a,area; a=3.6; area=S(a); printf(“area=%6.2fn”,area); 運行結果:area= 40.72說明:(1) 宏名與括弧之間不能有空格。(2) 宏調用時,實參的個數(shù)必須與形參的個數(shù)相同。(3) 帶參數(shù)的宏替換時不作語法檢查。(4) 宏定義時最好在參數(shù)兩側加括號和整個字符串外加括號,防止宏替換出錯。【例】分析以下程序運行結果#define SQ(y) (y)*(y)void main() int a,sq; printf(input a number: ); scanf(%d,&a); sq=160/SQ(a+1); printf(sq=%dn,sq)

39、;比較下面【例6】和【例7】程序的不同之處?!纠?】#define SQ(y) y*yvoid main() int a,sq; printf(input a number: ); scanf(%d,&a); sq=SQ(a+1); printf(sq=%dn,sq);運行結果為:input a number:3sq=7 /*宏代換后得到:sq=a+1*a+1; */【例7】#define SQ(y) (y)*(y)void main() int a,sq; printf(input a number: ); scanf(%d,&a); sq=SQ(a+1); printf(sq=%dn,sq

40、);運行結果為:input a number:3sq=16/*宏代換后得到:sq=(a+1)*(a+1); */宏調用和函數(shù)調用的主要區(qū)別:帶參宏函數(shù)處理過程不分配內存簡單的字符置換分配內存先求實參值,再代入形參處理時間編譯時程序運行時參數(shù)類型無類型問題定義實參,形參類型程序長度變長不變運行速度不占運行時間調用和返回占時間文件包含:就是將指定文件全部內容包含(裝入)到本文件中來。一般格式:#include“文件名” 或 #include功能:將指定的源文件全部內容包含進來,即裝入#include命令所處位置上使其成為一個程序。2 文件包含對文件包含命令還要說明以下幾點:1.指定文件名可以用雙引

41、號或尖括號括起來。例如:#includestdio.h#include二者的區(qū)別:用尖括弧時,直接在庫函數(shù)頭文件目錄中查找包含文件,稱為標準方式;用雙引號時,在用戶當前目錄中尋找包含的文件,若找不到,再按標準方式查找。一般情況下:包含庫函數(shù)用尖括弧節(jié)省時間;包含用戶自己編寫的文件用雙引號。2. 一個#include命令只能指定一個被包含文件。3. 文件包含允許嵌套,即在一個被包含的文件中又可以包含另一個文件。功能:一個源文件可將另一個源文件的內容全部包含進來一般形式: #include “文件名” 或 #include #include “file2.c”file1.cfile2.cfile1

42、.cfile2.cABA處理過程:預編譯時,用被包含文件的內容取代該預處理命令,再對“包含”后的文件作一個源文件編譯 直接按標準目錄搜索“” 先在當前目錄搜索,再搜索標準目錄可指定路徑文件包含源文件(*.c)頭文件(*.h)宏定義數(shù)據(jù)結構定義函數(shù)說明等文件包含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c被包含文件內容/* powers.h */#define sqr(x) (x)*(x)#define cube(x) (x)*(x)*(x)#define quad(x

43、) (x)*(x)*(x)*(x)/*a.c*/#include #include “powers.h#define MAX_POWER 10void main() int n; printf(numbert exp2t exp3t exp4n); printf(-t-t-t-n); for(n=1;n=MAX_POWER;n+) printf(%2dt %3dt %4dt %5dn,n,sqr(n),cube(n),quad(n);例 文件包含舉例【例8】給定半徑,計算圓的周長和圓的面積。設計三個包含文件,或稱為頭文件:第1個為:myin1.h#include#define PI 3.141

44、59第2個為:myin2.hfloat getlen(float r) return 2*getsr(r)/r; 第3個為:myin3.hfloat getsr(float r) return PI*r*r; 主函數(shù)的程序如下:#include “myin1.h”#include “myin3.h”#include “myin2.h”void main() float x=3.0;printf(“L=%fn”,getlen(x);printf(“S=%fn”,getsr(x); 因為:函數(shù)的調用關系,頭文件的包含順序應該必須是:myin1.h,然后myin3.h,最后是myin2.h。 一般情

45、況下,對源程序進行全部編譯。條件編譯:根據(jù)具體條件和需要只編譯源程序中的某些部分為條件編譯。條件編譯用途:可以用源程序產生不同版本。3 條件編譯1條件編譯的三種形式:形式一:#ifdef 標識符 程序段1#else 程序段2#endif功能:標識符已被 #define命令定義過則對程序段1進行編譯;否則對程序段2進行編譯。 形式二:#ifndef 標識符 程序段1 #else 程序段2 #endif功能:如果標識符未被#define命令定義過則對程序段1進行編譯,否則對程序段2進行編譯。形式三:#if 常量表達式 程序段1#else 程序段2#endif功能是,如常量表達式的值為真(非0),則

46、對程序段1 進行編譯,否則對程序段2進行編譯。#include #define LETTER 0int main( ) char str = C language; char c; int i; for (i = 0; stri != 0; i+) c = stri;#if LETTER if (c=a& c=A& c=Z) c=c+32;#endif printf(%c,c); putchar(n); return 0;運行結果:C LANGUAGE 上題如果將第一行改為:#define LETTER 0則在預處理時,對第二個IF語句處理,使大寫變?yōu)樾?。目的:掌握宏定義、宏調用,以及宏展的

47、處理過程,掌握文件包含的概念和使用。實訓內容:1試分析以下宏替換后的形式,計算輸出結果。要求:先計算運行結果,然后利用程序驗證。#include #define CX(y) 2.5+y#define PR(a) printf(%d,(int)(a)#define PR1(a) PR(a); putchar(n)int main(void) int x=2; PR1(CX(5)*x); return 0;5練習2.寫出下面程序的運行結果(2) #define M 3 #define N M+1 #define NN N*N/2 int main( ) printf(“%dn”, NN) prin

48、tf(“%dn”, 5*NN) ; (1) #define min(x, y) x str_cpy(char *src, char *des)數(shù)組作為函數(shù)返回值,必須通過指針實現(xiàn)char *str_cpy(char *src, char *des) 數(shù)組與指針2、指針數(shù)組:即數(shù)組的元素為指針類型。 char* var10; /10個int型指針的數(shù)組 sizeof(var) = ? var + 1 ?3、數(shù)組指針:即指針的類型為數(shù)組(指向數(shù)組的指針)。 char (*var)10; /指向10個int型數(shù)組的指針 sizeof(var) = ? var + 1 ?4、字符串與指針字符串是屬于典

49、型的字符數(shù)組,因而通常通過char型指針處理字符串 數(shù)組與指針將字符串直接賦值給指針,表示指針指向字符串內存首地址注意:字符串常量內存分配在只讀數(shù)據(jù)區(qū)(RODATA)實例:char *p = “xnf”; char arr = “xnf”;*p ? *p+ ? *+p ? *p = X ? arr0 = X ? strcpy(p, “XNF”) ? strcpy(arr, “XNF”) ? 數(shù)組與指針通過指針數(shù)組表示字符串數(shù)組char a16 = “welcome”, “to”, “xnf”; 主函數(shù)參數(shù)就是通過指針數(shù)組實現(xiàn)的: int main (int argc, char *argv)

50、結構與指針1、結構包含指針:結構體中包含指針域變量 如:學生信息中name與phone定義為指針 注意:在程序中動態(tài)修改學生信息表中的 name和phone域可行么? 結構與指針2、指向結構體的指針 結構體變量域通過.訪問,而結構體指針域通過-訪問 sizeof(info) = ? sizeof(p) = ? 下面這段代碼錯在哪里? 結構與指針 通過結構體指針傳遞參數(shù)比直接傳遞結構體變量更高效 實參傳遞給形參時只拷貝了4個字節(jié) 指針與指針1、指向指針變量的指針 int i = 100; int *p = &i; int *pp = &p; 實現(xiàn)指針二級訪問: 函數(shù)與指針1、指針作為函數(shù)的參數(shù)向

51、函數(shù)傳遞數(shù)組、字符串、結構: 如strc_py、show_info作為函數(shù)的輸出參數(shù)例如:實現(xiàn)交換兩個整數(shù)的函數(shù) void swap(int a, int b) 傳值,形參值改變并不能帶回給實參 傳址,在函數(shù)內改變地址內保存的內容 函數(shù)與指針問題: 要在函數(shù)能改變指針的值,怎么通過輸出參數(shù)返回?例如:void get_mem(char *pmem, int size)pmem = malloc(size); 動態(tài)分配的內存能通過pmem帶回么? 不能!要將實參指針的地址傳遞給形參(二級指針)才能實現(xiàn)! 更直接的方法是通過函數(shù)返回值實現(xiàn) 函數(shù)與指針2、指針作為函數(shù)的返回值 返回字符串、動態(tài)分配的

52、內存等,如 *strcpy, *malloc 注意返回地址的有效性(函數(shù)執(zhí)行完畢后該地址未被回收) 下面兩個函數(shù)哪個是合法的?函數(shù)與指針3、指向函數(shù)的指針 函數(shù)存放在TEXT段,同樣具有地址 函數(shù)名就是函數(shù)在TEXT段的入口地址 跟數(shù)組名一樣,函數(shù)名也可以看作是一個指針常量 所以,函數(shù)名也可以賦值給指針變量,那么該指針變量類型呢? 函數(shù)指針類型!通過函數(shù)指針,也可以間接調用函數(shù)。 函數(shù)與指針函數(shù)指針的應用:1、作為函數(shù)參數(shù)實現(xiàn)回調函數(shù) 所謂回調函數(shù)是指通過調用其他函數(shù)反 過來調用某個函數(shù) 模擬面向對象的多態(tài),在UI組件的大量使 用 函數(shù)與指針 2、作為結構體的動作域 模擬面向對象的類,在Lin

53、ux內核中大量使用 作為一個現(xiàn)實中的對象,不但有數(shù)據(jù)屬性,還需要有行為屬性 使用對象行為 3.2 Cortex-M3微控制器軟件接口標準什么是CMSIS微控制器軟件接口標準,即(Cortex Microcontroller Software Interface Standard, CMSIS)為什么推出CMSIS一個ARM內核會授權給多個廠家,生產種類繁多的產品開發(fā)者增加了軟件開發(fā)成本將所有Cortex芯片廠商產品的軟件接口標準化,制定了CMSIS標準。芯片廠商就能夠將他們的資源專注于產品外設特性的差異化,從而達到降低開發(fā)成本的目的。3.2 Cortex-M3微控制器軟件接口標準CMSIS軟件

54、架構3.2 Cortex-M3微控制器軟件接口標準CMSIS層由三部分構成(1) 核內外設訪問層(CPAL,Core Peripheral Access Layer):該層由ARM 負責實現(xiàn)。包括對寄存器名稱、地址的定義,對核寄存器、NVIC、調試子系統(tǒng)的訪問接口定義以及對特殊用途寄存器的訪問接口(例如:CONTROL,xPSR)定義。(2) 片上外設訪問層(DPAL, Device Peripheral Access Layer):該層由芯片廠商負責實現(xiàn)。該層的實現(xiàn)與CPAL 類似,負責對硬件寄存器地址以及外設訪問接口進行定義。該層可調用CPAL 層提供的接口函數(shù)同時根據(jù)設備特性對異常向量表

55、進行擴展,以處理相應外設的中斷請求。(3) 外設訪問函數(shù)(AFP, Access Functions for Peripherals):該層也由芯片廠商負責實現(xiàn),主要是提供訪問片上外設的訪問函數(shù),這一部分是可選的。概述STM32標準外設庫之前的版本也稱固件函數(shù)庫或簡稱固件庫,是一個固件函數(shù)包,它由程序、數(shù)據(jù)結構和宏組成,包括了微控制器所有外設的性能特征。每個外設驅動都由一組函數(shù)組成,這組函數(shù)覆蓋了該外設所有功能。每個器件的開發(fā)都由一個通用API (application programming interface 應用編程界面)驅動,API對該驅動程序的結構,函數(shù)和參數(shù)名稱都進行了標準化。ST

56、公司2007年10月發(fā)布了V1.0版本的固件庫,MDK ARM3.22之前的版本均支持該庫。2008年6月發(fā)布了V2.0版的固件庫,從2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件庫。V3.0以后的版本相對之前的版本改動較大,本書使用目前較新的V3.4版本。STM32F10 x標準外設庫概述STM32標準外設庫之前的版本也稱固件函數(shù)庫或簡稱固件庫,是一個固件函數(shù)包,它由程序、數(shù)據(jù)結構和宏組成,包括了微控制器所有外設的性能特征。每個外設驅動都由一組函數(shù)組成,這組函數(shù)覆蓋了該外設所有功能。每個器件的開發(fā)都由一個通用API (application programming

57、 interface 應用編程界面)驅動,API對該驅動程序的結構,函數(shù)和參數(shù)名稱都進行了標準化。ST公司2007年10月發(fā)布了V1.0版本的固件庫,MDK ARM3.22之前的版本均支持該庫。2008年6月發(fā)布了V2.0版的固件庫,從2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件庫。V3.0以后的版本相對之前的版本改動較大,本書使用目前較新的V3.4版本。STM32F10 x標準外設庫縮寫外設名稱縮寫外設名稱ADC模數(shù)轉換器I2SIIS總線接口BKP備份寄存器IWDG獨立看門狗CAN控制器局域網(wǎng)NVIC嵌套向量中斷控制器CRCCRC計算單元PWR電源控制DAC數(shù)模

58、轉換器RCC復位和時鐘控制DBGMCUMCU調試模塊RTC實時時鐘DMADMA控制器SDIOSDIO接口EXTI外部中斷/事件控制器SPISPI接口SysTick系統(tǒng)定時器FSMC靈活的靜態(tài)存儲器控制器FlashFlash存儲器TIM定時器GPIO通用輸入輸出USART通用同步異步收發(fā)器I2CIIC總線接口WWDG窗口看門狗STM32F10 x標準外設庫標準外設庫中包含了眾多的變量定義和功能函數(shù),如果不能了解他們的命名規(guī)范和使用規(guī)律將會給編程帶來很大的麻煩命名規(guī)則標準外設庫遵從以下命名規(guī)則 PPP表示任一外設縮寫,例如:ADC。源程序文件和頭文件命名都以“stm32f10 x_”作為開頭,例如

59、:stm32f10 x_conf.h。常量僅被應用于一個文件的,定義于該文件中;被應用于多個文件的,在對應頭文件中定義。所有常量都由英文字母大寫書寫。寄存器作為常量處理。他們的命名都由英文字母大寫書寫。在大多數(shù)情況下,他們采用與縮寫規(guī)范一致。外設函數(shù)的命名以該外設的縮寫加下劃線為開頭。每個單詞的第一個字母都由英文字母大寫書寫,例如:SPI_SendData。在函數(shù)名中,只允許存在一個下劃線,用以分隔外設縮寫和函數(shù)名的其它部分。STM32F10 x標準外設庫命名規(guī)則名為PPP_Init的函數(shù),其功能是根據(jù)PPP_InitTypeDef中指定的參數(shù),初始化外設PPP,例如TIM_Init.名為PPP_DeInit的函數(shù),其功能為復位外設PPP的所有寄

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論