国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

2021-2022(2)嵌入式系統(tǒng)期末復習提綱 (習題版)

這篇具有很好參考價值的文章主要介紹了2021-2022(2)嵌入式系統(tǒng)期末復習提綱 (習題版)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

2021-2022(2)嵌入式系統(tǒng)期末復習提綱 (習題版)

前言

??前段時間考完嵌入式系統(tǒng)的期末考試,這兩天抽出空來把之前整理的提綱發(fā)出來。
??在考試前按照老師給的復習提綱整理了一份知識點,看到提綱里沒有指令系統(tǒng),就沒有去看那一小節(jié)的內容,結果考試的時候選擇題考了好幾題指令系統(tǒng),心態(tài)都炸了??纪旰罄蠋熣f準備了兩套期末試卷,可能抽中的是另一套,這個解釋有點讓人難以接受,不過按照我下面準備的知識點來背還是可以應付期末考試的。
??最后我還是想強調一下,沒有什么投機取巧的道路,正如復習要點第一點中的通讀教材。好好背!

一、考試題型

  1. 選擇(20 分)
  2. 簡答(30 分)
  3. 程序題(20 分,內容包括代碼解釋、填空等)
  4. 論述題(30 分)

二、復習要點

  1. 通讀教材,突出重點
  2. 分析代碼,尤其初始化部分,動作部分,理解程序
  3. 了解嵌入式處理器的選型原則(根據(jù)需求,性能,成本,開發(fā)工具,已有資源)
  4. 了解嵌入式系統(tǒng)的發(fā)展趨勢

三、主要知識點

第 1 章 嵌入式系統(tǒng)概述

1.嵌入式系統(tǒng)概念、應用與特點

? 練習題:簡答題:簡述嵌入式系統(tǒng)的定義、應用和特點

? 定義:嵌入式系統(tǒng)是以應用為中心,以計算機技術為基礎,并且在軟、硬件方面可裁剪,適用于應用系統(tǒng)對功能、可靠性、成本、體積、功耗有嚴格要求的專用計算機系統(tǒng)。

? 應用:應用于國防軍事、工業(yè)控制、交通管理、信息家電、醫(yī)療保健設備、機器人等領域

? 特點:1.專用于特定任務、2.多類型處理器和處理器系統(tǒng)支持、3.通常極其關注成本、4.一般是實時系統(tǒng)、5.可裁剪性好、6.可靠性高、7.大多有功耗約束


? 練習題:簡答題:簡要敘述嵌入式系統(tǒng)的定義及組成

? 定義:嵌入式系統(tǒng)是以應用為中心,以計算機技術為基礎,并且在軟、硬件方面可裁剪,適用于應用系統(tǒng)對功能、可靠性、成本、體積、功耗有嚴格要求的專用計算機系統(tǒng)。

? 組成:它一般由嵌入式微處理器、外圍硬件設備、嵌入式操作系統(tǒng)以及用戶的應用程序等四個部分組成。


2.嵌入式系統(tǒng)的硬件(CPU、外設)

? 真題:(2016-2017問答題 第3題) 目前流行的嵌入式微處理器有哪幾種,各有何特點?

? 真題:(2017-2018問答題 第3題) 寫出至少4種目前流行的嵌入式微處理器及特點

? ①ARM微處理器:ARM公司提供IP授權生產(chǎn)的芯片,各具特色,占據(jù)32位市場份額90%以上

? ②MIPS微處理器:面向高性能、高檔次的32位和64位處理器市場

? ③PowerPC:品種良多,覆蓋范圍廣,從高端工作站到桌面計算機,從消費類電子產(chǎn)品到大型通信設備,無所不包;

? ④x86:源自Intel8080,最早的嵌入式芯片,良好的兼容性限制了其性能發(fā)展

? ⑤Motorola 68000: CISC架構,面向通信應用


3.主要嵌入式軟件系統(tǒng)(應用及 OS)

? 練習題:簡答題:嵌入式操作系統(tǒng)的定義

? 一種支持嵌入式系統(tǒng)應用的操作系統(tǒng)軟件,是嵌入式系統(tǒng)極為重要的組成部分。通常包括與硬件相關的底層驅動軟件、系統(tǒng)內核、設備驅動接口、通信協(xié)議、圖形界面等,嵌入式操作系統(tǒng)負責嵌入式系統(tǒng)的全部軟、硬件資源的分配、任務調度,控制、協(xié)調并發(fā)活動。


? 練習題:簡答題:列出常見的4種嵌入式操作系統(tǒng)

? ①μC/OS –II ②嵌入式Linux ③Windows Embedded ④VxWorks


? 練習題:簡答題:實時操作系統(tǒng)的評價指標有哪些

? ①上下文切換時間 ②搶占時間 ③中斷延時 ④信息量混洗時間


? 練習題:簡答題:簡述嵌入式操作系統(tǒng)與通用操作系統(tǒng)的區(qū)別

? 通用操作系統(tǒng)可運行在不同的硬件平臺,而嵌入式操作系統(tǒng)與一般的Windows操作系統(tǒng)不同,其是一種專用、可定制的操作系統(tǒng)。


4.嵌入式系統(tǒng)的發(fā)展趨勢

? ①嵌入式開發(fā)是一項系統(tǒng)工程

? ②網(wǎng)絡化、信息化的要求

? ③網(wǎng)絡互聯(lián)、移動互聯(lián)成為必然趨勢

? ④精簡系統(tǒng)內核、算法,降低功耗和軟硬件成本

? ⑤提供友好的多媒體人機界面。


第 2 章 ARM Cortex-M3微處理器基礎

1.ARM 處理器特點及應用

? 練習題:簡答題:ARM處理器有什么特點?

? ARM處理器的三大特點是:耗電少功能強、16位/32位雙指令集合作伙伴眾多

? ①體積小、低功耗、低成本、高性能

? ②支持Thumb(16位)/ARM(32位)雙指令集,能很好的兼容8位/16位器件

? ③大量使用寄存器,指令執(zhí)行速度更快

? ④大多數(shù)數(shù)據(jù)操作都在寄存器中完成

? ⑤尋址方式靈活簡單,執(zhí)行效率高

? ⑥指令長度固定


2.CM3 微控制器簡介

? 練習題:簡答題:ARM Cortex-M3采用的哪一種架構,能夠執(zhí)行的指令集有哪些?

? ①ARMv7-M架構

? ②16位Thumb指令集和32位Thumb-2指令集


? 練習題:簡答題:ARM Cortex-M3處理器系統(tǒng)的主要模塊包括?

? ①處理器內核

? ②嵌套向量中斷控制器NVIC

? ③總線矩陣

? ④存儲器保護單元MPU

? ⑤系統(tǒng)調試組件和調度端口

? ⑥喚醒中斷控制器WIC


? 練習題:簡答題:Cortex-M3的處理器有哪兩種工作模式和狀態(tài)?如何進行工作模式和狀態(tài)的切換?

? ①工作模式:線程模式和處理模式。

? 在復位時處理器進入線程模式,異常返回時也會進人該模式,特權模式和用戶(非特權)模式代碼能夠在線程模式下運行。

? 出現(xiàn)異常時處理器進人處理模式,在處理模式下,所有代碼都是特權訪問的。
? 工作狀態(tài):Thumb 狀態(tài)和調試狀態(tài)。

? Thumb 狀態(tài)是 16 位和 32 位 ” 半字對齊 ” 的 Thumb 和 Thumb-2 指令的執(zhí)行狀態(tài)。

? 調試狀態(tài)是處理器停止并進行調試時所進人的狀態(tài)。

? ②通過Bx Rn指令來進行兩種狀態(tài)的切換


? 練習題:簡答題:Cortex-M3的處理器支持哪兩種工作模式?特權模式有哪些?非特權模式有哪些?

? ①線程模式和處理模式

? ②特權模式:系統(tǒng)模式、一般中斷模式、快速中斷模式、管理模式、中止模式、未定義指令中止模式

? ③非特權模式:用戶模式


? 練習題:簡答題:ARM微處理器的運行模式有哪幾種,請列舉并說明

? ARM微處理器的運行模式有7種,分別為:

? ①用戶模式:正常程序執(zhí)行時,ARM處理器所處的狀態(tài)

? ②快速中斷模式:用于快速數(shù)據(jù)傳輸和通道處理

? ③外部中斷模式:用于通常的中斷處理

? ④特權模式:供操作系統(tǒng)使用的一種保護模式

? ⑤數(shù)據(jù)訪問中止模式:當數(shù)據(jù)或指令預取終止時進入該模式,用于虛擬存儲及存儲保護

? ⑥未定義指令終止模式:用于支持硬件協(xié)處理器軟件仿真

? ⑦系統(tǒng)模式:用于運行特權級的操作系統(tǒng)任務


3.CM3 存儲格式類型

? 練習題:簡答題:什么是大端格式?什么是小端格式?

? 在大端格式中,字數(shù)據(jù)的高字節(jié)存儲在低地址中,而字數(shù)據(jù)的低字節(jié)則存放在高地址中。

? 與大端存儲格式相反,在小端存儲格式中,低地址中存放的是字數(shù)據(jù)的低字節(jié),高地址存放的是字數(shù)據(jù)的高字節(jié)。


練習題:問答題:ARM里的大端格式和小端格式分別是什么意思?舉例畫圖說明。

? 當前的存儲器,多以byte為訪問的最小單元,當一個邏輯上的地址必須分割為物理上的若干單元時就存在了先放誰后放誰的問題,于是端的問題應運而生了,對于不同的存儲方法,就有大端和小端兩個描述。

? 大端:低地址存放高有效字節(jié)

? (1000 0000) 2 = 1

? 小端:低地址存放低有效字節(jié)

? (1000 0000) 2 = 128


4.CM3 嵌套向量中斷控制器 NVIC

? 真題:(2016-2017、2017-2018簡答題 第3題) NVIC中的末尾連鎖技術的作用是什么

? 作用是在連續(xù)兩次中斷時,將上一次的返回指令和下一次的調用指令執(zhí)行所花費的時間,由42個Cycles降低到6個Cycles


5.CM3 寄存器組織

真題:(2016-2017問答題 第2題) ARM Cortex-3的通用寄存器是如何組織的?

真題:(2017-2018問答題 第2題) ARM Cortex-3的通用寄存器有哪些?各有何作用?

? ARM Cortex-3擁有16個32位通用寄存器,名稱R0-R15,分為

? ①低寄存器:R0-R7,可被指定的所有指令訪問,復位初始值不可知;

? ②高寄存器:R8-R12,能被指定的所有32位指令訪問,復位初始值不可知;

? ③堆棧指針SP:R13,作為SP自動與字對齊([1:0]位忽略)。對應兩個不會被同時訪問的物理寄存器SP_main和SP_process;

? ④鏈接寄存器LR:R14,執(zhí)行分支指令時存儲一個返回地址;

? ⑤程序計數(shù)器PC:R15,指向當前的程序地址。


6.CM3 存儲映射

? 練習題:簡答題:說明ARM Cortex-M3處理器的存儲器系統(tǒng)特點及映射分區(qū)

? ARM Cortex-M3的存儲器映射是預定義的,他的存儲器系統(tǒng)支持位帶操作,實現(xiàn)了在特殊的存儲器區(qū)域對單一比特的原子操作。

? 映射分區(qū)有:①代碼區(qū)、②片上SRAM區(qū)、③片上外設區(qū)、④片外RAM區(qū)和片外外設區(qū)、⑤私有外設區(qū)、⑥芯片商指定區(qū)


7.CM3 異常與中斷

? 真題:(2016-2017、2017-2018簡答題 第1題) 辨析STM32中的異常和中斷概念

? 在STM32中,正常的程序執(zhí)行流程發(fā)生暫時停止的情形,統(tǒng)稱為異常;而由外部事件導致的程序執(zhí)行流程改變的情形也可以稱為中斷。因此,異常的概念包含了中斷,或者說,中斷是一種特殊的異常。


? 練習題:簡答題:ARM Cortex-M3處理器的中斷響應過程分為哪幾個步驟?

? ①入棧 ②取向量 ③更新寄存器


? 練習題:問答題:ARM Cortex-M3為什么能夠高效且低延遲地對異常進行處理?

? ①自動的狀態(tài)保存和恢復

? ②優(yōu)先級屏蔽支持臨界區(qū)

? ③自動讀取代碼存儲區(qū)或SRAM中包含ISR地址的向量表入口

? ④支持末尾鎖鏈,在末尾鎖鏈中,處理器在兩個ISR之間沒有對寄存器進行出棧和壓棧操作的情況下處理背對背中斷

? ⑤ISR Cortex-M3與NVIC之間采用緊耦合接口,通過該接口可以盡早地對中斷和高優(yōu)先級的遲來中斷進行處理

? ⑥中斷優(yōu)先級可動態(tài)重新設置

? ⑦中斷數(shù)目可設置為1-240

? ⑧中斷優(yōu)先級可配置為1-8位

? ⑨處理模式與線程模式具有獨立的堆棧和特權等級

? ⑩使用C/C++標準的調用規(guī)范:ARM架構的過程調用標準執(zhí)行ISR控制傳輸


? 練習題:問答題:ARM 處理器的異常主要有哪些表現(xiàn)形式

? ①快速中斷請求 ②中斷請求 ③軟件中斷 ④預取指中止 ⑤ 數(shù)據(jù)中止 ⑥未定義指令 ⑦復位


8.STM32 時鐘源與時鐘樹

? 真題:(2016-2017、2017-2018問答題 第1題) STM32平臺中提供哪些時鐘源,其各自的頻率范圍是多少?

? ①高速外部時鐘(HSE),頻率4-16MHz

? ②低速外部時鐘(LSE),頻率32.768kHz

? ③高速內部時鐘(HSI),頻率8MHz

? ④低速內部時鐘(LSI), 頻率40kHz

? ⑤鎖相環(huán)時鐘(PLL) ,頻率72MHz


? 練習題:簡答題:STM32有哪幾種時鐘源?他們的來源和作用分別是什么?

? ①高速外部時鐘(HSE),來源:外部晶體/陶瓷振蕩器,或用戶外部時鐘, 作用:驅動系統(tǒng)時鐘

? ②低速外部時鐘(LSE),來源:外部晶體或陶瓷振蕩器,或外部時鐘,作用:驅動RTC

? ③高速內部時鐘(HSI),來源:內部8MHz的RC振蕩器,作用:驅動系統(tǒng)時鐘

? ④低速內部時鐘(LSI),來源:內部RC振蕩器,作用:為獨立看門狗、RTC和自動喚醒單元提供時鐘

? ⑤鎖相環(huán)時鐘(PLL),來源:HSI或HSE,作用:驅動系統(tǒng)時鐘


9.STM32F10 系列的 GPIO

? 練習題:簡答題:什么是GPIO?

? GPIO是一個靈活的由軟件控制數(shù)字信號,每個GPIO都代表一個連接到CPU特定引腳的一個位。STM32的GPIO端口的每一位都可以由軟件配置成多種模式:輸入浮空、輸入上拉、輸入下拉、模擬輸入、開漏輸出、推挽輸出、推挽式復用功能、開漏復用功能。


? 練習題:簡答題:STM32的GPIO端口可以配置成哪幾種模式?

? 輸入浮空、輸入上拉、輸入下拉、模擬輸入、開漏輸出、推挽輸出、推挽式復用功能、開漏復用功能。


? 練習題:簡答題:STM32F103VBT6一共有多少組I/O口?每組有多少個I/O口?并簡述STM32的GPIO端口的特點(至少三點)

? ①5組

? ②16個

? ③特點如下:

? 1.通用輸入/輸出功能,可驅動LED等

? 2.單獨的位設置和位清除,每個端口可被獨立配置

? 3.所有端口都具有外部中斷能力

? 4.復用功能

? 5.軟件重映射端口復用

? 6.GPIO鎖定機制


? 練習題:簡答題:STM32F103VBT6的各個部分的含義是什么,有多少個IO?分成多少組?

? ①有80個IO,分為5組,每組16個IO

? ②STM32F103VBT6微控制器屬于STM32F103xx 增強系列。這個名字中的字母V表示有100腳封裝、字母B表示帶有128KB的閃存存儲器,T表示控制器采取QFP封裝,6表示工業(yè)級溫度范圍(-40℃-85℃)


練習題:簡答題:STM32F10系列的GPIO的端口復用和重映射的含義。

? 端口復用:在STM32中,有許多I/O端口,同時也內置了許多外設,為了節(jié)約引出管腳,這些內置外設引出管腳是與通用I/O管腳公用的,當I/O管腳作為這些外設模塊的功能引腳時就叫端口復用功能。

? 重映射:一個外設的引腳除了具有默認的引腳位外,還可以通過配置重映射寄存器的方式,把這個外設的引腳映射其他的引腳位。


第 3 章 嵌入式開發(fā)環(huán)境


1.嵌入式開發(fā)環(huán)境(交叉編譯、 開發(fā)工具:Keil μVision)

? 真題:(2016-2017、2017-2018簡答題 第4題) 什么是交叉編譯?

? 在某個主機平臺上(如PC)用交叉編譯器編譯出可在其他平臺上(如ARM)運行的代碼的過程。


? 練習題:簡答題:什么是交叉編譯,為什么要采用交叉編譯?

? 所謂交叉編譯,是指在一個平臺上編譯生成在另一個平臺上運行的可執(zhí)行程序。

? 之所以采用交叉編譯,是因為目標平臺上不具備直接運行開發(fā)環(huán)境的條件。


第 5 章 μC/OS –II及應用開發(fā)

1.嵌入式操作系統(tǒng)概念、特點及應用

? 練習題:問答題:什么是嵌入式操作系統(tǒng)?嵌入式操作系統(tǒng)的基本特點是什么?為什么需要嵌入式操作系統(tǒng)?

? ①一種支持嵌入式系統(tǒng)應用的操作系統(tǒng)軟件,是嵌入式系統(tǒng)極為重要的組成部分。通常包括與硬件相關的底層驅動軟件、系統(tǒng)內核、設備驅動接口、通信協(xié)議、圖形界面等,嵌入式操作系統(tǒng)負責嵌入式系統(tǒng)的全部軟、硬件資源的分配、任務調度,控制、協(xié)調并發(fā)活動。

? ②具有通用操作系統(tǒng)的基本特點:能夠有效管理越來越復雜的系統(tǒng)資源,能夠把硬件虛擬化,簡化的驅動程序移植和維護,能夠提供庫函數(shù)、驅動程序、工具集以及應用程序。

? ③嵌入式處理器性能提高,資源增多

? ④任務要求復雜,實時、多任務、編程困難

? ⑤許多的任務需求是相同的,完全可以將一些相同的功能作為一個通用模塊實現(xiàn),這就是操作系統(tǒng),它屏蔽了底層硬件的細節(jié),方便用戶,提供了標準的、可裁剪的系統(tǒng)服務軟組件。


? 練習題:問答題:請介紹一下μC/OS –II操作系統(tǒng),并簡述一下μC/OS –II操作系統(tǒng)的特點,并列出μC/OS –II的內核和內核結構?

? ①μC/OS –II是一個實時操作系統(tǒng)內核,它包含任務調度,任務管理,時間管理,內存管理和任務間的通信與同步等基本功能,而沒有輸入輸出管理,文件系統(tǒng),網(wǎng)絡之類的服務。

? ②μC/OS –II特點:

? 1.公開源代碼:μC/OS –II的全部源代碼全部公布出來,能夠在網(wǎng)上查詢。

? 2.可移植性:絕大部分的μC/OS –II的源碼使用移植性很強的ANSI C寫的,只有與微處理器硬件相關用匯編語言寫的。使用匯編寫的已經(jīng)縮減到最小,使得μC/OS –II便于移植

? 3.可固化:μC/OS –II是為嵌入式應用而設計的,因此,只要讀者有固化手段就能嵌入到讀者的產(chǎn)品中

? 4.可裁剪性:μC/OS –II可以只使用應用程序需要的那些服務

? 5.占先式:μC/OS –II占先式的實時內核,這表示μC/OS –II總是運行就緒狀態(tài)下優(yōu)先級最高的任務

? 6.多任務:μC/OS –II可管理64個任務,其中8個任務留給系統(tǒng),應用程序最多有56個任務,但每個任務的優(yōu)先級必須不同

? 7.可確定性:全部μC/OS –II的函數(shù)調用和服務的執(zhí)行時間具有可確定性,也就是:全部μC/OS –II的函數(shù)調用和服務的執(zhí)行時間可預知的

? 8.任務棧:μC/OS –II允許每個任務有不同的??臻g,每個任務有自己單獨的棧,以便壓低應用程序對RAM的需求

? 9.系統(tǒng)服務:μC/OS –II提供了很多系統(tǒng)服務,例如郵箱,消息隊列,信號量,塊大小固定的內存的申請與釋放等

? 10.中斷管理:中斷可以使正在執(zhí)行的任務暫時掛起,允許中斷嵌套,中斷嵌套層數(shù)可達255層

? 11.穩(wěn)定性和可靠性:μC/OS –II是基于μC/OS 的,μC/OS 自使用以來已經(jīng)被好幾百個商業(yè)應用

? ③μC/OS –II的內核

? 1.任務管理 2.時間管理 3.任務之間的通信與同步 4.內存管理 5.μC/OS的中斷處理 6.μC/OS –II的初始化 7.μC/OS –II的啟動

? ④μC/OS –II的內核結構:

? 1.臨界段 2.任務 3.任務狀態(tài) 4.任務控制塊 5.任務調度 6.空閑任務


? 練習題:簡答題:μC/OS –II通過哪些方法實現(xiàn)任務之間的通信與同步,并簡要說明。

? ①事件控制塊ECB:所有的通信信號都被看成是事件,μC/OS –II通過μC/OS –II.H中定義的一個被稱為事件控制塊的數(shù)據(jù)結構OS_EVENT來表征每一個具體的事件

? ②信號量:μC/OS –II系統(tǒng)中信號量由兩部分組成,信號量的計數(shù)值和等待該信號任務的等待任務表。信號量在多任務系統(tǒng)中用于控制共享資源的使用權,標志事件的發(fā)生,使兩個任務的行為同步

? ③郵箱:郵箱是μC/OS –II系統(tǒng)中另一種通信機制,他可以使一個任務或者中斷服務的子程序向另一個任務發(fā)送一個指針型的變量

? ④消息隊列:消息隊列也是μC/OS –II中的一種通信機制,它可以使一個任務或者中斷服務子程序向另一個任務發(fā)送以指針方式定義的變量


2.任務狀態(tài)

? (2017-2018 填空題) μC/OS –II的任務共有休眠、就緒、運行、中斷服務以及等待或掛起五個狀態(tài)


第 4 章 STM32-A平臺開發(fā)基礎(理論)

? 練習題:簡答題:USART、NVIC等常見名詞分別是指什么?

? ①UART是一種通用串行數(shù)據(jù)總線,用于異步通信,該總線雙向通信,可以實現(xiàn)全雙工傳輸和接收

? ②NVIC是內嵌向量中斷控制器,提供中斷控制器,用于總體管理異常


? 練習題:問答題:什么是看門狗,看門狗的作用是什么?

? ①為了檢測和解決由軟件錯誤引起的故障,嵌入式處理器通常具有一種叫做看門狗的模塊

? ②這種模塊一般是倒計數(shù)器,其作用是以一定的周期產(chǎn)生復位信號使系統(tǒng)復位,產(chǎn)生復位信號的時刻一般是倒計數(shù)到某個值(例如0)的時刻

? ③在設計嵌入式系統(tǒng)軟件時,通過在看門狗產(chǎn)生復位信號前執(zhí)行喂狗操作(即讓看門狗的倒計數(shù)值重新從某個設定的倒計數(shù)值開始)來避免看門狗倒計數(shù)到產(chǎn)生復位信號的值


第 4 章 STM32-A平臺開發(fā)基礎(實驗)

P105-P116
GPIO 8種模式:輸入浮空、輸入下、輸入上拉、模擬輸入、開漏輸出、推挽式輸出、推挽式復用功能、開漏復用功能;
3個最大輸出速度:2MHz、10MHz、50MHz

位帶操作
typedef unsigned long  u32;

#define RCC_APB2ENR ((u32 *)0x40021018)  //定義APB2ENR寄存器    地址
#define AFIO_MAPR   ((u32 *)0x40010004)  //定義APIO的MAPR寄存器

#define GPIOB_CRL (*(u32 *)0x40010C00)    //定義GPIOB_CRL寄存器  值
#define GPIOB_ODR (*(u32 *)0x40010C0C)    //定義GPIOB_ODR寄存器
#define GPIOE_CRH (*(u32 *)0x40011804)    //定義GPIOE_CRH寄存器
#define GPIOE_ODR (*(u32 *)0x4001180C)    //定義GPIOE_ODR寄存器
u32 *gpio_odr=((u32 *)0x4001180c);        //定義成地址變量
	
u32 *PEO8 = (u32 *)(0x42000000 +(0x4001180C-0x40000000)*32 + 8*4);  //位帶定義PE08
u32 *PEO9 = (u32 *)(0x42000000 +(0x4001180C-0x40000000)*32 + 9*4);  //位帶定義PE09

int delay(int Time)
{ //簡單延時程序
	unsigned short t,i,j;
	for(t=0;t<Time;t++)
		for(i=0;i<1000;i++)
			for(j=0;j<1000;j++)
				;
	return 0;
}


int  main(void)
{
	*RCC_APB2ENR|=1<<0;	//使能AFIO
	*RCC_APB2ENR|=1<<3; //使能PORTB時鐘
	*RCC_APB2ENR|=1<<6;	//使能PORTE時鐘

	*AFIO_MAPR |= 0x02000000; //設置PB.3為I/O口可用,且可以SW仿真

	GPIOB_CRL &= 0xFFFF0FFF; //清除PB.3原先配置
	GPIOB_CRL = GPIOB_CRL | 0x00003000; //PB.3配置為推挽輸出
	GPIOB_ODR |= 0x00000008; //PB.3輸出高,選擇控制LED燈
	
	GPIOE_CRH &=0X00000000;  //清除PE.8-15原先配置
	GPIOE_CRH |= 0X33333333; //PE.8-15配置為推挽輸出
	GPIOE_ODR |= 0x0000FF00; //PE.8-15輸出高,八個LED燈全亮

	delay(2);

	while(1)
	{
		GPIOE_ODR = 0x00000100; //僅LED1亮,其他燈滅
		delay(2);
		*PEO8 = 0;  //LED1滅
		delay(2);
		*PEO8 = 1;  //LED1亮
		delay(2);
		*PEO9 = 1;  //LED2亮
		delay(2);
		GPIOE_ODR = 0x00000400; //僅LED3亮,其他燈滅
		delay(2);
		GPIOE_ODR = 0x00000800; //僅LED4亮,其他燈滅
		delay(2);
		GPIOE_ODR = 0x00001000; //僅LED5亮,其他燈滅
		delay(2);
		GPIOE_ODR = 0x00002000; //僅LED6亮,其他燈滅
		delay(2);
		(*(u32 *)0x4001180C) = 0x00004000; //僅LED7亮,其他燈滅
		delay(2);
		*gpio_odr = 0x00008000; //僅LED8亮,其他燈滅
		delay(2);
	}
	//永遠不會執(zhí)行到這
	return 0;
}
寄存器版本

led.c

#include "stm32f10x_map.h"
#include "stm32f10x_nvic.h"
#include "led.h"

void LED_Init(void)
{
	RCC->APB2ENR|=1<<0;	//使能AFIO
	RCC->APB2ENR|=1<<3;  //使能PORTB時鐘
	RCC->APB2ENR|=1<<6;	//使能PORTE時鐘	 
	   	 
	AFIO->MAPR |= 0x02000000; //設置PB.3為I/O口可用,且可以SW仿真
	GPIOB->CRL &= 0xFFFF0FFF;
	GPIOB->CRL |= 0x00003000;  //PB.3推挽輸出
	GPIOB->ODR |= 0x00000008; //PB.3輸出高
												  
	GPIOE->CRH&=0X00000000;
	GPIOE->CRH|=0X33333333;  //PE.8-15推挽輸出
	GPIOE->ODR|=0x0000FF00; //PE.8-15輸出高 
	
}

led.h

#ifndef __LED_H
#define __LED_H
	 
#include "sys.h"

//LED驅動代碼			 


//LED端口定義
#define LED_SEL PBout(3) //PB3

//位選
#define SEL0 PBout(0)
#define SEL1 PBout(1)
#define SEL2 PBout(2)

//段選
#define LED0 PEout(8)
#define LED1 PEout(9)
#define LED2 PEout(10)
#define LED3 PEout(11)
#define LED4 PEout(12)
#define LED5 PEout(13)
#define LED6 PEout(14)
#define LED7 PEout(15)



void LED_Init(void);//初始化		 				    
#endif

main.c

/******************************流水燈************************
* 流水燈
* 現(xiàn)象:二極管從左至右依次全部點亮
*************************************************************/

#include "sys.h"
#include "delay.h"
#include "led.h"

u8 light;

int main( void )
{
	Stm32_Clock_Init( 6 );  //6倍頻
	delay_init( 72 ); //12M外部晶振
	LED_Init();
	GPIOE->ODR &= ~(0xff<<8);
	LED_SEL = 1; //選擇二極管	
	light = 0x01;
	while( 1 )
	{
		GPIOE->ODR |= (light<<8);
		delay_ms( 300 ); 
		light = light<<1;
		
		if( light==0x00 )
		{
			GPIOE->ODR &= ~(0xff<<8);
			delay_ms( 300 ); 
			light = 0x01;
		}					
	}
}

2.中斷基本概念與中斷程序設計

P116-P128

按鍵

通常的按鍵所用開關為機械彈性開關,當機械觸點斷開、閉合時,電壓信號波型如下圖。由于機械觸點的彈性作用,一個按鍵開關在閉合時不會馬上穩(wěn)定地接通,在斷開時也不會一下子斷開。因而在閉合及斷開的瞬間均伴隨有一連串的抖動,如下圖。抖動時間的長短由按鍵的機械特性決定,一般為5ms~10ms。這是一個很重要的時間參數(shù),在很多場合都要用到。按鍵穩(wěn)定閉合時間的長短則是由操作人員的按鍵動作決定的,一般為零點幾秒至數(shù)秒。鍵抖動會引起一次按鍵被誤讀多次。為確保CPU對鍵的一次閉合僅作一次處理,必須去除鍵抖動。在鍵閉合穩(wěn)定時讀取鍵的狀態(tài),并且必須判別到鍵釋放穩(wěn)定后再作處理。

key.c

#include "key.h"
#include "delay.h"
//按鍵輸入 驅動代碼		   
//PC0.1.2 設置成輸入
void KEY_Init(void)
{
	RCC->APB2ENR|=1<<4;     //使能PORTC時鐘
	GPIOC->CRL&=0XFFFFF000; //PC0-2設置成輸入	  
	GPIOC->CRL|=0X00000444; //用上拉輸入或者浮空輸入都可以,模擬輸入不行。
	//GPIOC->ODR|=0x7;        //上拉輸入//ODR復位值為0,缺省為下拉輸入。
} 
//按鍵處理函數(shù)
//返回按鍵值
//0,沒有任何按鍵按下
//1,KEY1按下
//2,KEY2按下
//3,KEY3按下
//注意此函數(shù)有響應優(yōu)先級,KEY1>KEY2>KEY3!!
u8 KEY_Scan(void)
{	 
	static u8 key_up=1;//按鍵按松開標志
	
	if(key_up && (KEY1==0 || KEY2==0 || KEY3==0))
	{
		delay_ms(10);//去抖動 
		key_up=0;
		if(KEY1==0)
		{
			return 1;
		}
		else if(KEY2==0)
		{
			return 2;
		}
		else if(KEY3==0)
		{
			return 3;
		}
	}
	else if(KEY1==1 && KEY2==1 && KEY3==1)
		key_up=1;
	
	return 0;// 無按鍵按下
}

key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"
//	 
//按鍵輸入 驅動代碼		   
//********************************************************************************
//V1.1修改說明
//修改按鍵掃描函數(shù),使整個代碼可以支持SWD下載。
//	 


#define KEY1 PCin(2)   //PC2
#define KEY2 PCin(1)	//PC1 
#define KEY3 PCin(0)	//PC0
	 
void KEY_Init(void);//IO初始化
u8 KEY_Scan(void);  //按鍵掃描函數(shù)					    
#endif

main.c

#include "sys.h"
#include "delay.h"	
#include "led.h" 
#include "key.h"	 	 
//按鍵輸入實驗
int main(void)
{								  
	u8 t;	  
	Stm32_Clock_Init(9); //系統(tǒng)時鐘設置
	delay_init(72);	     //延時初始化 
	LED_Init();		  	 //初始化與LED連接的硬件接口
	KEY_Init();          //初始化與按鍵連接的硬件接口
	while(1)
	{
		t=KEY_Scan();//得到鍵值
	   	if(t)
		{						   
			switch(t)
			{				 
				case 1:
					LED0=!LED0;
					break;
				case 2:
					LED3=!LED3;
					break;
				case 3:				
					LED7=!LED7;
					break;
			}
		}else delay_ms(10); 
	}	 
}
中斷

exit.c

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
//	 
//外部中斷 驅動代碼			   
// 	  

//外部中斷0服務程序
void EXTI0_IRQHandler(void)
{
	delay_ms(10);//消抖
	if(KEY3==0)	 //按鍵3
	{
		LED7=!LED7;
	}		 
	EXTI->PR=1<<0;  //清除LINE0上的中斷標志位  
}

//外部中斷1服務程序
void EXTI1_IRQHandler(void)
{
	delay_ms(10);//消抖
	if(KEY2==0)	 //按鍵2
	{
		LED3=!LED3;
	}		 
	EXTI->PR=1<<1;  //清除LINE1上的中斷標志位  
}

//外部中斷2服務程序
void EXTI2_IRQHandler(void)
{
	delay_ms(10);//消抖
	if(KEY1==0)	 //按鍵1
	{
		LED0=!LED0;
	}		 
	EXTI->PR=1<<2;  //清除LINE2上的中斷標志位  
}

//外部中斷初始化程序
//初始化PC0-2為中斷輸入.
void EXTIX_Init(void)
{
	RCC->APB2ENR|=1<<4;     //使能PORTC時鐘
	GPIOC->CRL&=0XFFFFF000;//PC0-2設置成輸入	  
	GPIOC->CRL|=0X00000888;
	
	Ex_NVIC_Config(GPIO_C,0,FTIR);//下降沿觸發(fā)
	Ex_NVIC_Config(GPIO_C,1,FTIR);//下降沿觸發(fā)
	Ex_NVIC_Config(GPIO_C,2,FTIR);//下降沿觸發(fā)

	MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);//搶占2,子優(yōu)先級2,組2
	MY_NVIC_Init(2,1,EXTI1_IRQChannel,2);//搶占2,子優(yōu)先級1,組2	   
	MY_NVIC_Init(2,0,EXTI2_IRQChannel,2);//搶占2,子優(yōu)先級1,組2
}

main.c

#include "sys.h"
#include "delay.h"	
#include "led.h" 
#include "key.h"
#include "exti.h"	 	 

//外部中斷實驗

//注意,此代碼還是無法進行SWD仿真!因為使用了中斷,沒法用普通的方法來考慮間歇復用SWD口! 
int main(void)
{			
 	Stm32_Clock_Init(9); //系統(tǒng)時鐘設置
	delay_init(72);	     //延時初始化
	LED_Init();	         //初始化與LED連接的硬件接口
	EXTIX_Init();	       //外部中斷初始化
	while(1)
	{	    
		delay_ms(100);	  
	}	 
}

3.串口通信原理與程序設計

P128-P135

#include "sys.h"
#include "usart.h"
//	 
//本程序只供學習使用,未經(jīng)作者許可,不得用于其它任何用途
//********************************************************************************
//V1.3 
//支持適應不同頻率下的串口波特率設置.
//加入了對printf的支持
//增加了串口接收命令功能.
//修正了printf第一個字符丟失的bug
// 	  

//
//加入以下代碼,支持printf函數(shù),而不需要選擇use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//標準庫需要的支持函數(shù)                 
struct __FILE 
{ 
	int handle; 
	/* Whatever you require here. If the only file you are using is */ 
	/* standard output using printf() for debugging, no file handling */ 
	/* is required. */ 
}; 
/* FILE is typedef’ d in stdio.h. */ 
FILE __stdout;       
//定義_sys_exit()以避免使用半主機模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定義fputc函數(shù) 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢   
	USART1->DR = (u8) ch;      
	return ch;
}
#endif 
//end
//

#ifdef EN_USART1_RX   //如果使能了接收
//串口1中斷服務程序
//注意,讀取USARTx->SR能避免莫名其妙的錯誤   	
u8 USART_RX_BUF[64];     //接收緩沖,最大64個字節(jié).
//接收狀態(tài)
//bit7,接收完成標志
//bit6,接收到0x0d
//bit5~0,接收到的有效字節(jié)數(shù)目
u8 USART_RX_STA=0;       //接收狀態(tài)標記	  
  
void USART1_IRQHandler(void)
{
	u8 res;	    
	if(USART1->SR&(1<<5))//接收到數(shù)據(jù)
	{	 
		res=USART1->DR; 
		if((USART_RX_STA&0x80)==0)//接收未完成
		{
			if(USART_RX_STA&0x40)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收錯誤,重新開始
				else USART_RX_STA|=0x80;	//接收完成了 
			}else //還沒收到0X0D
			{	
				if(res==0x0d)USART_RX_STA|=0x40;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3F]=res;
					USART_RX_STA++;
					if(USART_RX_STA>63)USART_RX_STA=0;//接收數(shù)據(jù)錯誤,重新開始接收	  
				}		 
			}
		}  		 									     
	}  											 
} 
#endif										 
//初始化IO 串口1
//pclk2:PCLK2時鐘頻率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{  	 
	float temp;
	u16 mantissa;
	u16 fraction;	   
	temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
	mantissa=temp;				 //得到整數(shù)部分
	fraction=(temp-mantissa)*16; //得到小數(shù)部分	 
    mantissa<<=4;
	mantissa+=fraction; 
	RCC->APB2ENR|=1<<2;   //使能PORTA口時鐘  
	RCC->APB2ENR|=1<<14;  //使能串口時鐘 
	GPIOA->CRH&=0XFFFFF00F; 
	GPIOA->CRH|=0X000008B0;//IO狀態(tài)設置
		  
	RCC->APB2RSTR|=1<<14;   //復位串口1
	RCC->APB2RSTR&=~(1<<14);//停止復位	   	   
	//波特率設置
 	USART1->BRR=mantissa; // 波特率設置	 
	USART1->CR1|=0X200C;  //1位停止,無校驗位.
#ifdef EN_USART1_RX		  //如果使能了接收
	//使能接收中斷
	USART1->CR1|=1<<8;    //PE中斷使能
	USART1->CR1|=1<<5;    //接收緩沖區(qū)非空中斷使能	    	
	MY_NVIC_Init(3,3,USART1_IRQChannel,2);//組2,最低優(yōu)先級 
#endif
}

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"

int main( void )
{
	/*u8 i = 1;
	Stm32_Clock_Init( 6 );  //9倍頻
	delay_init( 72 ); //12M外部晶振
	uart_init( 72, 9600 );
	while( 1 )
	{
		//printf( "i = %d\r\n", i );
		i++;
		delay_ms( 500 );
	}
	*/
	u8 t;
	u8 len;	
	u16 times=0;  
	Stm32_Clock_Init(6); //系統(tǒng)時鐘設置
	delay_init(72);	     //延時初始化 
	uart_init(72,9600);	 //串口初始化為9600
	LED_Init();		  	 //初始化與LED連接的硬件接口    
	while(1)
	{
		if(USART_RX_STA&0x80)
		{					   
			len=USART_RX_STA&0x3f;//得到此次接收到的數(shù)據(jù)長度
			printf("\n Your MSG: \n");
			for(t=0;t<len;t++)
			{
				USART1->DR=USART_RX_BUF[t];
				while((USART1->SR&0X40)==0);//等待發(fā)送結束
			}
			printf("\n\n");//插入換行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\nSTM32A Usart\n");
			}
			if(times%200==0) printf("Please Input end with return\n");  
			if(times%30==0) LED0=!LED0;//閃爍LED,提示系統(tǒng)正在運行.
			delay_ms(10);   
		}
	}	
}

4.模數(shù)轉換原理與程序設計

P139-P149

adc.c

/******************************************************
* 雙ADC通道測電壓值
* 測量電壓應<3.3  PA0或PA1接正極,負極接地
* PA0測量的電壓顯示與左邊,PA1測量的電壓值顯示與右邊

******************************溫度與光照測量************************
* 溫度與光照
* 溫度顯示與左邊,光照顯示在右邊
***********************************END******************************
作者:寧曉蘭
******************************************************************/
#include "adc.h"
#include "math.h"

/****************初始化函數(shù)********************
* 初始化
* IO口初始化、ADC1初始化、ADC2初始化
******************************************************/
void VoltageAdcInit(void)
{
	//初始化IO口
	RCC->APB2ENR |= 1<<2;     //使能PORTA口時鐘
	GPIOA->CRL &= 0xffffff00; //PA0 1  模擬輸入
	
	RCC->CFGR &= ~(3<<14);    //分頻因子清零
	RCC->CFGR |= 2<<14;       //6分頻  SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC1最大時鐘不能超過14M!
	
	VoltageAdc1Init();
	VoltageAdc2Init();
}

/****************初始化函數(shù)********************
* ADC1初始化
******************************************************/
void VoltageAdc1Init(void)
{
	RCC->APB2ENR |= 1<<9;      //ADC1時鐘使能
	RCC->APB2RSTR |= 1<<9;     //ADC1復位
	RCC->APB2RSTR &= ~(1<<9);  //復位結束
	
	ADC1->CR1 &= 0xf0ffff;     //工作模式清零
	ADC1->CR1 |= 0<<16;        //獨立工作模式
	ADC1->CR1 &= ~(1<<8);      //非掃描模式
	ADC1->CR2 &= ~(1<<1);      //單次轉換模式
	ADC1->CR2 &= ~(7<<17); 
	ADC1->CR2 |= 7<<17;        //SWSTART:軟件控制轉換
	ADC1->CR2 |= 1<<20;        //使用外部觸發(fā)(SWSTART),必須使用一個事件來觸發(fā)
	ADC1->CR2 &= ~(1<<11);     //右對齊
	ADC1->SQR1 &= ~(0xf<<20);
	ADC1->SQR1 &= 0<<20;       //1個轉換在規(guī)則序列中,也就是只轉換規(guī)則序列1
	
	ADC1->SMPR2 &= 0xfffffff0; //通道0采樣時間清空
	ADC1->SMPR2 |= 7<<0;       //通道0 239.5周期,提高采用時間可以提高精確度
	
	ADC1->CR2 |= 1<<0;         //開啟AD轉換器
	ADC1->CR2 |= 1<<3;         //使能復位校準
	while( ADC1->CR2 & 1<<3 )
		;                        //等待校準結束
	ADC1->CR2 |= 1<<2;         //開啟AD校準
	while( ADC1->CR2 & 1<<2 )
		;                        //等待校準結束
}

/****************初始化函數(shù)********************
* ADC2初始化
******************************************************/
void VoltageAdc2Init(void)
{
	RCC->APB2ENR |= 1<<10;     //ADC1時鐘使能
	RCC->APB2RSTR |= 1<<10;    //ADC1復位
	RCC->APB2RSTR &= ~(1<<10); //復位結?
	
	ADC2->CR1 &= 0xf0ffff;     //工作模式清零
	ADC2->CR1 |= 0<<16;        //獨立工作模式
	ADC2->CR1 &= ~(1<<8);      //非掃描模式
	ADC2->CR2 &= ~(1<<1);      //單次轉換模式
	ADC2->CR2 &= ~(7<<17); 
	ADC2->CR2 |= 7<<17;        //SWSTART:軟件控制轉換
	ADC2->CR2 |= 1<<20;        //使用外部觸發(fā)(SWSTART),必須使用一個事件來觸發(fā)
	ADC2->CR2 &= ~(1<<11);     //右對齊
	ADC2->SQR1 &= ~(0xf<<20);
	ADC2->SQR1 &= 0<<20;       //1個轉換在規(guī)則序列中,也就是只轉換規(guī)則序列1
	
	ADC2->SMPR2 &= ~(7<<3);    //通道1采樣時間清空
	ADC2->SMPR2 |= 7<<3;       //通道1 239.5周期,提高采用時間可以提高精確度
	
	ADC2->CR2 |= 1<<0;         //開啟AD轉換器
	ADC2->CR2 |= 1<<3;         //使能復位校準
	while( ADC2->CR2 & 1<<3 )
		;                        //等待校準結束
	ADC2->CR2 |= 1<<2;         //開啟AD校準
	while( ADC2->CR2 & 1<<2 )
		;                        //等待校準結束
}

/****************獲取ADC值函數(shù)********************
* 獲取ADC的值,測量的電壓應<3.3  PA0或PA1接正極,負極接地
* adcx: 1表示ADC1; 2表示ADC2
* ch: 通道值
* 返回得到的ADC的值
******************************************************/
u16 GetAdc(u8 adcx, u8 ch)
{
	u16 adcValue = 0;
	if( adcx==1 )
	{
		//設置轉換序列
		ADC1->SQR3 &= 0xffffffe0; //規(guī)則序列1 通道ch
		ADC1->SQR3 |= ch;
		ADC1->CR2 |= 1<<22;       //啟動規(guī)則轉換通道
		while( !(ADC1->SR & 1<<1) )
			;                       //等待轉換結束
		adcValue = ADC1->DR;
	}
	else if( adcx==2 )
	{
		//設置轉換序列
		ADC2->SQR3 &= 0xffffffe0; //規(guī)則序列1 通道ch
		ADC2->SQR3 |= ch;
		ADC2->CR2 |= 1<<22;       //啟動規(guī)則轉換通道
		while( !(ADC2->SR & 1<<1) )
			;                       //等待轉換結束
		adcValue = ADC2->DR;
	}
	return adcValue;            //返回ADC的值
}

/****************獲取電壓值函數(shù)********************
* ADC轉化為電壓值
* adcx: 1表示ADC1; 2表示ADC2
* ch: 通道值
* 返回電壓值
******************************************************/
float GetVoltage(u8 adcx, u8 ch)
{
	u16 adcValue = 0;
	float vol = 0;
	adcValue = GetAdc( adcx, ch );
	vol = 3.3*(float)adcValue/4096;
	return vol;
}

/****************顯示對應端口的電壓值函數(shù)********************
* 顯示,占三位
* adcx: 1表示ADC1; 2表示ADC2
* vol: 電壓值
* PA0測量的電壓顯示與左邊,PA1測量的電壓值顯示與右邊
******************************************************/
void VoltageDisplay(u8 adcx, float vol)
{
	u8 baiWei, shiWei, geWei;

  baiWei = (u8)vol % 10;
	shiWei = (u8)(vol*10)%10;
	geWei = (u8)(vol*100)%10;
	if( adcx==1 )
	{
		PortationDisplay(0, baiWei);
		delay_ms(1);
		SetLed(1, shiWei);
		delay_ms(1);
		SetLed(2, geWei);
		delay_ms(1);
	}
	else if( adcx==2 )
	{
		PortationDisplay(5, baiWei);
		delay_ms(1);
		SetLed(6, shiWei);
		delay_ms(1);
		SetLed(7, geWei);
		delay_ms(1);
  }
}

/***************溫度和光照ADC的初始化函數(shù)********************
* 初始化ADC1,通道14 15
******************************************************/
void TemperatureAndLightAdcInit(void)
{
	//初始化IO口
	RCC->APB2ENR |= 1<<4;      //使能PORTC口時鐘
	GPIOA->CRL &= 0xff00ffff;  //PC4 5  模擬輸入
	
	RCC->CFGR &= ~(3<<14);     //分頻因子清零
	RCC->CFGR |= 2<<14;        //6分頻  SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC1最大時鐘不能超過14M!
	
	RCC->APB2ENR |= 1<<9;      //ADC1時鐘使能
	RCC->APB2RSTR |= 1<<9;     //ADC1復位
	RCC->APB2RSTR &= ~(1<<9);  //復位結束
	
	ADC1->CR1 &= 0xf0ffff;     //工作模式清零
	ADC1->CR1 |= 0<<16;        //獨立工作模式
	ADC1->CR1 &= ~(1<<8);      //非掃描模式
	ADC1->CR2 &= ~(1<<1);      //單次轉換模式
	ADC1->CR2 &= ~(7<<17); 
	ADC1->CR2 |= 7<<17;        //SWSTART:軟件控制轉換
	ADC1->CR2 |= 1<<20;        //使用外部觸發(fā)(SWSTART),必須使用一個事件來觸發(fā)
	ADC1->CR2 &= ~(1<<11);     //右對齊
	ADC1->SQR1 &= ~(0xf<<20);
	ADC1->SQR1 &= 0<<20;       //1個轉換在規(guī)則序列中,也就是只轉換規(guī)則序列1
	
	ADC1->SMPR1 &= 0xfffc0fff; //通道14,15采樣時間清空
	ADC1->SMPR1 |= 7<<12;      //通道14 239.5周期,提高采用時間可以提高精確度
	ADC1->SMPR1 |= 7<<15;      //通道15 239.5周期,提高采用時間可以提高精確度
	
	ADC1->CR2 |= 1<<0;         //開啟AD轉換器
	ADC1->CR2 |= 1<<3;         //使能復位校準
	while( ADC1->CR2 & 1<<3 )
		;                        //等待校準結束
	ADC1->CR2 |= 1<<2;         //開啟AD校準
	while( ADC1->CR2 & 1<<2 )
		;                        //等待校準結束
}

/***************獲取溫度的ADC的值函數(shù)********************
* 獲取ADC1的ADC值
* ch為通道值
* 返回ADC1的ADC值
******************************************************/
u16 GetTemperatureAdc(u8 ch)
{
	u16 adcValue = 0;
	adcValue = GetAdc( 1,ch );
	return adcValue;
}

/***************ADC值轉換成溫度值函數(shù)********************
* 通過ADC值計算溫度值
* 返回溫度值
******************************************************/
float GetTemperature( void )
{
	u16 temperatureAdc = 0;
	float temperature = 0.0;
 	temperatureAdc = GetTemperatureAdc( 15 );       //通道15注入的AD值
	temperature = (float)temperatureAdc*(3.3/4096); //當前溫度電壓值
	temperature = temperature *10000/(3.3-temperature)/1000; //溫度電阻阻值
	temperature = (float)1.0/( (float)log(temperature*1000/10000)/3950 + 1.0/(273.16+25) ) - 273.16; //計算溫度
	
	return temperature;
}

/***************光照強度的ADC值函數(shù)********************
* 光照強度的ADC值
* ch為通道值
* 返回光照的ADC值
******************************************************/
u16 GetLightAdc(u8 ch)
{
	u16 adcValue = 0;
	adcValue = GetAdc(1, ch);
	return adcValue;
}

adc.h

/******************************ADC頭文件************************
* 作者:寧曉蘭
******************************************************************/

#ifndef _ADC_H
#define _ADC_H

#include "sys.h"
#include "led.h"
#include "delay.h"

#define PA0 PAin(0)
#define PA1 PAin(1)

#define V_Ro PCin(4) //測光
#define V_Rt PCin(5) //測溫


void VoltageAdcInit(void); //端口初始化,ADC1初始化,ADC2初始化
void VoltageAdc1Init(void); //電壓測量ADC1初始化
void VoltageAdc2Init(void); //電壓測量ADC2初始化
float GetVoltage(u8 adcx, u8 ch); //獲取電壓值
void VoltageDisplay(u8 adcx, float vol); //顯示電壓值

u16 GetAdc(u8 adcx, u8 ch); //獲取ADC

void UltrasonicAdcInit(void);//超聲波測量ADC初始化
u16 GetUltrasonicAdc(u8 ch); 

/******************溫度和光照***********************/
void TemperatureAndLightAdcInit(void); //端口,ADC1初始化,通道14、15
u16 GetTemperatureAdc(u8 ch);
float GetTemperature(void);
u16 GetLightAdc(u8 ch);

#endif


/******************************溫度與光照測量************************
* 溫度與光照
* 溫度顯示與左邊,光照顯示在右邊
******************************************************************/

#include "sys.h"
#include "led.h"
#include "delay.h"
#include "adc.h"

/***************************主函數(shù)*****************************/
int main()
{
 	float adcx = 0.0;
	u16 adcValue = 0;
	u8 i = 0;
	Stm32_Clock_Init( 6 ); 
	delay_init( 72 );
	TemperatureAndLightAdcInit();
	LED_Init();
	LED_SEL = 0;
	adcx = GetTemperature();        //使用PC5 ADC1, 通道15
			adcValue = GetLightAdc(14); //使用PC4 ADC1, 通道14
	while(1)
	{		
		i++;
		if( i > 50 )                  //大約每隔100個循環(huán)周期重新掃描一次ADC的值
		{
			adcx = GetTemperature();    //使用PC5 ADC1, 通道15
			adcValue = GetLightAdc(14); //使用PC4 ADC1, 通道14
			i = 0;
		}
		//溫度
		SetLed(0, adcx/10);
		delay_ms(1);
		PortationDisplay(1,(u8)adcx%10);
		delay_ms(1);
		SetLed(2, (u8)(adcx*10)%10);
		delay_ms(1);
		
		//光照
		SetLed(4, adcValue/1000);
		delay_ms(1);
		SetLed(5, adcValue%1000/100);
		delay_ms(1);
		SetLed(6, adcValue%100/10);
		delay_ms(1);
		SetLed(7, adcValue%10);
		delay_ms(1);
	}	
}


main.c

/******************************溫度與光照測量************************
* 溫度與光照
* 溫度顯示與左邊,光照顯示在右邊
******************************************************************/

#include "sys.h"
#include "led.h"
#include "delay.h"
#include "adc.h"

/***************************主函數(shù)*****************************/
int main()
{
 	float adcx = 0.0;
	u16 adcValue = 0;
	u8 i = 0;
	Stm32_Clock_Init( 6 ); 
	delay_init( 72 );
	TemperatureAndLightAdcInit();
	LED_Init();
	LED_SEL = 0;
	adcx = GetTemperature();        //使用PC5 ADC1, 通道15
			adcValue = GetLightAdc(14); //使用PC4 ADC1, 通道14
	while(1)
	{		
		i++;
		if( i > 50 )                  //大約每隔100個循環(huán)周期重新掃描一次ADC的值
		{
			adcx = GetTemperature();    //使用PC5 ADC1, 通道15
			adcValue = GetLightAdc(14); //使用PC4 ADC1, 通道14
			i = 0;
		}
		//溫度
		SetLed(0, adcx/10);
		delay_ms(1);
		PortationDisplay(1,(u8)adcx%10);
		delay_ms(1);
		SetLed(2, (u8)(adcx*10)%10);
		delay_ms(1);
		
		//光照
		SetLed(4, adcValue/1000);
		delay_ms(1);
		SetLed(5, adcValue%1000/100);
		delay_ms(1);
		SetLed(6, adcValue%100/10);
		delay_ms(1);
		SetLed(7, adcValue%10);
		delay_ms(1);
	}	
}

5.定時器與看門狗原理與程序設計

P154-P167

timer.c

/****************定時器實現(xiàn)********************
* 
* 作者:寧曉蘭
***************************************************/

#include "timer.h"

//數(shù)字鐘的時,分、秒
u8 hour = 0, minute = 0, second = 0;

/****************普通按鍵初始化函數(shù)********************
* 通用定時器中斷初始化
* 這里時鐘選擇為APB1的2倍,而APB1為36M
* arr:自動重裝值。
* psc:時鐘預分頻數(shù)
* 這里使用的是定時器3!
******************************************************/
void TimerxInit(u16 arr, u16 psc)
{
	RCC->APB1ENR |= 1<<1; //TIM3時鐘使能
	TIM3->ARR = arr;      //設定計數(shù)器自動重裝值,10為1ms
	TIM3->PSC = psc;      //預分頻器7200,得到10KHZ的計數(shù)時鐘
	
	TIM3->DIER |= 1<<0;   //允許更新中斷
	TIM3->CR1 |= 0x01;    //使能定時器3
	
	MY_NVIC_Init(1, 3, TIM3_IRQChannel, 2); //搶占1,子優(yōu)先級3,組2
}

/****************定時器3的中斷函數(shù)********************
* 定時器3的中斷函數(shù)
* 每次中斷,second加一
******************************************************/

void TIM3_IRQHandler( void )
{
	if( TIM3->SR & 0x0001) //溢出中斷
	{
		second++;
		if( second>59 )
		{
			second = 0;
			minute++;
			if( minute>59 )
			{
				minute = 0;
				hour++;
				if( hour>23 )
					hour = 0;
			}
		}
	}
	TIM3->SR &= ~(1<<0); //清除中斷標志位
}

/*****************************************************
* 數(shù)字鐘顯示函數(shù)
******************************************************/
void DisplayDigitalClock(void)
{
	SetLed(0, hour/10);  //顯示 時
	delay_ms(1);
	SetLed(1, hour%10);
	delay_ms(1);
	SetLed(2, 10);        //顯示"-"符號
	delay_ms(1);
	SetLed(3, minute/10); //顯示 分
	delay_ms(1);
	SetLed(4, minute%10);
	delay_ms(1);
	SetLed(5, 10);        //顯示"-"符號
	delay_ms(1);
	SetLed(6, second/10); //顯示 秒
	delay_ms(1);
	SetLed(7, second%10);
	delay_ms(1);
}

獨立看門狗

wdg.c

#include "wdg.h"
//	 
//看門狗 驅動代碼		   
// 	  
  	 

//初始化獨立看門狗
//prer:分頻數(shù):0~7(只有低3位有效!)
//分頻因子=4*2^prer.但最大值只能是256!
//rlr:重裝載寄存器值:低11位有效.
//時間計算(大概):Tout=((4*2^prer)*rlr)/40 (ms).
void IWDG_Init(u8 prer,u16 rlr) 
{
	IWDG->KR=0X5555;//使能對IWDG->PR和IWDG->RLR的寫		 										  
  IWDG->PR=prer;  //設置分頻系數(shù)   
  IWDG->RLR=rlr;  //從加載寄存器 IWDG->RLR  
	IWDG->KR=0XAAAA;//reload											   
  IWDG->KR=0XCCCC;//使能看門狗	
}
//喂獨立看門狗
void IWDG_Feed(void)
{
	IWDG->KR=0XAAAA;//reload											   
}

main.c

#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h" 
#include "key.h"
//#include "exti.h"
#include "wdg.h"	 	 
//獨立看門狗實驗
int main(void)
{			
 	Stm32_Clock_Init(9); //系統(tǒng)時鐘設置
	delay_init(72);	     //延時初始化
	uart_init(72,9600);  //串口初始化 
	LED_Init();		  	   //初始化與LED連接的硬件接口
	KeyInit();           //按鍵初始化	 
	delay_ms(300);   	   //讓人看得到滅
	IWDG_Init(4,625);    //與分頻數(shù)為64,重載值為625,溢出時間為1s	   
	LED0=1;				       //點亮LED0
	LED3=1;
	while(1)
	{
		if(KeyScan()==1) IWDG_Feed();//如果K1按下,則喂狗
		delay_ms(10);
	}	 
}

窗口看門狗

main.c

#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h"   
#include "wdg.h" 
//窗口看門狗實驗   

int main(void)
{			
  	Stm32_Clock_Init(9); //系統(tǒng)時鐘設置
	delay_init(72);	     //延時初始化
	uart_init(72,9600);  //串口初始化 
	LED_Init();		  	 //初始化與LED連接的硬件接口
	LED0=0;
	delay_ms(300);	  
	WWDG_Init(0X7F,0X5F,3);//計數(shù)器值為7f,窗口寄存器為5f,分頻數(shù)為8	   
 	while(1)
	{
		LED0=1;			  	   
	}
}

wdg.c文章來源地址http://www.zghlxwxcb.cn/news/detail-450316.html

#include "wdg.h"
#include "led.h"
//看門狗 驅動代碼		   

//保存WWDG計數(shù)器的設置值,默認為最大. 
u8 WWDG_CNT=0x7f; 
//初始化窗口看門狗 	
//tr   :T[6:0],計數(shù)器值 
//wr   :W[6:0],窗口值 
//fprer:分頻系數(shù)(WDGTB),僅最低2位有效 
//Fwwdg=PCLK1/(4096*2^fprer). 
void WWDG_Init(u8 tr,u8 wr,u8 fprer) 
{    
	RCC->APB1ENR|=1<<11; 	//使能wwdg時鐘 
	WWDG_CNT=tr&WWDG_CNT;   //初始化WWDG_CNT.     
	WWDG->CFR|=fprer<<7;    //PCLK1/4096再除2^fprer 
	WWDG->CFR&=0XFF80;      
	WWDG->CFR|=wr;     		//設定窗口值      
	WWDG->CR|=WWDG_CNT; 	//設定計數(shù)器值 
	WWDG->CR|=1<<7;  		//開啟看門狗      
	MY_NVIC_Init(2,3,WWDG_IRQn,2);//搶占2,子優(yōu)先級3,組2     
	WWDG->SR=0X00; 			//清除提前喚醒中斷標志位 
	WWDG->CFR|=1<<9;        //使能提前喚醒中斷 
} 
//重設置WWDG計數(shù)器的值 
void WWDG_Set_Counter(u8 cnt) 
{ 
	WWDG->CR =(cnt&0x7F);//重設置7位計數(shù)器 
} 
//窗口看門狗中斷服務程序 
void WWDG_IRQHandler(void) 
{      
	WWDG_Set_Counter(WWDG_CNT);//重設窗口看門狗的值!         
	WWDG->SR=0X00;//清除提前喚醒中斷標志位 
	LED1=!LED1; 
}

到了這里,關于2021-2022(2)嵌入式系統(tǒng)期末復習提綱 (習題版)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 嵌入式期末復習題(一)選擇題

    1.ARM Cortex-M3不可以通過( D??)喚醒CPU。 A.I/O端口 ???B.RTC 鬧鐘 ???C.USB喚醒事件 D.PLL 2 . ? STM32F103 微控制器是基于( ? A ??)內核的 32 位微處理器。 A.Cortex-M3 ? B. Cortex-M4 ? C. Cortex-M6 ?D . Cortex-M8 3 .下面 哪種開發(fā)方式不適合STM32F103系列微處理器的開發(fā)?(?

    2024年02月03日
    瀏覽(21)
  • 嵌入式原理與應用期末復習匯總(附某高校期末真題試卷)

    嵌入式原理與應用期末復習匯總(附某高校期末真題試卷)

    1、為保證在啟動服務器時自動啟動DHCP進程,應對( B )文件進行編輯。 A、 /etc/rc.d/rc.inet2 B、/etc/rc.d/rc.inet1 C、/etc/dhcpd.conf D、/etc/rc.d/rc.S 2、文件exer1的訪問權限為rw-r–r–,現(xiàn)要增加所有用戶的執(zhí)行權限和同組用戶的寫權限,下列命令正確的是( A )。 A 、chmod a+x g+w exer1

    2024年02月08日
    瀏覽(26)
  • 嵌入式學習stm32基礎知識(期末復習)

    嵌入式學習stm32基礎知識(期末復習)

    1. 計算機的體系架構 馮諾依曼架構 ? 在完整的計算機系統(tǒng)中,包含五個部分,儲存器,運算器,控制器輸入設備和輸出設備。 改進的馮諾依曼架構 改進型架構的各模塊的高速數(shù)據(jù)交換中心利用儲存器這個大容量,極大的提高了效率。 哈佛架構 ? 哈佛結構數(shù)據(jù)空間和地址

    2024年02月07日
    瀏覽(72)
  • 嵌入式系統(tǒng)復習要點

    嵌入式系統(tǒng)復習要點

    目錄 1、嵌入式系統(tǒng)的核心部分主要由硬件和軟件兩部分組成: 2、嵌入式系統(tǒng)硬件: 3、嵌入式處理器從體系上分類,可以分為馮·諾依曼結構和哈佛結構兩種: 4、幾類常見的嵌入式處理器類型: 5、MCU組成結構: 7、DSP組成結構: 8、SoC組成結構: 9、MPU組成結構: 10、嵌入

    2024年02月12日
    瀏覽(24)
  • 西郵嵌入式系統(tǒng)復習

    西郵嵌入式系統(tǒng)復習

    可以私聊我獲取pdf版本! 提示:這里可以添加本文要記錄的大概內容: 期末復習知識點總結 第一次整理 提示:以下是本篇文章正文內容,下面案例可供參考 1.1.0 嵌入式系統(tǒng)發(fā)展 (選擇 4個階段) 無操作系統(tǒng)的單片機階段–以微控制器為基礎、以簡單操 作系統(tǒng)為核心的嵌入

    2024年02月15日
    瀏覽(25)
  • 【嵌入式系統(tǒng)】課程復習資料整理

    【嵌入式系統(tǒng)】課程復習資料整理

    【嵌入式系統(tǒng)】課程復習資料整理 一、緒論 1.定義 從技術的角度定義:以應用為中心、以計算機技術為基礎、軟件硬件可裁剪、對功能、可靠性、成本、體積、功耗嚴格要求的專用計算機系統(tǒng)。 從系統(tǒng)的角度定義:嵌入式系統(tǒng)是設計完成復雜功能的硬件和軟件,并使其緊密

    2024年02月03日
    瀏覽(23)
  • 2022嵌入式芯片與系統(tǒng)設計競賽

    2022嵌入式芯片與系統(tǒng)設計競賽

    2022嵌入式芯片與系統(tǒng)設計競賽 這是我們第一次參加相關的學科競賽,基本上算是摸著石頭過河,盡管有老師和同學的幫助但是還是走了不少的彎路。我們屬于中部賽區(qū),選的是芯片應用賽道,使用的是赤菟CH32V307開發(fā)板。 我們的項目是:基于(CH32V307VCT6)的智能配送小車 該

    2023年04月09日
    瀏覽(25)
  • 嵌入式系統(tǒng)設計師考試筆記之操作系統(tǒng)基礎復習筆記二

    嵌入式系統(tǒng)設計師考試筆記之操作系統(tǒng)基礎復習筆記二

    目錄 3、任務管理 (1)嵌入式操作系統(tǒng)的任務管理可以分為 (2)進程 (3)線程 (4)任務 (5)任務的創(chuàng)建與中止 (6)任務的狀態(tài)任務有三中基本狀態(tài): (7)任務控制塊 TCB (8)任務的切換 (9)任務的調度 (10)實時系統(tǒng)調度 (11)任務互斥 (12)信號量 (13)任務同

    2024年02月08日
    瀏覽(91)
  • 南郵-嵌入式復習附錄/習題

    附錄1-6 內容可能有誤,歡迎大家指正。 (1)ARM匯編程序由 機器 指令、 匯編 指令和 偽 指令構成。 (2)ARM偽指令可以分為以下幾類:符號定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令和宏指令等。 (3)假設存儲數(shù)據(jù)0x12345678于ARM微處理器內存0X30000000開始的位置,則0X3

    2024年02月05日
    瀏覽(17)
  • 嵌入式學習之C語言指針部分復習

    嵌入式學習之C語言指針部分復習

    今天主要把C語言的指針部分再次認真的復習了一下,對于指針的整體框架有了更加深刻的理解,特別要重點區(qū)分函數(shù)指針,指針函數(shù),數(shù)組指針,指針數(shù)組部分,對于這部分的應用非常重要,而且C語言指針部分是面試的重中之重,所以要加強練習才行。 今天的學習是充滿動

    2024年02月12日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包