嵌入式單片機STM32應用技術(課本)

目錄
SAIU R20 1 6 第1頁
第1 章. 初識STM32...................................................................................................................... 1
1.1. 課前預習........................................................................................................................................... 1
1.2. 概述.................................................................................................................................................... 1
1.3. 什麼是STM32....................................................................................................................................1
1.4. STM32 能作什麼............................................................................................................................... 2
1.5. STM32 怎麼選型.............................................................................................................................. 3
1.5.1. STM32 分類................................................................................................................................. 3
1.5.2. STM32 命名方法........................................................................................................................ 4
1.5.3. 選擇合適的MCU...................................................................................................................... 4
1.5.4. PCB 哪裏打樣..............................................................................................................................6
1.6. 總結.................................................................................................................................................... 7
1.7. 課後練習........................................................................................................................................... 7
第2 章. STM32 的結構和組成...................................................................................................... 8
2.1. 課前預習........................................................................................................................................... 8
2.2. 概述.................................................................................................................................................... 8
2.3. 什麼是寄存器.................................................................................................................................. 8
2.4. STM 32 長啥樣..................................................................................................................................8
2.5. 芯片裏面有什麼............................................................................................................................10
2.5.1. ICode 總線.................................................................................................................................10
2.5.2. 驅動單元....................................................................................................................................10
2.5.3. 被動單元....................................................................................................................................11
2.6. 存儲器映射.....................................................................................................................................13
2.7. 寄存器映射.....................................................................................................................................14
2.7.1. STM32 的外設地址映射.......................................................................................................... 15
2.7.2. 總線基地址................................................................................................................................15
2.7.3. 外設基地址................................................................................................................................15
2.7.4. 外設寄存器................................................................................................................................16
2.8. C 語言對寄存器的封裝................................................................................................................16
2.8.1. 封裝總線和外設基地址........................................................................................................... 16
2.8.2. 封裝寄存器列表....................................................................................................................... 17
2.9. 課後練習......................................................................................................................................... 20
第3 章. 初識STM32 標準庫..................................................................................................... 21
3.1. 課前預習......................................................................................................................................... 21
3.2. 概述.................................................................................................................................................. 21
3.3. 庫目錄、文件簡介....................................................................................................................... 21
3.4. STM32F10x_StdPeriph_Driver 文件夾..................................................................................24
3.5. 庫各文件間的關係....................................................................................................................... 26
3.6. 初識庫函數.....................................................................................................................................28
目錄
第2 頁SAIUR201 6
陳德金老師編著
3.7. 課後練習......................................................................................................................................... 29
第4 章. GPIO 的使用.................................................................................................................. 30
4.1. 課前預習......................................................................................................................................... 30
4.2. 概述.................................................................................................................................................. 30
4.3. GPIO 簡介.......................................................................................................................................30
4.4. GPIO 框圖剖析.............................................................................................................................. 31
4.4.1. 保護二極管及上、下拉電阻................................................................................................... 31
4.4.2. P-MOS 管和N-MOS 管......................................................................................................... 31
4.4.3. 輸出數據寄存器....................................................................................................................... 33
4.4.4. 複用功能輸出........................................................................................................................... 34
4.4.5. 輸入數據寄存器....................................................................................................................... 34
4.4.6. 複用功能輸入........................................................................................................................... 34
4.4.7. 模擬輸入輸出........................................................................................................................... 34
4.5. GPIO 工做模式.............................................................................................................................. 35
4.5.1. 輸入模式(模擬/浮空/上拉/下拉)............................................................................................. 35
4.5.2. 輸出模式(推輓/開漏)................................................................................................................35
4.5.3. 複用功能(推輓/開漏)................................................................................................................35
4.6. 點亮LED-硬件設計...................................................................................................................... 37
4.7. 點亮LED-編程要點...................................................................................................................... 38
4.8. 點亮LED-代碼分析...................................................................................................................... 38
4.8.1. LED 燈引腳宏定義...................................................................................................................38
4.8.2. 控制LED 燈亮滅狀態的宏定義........................................................................................... 39
4.8.3. LED GPIO 初始化函數............................................................................................................ 40
4.8.4. 主函數........................................................................................................................................41
4.9. 點亮LED-下載驗證...................................................................................................................... 42
4.10. 課後練習.......................................................................................................................................42
第5 章. STM32 RCC 時鐘系統.................................................................................................... 43
5.1. 課前預習......................................................................................................................................... 43
5.2. 概述.................................................................................................................................................. 43
5.3. RCC 主要做用—時鐘部分.......................................................................................................... 43
5.4. RCC 框圖剖析—時鐘部分.......................................................................................................... 43
5.5. 系統時鐘......................................................................................................................................... 44
5.5.1. HSE 高速外部時鐘信號...........................................................................................................44
5.5.2. PLL 時鐘源............................................................................................................................... 45
5.5.3. PLL 時鐘PLLCLK.................................................................................................................. 45
5.5.4. 系統時鐘SYSCLK.................................................................................................................. 45
5.5.5. AHB 總線時鐘HCLK............................................................................................................. 45
5.5.6. APB2 總線時鐘HCLK2..........................................................................................................45
目錄
SAIU R20 1 6 第3頁
5.5.7. 總線時鐘HCLK1.....................................................................................................................46
5.6. 設置系統時鐘庫函數................................................................................................................... 46
5.7. 其餘時鐘......................................................................................................................................... 47
5.7.1. USB 時鐘...................................................................................................................................47
5.7.2. Cortex 系統時鐘........................................................................................................................47
5.7.3. ADC 時鐘.................................................................................................................................. 48
5.7.4. RTC 時鐘、獨立看門狗時鐘.................................................................................................. 48
5.7.5. MCO 時鐘輸出......................................................................................................................... 48
5.8. 配置系統時鐘實驗....................................................................................................................... 48
5.8.1. 使用HSE..................................................................................................................................48
5.8.2. 使用HSI................................................................................................................................... 48
5.8.3. 硬件設計....................................................................................................................................49
5.8.4. 軟件設計....................................................................................................................................49
5.8.5. 編程要點....................................................................................................................................49
5.8.6. 代碼分析....................................................................................................................................49
5.8.7. 下載驗證....................................................................................................................................54
第6 章. STM32 中斷應用概覽................................................................................................... 55
6.1. 課前預習......................................................................................................................................... 55
6.2. 概述.................................................................................................................................................. 55
6.3. 異常類型......................................................................................................................................... 55
6.4. NVIC 簡介.......................................................................................................................................56
6.5. NVIC 寄存器簡介..........................................................................................................................56
6.6. NVIC 中斷配置固件庫.................................................................................................................57
6.7. 優先級的定義................................................................................................................................ 58
6.7.1. 優先級定義................................................................................................................................58
6.7.2. 優先級分組................................................................................................................................58
6.8. 中斷編程......................................................................................................................................... 59
6.9. 課後練習......................................................................................................................................... 60
第7 章. EXTI—外部中斷/事件控制器..................................................................................... 61
7.1. 課前預習......................................................................................................................................... 61
7.2. 概述.................................................................................................................................................. 61
7.3. EXTI 簡介.......................................................................................................................................61
7.4. EXTI 功能框圖.............................................................................................................................. 61
7.5. 中斷/事件線.................................................................................................................................. 63
7.6. EXTI 初始化結構體詳解............................................................................................................ 64
7.7. 外部中斷控制實驗....................................................................................................................... 65
7.7.1. 硬件設計....................................................................................................................................65
7.7.2. 軟件設計....................................................................................................................................65
目錄
第4 頁SAIUR201 6
陳德金老師編著
7.7.3. 編程要點....................................................................................................................................65
7.7.4. 代碼分析....................................................................................................................................65
7.7.5. 下載驗證....................................................................................................................................69
7.8. 課後練習......................................................................................................................................... 69
第8 章. SysTick 系統定時器.................................................................................................... 70
8.1. 課前預習......................................................................................................................................... 70
8.2. 概述.................................................................................................................................................. 70
8.3. SysTick 簡介................................................................................................................................ 70
8.4. SysTick 寄存器介紹................................................................................................................... 70
8.5. SysTick 定時實驗.......................................................................................................................... 72
8.5.1. 硬件設計....................................................................................................................................72
8.5.2. 軟件設計....................................................................................................................................72
8.5.3. 編程要點....................................................................................................................................72
8.5.4. 代碼分析....................................................................................................................................73
8.6. 課後練習......................................................................................................................................... 79
第9 章. USART—串口通信......................................................................................................... 80
9.1. 課前預習......................................................................................................................................... 80
9.2. 概述.................................................................................................................................................. 80
9.3. 串口通信協議簡介....................................................................................................................... 80
9.3.1. 物理層........................................................................................................................................80
9.3.2. 協議層........................................................................................................................................84
9.4. STM32 的USART 簡介................................................................................................................ 85
9.5. USART 功能框圖............................................................................................................................85
9.6. USART 初始化結構體詳解.......................................................................................................... 90
9.7. USART1 接發通訊實驗.................................................................................................................91
9.7.1. 硬件設計....................................................................................................................................92
9.7.2. 軟件設計....................................................................................................................................92
9.7.3. 編程要點....................................................................................................................................92
9.7.4. 代碼分析....................................................................................................................................93
9.7.5. 下載驗證....................................................................................................................................97
9.8. 課後練習......................................................................................................................................... 97
第10 章. DMA 直接存儲區訪問.................................................................................................. 98
10.1. 課前預習.......................................................................................................................................98
10.2. 概述................................................................................................................................................98
10.3. DMA 簡介.......................................................................................................................................98
10.4. DMA 功能框圖.............................................................................................................................. 98
10.5. DMA 數據配置............................................................................................................................100
10.6. DMA 初始化結構體詳解.......................................................................................................... 101
目錄
SAIU R20 1 6 第5頁
10.7. DMA 存儲器到存儲器模式實驗.............................................................................................103
10.7.1. 硬件設計................................................................................................................................103
10.7.2. 軟件設計................................................................................................................................103
10.7.3. 編程要點................................................................................................................................103
10.7.4. 代碼分析................................................................................................................................104
10.7.5. 下載驗證................................................................................................................................107
10.8. 課後練習.....................................................................................................................................107
第11 章. TIM 基本定時器........................................................................................................ 108
11.1. 課前預習.....................................................................................................................................108
11.2. 概述..............................................................................................................................................108
11.3. 定時器分類................................................................................................................................ 108
11.4. 基本定時器功能框圖講解......................................................................................................109
11.5. 定時器初始化結構體詳解......................................................................................................110
11.6. 基本定時器定時實驗...............................................................................................................111
11.6.1. 硬件設計................................................................................................................................111
11.6.2. 軟件設計................................................................................................................................111
11.6.3. 編程要點................................................................................................................................111
11.6.4. 軟件分析................................................................................................................................111
11.6.5. 下載驗證................................................................................................................................114
11.7. 課後練習.....................................................................................................................................114
第12 章. TIM 高級定時器........................................................................................................ 115
12.1. 課前預習.....................................................................................................................................115
12.2. 概述..............................................................................................................................................115
12.3. 高級控制定時器....................................................................................................................... 115
12.4. 高級控制定時器功能框圖........................................................................................................116
12.4.1. 時鐘源....................................................................................................................................117
12.4.2. 外部時鐘模式1................................................................................................................... 117
12.4.3. 外部時鐘模式2................................................................................................................... 118
12.4.4. 內部觸發輸入....................................................................................................................... 119
12.4.5. 輸入捕獲................................................................................................................................121
12.4.6. 輸出比較................................................................................................................................122
12.4.7. 斷路功能................................................................................................................................125
12.5. 輸入捕獲應用............................................................................................................................125
12.5.1. 測量頻率................................................................................................................................126
12.5.2. 測量脈寬................................................................................................................................126
12.6. PWM 輸入模式............................................................................................................................126
12.7. 輸出比較應用............................................................................................................................128
12.7.1. PWM 輸出模式.....................................................................................................................128
目錄
第6 頁SAIUR201 6
陳德金老師編著
12.7.2. PWM 邊沿對齊模式.............................................................................................................128
12.7.3. PWM 中心對齊模式.............................................................................................................129
12.8. 定時器初始化結構體詳解......................................................................................................129
12.8.1. TIM_TimeBaseInitTypeDef...................................................................................................130
12.8.2. TIM_OCInitTypeDef..............................................................................................................130
12.8.3. TIM_ICInitTypeDef............................................................................................................... 131
12.8.4. TIM_BDTRInitTypeDef.........................................................................................................132
12.9. PWM 互補輸出實驗................................................................................................................... 133
12.9.1. 硬件設計................................................................................................................................133
12.9.2. 軟件設計................................................................................................................................133
12.9.3. 編程要點................................................................................................................................133
12.9.4. 軟件分析................................................................................................................................134
12.9.5. 下載驗證................................................................................................................................136
第13 章. I2C 通信.................................................................................................................... 138
13.1. 課前預習.....................................................................................................................................138
13.2. 概述..............................................................................................................................................138
13.3. I2C 協議簡介............................................................................................................................138
13.3.1. I2C 物理層............................................................................................................................. 139
13.3.2. 協議層....................................................................................................................................140
13.3.3. 通信的起始和中止信號....................................................................................................... 141
13.4. STM32 的I2C 特性及架構................................................................................................... 144
13.4.1. STM32 的I2C 外設簡介.................................................................................................... 144
13.4.2. STM32 的I2C 架構剖析.................................................................................................... 145
13.4.3. 通信過程................................................................................................................................147
13.5. I2C 初始化結構體詳解.......................................................................................................... 149
13.6. I2C—讀寫EEPROM 實驗........................................................................................................150
13.6.1. 硬件設計................................................................................................................................150
13.6.2. 軟件設計................................................................................................................................151
13.6.3. 編程要點................................................................................................................................151
13.6.4. 代碼分析................................................................................................................................152
13.6.5. 下載驗證................................................................................................................................167
13.7. 課後練習.....................................................................................................................................168
第14 章. SPI 通信.................................................................................................................... 169
14.1. 課前預習.....................................................................................................................................169
14.2. 概述..............................................................................................................................................169
14.3. SPI 協議簡介............................................................................................................................169
14.3.1. SPI 物理層.............................................................................................................................169
14.3.2. 協議層....................................................................................................................................171
目錄
SAIU R20 1 6 第7頁
14.4. STM32 的SPI 特性及架構................................................................................................... 173
14.4.1. STM32 的SPI 外設簡介.................................................................................................... 173
14.4.2. TM32 的SPI 架構剖析...................................................................................................... 174
14.4.3. 通信過程................................................................................................................................175
14.5. SPI 初始化結構體詳解.......................................................................................................... 177
14.6. SPI—讀寫串行FLASH 實驗................................................................................................. 178
14.6.1. 硬件設計................................................................................................................................179
14.6.2. 軟件設計................................................................................................................................179
14.6.3. 編程要點................................................................................................................................180
14.6.4. 代碼分析................................................................................................................................180
14.6.5. 下載驗證................................................................................................................................198
14.7. 課後練習.....................................................................................................................................198
第15 章. 陀螺儀姿態檢測....................................................................................................... 199
15.1. 課前預習.....................................................................................................................................199
15.2. 概述..............................................................................................................................................199
15.3. 姿態檢測.....................................................................................................................................199
15.3.1. 基本認識................................................................................................................................199
15.3.2. 座標系....................................................................................................................................200
15.4. 利用陀螺儀檢測角度...............................................................................................................201
15.5. 利用加速度計檢測角度............................................................................................................ 202
15.6. 利用磁場檢測角度................................................................................................................... 203
15.7. 利用GPS 檢測角度................................................................................................................ 204
15.8. 姿態融合與四元數..................................................................................................................... 204
15.9. MPU6050 模塊簡介...................................................................................................................... 204
15.9.1. MPU6050 模塊功能及外觀..................................................................................................204
15.9.2. MPU6050 模塊的引腳功能說明......................................................................................... 205
15.9.3. MPU6050 模塊的硬件原理圖..............................................................................................205
15.10. MPU6050 模塊的特性參數.......................................................................................................206
15.11. MPU6050—獲取原始數據實驗............................................................................................. 207
15.11.1. 硬件設計............................................................................................................................. 207
15.11.2. 配套程序簡介..................................................................................................................... 208
15.11.3. 軟件設計............................................................................................................................. 209
15.11.4. 程序設計要點..................................................................................................................... 209
15.11.5. 代碼分析............................................................................................................................. 209
15.11.6. 下載驗證............................................................................................................................. 215
15.12. MPU6050—利用DMP 進行姿態解算..................................................................................216
15.12.1. 硬件設計............................................................................................................................. 216
15.12.2. 軟件設計............................................................................................................................. 216
15.12.3. 程序設計要點..................................................................................................................... 216
目錄
第8 頁SAIUR201 6
陳德金老師編著
15.12.4. 代碼分析............................................................................................................................. 216
15.12.5. 下載驗證............................................................................................................................. 226
15.13. MPU6050—使用第三方上位機............................................................................................. 227
15.13.1. 硬件設計............................................................................................................................. 227
15.13.2. 軟件設計............................................................................................................................. 227
15.13.3. 程序設計要點..................................................................................................................... 227
15.13.4. 代碼分析............................................................................................................................. 227
15.13.5. 下載驗證............................................................................................................................. 231
第1 章.初識STM32
SAIU R20 1 6 第1頁
第1 章. 初識STM32
1.1. 課前預習
在書上找到答案。
1. 什麼是STM32。
2. STM32 能作什麼什麼?
1.2. 概述
本章所講內容:
(1)STM32 簡介
(2)STM32 功能介紹
1.3. 什麼是STM32
STM32,從字面上來理解,ST 是意法半導體,M 是Microelectronics 的縮寫,32 表示32 位,
合起來理解,STM32 就是指ST 公司開發的32 位微控制器。在現在的32 位控制器當中,STM32 可
以說是最璀璨的新星,它受寵若嬌,大受工程師和市場的青睞,無芯能出其右。
51 是嵌入式學習中一款入門級的精典MCU,因其結構簡單,易於教學,且能夠經過串口編程而不
須要額外的仿真器,因此在教學時被大量採用,至今不少大學在嵌入式教學中用的仍是51。51 誕生
於70 年代,屬於傳統的8 位單片機,現在,久經歲月的洗禮,既有其輝煌又有其不足。如今的市場
產品競爭愈來愈激烈,對成本極其敏感,相應地對MCU 的性能要求也更苛刻:更多功能,更低功耗,
易用界面和多任務。面對這些要求,51 現有的資源就顯得得抓襟見肘。因此不管是高校教學仍是市
場需求,都急需一款新的MCU 來爲這個領域注入新的活力。基於這樣的市場需求, ARM 公司推出了其
全新的基於ARMv7 架構的32 位Cortex-M3 微控制器內核。緊隨其後,ST(意法半導體)公司就推出
了基於Cortex-M3 內核的MCU— STM32。STM32 憑藉其產品線的多樣化、極高的性價比、簡單易用的
庫開發方式,迅速在衆多Cortex-M3 MCU 中脫穎而出,成爲最閃亮的一顆新星。STM32 一上市就迅
速佔領了中低端MCU 市場,受到了市場和工程師的無比青睞,很有星火燎原之勢。做爲一名合格的嵌
入式工程師,面對新出現的技術,咱們不是充耳不聞,而是要儘快吻合市場的須要,跟上技術的潮流。
第1 章.初識STM32
第2 頁SAIUR201 6
圖1-2 STM32F103 搭建的系統界面
現在STM32 的出現就是一種趨勢,一種潮流,咱們要作的就是搭上這趟快車,讓本身的技術更有競爭
力。
1.4. STM32 能作什麼
STM32 屬於一個微控制器,自帶了各類經常使用通訊接口,好比USART、I2C、SPI 等,可接很是多的傳感
器,能夠控制不少的設備。現實生活中,咱們接觸到的不少電器產品都有STM32 的身影,好比智能手環,
微型四軸飛行器,平衡車、移動POST 機,智能電飯鍋,3D 打印機等等。下面咱們以最近最爲火爆的兩個
產品來說解下,一個是手環,一個是飛行器。
圖1-1 三星GearFit 智能手環
紅圈:STM32F439ZIY6S 處理器,2048KB FLASH ,256KB RAM ,WLCSP143 封裝。橙圈:Macronix
MX69V28F64 16 MB 閃存,基於MCP 封裝的存儲器,是一種包含了NOR 和SRAM 的閃存,這在手環手
機這種移動設備中常用,優勢是體積小,能夠減少PCB 的尺寸。這個閃存用的439 的FSMC 接口
驅動。黃圈:InvenSense MPU-6500 陀螺儀/加速度計,用
439 的I2C 接口驅動。綠圈:博通BCM4334WKUBG 芯片,
支持802.11n,藍牙4.0+HS 以及FM 接收芯片,用439 的
SDIO 或者SPI 接口驅動。顯示:1.84"可彎曲屏幕(Super
AMOLED),432 x 128 像素。觸摸部分用439 的I2C 接口
驅動,OLED 顯示部分用LTDC 接口驅動。
除了這幾個重要資源的對比,咱們的霸道開發板上還集
成了以太網,音頻,CAN, 485 , 232 , USB 轉串口, 蜂
鳴器, LED , 電容按鍵等外設資源, 能夠充分的學習
STM32F103ZET6 這個芯片。在板子上面,還能夠跑系統
ucosiii,學習圖形界面emwin。若是功夫所至,學完以後,
本身均可以作一個相似Gear Fit 這樣的手環。可不少人又
會說,Gear Fit 涉及硬件和軟件,整個系統這麼複雜,並不
是一我的能夠完成的。說的沒錯,咱們能夠作不了,可是咱們
第1 章.初識STM32
SAIU R20 1 6 第3頁
的能力能夠無限接近,多學點,技多不壓身嘛。如今無人機很是火熱,高端的無人機用STM32 作不來,
可是小型的四軸飛行器用STM32 仍是綽綽有餘的。如圖1-3 所示飛行器的基本均可以用STM32 搞定。
圖1-3 四軸飛行器
1.5. STM32 怎麼選型
1.5.1. STM32 分類
STM32 有不少系列,能夠知足市場的各類需求,從內核上分有Cortex-M0、M三、M4 和M7 這幾
種,每一個內核又大概分爲主流、高性能和低功耗。具體的見表格1-1。
表格1-2 STM8 和STM32 分類
單純從學習的角度出發,能夠選擇F1 和F4,F1 表明了基礎型,基於Cortex-M3 內核,主頻爲
72MHZ,F4 表明了高性能,基於Cortex-M4 內核,主頻180M。之於F1,F4(429 系列以上)除了
內核不一樣和主頻的提高外,升級的明顯特點就是帶了LCD 控制器和攝像頭接口,支持SDRAM,這
個區別在項目選型上會被優先考慮。可是從大學教學和用戶初學來講,仍是首選F1 系列,目前在市
場上資料最多,產品佔有量最多的就是F1 系列的STM32。
第1 章.初識STM32
第4 頁SAIUR201 6
1.5.2. STM32 命名方法
這裏咱們以STM32F103ZET6 來說解下STM32 的命名方法。
表1--3 STM32F103ZET6 命名解釋
有關更詳細的命名方法見圖1-4。
圖1-4 STM8 和STM32 命名方法
1.5.3. 選擇合適的MCU
瞭解了STM32 的分類和命名方法以後,就能夠根據項目的具體需求先大概選擇哪類內核的
MCU,普通應用,不須要接大屏幕的通常選擇Cortex-M3 內核的F1 系列,若是要追求高性能,須要
大量的數據運算,且須要外接RGB 大屏幕的則選擇Cortex-M4 內核的F429 系列。明確了大方向以後,
接下來就是細分選型,先肯定引腳,引腳多的功能就多,價格也貴,具體得根據實際項目中須要使用到
什麼功能,夠用就好。肯定好了引腳數目以後再選擇FLASH 大小,相同引腳數的MCU 會有不一樣的
FLASH 大小可供選擇,這個也是根據實際須要選擇,程序大的就選擇大點的FLASH,要是產品一量
產,這些省下來的都是錢啊。有些月出貨量以KK(百萬數量級)爲單位的產品,不只是MCU,連電
第1 章.初識STM32
SAIU R20 1 6 第5頁
阻電容能少用就少用,更甚者連PCB 的過孔的多少都有講究。項目中的元器件的選型的水深的很,很
多學問。
如何分配原理圖IO
在畫原理圖以前,通常的作法是先把引腳分類好,而後纔開始畫原理圖,引腳分類具體見表格1-5。
表格1-5 畫原理圖時的引腳分類
要想根據功能來分配IO,那就得先知道每一個IO 的功能說明,這個咱們能夠從官方的數據手冊裏
面找到。在學習的時候,有兩個官方資料咱們會常常用到,一個是參考手冊(英文叫Reference manual),
另一個是數據手冊(英文叫Data Sheet)。二者的具體區別見表格1-6。
表格1-6 參考手冊和數據手冊的內容區別
一句話歸納:數據手冊主要用於芯片選型和設計原理圖時參考,參考手冊主要用於在編程的時
候查閱。官方的這兩個文檔能夠從官方網址裏面下載:
http://www.stmcu.org/document/list/index/category-150
在數據手冊中,有關引腳定義的部分在Pinouts and pin description 這個小節中,具體定義見表格
1-7。
第1 章.初識STM32
第6 頁SAIUR201 6
表格1-7 數據手冊中對引腳定義
表格1-8 對引腳定義的解讀
開始分配原理圖IO
好比MCU 型號是STM32F103ZET6,封裝爲LQFP144,咱們在數據手冊中找到這個封裝的引腳
定義,而後根據引腳序號,一個一個複製出來,整理成excel 表。具體整理方法按照表格5-4 畫原理
圖時的引腳分類便可。分配好以後就開始畫原理圖。
1.5.4. PCB 哪裏打樣
設計好原理圖,畫好PCB 以後,須要把板子作出來,進行軟硬件聯調。首先得PCB 打樣,能夠
在網上找到一些專業的公司幫忙作,若是你足夠懶,不想本身焊接電阻電容二三極管什麼的,還能夠幫
你把PCB 樣板上的阻容貼好給你,打樣貼片一條龍。
第1 章.初識STM32
SAIU R20 1 6 第7頁
1.6. 總結
本章介紹了STM32 的基本概念、應用領域和芯片的選型方法。主要對STM32 芯片有一個比較清
晰的認識,後續章節將會詳細介紹這個芯片的各個模塊和功能。
1.7. 課後練習
1. 查看實訓室的無人機和機器人使用的芯片是哪一個?哪些使用的是STM32?
第2 章.STM32 的結構和組成
第8 頁SAIUR201 6
陳德金老師編著
第2 章. STM32 的結構和組成
2.1. 課前預習
在書上找到答案。
1. STM32 裏面有什麼?
2. STM32 的開發方式和51 單片機有什麼區別?
2.2. 概述
本章所講內容:
(1)STM32 芯片結構
(2)寄存器映射
2.3. 什麼是寄存器
咱們常常說寄存器,那麼什麼是寄存器?這是咱們本章須要講解的內容,在學習的過程當中,你們
帶着這個疑問好好思考下,到最後看看你們可否用一句話給寄存器下一個定義。
2.4. STM 32 長啥樣
STM32 的基本結構咱們開發板中使用的芯片是144pin 的STM32F103ZET6,具體見圖6-1。這個就
是咱們接下來要學習的STM32,它將帶領咱們進入嵌入式的殿堂。芯片正面是絲印,ARM 應該是表示該
芯片使用的是ARM 的內核,STM32F103ZET6 是芯片型號,後面的字應該是跟生產批次相關,最上面的
是ST 的LOGO。芯片四周是引腳,左下角的小圓點表示1 腳,而後從1 腳起按照逆時針的順序排列
(全部芯片的引腳順序都是逆時針排列的)。開發板中把芯片的引腳引出來,鏈接到各類傳感器上,
而後在STM32 上編程(實際就是經過程序控制這些引腳輸出高電平或者低電平)來控制各類傳感器工
做,經過作實驗的方式來學習STM32 芯片的各個資源。開發板是一種評估板,板載資源很是豐富,引
腳複用比較多,力求在一個板子上驗證芯片的所有功能。圖2-1 STM32F103ZET6 實物圖(紅色框中部
分)
第2 章.STM32 的結構和組成
SAIU R20 1 6 第9頁
圖2-1 STM32F103ZET6 實物圖
圖2-2 STM32F103ZET6 正面引腳圖
第2 章.STM32 的結構和組成
第10 頁SAIUR2016
陳德金老師編著
2.5. 芯片裏面有什麼
咱們看到的STM32 芯片是已經封裝好的成品,主要由內核和片上外設組成。若與電腦類比,內
核與外設就如同電腦上的CPU 與主板、內存、顯卡、硬盤的關係。STM32F103 採用的是Cortex-M3 內
核,內核即CPU,由ARM 公司設計。ARM 公司並不生產芯片,而是出售其芯片技術受權。芯片生產廠
商(SOC)如ST、TI、Freescale,負責在內核以外設計部件並生產整個芯片,這些內核以外的部件被稱
爲核外外設或片上外設。如GPIO、USART(串口)、I2C、SPI 等都叫作片上外設。具體見圖2-3。
圖2-3 STM32 芯片架構簡圖
芯片(這裏指內核,或者叫CPU)和外設之間經過各類總線鏈接,其中驅動單元有4 個,被動單
元也有4 個,具體見圖2-4。爲了方便理解,咱們均可以把驅動單元理解成是CPU 部分,被動單元
都理解成外設。下面咱們簡單介紹下驅動單元和被動單元的各個部件。
2.5.1. ICode 總線
ICode 中的I 表示Instruction,即指令。咱們寫好的程序編譯以後都是一條條指令,存放在
FLASH 中,內核要讀取這些指令來執行程序就必須經過ICode 總線,它幾乎每時每刻都須要被使用,
它是專門用來取指的。
2.5.2. 驅動單元
DCode 總線
第2 章.STM32 的結構和組成
SAIUR201 6 第11頁
DCode 中的D 表示Data,即數據,那說明這條總線是用來取數的。咱們在寫程序的時候,數據
有常量和變量兩種,常量就是固定不變的,用C 語言中的const 關鍵字修飾,是放到內部的FLASH 當
中的,變量是可變的,無論是全局變量仍是局部變量都放在內部的SRAM。由於數據能夠被Dcode 總
線和DMA 總線訪問,因此爲了不訪問衝突,在取數的時候須要通過一個總線矩陣來仲裁,決定哪
個總線在取數。
系統總線
系統總線主要是訪問外設的寄存器,咱們一般說的寄存器編程,即讀寫寄存器都是經過這根系統
總線來完成的。
DMA 總線
DMA 總線也主要是用來傳輸數據,這個數據能夠是在某個外設的數據寄存器,能夠在SRAM,可
以在內部的FLASH。由於數據能夠被Dcode 總線和DMA 總線訪問,因此爲了不訪問衝突,在取
數的時候須要通過一個總線矩陣來仲裁,決定哪一個總線在取數。
2.5.3. 被動單元
內部的閃存存儲器
內部的閃存存儲器即FLASH,咱們編寫好的程序就放在這個地方。內核經過ICode 總線來取裏
面的指令。
內部的SRAM
內部的SRAM,即咱們一般說的RAM,程序的變量,堆棧等的開銷都是基於內部的SRAM。內
核經過DCode 總線來訪問它。
FSMC
FSMC 的英文全稱是Flexible static memory controller,叫靈活的靜態的存儲器控制器, 是
STM32F10xx 中一個頗有特點的外設,經過FSMC,咱們能夠擴展內存,如外部的SRAM,NANDFLASH
和NORFLASH。但有一點咱們要注意的是,FSMC 只能擴展靜態的內存,即名稱裏面的S:static,
不能是動態的內存,好比SDRAM 就不能擴展。
第2 章.STM32 的結構和組成
第12 頁SAIUR2016
陳德金老師編著
AHB 到APB 的橋
從AHB 總線延伸出來的兩條APB2 和APB1 總線,上面掛載着STM32 各類各樣的特點外
設。咱們常常說的GPIO、串口、I2C、SPI 這些外設就掛載在這兩條總線上,這個是咱們學習STM32
的重點,就是要學會編程這些外設去驅動外部的各類設備。
圖2-4 STM32F10xx 系統框圖(不包括互聯型)
第2 章.STM32 的結構和組成
SAIUR201 6 第13頁
2.6. 存儲器映射
在圖2-4 中,被控單元的FLASH,RAM,FSMC 和AHB 到APB 的橋(即片上外設),這些功能部
件共同排列在一個4GB 的地址空間內。咱們在編程的時候,能夠經過他們的地址找到他們,而後來操
做他們(經過C 語言對它們進行數據的讀和寫)。存儲器自己不具備地址信息,它的地址是由芯片廠
商或用戶分配,給存儲器分配地址的過程就稱爲存儲器映射,具體見圖2-5。若是給存儲器再分配一
個地址就叫存儲器重映射。
圖2-5 存儲器映射
第2 章.STM32 的結構和組成
第14 頁SAIUR2016
陳德金老師編著
在這4GB 的地址空間中,ARM 已經粗線條的平均分紅了8 個塊,每塊512MB,每一個塊也都規
定了用途,具體分類見表格6-1。每一個塊的大小都有512MB,顯然這是很是大的,芯片廠商在每一個塊
的範圍內設計各具特點的外設時並不必定都用得完,都是隻用了其中的一部分而已。
表格2-1 存儲器功能分類
在這8 個Block 裏面,有3 個塊很是重要,也是咱們最關心的三個塊。Block0 用來設計成內
部FLASH,Block1 用來設計成內部RAM,Block2 用來設計成片上的外設,下面咱們簡單的介紹下
這三個Block 裏面的具體區域的功能劃分。存儲器Block0 內部區域功能劃分Block0 主要用於設計片
內的FLASH , 咱們使用的STM32F103ZET6 的FLASH 是512KB,屬於大容量。要在芯片
內部集成更大的FLASH 或者SRAM 都意味着芯片成本的增長,每每片內集成的FLASH 都不會太
大,ST 能在追求性價比的同時作到512KB,實乃良心之舉。
2.7. 寄存器映射
咱們知道,存儲器自己沒有地址,給存儲器分配地址的過程叫存儲器映射,那什麼叫寄存器映射?
寄存器究竟是什麼?在存儲器Block2 這塊區域,設計的是片上外設,它們以四個字節爲一個單元,共
32bit,每個單元對應不一樣的功能,當咱們控制這些單元時就能夠驅動外設工做。咱們能夠找到每一個
單元的起始地址,而後經過C 語言指針的操做方式來訪問這些單元,若是每次都是經過這種地址的
方式來訪問,不只很差記憶還容易出錯,這時咱們能夠根據每一個單元功能的不一樣,以功能爲名給這個
內存單元取一個別名,這個別名就是咱們常常說的寄存器,這個給已經分配好地址的有特定功能的內
存單元取別名的過程就叫寄存器映射。好比,咱們找到GPIOB 端口的輸出數據寄存器ODR 的地址
是0x4001 0C0C(至於這個地址如何找到能夠先跳過,後面咱們會有詳細的講解),ODR 寄存器是
32bit,低16bit 有效,對應着16 個外部IO,寫0/1 對應的的IO 則輸出低/高電平。如今咱們經過C
語言指針的操做方式,讓GPIOB 的16 個IO 都輸出高電平,具體見代碼2-1。
第2 章.STM32 的結構和組成
SAIUR201 6 第15頁
代碼2-1 經過絕對地址訪問內存單元
0x4001 0C0C 在咱們看來是GPIOB 端口ODR 的地址,可是在編譯器看來,這只是一個普通的
變量,是一個當即數,要想讓編譯器也認爲是指針,咱們得進行強制類型轉換,把它轉換成指針,即
(unsigned int *)0x4001 0C0C,而後再對這個指針進行* 操做。剛剛咱們說了,經過絕對地址訪問內存
單元很差記憶且容易出錯,咱們能夠經過寄存器的方式來操做,具體見代碼2-2。
代碼2-2 經過寄存器別名方式訪問內存單元
爲了方便操做,咱們乾脆把指針操做「*」也定義到寄存器別名裏面,具體見代碼2-3。
代碼2-3 經過寄存器別名訪問內存單元
2.7.1. STM32 的外設地址映射
片上外設區分爲三條總線,根據外設速度的不一樣,不一樣總線掛載着不一樣的外設,APB1 掛載低速外
設,APB2 和AHB 掛載高速外設。相應總線的最低地址咱們稱爲該總線的基地址,總線基地址也是掛
載在該總線上的首個外設的地址。其中APB1 總線的地址最低,片外設從這裏開始,也叫外設基地址。
2.7.2. 總線基地址
表格2-2 總線基地址
表格2-2 的「相對外設基地址偏移」即該總線地址與「片上外設」基地址0x4000 0000 的差值。關於
地址的偏移咱們後面還會講到。
2.7.3. 外設基地址
總線上掛載着各類外設,這些外設也有本身的地址範圍,特定外設的首個地址稱爲「XX 外設基地
址」,也叫XX 外設的邊界地址。具體有關STM32F10xx 外設的邊界地址請參考《STM32F10xx 參考
手冊》的2.3 小節的存儲器映射的表1:STM32F10xx 寄存器邊界地址。這裏面咱們以GPIO 這個外
設來說解外設的基地址,GPIO 屬於高速的外設,掛載到APB2 總線上,具體見表格2-3。
第2 章.STM32 的結構和組成
第16 頁SAIUR2016
陳德金老師編著
表格2-3 外設GPIO 基地址
2.7.4. 外設寄存器
在XX 外設的地址範圍內,分佈着的就是該外設的寄存器。以GPIO 外設爲例,GPIO 是通用輸
入輸出端口的簡稱,簡單來講就是STM32 可控制的引腳,基本功能是控制引腳輸出高電平或者低電
平。最簡單的應用就是把GPIO 的引腳鏈接到LED 燈的陰極,LED 燈的陽極接電源,而後經過
STM32 控制該引腳的電平,從而實現控制LED 燈的亮滅。GPIO 有不少個寄存器,每個都有特定
的功能。每一個寄存器爲32bit,佔四個字節,在該外設的基地址上按照順序排列,寄存器的位置都以相
對該外設基地址的偏移地址來描述。
2.8. C 語言對寄存器的封裝
以上全部的關於存儲器映射的內容,最終都是爲你們更好地理解如何用C 語言控制讀寫外設寄存
器作準備,此處是本章的重點內容。
2.8.1. 封裝總線和外設基地址
在編程上爲了方便理解和記憶,咱們把總線基地址和外設基地址都以相應的宏定義起來,總線或者
外設都以他們的名字做爲宏名,具體見代碼2-4。
第2 章.STM32 的結構和組成
SAIUR201 6 第17頁
代碼2-4 總線和外設基址宏定義
代碼2-4 首先定義了「片上外設」基地址PERIPH_BASE,接着在PERIPH_BASE 上加入各個總
線的地址偏移, 獲得APB1 、APB2 總線的地址APB1PERIPH_BASE 、APB2PERIPH_BASE,在
其之上加入外設地址的偏移,獲得GPIOA-G 的外設地址,最後在外設地址上加入各寄存器的地址偏
移,獲得特定寄存器的地址。一旦有了具體地址,就能夠用指針讀寫,具體見代碼2-5。
代碼2-5 使用指針控制BSRR 寄存器
2.8.2. 封裝寄存器列表
用上面的方法去定義地址,仍是稍顯繁瑣,例如GPIOA-GPIOE 都各有一組功能相同的寄存器,
如GPIOA_ODR/GPIOB_ODR/GPIOC_ODR 等等,它們只是地址不同,但卻要爲每一個寄存器都定義
它的地址。爲了更方便地訪問寄存器,咱們引入C 語言中的結構體語法對寄存器進行封裝,具體見代
碼2-6。
第2 章.STM32 的結構和組成
第18 頁SAIUR2016
陳德金老師編著
代碼2-6 使用結構體對GPIO 寄存器組的封裝
這段代碼用typedef 關鍵字聲明瞭名爲GPIO_TypeDef 的結構體類型,結構體內有7 個成員變
量,變量名正好對應寄存器的名字。C 語言的語法規定,結構體內變量的存儲空間是連續的,其中32
位的變量佔用4 個字節,16 位的變量佔用2 個字節,具體見圖2-6。
圖2-6 GPIO_TypeDef 結構體成員的地址偏移
也就是說,咱們定義的這個GPIO_TypeDef ,假如這個結構體的首地址爲0x4001 0C00(這也是
第一個成員變量CRL 的地址), 那麼結構體中第二個成員變量CRH 的地址即爲0x4001 0C00
+0x04 ,加上的這個0x04 ,正是表明CRL 所佔用的4 個字節地址的偏移量,其它成員變量相對於
結構體首地址的偏移,在上述代碼右側註釋已給。這樣的地址偏移與STM32 GPIO 外設定義的寄存器
地址偏移一一對應,只要給結構體設置好首地址,就能把結構體內成員的地址肯定下來,而後就能以結
構體的形式訪問寄存器,具體見代碼2-7。
第2 章.STM32 的結構和組成
SAIUR201 6 第19頁
代碼2-7 經過結構體指針訪問寄存器
這段代碼先用GPIO_TypeDef 類型定義一個結構體指針GPIOx , 並讓指針指向地址
GPIOB_BASE(0x4001 0C00),使用地址肯定下來,而後根據C 語言訪問結構體的語法,用GPIOx->ODR
及GPIOx->IDR 等方式讀寫寄存器。最後,咱們更進一步,直接使用宏定義好GPIO_TypeDef 類型的
指針,並且指針指向各個GPIO 端口的首地址,使用時咱們直接用該宏訪問寄存器便可,具體代碼2-8。
代碼2-8 定義好GPIO 端口首地址址針
這裏咱們僅是以GPIO 這個外設爲例,給你們講解了C 語言對寄存器的封裝。以此類推,其餘外
設也一樣能夠用這種方法來封裝。好消息是,這部分工做都由固件庫幫咱們完成了,這裏咱們只是分析
了下這個封裝的過程,讓你們知其然,也只其因此然。
第2 章.STM32 的結構和組成
第20 頁SAIUR2016
陳德金老師編著
2.9. 課後練習
一、什麼是存儲器映射?什麼是存儲器重映射?
二、什麼是寄存器?
第3 章.初識STM32 標準庫
SAIUR201 6 第21頁
第3 章. 初識STM32 標準庫
3.1. 課前預習
在書上找到答案。
1. 什麼是STM32 標準庫。
2. STM32 使用標準庫的開發方式和之前學的寄存器方式有什麼不一樣
3.2. 概述
本章所講內容:
(1)STM32 標準庫的簡介
(2)STM32 標準庫的文件夾和功能介紹
在上一章中,咱們構建了幾個控制GPIO 外設的函數,算是實現了函數庫的雛形,但GPIO 還有
不少功能函數咱們沒有實現,並且STM32 芯片不只僅只有GPIO 這一個外設。若是咱們想要親自完
成這個函數庫,工做量很是巨大。ST 公司提供的標準軟件庫,包含了STM32 芯片全部寄存器的控制
操做,咱們直接學習如何使用ST 標準庫,會極大地方便控制STM32 芯片。
3.3. 庫目錄、文件簡介
STM32 標準庫能夠從官網得到,也能夠直接從本書的配套資料獲得。本書講解的例程所有采用
3.5.0 庫文件。如下內容請你們打開STM32 標準庫文件配合閱讀。解壓庫文件後進入其目錄:
「STM32F10x_StdPeriph_Lib_V3.5.0\」軟件庫各文件夾的內容說明見圖3-1。
第3 章.初識STM32 標準庫
第22 頁SAIUR2016
陳德金老師編著
圖3-1 ST 標準庫目錄:STM32F10x_StdPeriph_Lib_V3.5.0\
1. Libraries:文件夾下是驅動庫的源代碼及啓動文件,這個很是重要,咱們要使用的固件庫就在這
個文件夾裏面。
2. Project :文件夾下是用驅動庫寫的例子和工程模板,其中那些爲每一個外設寫好的例程對咱們很是
有用,咱們在學習的時候就能夠參考這裏面的例程,很是全面,簡直就是窮盡了外設的全部功能。
3. Utilities:包含了基於ST 官方實驗板的例程,不須要用到,略過便可。
4. stm32f10x_stdperiph_lib_um.chm: 庫幫助文檔,這個頗有用,不喜歡直接看源碼的能夠在合理查
詢每一個外設的函數說明,很是詳細。這是一個已經編譯好的HTML 文件, 主要講述如何使用驅
動庫來編寫本身的應用程序。說得形象一點,這個HTML 就是告訴咱們:ST 公司已經爲你寫好
了每一個外設的驅動了,想知道如何運用這些例子就來向我求救吧。不幸的是,這個幫助文檔是英
文的,這對不少英文很差的朋友來講是一個很大的障礙。但這裏要告訴你們,英文僅僅是一種工
具,絕對不能讓它成爲咱們學習的障礙。其實這些英文仍是很簡單的,咱們須要的是拿下它的勇
氣。在使用庫開發時,咱們須要把libraries 目錄下的庫函數文件添加到工程中,並查閱庫幫助文
檔來了解ST 提供的庫函數,這個文檔說明了每個庫函數的使用方法。進入Libraries 文件夾
看到, 關於內核與外設的庫文件分別存放在CMSIS 和STM32F10x_StdPeriph_Driver 文件夾
中。
STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\文件夾展開內容見圖3-2。
第3 章.初識STM32 標準庫
SAIUR201 6 第23頁
圖3-2 CMSIS 文件夾內容目錄:Libraries\CMSIS\
其中黃色框框住的是咱們須要用到的內容,下面咱們一一講解下這幾個文件的做用。內核相關文件
在CoreSupport 文件夾中有core_cm3.c 和core_cm3.h 兩個文件。Core_cm3.h 頭文件裏面實現了內核
的寄存器映射,對應外設頭文件stm32f10x.h,區別就是一個針對內核的外設,一個針對片上(內核之
外)的外設。core_cm3.c 文件實現了一下操做內核外設寄存器的函數,用的比較少。咱們還須要瞭解
的是core_cm3.h 頭文件中包含了「stdint.h」 這個頭文件,這是一個ANSI C 文件,是獨立於處理器之
外的,就像咱們熟知的C 語言頭文件「stdio.h」 文件同樣。位於RVMDK 這個軟件的安裝目錄下,主
要做用是提供一些類型定義。見代碼清單3-1。
代碼清單3-1:stdint.h 文件中的類型定義
這些新類型定義屏蔽了在不一樣芯片平臺時,出現的諸如int 的大小是16 位,仍是32 位的差別。
因此在咱們之後的程序中,都將使用新類型如uint8_t 、uint16_t 等。在稍舊版的程序中還常常會出現
如u八、u1六、u32 這樣的類型,分別表示的無符號的8 位、16 位、32 位整型。初學者碰到這樣的舊
類型感受一頭霧水,它們定義的位置在STM32f10x.h 文件中。建議在之後的新程序中儘可能使用
第3 章.初識STM32 標準庫
第24 頁SAIUR2016
陳德金老師編著
uint8_t 、uint16_t 類型的定義。啓動文件啓動文件放在startup/arm 這個文件夾下面,這裏面啓動文件
有不少個,不一樣型號的單片機用的啓動文件不同,有關每一個啓動文件的詳細說明見表
咱們開發板中用的STM32F103VET6 或者STM32F103ZET6 的FLASH 都是512K,屬於基本型
的大容量產品,啓動文件統一選擇startup_stm32f10x_hd.s。
Stm32f10x.h
這個頭文件實現了片上外設的因此寄存器的映射,是一個很是重要的頭文件,在內核中與之想對應
的頭文件是core_cm3.h。
system_stm32f10x.c
system_stm32f10x.c 文件實現了STM32 的時鐘配置,操做的是片上的RCC 這個外設。系統在
上電以後,首選會執行由彙編編寫的啓動文件,啓動文件中的復位函數中調用的SystemInit 函數就在
這個文件裏面定義。調用完以後,系統的時鐘就被初始化成72M。若是後面咱們須要從新配置系統時
鍾,咱們就能夠參考這個函數重寫。爲了維持庫的完整性, 咱們不會直接在這個文件裏面修改時鐘配
置函數。
3.4. STM32F10x_StdPeriph_Driver 文件夾
文件目錄: Libraries\STM32F10x_StdPeriph_Driver 進入libraries 目錄下的
STM32F10x_StdPeriph_Driver 文件夾,見圖3-3。
圖3-3 外設驅動
第3 章.初識STM32 標準庫
SAIUR201 6 第25頁
STM32F10x_StdPeriph_Driver 文件夾下有inc(include 的縮寫)跟src(source 的簡寫) 這兩
個文件夾,這裏的文件屬於CMSIS 以外的的、芯片片上外設部分。src 裏面是每一個設備外設的驅動
源程序,inc 則是相對應的外設頭文件。src 及inc 文件夾是ST 標準庫的主要內容,甚至很多人直接
認爲ST 標準庫就是指這些文件,可見其重要性。在src 和inc 文件夾裏的就是ST 公司針對每一個
STM32 外設而編寫的庫函數文件,每一個外設對應一個.c 和.h 後綴的文件。咱們把這類外設文件統稱
爲: stm32f10x_ppp.c 或stm32f10x_ppp.h 文件,PPP 表示外設名稱。如在上一章中咱們自建的
stm32f10x_gpio.c 及tm32f10x_gpio.h 文件,就屬於這一類。如針對模數轉換(ADC)外設,在src 文件
夾下有一個stm32f10x_adc.c 源文件,在inc 文件夾下有一個stm32f10x_adc.h 頭文件,若咱們開發的
工程中用到了STM32 內部的ADC,則至少要把這兩個文件包含到工程裏。見圖3-4。
圖3-4 驅動的源文件及頭文件
這兩個文件夾中,還有一個很特別的misc.c 文件,這個文件提供了外設對內核中的NVIC(中斷向
量控制器) 的訪問函數, 在配置中斷時, 咱們必須把這個文件添加到工程中。stm32f10x_it.c 、
stm32f10x_conf.h 和system_stm32f10x.c 文件
stm32f10x_it.c:這個文件是專門用來編寫中斷服務函數的,在咱們修改前,這個文件
已經定義了一些系統異常(特殊中斷)的接口,其它普通中斷服務函數由咱們本身添加。可是咱們怎麼知
道這些中斷服務函數的接口如何寫?是否是能夠自定義呢?答案固然不是,
這些均可以在彙編啓動文件中找到,在學習中斷和啓動文件的時候咱們會詳細介紹
system_stm32f10x.c:這個文件包含了STM32 芯片上電後初始化系統時鐘、擴展外部存儲器用的
第3 章.初識STM32 標準庫
第26 頁SAIUR2016
陳德金老師編著
函數,例如咱們前兩章提到供啓動文件調用的「SystemInit」函數,用於上電後初始化時鐘,該函數的定
義就存儲在system_stm32f10x.c 文件。STM32F103 系列的芯片,調用庫的這個SystemInit 函數後,
系統時鐘被初始化爲72MHz,若有須要能夠修改這個文件的內容,設置成本身所需的時鐘頻率,但鑑
於保持庫的完整性,咱們在作系統時鐘配置的時候會另外重寫時鐘配置函數。
stm32f10x_conf.h:這個文件被包含進stm32f10x.h 文件。當咱們使用固件庫編程的時候,若是需
要某個外設的驅動庫,就須要包含該外設的頭文件:stm32f10x_ppp.h,包含一個還好,若是是用了多
外設,就須要包含多個頭文件,這不只影響代碼美觀也很差管理,現咱們用一個頭文件stm32f10x_conf.h
把這些外設的頭文件都包含在裏面,讓這個配置頭文件統一管理這些外設的頭文件,咱們在應用程序中
只須要包含這個配置頭文件便可,咱們又知道這個頭文件在stm32f10x.h 的最後被包含,因此最終我
們只須要包含stm32f10x.h 這個頭文件便可,很是方便。Stm32f10x_conf.h 見代碼清單3-2。默認狀況
下是因此頭文件都被包含,沒有被註釋掉。咱們也能夠把不要的都註釋掉,只留下須要使用的便可。
代碼清單3-2 stm32f10x_conf.h 文件配置軟件庫
3.5. 庫各文件間的關係
前面向你們簡單介紹了各個庫文件的做用,庫文件是直接包含進工程便可,絲絕不用修改,而有的
文件就要咱們在使用的時候根據具體的須要進行配置。接下來從總體上把握一下各個文件在庫工程中的
層次或關係,這些文件對應到CMSIS 標準架構上。見圖3-5。
第3 章.初識STM32 標準庫
SAIUR201 6 第27頁
圖3-5 庫各文件關係
圖3-5 描述了STM32 庫各文件之間的調用關係,在實際的使用庫開發工程的過程當中,咱們把位
於CMSIS 層的文件包含進工程,除了特殊系統時鐘須要修改system_stm32f10x.c,其它文件絲絕不用
修改,也不建議修改。對於位於用戶層的幾個文件,就是咱們在使用庫的時候,針對不一樣的應用對庫文
件進行增刪(用條件編譯的方法增刪)和改動的文件。
第3 章.初識STM32 標準庫
第28 頁SAIUR2016
陳德金老師編著
3.6. 初識庫函數
所謂庫函數,就是STM32 的庫文件中爲咱們編寫好驅動外設的函數接口,咱們只要調用這些庫
函數,就能夠對STM32 進行配置,達到控制目的。咱們能夠不知道庫函數是如何實現的,但咱們調
用函數必需要知道函數的功能、可傳入的參數及其意義、和函數的返回值。因而,有讀者就問那麼多函
數我怎麼記呀?個人回答是:會查就好了,哪一個人記得了那麼多。因此咱們學會查閱庫幫助文檔是很
有必要的。打開庫幫助文檔《stm32f10x_stdperiph_lib_um.chm》見圖3-6
圖3-6 庫幫助文檔
層層打開文檔的目錄標籤:標籤目錄:Modules\STM32F10x_StdPeriph_Driver\可看到STM32F10x
_StdPeriph_Driver 標籤下有不少外設驅動文件的名字MISC、ADC、BKP、CAN 等標籤。咱們試着查
看GPIO 的「 位設置函數GPIO_SetBits」 看看, 打開標籤: 標籤目錄:
Modules\STM32F10x_StdPeriph_Driver\GPIO\Functions\GPIO_SetBits 見圖3-7。
第3 章.初識STM32 標準庫
SAIUR201 6 第29頁
圖3-7 庫幫助文檔的函數說明
利用這個文檔,咱們即便沒有去看它的具體源代碼,也知道要怎麼利用它了。如GPIO_SetBits,
函數的原型爲void GPIO_SetBits(GPIO_TypeDef * GPIOx , uint16_tGPIO_Pin)。它的功能是:輸入一
個類型爲GPIO_TypeDef 的指針GPIOx 參數,選定要控制的GPIO 端口;輸入GPIO_Pin_x 宏,其
中x 指端口的引腳號,指定要控制的引腳。其中輸入的參數GPIOx 爲ST 標準庫中定義的自定義數
據類型,這兩個傳入參數均爲結構體指針。初學時,咱們並不知道如GPIO_TypeDef 這樣的類型是什
麼意思,能夠點擊函數原型中帶下劃線的GPIO_TypeDef 就能夠查看這個類型的聲明瞭。就這樣初步
瞭解了一下庫函數,讀者就能夠發現STM32 的庫是寫得很優美的。每一個函數和數據類型都符合見名
知義的原則,固然,這樣的名稱寫起來特別長,並且對於咱們來講要輸入這麼長的英文,很容易出錯,
因此在開發軟件的時候,在用到庫函數的地方,直接把庫幫助文檔中的函數名稱複製粘貼到工程文件就
能夠了。並且,配合MDK 軟件的代碼自動補全功能,能夠減小輸入量。有的用戶以爲使用庫文檔麻
煩,也能夠直接查閱STM32 標準庫的源碼,庫幫助文檔的說明都是根據源碼生成的,因此直接看源
碼也能夠了解函數功能。
3.7. 課後練習
打開ST 標準庫,查看它的各個文件,對比一下ST 標準庫與咱們上一章中工程裏的同名文件,
查看有何差別。
第4 章.GPIO 的使用
第30 頁SAIUR2016
第4 章. GPIO 的使用
4.1. 課前預習
在書上找到答案。
1. STM32 f103zet6 的GPIO 有多少個?
2. STM32 f103zet6 的GPIO 工做模式有哪些?
4.2. 概述
本章所講內容:
(1)STM32 的GPIO 的結構和功能
(2)使用GPIO 點亮LED 燈
利用庫創建好的工程模板,就能夠方便地使用STM32 標準庫編寫應用程序,能夠說從這一章我
們真正開始邁入STM32 固件庫開發的大門。
4.3. GPIO 簡介
GPIO 是通用輸入輸出端口的簡稱,簡單來講就是STM32 可控制的引腳,STM32 芯片的GPIO
引腳與外部設備鏈接起來,從而實現與外部通信、控制以及數據採集的功能。STM32 芯片的GPIO 被
分紅不少組,每組有16 個引腳,如型號爲STM32F103ZET6 型號的芯片有GPIOA、GPIOB、GPIOC
至GPIOG 共7 組GPIO,芯片一共144 個引腳,其中GPIO 就佔了一大部分,全部的GPIO 引腳
都有基本的輸入輸出功能。最基本的輸出功能是由STM32 控制引腳輸出高、低電平,實現開關控制,
如把GPIO 引腳接入到LED 燈,那就能夠控制LED 燈的亮滅,引腳接入到繼電器或三極管,那就可
以經過繼電器或三極管控制外部大功率電路的通斷。最基本的輸入功能是檢測外部輸入電平,如把
GPIO 引腳鏈接到按鍵,經過電平高低區分按鍵是否被按下。
第4 章.GPIO 的使用
SAIUR201 6 第31頁
4.4. GPIO 框圖剖析
圖4-1 GPIO 結構框圖
經過GPIO 硬件結構框圖,就能夠從總體上深刻了解GPIO 外設及它的各類應用模式。該圖從最
右端看起,最右端就是表明STM32 芯片引出的GPIO 引腳,其他部件都位於芯片內部。
4.4.1. 保護二極管及上、下拉電阻
引腳的兩個保護二級管能夠防止引腳外部太高或太低的電壓輸入,當引腳電壓高於VDD 時,上方
的二極管導通,當引腳電壓低於VSS 時,下方的二極管導通,防止不正常電壓引入芯片致使芯片燒
毀。儘管有這樣的保護,並不意味着STM32 的引腳能直接外接大功率驅動器件,如直接驅動電機,
強制驅動要麼電機不轉,要麼致使芯片燒壞,必需要加大功率及隔離電路驅動。
4.4.2. P-MOS 管和N-MOS 管
GPIO 引腳線路通過兩個保護二極管後,向上流向「輸入模式」結構,向下流向「輸出模式」結構。
先看輸出模式部分,線路通過一個由P-MOS 和N-MOS 管組成的單元電路。這個結構使GPIO 具備
了「推輓輸出」和「開漏輸出」兩種模式。所謂的推輓輸出模式,是根據這兩個MOS 管的工做方式來命名
的。在該結構中輸入高電平時,通過反向後,上方的P-MOS 導通,下方的N-MOS 關閉,對外輸出
高電平;而在該結構中輸入低電平時,通過反向後,N-MOS 管導通,P-MOS 關閉,對外輸出低電平。
當引腳高低電平切換時,兩個管子輪流導通,P 管負責灌電流,N 管負責拉電流,使其負載能力和開
關速度都比普通的方式有很大的提升。推輓輸出的低電平爲0 伏,高電平爲3.3 伏,具體參考圖4-2,
它是推輓輸出模式時的等效電路。
第4 章.GPIO 的使用
第32 頁SAIUR2016
圖4-2 推輓等效電路
而在開漏輸出模式時,上方的P-MOS 管徹底不工做。若是咱們控制輸出爲0,低電平,則P-MOS
管關閉,N-MOS 管導通,使輸出接地,若控制輸出爲1 (它沒法直接輸出高電平)時,則P-MOS 管和
N-MOS 管都關閉,因此引腳既不輸出高電平,也不輸出低電平,爲高阻態。爲正常使用時必須外部
接上拉電阻,參考圖8-3 中等效電路。它具備「線與」特性, 也就是說,如有不少個開漏模式引腳鏈接
到一塊兒時,只有當全部引腳都輸出高阻態,才由上拉電阻提供高電平,此高電平的電壓爲外部上拉電
阻所接的電源的電壓。若其中一個引腳爲低電平,那線路就至關於短路接地,使得整條線路都爲低電
平,0 伏。推輓輸出模式通常應用在輸出電平爲0 和3.3 伏並且須要高速切換開關狀態的場合。在
STM32 的應用中,除了必須用開漏模式的場合,咱們都習慣使用推輓輸出模式。開漏輸出通常應用在
I2C、SMBUS 通信等須要「線與」功能的總線電路中。除此以外,還用在電平不匹配的場合,如須要輸
出5 伏的高電平,就能夠在外部接一個上拉電阻,上拉電源爲5 伏,而且把GPIO 設置爲開漏模式,
當輸出高阻態時,由上拉電阻和電源向外輸出5 伏的電平,具體見圖4-3。
第4 章.GPIO 的使用
SAIUR201 6 第33頁
圖4-3 STM32 IO 對外輸出5V 電平
4.4.3. 輸出數據寄存器
前面提到的雙MOS 管結構電路的輸入信號,是由GPIO「輸出數據寄存器GPIOx_ODR」提供的,
所以咱們經過修改輸出數據寄存器的值就能夠修改GPIO 引腳的輸出電平。而「置位/復位寄存器
GPIOx_BSRR」能夠經過修改輸出數據寄存器的值從而影響電路的輸出。
第4 章.GPIO 的使用
第34 頁SAIUR2016
4.4.4. 複用功能輸出
「複用功能輸出」中的「複用」是指STM32 的其它片上外設對GPIO 引腳進行控制,此時GPIO 引
腳用做該外設功能的一部分,算是第二用途。從其它外設引出來的「複用功能輸出信號」與GPIO 自己
的數據據寄存器都鏈接到雙MOS 管結構的輸入中,經過圖中的梯形結構做爲開關切換選擇。例如我
們使用USART 串口通信時,須要用到某個GPIO 引腳做爲通信發送引腳,這個時候就能夠把該
GPIO 引腳配置成USART 串口複用功能,由串口外設控制該引腳,發送數據。
4.4.5. 輸入數據寄存器
GPIO 結構框圖的上半部分,GPIO 引腳通過內部的上、下拉電阻,能夠配置成上/下拉輸入,然
後再鏈接到施密特觸發器,信號通過觸發器後,模擬信號轉化爲0、1 的數字信號,而後存儲在「輸入
數據寄存器GPIOx_IDR」中,經過讀取該寄存器就能夠了解GPIO 引腳的電平狀態。
4.4.6. 複用功能輸入
與「複用功能輸出」模式相似,在「複用功能輸入模式」時,GPIO 引腳的信號傳輸到STM32 其它片
上外設,由該外設讀取引腳狀態。一樣,如咱們使用USART 串口通信時,須要用到某個GPIO 引腳
做爲通信接收引腳,這個時候就能夠把該GPIO 引腳配置成USART 串口複用功能,使USART 能夠
經過該通信引腳的接收遠端數據。
4.4.7. 模擬輸入輸出
當GPIO 引腳用於ADC 採集電壓的輸入通道時,用做「模擬輸入」功能,此時信號是不通過施密
特觸發器的,由於通過施密特觸發器後信號只有0、1 兩種狀態,因此ADC 外設要採集到原始的模
擬信號,信號源輸入必須在施密特觸發器以前。相似地,當GPIO 引腳用於DAC 做爲模擬電壓輸出
通道時,此時做爲「模擬輸出」功能,DAC 的模擬信號輸出就不通過雙MOS 管結構,模擬信號直接
輸出到引腳。
第4 章.GPIO 的使用
SAIUR201 6 第35頁
4.5. GPIO 工做模式
總結一下,由GPIO 的結構決定了GPIO 能夠配置成如下模式:
在固件庫中,GPIO 總共有8 種細分的工做模式,稍加整理能夠大體歸類爲如下三類:
4.5.1. 輸入模式(模擬/浮空/上拉/下拉)
在輸入模式時,施密特觸發器打開,輸出被禁止,可經過輸入數據寄存器GPIOx_IDR 讀取I/O 狀
態。其中輸入模式,可設置爲上拉、下拉、浮空和模擬輸入四種。上拉和下拉輸入很好理解,默認的電
平由上拉或者下拉決定。浮空輸入的電平是不肯定的,徹底由外部的輸入決定,通常接按鍵的時候用的
是這個模式。模擬輸入則用於ADC 採集。
4.5.2. 輸出模式(推輓/開漏)
在輸出模式中,推輓模式時雙MOS 管以輪流方式工做,輸出數據寄存器GPIOx_ODR 可控制I/O
輸出高低電平。開漏模式時,只有N-MOS 管工做,輸出數據寄存器可控制I/O 輸出高阻態或低電平。
輸出速度可配置,有2MHz\10MHz\50MHz 的選項。此處的輸出速度即I/O 支持的高低電平狀態最
高切換頻率,支持的頻率越高,功耗越大,若是功耗要求不嚴格,把速度設置成最大便可。在輸出模式
時施密特觸發器是打開的,即輸入可用,經過輸入數據寄存器GPIOx_IDR 可讀取I/O 的實際狀態。
4.5.3. 複用功能(推輓/開漏)
複用功能模式中,輸出使能,輸出速度可配置,可工做在開漏及推輓模式,可是輸出信號源於其
它外設,輸出數據寄存器GPIOx_ODR 無效;輸入可用,經過輸入數據寄存器可獲取I/O 實際狀態,
但通常直接用外設的寄存器來獲取該數據信號。經過對GPIO 寄存器寫入不一樣的參數,就能夠改變
GPIO 的工做模式,在GPIO 外設中,控制端口高低控制寄存器CRH 和CRL 能夠配置每一個GPIO 的
工做模式和工做的速度,每4 個位控制一個IO,CRH 控制端口的高八位,CRL 控制端口的低8 位,
具體的看CRH 和CRL 的寄存器描述。
第4 章.GPIO 的使用
第36 頁SAIUR2016
圖4-4 GPIO 端口配置低寄存器
第4 章.GPIO 的使用
SAIUR201 6 第37頁
圖4-5 GPIO 端口配置高寄存器
4.6. 點亮LED-硬件設計
在本教程中STM32 芯片與LED 燈的鏈接見圖12-1,這是一個RGB 燈,裏面由紅藍綠三個小燈構
成, 使用PWM 控制時能夠混合成256*256*256 種不一樣的顏色。
圖4-6 LED 硬件原理圖
第4 章.GPIO 的使用
第38 頁SAIUR2016
這些LED 燈的陰極都是鏈接到STM32 的GPIO 引腳,只要咱們控制GPIO 引腳的電平輸出
狀態,便可控制LED 燈的亮滅。若您使用的實驗板LED 燈的鏈接方式或引腳不同, 只需根據我
們的工程修改引腳便可,程序的控制原理相同。點亮LED-軟件設計這裏只講解核心部分的代碼,有些
變量的設置,頭文件的包含等可能不會涉及到,完整的代碼請參考本章配套的工程。爲了使工程更加有
條理,咱們把LED 燈控制相關的代碼獨立分開存儲,方便之後移植。在「工程模板」之上新建
「 bsp_led.c」及「bsp_led.h 」文件,其中的「bsp 」即Board Support Packet 的縮寫(板級支持包),這些文件也
可根據您的喜愛命名,這些文件不屬於STM32 標準庫的內容,是由咱們本身根據應用須要編寫的。
4.7. 點亮LED-編程要點
1. 使能GPIO 端口時鐘;
2. 初始化GPIO 目標引腳爲推輓輸出模式;
3. 編寫簡單測試程序,控制GPIO 引腳輸出高、低電平。
4.8. 點亮LED-代碼分析
4.8.1. LED 燈引腳宏定義
在編寫應用程序的過程當中,要考慮更改硬件環境的狀況,例如LED 燈的控制引腳與當前的不同,
咱們但願程序只須要作最小的修改便可在新的環境正常運行。這個時候通常把硬件相關的部分使用宏來
封裝,若更改了硬件環境,只修改這些硬件相關的宏便可,這些定義通常存儲在頭文件,即本例子中的
「bsp_led.h」文件中,見代碼清單4-1。
代碼清單4-1 LED 控制引腳相關的宏
以上代碼分別把控制LED 燈的GPIO 端口、GPIO 引腳號以及GPIO 端口時鐘封裝起來了。在
實際控制的時候咱們就直接用這些宏,以達到應用代碼硬件無關的效果。其中的GPIO 時鐘宏
「RCC_APB2Periph_GPIOB」 是STM32 標準庫定義的GPIO 端口時鐘相關的宏, 它的做用與
「GPIO_Pin_x」這類宏相似,是用於指示寄存器位的,方便庫函數使用,下面初始化GPIO 時鐘的時候
能夠看到它的用法。
第4 章.GPIO 的使用
SAIUR201 6 第39頁
4.8.2. 控制LED 燈亮滅狀態的宏定義
爲了方便控制LED 燈,咱們把LED 燈經常使用的亮、滅及狀態反轉的控制也直接定義成宏,見代碼清單4-2。
代碼清單4-2 控制LED 亮滅的宏
第4 章.GPIO 的使用
第40 頁SAIUR2016
這部分宏控制LED 亮滅的操做是直接向BSRR、BRR 和ODR 這三個寄存器寫入控制指令來實
現的,對BSRR 寫1 輸出高電平,對BRR 寫1 輸出低電平,對ODR 寄存器某位進行異或操做可
反轉位的狀態。RGB 彩燈能夠實現混色,如最後一段代碼咱們控制紅燈和綠燈亮而藍燈滅,可混出黃
色效果。代碼中的「\」是C 語言中的續行符語法,表示續行符的下一行與續行符所在的代碼是同一行。
代碼中由於宏定義關鍵字「#define」只是對當前行有效,因此咱們使用續行符來鏈接起來,如下的代碼是
等效的:
#define LED_YELLOW LED1_ON; LED2_ON; LED3_OFF
應用續行符的時候要注意,在「\」後面不能有任何字符(包括註釋、空格),只能直接回車。
4.8.3. LED GPIO 初始化函數
利用上面的宏,編寫LED 燈的初始化函數,見代碼清單4-3。
代碼清單4-3 LED GPIO 初始化函數
第4 章.GPIO 的使用
SAIUR201 6 第41頁
整個函數與「構建庫函數雛形」章節中的相似,主要區別是硬件相關的部分使用宏來代替,初始化
GPIO 端口時鐘時也採用了STM32 庫函數,函數執行流程以下:
1. 使用GPIO_InitTypeDef 定義GPIO 初始化結構體變量,以便下面用於存儲GPIO 配置。
2. 調用庫函數RCC_APB2PeriphClockCmd 來使能LED 燈的GPIO 端口時鐘,在前面的章節中我
們是直接向RCC 寄存器賦值來使能時鐘的,不如這樣直觀。該函數有兩個輸入參數,第一個參
數用於指示要配置的時鐘,如本例中的「RCC_ APB2Periph_GPIOB」, 應用時咱們使用「|」操做同時
配置3 個LED 燈的時鐘;函數的第二個參數用於設置狀態,可輸入「Disable」關閉或「Enable」使
能時鐘。
3. 向GPIO 初始化結構體賦值, 把引腳初始化成推輓輸出模式, 其中的GPIO_Pin 使用宏
「LEDx_GPIO_PIN」來賦值,使函數的實現方便移植。
4. 使用以上初始化結構體的配置,調用GPIO_Init 函數向寄存器寫入參數,完成GPIO 的初始化,
這裏的GPIO 端口使用「LEDx_GPIO_PORT」宏來賦值,也是爲了程序移植方便。
5. 使用一樣的初始化結構體,只修改控制的引腳和端口,初始化其它LED 燈使用的GPIO 引腳。
6. 使用宏控制RGB 燈默認關閉。
4.8.4. 主函數
編寫完LED 燈的控制函數後,就能夠在main 函數中測試了,見代碼清單4-4。
代碼清單4-4 控制LED 燈,main 文件
第4 章.GPIO 的使用
第42 頁SAIUR2016
代碼清單4-4 控制LED 燈,main 文件main 函數中,調用咱們前面定義的LED_GPIO_Config
初始化好LED 的控制引腳,而後直接調用各類控制LED 燈亮滅的宏來實現LED 燈的控制。以上,
就是一個使用STM32 標準軟件庫開發應用的流程。
4.9. 點亮LED-下載驗證
把編譯好的程序下載到開發板並復位,可看到RGB 彩燈輪流顯示不一樣的顏色。
4.10. 課後練習
使用GPIO 讓LED 燈顯示不一樣的顏色。
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第43頁
第5 章. STM32 RCC 時鐘系統
5.1. 課前預習
在書上找到答案。
1. APB2 時鐘最大爲多少?
2. 使用標準庫怎麼配置GPIO 的時鐘?
5.2. 概述
本章所講內容:
(1)時鐘系統的結構和使用分析
(2)使用標準庫配置系統時鐘
RCC :reset clock control 復位和時鐘控制器。本章咱們主要講解時鐘部分,特別是要着重理解時
鍾樹,理解了時鐘樹,STM32 的一切時鐘的前因後果都會了如指掌。
5.3. RCC 主要做用—時鐘部分
設置系統時鐘SYSCLK、設置AHB 分頻因子(決定HCLK 等於多少)、設置APB2 分頻因子
(決定PCLK2 等於多少)、設置APB1 分頻因子(決定PCLK1 等於多少)、設置各個外設的分頻
因子;控制AHB、APB2 和APB1 這三條總線時鐘的開啓、控制每一個外設的時鐘的開啓。對於
SYSCLK、HCLK、PCLK二、PCLK1 這四個時鐘的配置通常是:PCLK2 = HCLK = SYSCLK=PLLCLK =
72M,PCLK1=HCLK/2 = 36M。這個時鐘配置也是庫函數的標準配置,咱們用的最多的就是這個。
5.4. RCC 框圖剖析—時鐘部分
時鐘樹單純講理論的話會比較枯燥,若是選取一條主線,並輔以代碼,先主後次講解的話會很容
易, 並且記憶還更深入。咱們這裏選取庫函數時鐘系統時鐘函數: SetSysClockTo72(); 以這個函數的
編寫流程來說解時鐘樹,這個函數也是咱們用庫的時候默認的系統時鐘設置函數。該函數的功能是利
第5 章.STM32 RCC 時鐘系統
第44 頁SAIUR2016
用HSE 把時鐘設置爲:PCLK2 = HCLK = SYSCLK = 72M,PCLK1=HCLK/2 = 36M。下面咱們就以這
個代碼的流程爲主線,來分析時鐘樹,對應的是圖中的黃色部分,代碼流程在時鐘樹中以數字的大小順
序標識。
圖5-1 STM32 時鐘樹
5.5. 系統時鐘
5.5.1. HSE 高速外部時鐘信號
HSE 是高速的外部時鐘信號,能夠由有源晶振或者無源晶振提供,頻率從4-16MHZ 不等。當使
用有源晶振時,時鐘從OSC_IN 引腳進入,OSC_OUT 引腳懸空,當選用無源晶振時,時鐘從OSC_IN
和OSC_OUT 進入,而且要配諧振電容。HSE 最常使用的就是8M 的無源晶振。當肯定PLL 時鐘來
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第45頁
源的時候,HSE 能夠不分頻或者2 分頻,這個由時鐘配置寄存器CFGR 的位17:PLLXTPRE 設置,
咱們設置爲HSE 不分頻。
5.5.2. PLL 時鐘源
PLL 時鐘來源能夠有兩個,一個來自HSE,另一個是HSI/2,具體用哪一個由時鐘配置寄存器
CFGR 的位16:PLLSRC 設置。HSI 是內部高速的時鐘信號,頻率爲8M,根據溫度和環境的狀況頻
率會有漂移,通常不做爲PLL 的時鐘來源。這裏咱們選HSE 做爲PLL 的時鐘來源。
5.5.3. PLL 時鐘PLLCLK
經過設置PLL 的倍頻因子, 能夠對PLL 的時鐘來源進行倍頻, 倍頻因子能夠
是:[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],具體設置成多少,由時鐘配置寄存器CFGR 的位21-18:
PLLMUL[3:0]設置。咱們這裏設置爲9 倍頻,由於上一步咱們設置PLL 的時鐘來源爲HSE=8M,
因此通過PLL 倍頻以後的PLL 時鐘:PLLCLK = 8M *9 = 72M。72M 是ST 官方推薦的穩定運行時
鍾,若是你想超頻的話,增大倍頻因子便可,最高爲128M。咱們這裏設置PLL 時鐘:PLLCLK = 8M
*9 = 72M。
5.5.4. 系統時鐘SYSCLK
系統時鐘來源能夠是:HSI、PLLCLK、HSE,具體的時鐘配置寄存器CFGR 的位1-0:SW[1:0]
設置。咱們這裏設置系統時鐘:SYSCLK = PLLCLK = 72M。
5.5.5. AHB 總線時鐘HCLK
系統時鐘SYSCLK 通過AHB 預分頻器分頻以後獲得時鐘叫APB 總線時鐘,即HCLK,分頻因
子能夠是:[1,2,4,8,16,64,128,256,512],具體的由時鐘配置寄存器CFGR 的位7-4 :HPRE[3:0]
設置。片上大部分外設的時鐘都是通過HCLK 分頻獲得,至於AHB 總線上的外設的時鐘設置爲多少,
得等到咱們使用該外設的時候才設置,咱們這裏只需粗線條的設置好APB 的時鐘便可。咱們這裏設
置爲1 分頻,即HCLK=SYSCLK=72M。
5.5.6. APB2 總線時鐘HCLK2
APB1 APB2 總線時鐘PCLK2 由HCLK 通過高速APB2 預分頻器獲得,分頻因子能夠
是:[1,2,4,8,16],具體由時鐘配置寄存器CFGR 的位13-11:PPRE2[2:0]決定。HCLK2 屬於高速的
總線時鐘,片上高速的外設就掛載到這條總線上,好比所有的GPIO、USART一、SPI1 等。至於APB2
總線上的外設的時鐘設置爲多少,得等到咱們使用該外設的時候才設置,咱們這裏只需粗線條的設置好
APB2 的時鐘便可。咱們這裏設置爲1 分頻,即PCLK2 = HCLK =72M。
第5 章.STM32 RCC 時鐘系統
第46 頁SAIUR2016
5.5.7. 總線時鐘HCLK1
APB1 總線時鐘PCLK1 由HCLK 通過低速APB 預分頻器獲得,分頻因子能夠是:[1,2,4,8,16],
具體的由時鐘配置寄存器CFGR 的位10-8:PRRE1[2:0]決定。HCLK1 屬於低速的總線時鐘,最高爲
36M,片上低速的外設就掛載到這條總線上,好比USART2/3/4/五、SPI2/3,I2C1/2 等。至於APB1 總
線上的外設的時鐘設置爲多少,得等到咱們使用該外設的時候才設置,咱們這裏只需粗線條的設置好
APB1 的時鐘便可。咱們這裏設置爲2 分頻,即PCLK1 = HCLK/2 = 36M。
5.6. 設置系統時鐘庫函數
上面的7 個步驟對應的設置系統時鐘庫函數以下, 該函數截取自固件庫文件
system_stm32f10x.c。爲了方便閱讀,我已把互聯型相關的代碼刪掉,把英文註釋翻譯成了中文,並把
代碼標上了序號,總共七個步驟。該函數是直接操做寄存器的,有關寄存器部分請參考數據手冊的RCC
的寄存器描述部分。
代碼5-1 設置系統時鐘庫函數
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第47頁
5.7. 其餘時鐘
經過對系統時鐘設置的講解,整個時鐘樹咱們已經把握的有六七成,剩下的時鐘部分咱們講解幾個
重要的。
5.7.1. USB 時鐘
USB 時鐘是由PLLCLK 通過USB 預分頻器獲得,分頻因子能夠是:[1,1.5],具體的由時鐘配置
寄存器CFGR 的位22:USBPRE 配置。USB 的時鐘最高是48M,根據分頻因子反推過來算,PLLCLK
只能是48M 或者是72M 。通常咱們設置PLLCLK=72M , USBCLK=48M。USB 對時鐘要求比較
高,因此PLLCLK 只能是由HSE 倍頻獲得,不能使用HSI 倍頻。
5.7.2. Cortex 系統時鐘
Cortex 系統時鐘由HCLK 8 分頻獲得,等於9M,Cortex 系統時鐘用來驅動內核的系統定時器
SysTick,SysTick 通常用於操做系統的時鐘節拍,也能夠用作普通的定時。
第5 章.STM32 RCC 時鐘系統
第48 頁SAIUR2016
5.7.3. ADC 時鐘
ADC 時鐘由PCLK2 通過ADC 預分頻器獲得,分頻因子能夠是[2,4,6,8],具體的由時鐘配置寄
存器CFGR 的位15-14:ADCPRE[1:0]決定。很奇怪的是怎麼沒有1 分頻。ADC 時鐘最高只能是
14M,若是採樣週期設置成最短的1.5 個週期的話,ADC 的轉換時間能夠達到最短的1us。若是真要
達到最短的轉換時間1us 的話,那ADC 的時鐘就得是14M,反推PCLK2 的時鐘只能是:28M、56M、
84M、112M,鑑於PCLK2 最高是72M,因此只能取28M 和56M。
5.7.4. RTC 時鐘、獨立看門狗時鐘
RTC 時鐘可由HSE/128 分頻獲得,也可由低速外部時鐘信號LSE 提供,頻率爲32.768KHZ,也
可由低速內部時鐘信號HSI 提供,具體選用哪一個時鐘由備份域控制寄存器BDCR 的位9-8:
RTCSEL[1:0]配置。獨立看門狗的時鐘由LSI 提供,且只能是由LSI 提供,LSI 是低速的內部時鐘信
號,頻率爲30~60KHZ 直接不等,通常取40KHZ。
5.7.5. MCO 時鐘輸出
MCO 是microcontroller clock output 的縮寫,是微控制器時鐘輸出引腳,在STM32 F1 系列中由
PA8 複用所得,主要做用是能夠對外提供時鐘,至關於一個有源晶振。MCO 的時鐘來源能夠是:
PLLCLK/2 、HSI、HSE 、SYSCLK ,具體選哪一個由時鐘配置寄存器CFGR 的位26-24:MCO[2:0]
決定。除了對外提供時鐘這個做用以外,咱們還能夠經過示波器監控MCO 引腳的時鐘輸出來驗證我
們的系統時鐘配置是否正確。
5.8. 配置系統時鐘實驗
5.8.1. 使用HSE
通常狀況下,咱們都是使用HSE,而後HSE 通過PLL 倍頻以後做爲系統時鐘。一般的配置是:
HSE=8M,PLL 的倍頻因子爲:9,系統時鐘就設置成:SYSCLK = 8M * 9 = 72M。使用HSE,系統時鐘
SYSCLK 最高是128M。咱們使用的庫函數就是這麼幹的, 當程序來到main 函數以前,啓動文件:
statup_stm32f10x_hd.s 已經調用SystemInit()函數把系統時鐘初始化成72MHZ,SystemInit()在庫文件:
system_stm32f10x.c 中定義。若是咱們想把系統時鐘設置低一點或者超頻的話,能夠修改底層的庫文件,
可是爲了維持庫的完整性,咱們能夠根據時鐘樹的流程自行寫一個。
5.8.2. 使用HSI
HSE 故障的時候,若是PLL 的時鐘來源是HSE,那麼當HSE 故障的時候,不只HSE 不能使
用,連PLL 也會被關閉,這個時候系統會自動切換HSI 做爲系統時鐘,此時SYSCLK=HSI=8M,如
果沒有開啓CSS 和CSS 中斷的話,那麼整個系統就只能在低速率運行,這是系統跟癱瘓沒什麼兩樣。
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第49頁
若是開啓了CSS 功能的話,那麼能夠當HSE 故障時,在CSS 中斷裏面採起補救措施,使用HSI,
並把系統時鐘設置爲更高的頻率,最高是64M, 64M 的頻率足夠通常的外設使用,如:ADC 、SPI、
I2C 等。可是這裏就又有一個問題了, 原來SYSCLK=72M,如今由於故障改爲64M,那麼那些外設
的時鐘確定被改變了,那麼外設工做就會被打亂,那咱們是否是在設置HSI 時鐘的時候,也從新調
整外設總線的分頻因子,即AHB,APB2 和APB1 的分頻因子,使外設的時鐘達到跟HSE 沒有故
障以前同樣。可是這個也不是最保障的辦法,畢竟不能一直使用HSI,因此當HSE 故障時仍是要採
取報警措施。還有一種狀況是,有些用戶不想用HSE,想用HSI,可是又不知道怎麼用HSI 來設置
系統時鐘,由於調用庫函數都是使用HSE,下面咱們給出個使用HSI 配置系統時鐘例子, 起個拋磚
引玉的做用。
5.8.3. 硬件設計
一、RCC
二、LED 一個
RCC 是單片機內部資源,不須要外部電路。經過LED 閃爍的頻率來直觀的判斷不一樣系統時鐘頻
率對軟件延時的效果。
5.8.4. 軟件設計
咱們編寫兩個RCC 驅動文件,bsp_clkconfig.h 和bsp_clkconfig.c,用來存放RCC 系統時鐘配置
函數。
5.8.5. 編程要點
編程要點對應着時鐘樹圖中的序號。
一、開啓HSE/HSI ,並等待HSE/HSI 穩定
二、設置AHB、APB二、APB1 的預分頻因子
三、設置PLL 的時鐘來源,和PLL 的倍頻因子,設置各類頻率主要就是在這裏設置
四、開啓PLL,並等待PLL 穩定
五、把PLLCK 切換爲系統時鐘SYSCLK
六、讀取時鐘切換狀態位,確保PLLCLK 被選爲系統時鐘
5.8.6. 代碼分析
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參考
本章配套的工程。使用HSE 配置系統時鐘
第5 章.STM32 RCC 時鐘系統
第50 頁SAIUR2016
代碼5-2 HSE 做爲系統時鐘來源
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第51頁
這個函數採用庫函數編寫, 函數有個形參pllmul,pllmul 用來設置PLL 的倍頻因子,在調用的
時候形參能夠是:RCC_PLLMul_x , x:[2,3,...16],這些宏來源於庫函數的定義,宏展開是一些32 位的
十六進制數,具體功能是配置了時鐘配置寄存器CFGR 的位21-18 PLLMUL[3:0],預先定義好倍頻因
子,方便調用。函數調用舉例:HSE_SetSysClock(RCC_PLLMul_9); 則設置系統時鐘爲:8MHZ * 9 =
72MHZ。HSE_SetSysClock(RCC_PLLMul_16); 則設置系統時鐘爲:8MHZ * 16 = 128MHZ 超頻慎用。
代碼5-3 實用HSI 配置系統時鐘
第5 章.STM32 RCC 時鐘系統
第52 頁SAIUR2016
HSI 設置
系統時鐘函數跟HSE 設置系統時鐘函數在原理上是同樣的,有一個區別的地方就是,HSI 必須2 分
頻以後才能做爲PLL 的時鐘來源,因此使用HSI 時,最大的系統時鐘SYSCLK 只能是
HSI/2*16=4*16=64MHZ。函數調用舉例:HSI_SetSysClock(RCC_PLLMul_9); 則設置系統時鐘爲:4MHZ
* 9 =使用HSI 配置系統時鐘36MHZ。軟件延時
軟件延時函數,使用不一樣的系統時鐘,延時時間不同,能夠經過LED 閃爍的頻率來判斷。
MCO 輸出
在STM32F103 系列中,PA8 能夠複用爲MCO 引腳,對外提供時鐘輸出,咱們也能夠用示波器
監控該引腳的輸出來判斷咱們的系統時鐘是否設置正確。
第5 章.STM32 RCC 時鐘系統
SAIUR201 6 第53頁
代碼5-4 MCO GPIO 初始化
代碼5-5 MCO 輸出時鐘選擇
咱們初始化MCO 引腳以後,能夠直接調用庫函數RCC_MCOConfig()來選擇MCO 時鐘來源。主
函數如代碼5-5
第5 章.STM32 RCC 時鐘系統
第54 頁SAIUR2016
代碼5-5 主函數
在主函數中,能夠調用HSE_SetSysClock()或者HSI_SetSysClock()這兩個函數把系統時鐘設置成
各類經常使用的時鐘,而後經過MCO 引腳監控,或者經過LED 閃爍的快慢體驗不一樣的系統時鐘對同一
個軟件延時函數的影響。
5.8.7. 下載驗證
把編譯好的程序下載到開發板,能夠看到設置不一樣的系統時鐘時,LED 閃爍的快慢不同。更精
確的數據咱們能夠用示波器監控MCO 引腳看到。
圖5-2 MCO=SYSCLK=72M 圖5-3 MCO=HSI=8M
第6 章.STM32 中斷應用概述
SAIUR201 6 第55頁
第6 章. STM32 中斷應用概覽
6.1. 課前預習
在書上找到答案。
1. 什麼是中斷控制器?
2. 怎麼配置NVIC 寄存器
6.2. 概述
本章所講內容:
(1)NVIC 的介紹
(2)NVIC 的配置方法
STM32 中斷很是強大,每一個外設均可以產生中斷,因此中斷的講解放在哪個外設裏面去講都
不合適,這裏單獨抽出一章來作一個總結性的介紹,這樣在其餘章節涉及到中斷部分的知識咱們就不
用費很大的篇幅去講解,只要示意性帶過便可。本章如無特別說明,異常就是中斷,中斷就是異常,請
不要刻意鑽牛角尖較勁。
6.3. 異常類型
STM32F103 在內核水平上搭載了一個異常響應系統, 支持爲數衆多的系統異常和外部中斷。其
中系統異常有8 個(若是把Reset 和HardFault 也算上的話就是10 個),外部中斷有60 個。除了
個別異常的優先級被定死外,其它異常的優先級都是可編程的。有關具體的系統異常和外部中斷可在標
準庫文件stm32f10x.h 這個頭文件查詢到,在IRQn_Type 這個結構體裏面包含了F103 系列所有的異
常聲明。
表格6-1 F103 系統異常清單
第6 章.STM32 中斷應用概述
第56 頁SAIUR2016
表格6-2 F103 外部中斷清單
6.4. NVIC 簡介
在講如何配置中斷優先級以前,咱們須要先了解下NVIC。NVIC 是嵌套向量中斷控制器,控制着
整個芯片中斷相關的功能,它跟內核緊密耦合,是內核裏面的一個外設。可是各個芯片廠商在設計芯片
的時候會對Cortex-M3 內核裏面的NVIC 進行裁剪,把不須要的部分去掉,因此說STM32 的NVIC
是Cortex-M3 的NVIC 的一個子集。
6.5. NVIC 寄存器簡介
在固件庫中,NVIC 的結構體定義可謂是很有遠慮,給每一個寄存器都預留了不少位,恐怕爲的是日
後擴展功能。不過STM32F103 可用不了這麼多,只是用了部分而已,具體使用了多少可參考
第6 章.STM32 中斷應用概述
SAIUR201 6 第57頁
《Cortex-M3 內核編程手冊》-4.3.11:NVIC 寄存器映射。
代碼6-1 NVIC 結構體定義,來自固件庫頭文件:core_cm3.h
在配置中斷的時候咱們通常只用ISER、ICER 和IP 這三個寄存器,ISER 用來使能中斷,ICER 用
來失能中斷,IP 用來設置中斷優先級。
6.6. NVIC 中斷配置固件庫
固件庫文件core_cm3.h 的最後,還提供了NVIC 的一些函數,這些函數遵循CMSIS 規則,只
要是Cortex-M3 的處理器均可以使用,具體以下:
表格6-3 符合CMSIS 標準的NVIC 庫函數
這些庫函數咱們在編程的時候用的都比較少,甚至基本都不用。在配置中斷的時候咱們還有更簡潔
的方法,請看中斷編程小節。
第6 章.STM32 中斷應用概述
第58 頁SAIUR2016
6.7. 優先級的定義
6.7.1. 優先級定義
在NVIC 有一個專門的寄存器:中斷優先級寄存器NVIC_IPRx,用來配置外部中斷的優先級,IPR
寬度爲8bit,原則上每一個外部中斷可配置的優先級爲0~255,數值越小,優先級越高。可是絕大多數
CM3 芯片都會精簡設計,以至實際上支持的優先級數減小,在F103 中,只使用了高4bit,以下所示:
表格6-4 F103 使用4bit 表達優先級
用於表達優先級的這4bit,又被分組成搶佔優先級和子優先級。若是有多箇中斷同時響應,搶佔
優先級高的就會搶佔搶佔優先級低的優先獲得執行,若是搶佔優先級相同,就比較子優先級。若是搶
佔優先級和子優先級都相同的話,就比較他們的硬件中斷編號,編號越小,優先級越高。
6.7.2. 優先級分組
優先級的分組由內核外設SCB 的應用程序中斷及復位控制寄存器AIRCR 的
PRIGROUP[10:8]位決定,F103 分爲了5 組,具體以下:主優先級=搶佔優先級
表格6-5 優先級表
設置優先級分組可調用庫函數NVIC_PriorityGroupConfig()實現,有關NVIC 中斷相關的庫函數
都在庫文件misc.c 和misc.h 中。
表格6-7 優先級分組真值表
第6 章.STM32 中斷應用概述
SAIUR201 6 第59頁
代碼6-2 中斷優先級分組庫函數NVIC_PriorityGroupConfig()
6.8.中斷編程
在配置每一箇中斷的時候通常有3 個編程要點:
1. 使能外設某個中斷,這個具體由每一個外設的相關中斷使能位控制。好比串口有發送完成中斷,接
收完成中斷,這兩個中斷都由串口控制寄存器的相關中斷使能位控制。
2. 初始化NVIC_InitTypeDef 結構體,配置中斷優先級分組,設置搶佔優先級和子優先級,使能中
斷請求。NVIC_InitTypeDef 結構體在固件庫頭文件misc.h 中定義。
代碼6-3 NVIC 初始化結構體
有關NVIC 初始化結構體的成員咱們一一解釋下:
NVIC_IROChannel:用來設置中斷源,不一樣的中斷中斷源不同,且不可寫錯,即便寫錯了程序也不會
報錯,只會致使不響應中斷。具體的成員配置可參考stm32f10x.h 頭文件裏面的IRQn_Type 結構體定
義,這個結構體包含了全部的中斷源。
代碼6-4 IRQn_Type 中斷源結構體
第6 章.STM32 中斷應用概述
第60 頁SAIUR2016
NVIC_IRQChannelPreemptionPriority:搶佔優先級,具體的值要根據優先級分組來肯定.。
NVIC_IRQChannelSubPriority:子優先級,具體的值要根據優先級分組來肯定,具體參考表格17-5 優
先級分組真值表。
NVIC_IRQChannelCmd:中斷使能(ENABLE)或者失能(DISABLE)。操做的是NVIC_ISER 和
NVIC_ICER 這兩個寄存器。
3. 編寫中斷服務函數
在啓動文件startup_stm32f10x_hd.s 中咱們預先爲每一箇中斷都寫了一箇中斷服務函數, 只是這些
中斷函數都是爲空,爲的只是初始化中斷向量表。實際的中斷服務函數都須要咱們從新編寫,爲了方
便管理咱們把中斷服務函數統一寫在stm32f10x_it.c 這個庫文件中。關於中斷服務函數的函數名必須
跟啓動文件裏面預先設置的同樣,若是寫錯,系統就在中斷向量表中找不到中斷服務函數的入口,直
接跳轉到啓動文件裏面預先寫好的空函數, 而且在裏面無限循環,實現不了中斷。
6.9. 課後練習
一、庫文件core_cm3.h 主要實現了什麼?
二、庫文件mics.c 和mics.h 主要實現了什麼?
三、若是實現一次軟件系統復位,具體是操做哪一個寄存器的哪一個位實現?
第7 章.EXTI-外部中斷/事件控制器
SAIUR201 6 第61頁
第7 章. EXTI—外部中斷/事件控制器
7.1. 課前預習
在書上找到答案。
1. EXTI 有多少種?
2. 怎麼使用標準庫配置EXTI
7.2. 概述
本章所講內容:
(1)EXTI 的介紹
(2)EXTI 的配置方法
上一章節咱們已經詳細介紹了NVIC,對STM32F10x 系列中斷管理系統有個全局的瞭解,咱們
這章的內容是NVIC 的實例應用,也是STM32F10x 控制器很是重要的一個資源。學習本章時,配
合《STM32F10X-中文參考手冊》中斷和事件章節一塊兒閱讀,效果會更佳,特別是涉及到寄存器說明的
部分。
7.3. EXTI 簡介
EXTI(External interrupt/event controller)—外部中斷/事件控制器,管理了控制器的20 箇中斷/事
件線。每一箇中斷/事件線都對應有一個邊沿檢測器,能夠實現輸入信號的上升沿檢測和降低沿的檢測。
EXTI 能夠實現對每一箇中斷/事件線進行單獨配置,能夠單獨配置爲中斷或者事件,以及觸發事件的屬
性。
7.4. EXTI 功能框圖
EXTI 的功能框圖包含了EXTI 最核心內容,掌握了功能框圖,對EXTI 就有一個總體的把握,
在編程時思路就很是清晰。EXTI 功能框圖見圖7-1。在圖18-1 能夠看到不少在信號線上打一個斜槓
並標註「20」字樣,這個表示在控制器內部相似的信號線路有20 個,這與EXTI 總共有20 箇中斷/事
陳德金老師編著
第7 章.EXTI-外部中斷/事件控制器
第62 頁SAIUR2016
件線是吻合的。因此咱們只要明白其中一個的原理,那其餘19 個線路原理也就知道了。
圖7-1 EXTI 功能框圖
EXTI 可分爲兩大部分功能,一個是產生中斷,另外一個是產生事件,這兩個功能從硬件上就有所不
同。首先咱們來看圖18-1 中紅色虛線指示的電路流程。它是一個產生中斷的線路,最終信號流入到
NVIC 控制器內。編號1 是輸入線,EXTI 控制器有19 箇中斷/事件輸入線,這些輸入線能夠經過寄
存器設置爲任意一個GPIO,也能夠是一些外設的事件,這部份內容咱們將在後面專門講解。輸入線一
般是存在電平變化的信號。編號2 是一個邊沿檢測電路,它會根據上升沿觸發選擇寄存器(EXTI_RTSR)
和降低沿觸發選擇寄存器(EXTI_FTSR)對應位的設置來控制信號觸發。邊沿檢測電路以輸入線做爲信號
輸入端,若是檢測到有邊沿跳變就輸出有效信號1 給編號3 電路,不然輸出無效信號0。而
EXTI_RTSR 和EXTI_FTSR 兩個寄存器能夠控制器須要檢測哪些類型的電平跳變過程,能夠是隻有上
升沿觸發、只有降低沿觸發或者上升沿和降低沿都觸發。編號3 電路實際就是一個或門電路,它一個
輸入來自編號2 電路,另一個輸入來自軟件中斷事件寄存器(EXTI_SWIER)。EXTI_SWIER 容許我
們經過程序控制就能夠啓動中斷/事件線,這在某些地方很是有用。咱們知道或門的做用就是有1 就爲
1,因此這兩個輸入隨便一個有有效信號1 就能夠輸出1 給編號4 和編號6 電路。編號4 電路是一
個與門電路,它一個輸入是編號3 電路,另一個輸入來自中斷屏蔽寄存器(EXTI_IMR)。與門電路要
求輸入都爲1 才輸出1,致使的結果是若是EXTI_IMR 設置爲0 時,那無論編號3 電路的輸出信
號是1 仍是0,最終編號4 電路輸出的信號都爲0;若是EXTI_IMR 設置爲1 時,最終編號4 電
路輸出的信號才由編號3 電路的輸出信號決定,這樣咱們能夠簡單的控制EXTI_IMR 來實現是否產
生中斷的目的。編號4 電路輸出的信號會被保存到掛起寄存器(EXTI_PR)內,若是肯定編號4 電路輸
出爲1 就會把EXTI_PR 對應位置1。編號5 是將EXTI_PR 寄存器內容輸出到NVIC 內,從而實
現系統中斷事件控制。接下來咱們來看看綠色虛線指示的電路流程。它是一個產生事件的線路,最終
第7 章.EXTI-外部中斷/事件控制器
SAIUR201 6 第63頁
輸出一個脈衝信號。產生事件線路是在編號3 電路以後與中斷線路有所不一樣,以前電路都是共用的。
編號6 電路是一個與門,它一個輸入來自編號3 電路, 另一個輸入來自事件屏蔽寄存器
(EXTI_EMR)。若是EXTI_EMR 設置爲0 時,那無論編號3 電路的輸出信號是1 仍是0,最終編
號6 電路輸出的信號都爲0;若是EXTI_EMR 設置爲1 時,最終編號6 電路輸出的信號才由編號
3 電路的輸出信號決定,這樣咱們能夠簡單的控制EXTI_EMR 來實現是否產生事件的目的。編號7 是
一個脈衝發生器電路,當它的輸入端,即編號6 電路的輸出端,是一個有效信號1 時就會產生一個
脈衝;若是輸入端是無效信號就不會輸出脈衝。編號8 是一個脈衝信號,就是產生事件的線路最終的
產物,這個脈衝信號能夠給其餘外設電路使用,好比定時器TIM、模擬數字轉換器ADC 等等,這樣
的脈衝信號通常用來觸發TIM 或者ADC 開始轉換。產生中斷線路目的是把輸入信號輸入到NVIC,
進一步會運行中斷服務函數,實現功能,這樣是軟件級的。而產生事件線路目的就是傳輸一個脈衝信號
給其餘外設使用,而且是電路級別的信號傳輸,屬於硬件級的。另外,EXTI 是在APB2 總線上的,
在編程時候須要注意到這點。
7.5. 中斷/事件線
EXTI 有20 箇中斷/事件線,每一個GPIO 均可以被設置爲輸入線,佔用EXTI0 至EXTI15,還有另外
七根用於特定的外設事件,見表7-1。4 根特定外設中斷/事件線由外設觸發。
表7-1 EXTI 中斷/事件線
EXTI0 至EXTI15 用於GPIO,經過編程控制能夠實現任意一個GPIO 做爲EXTI 的輸入源。
陳德金老師編著
第7 章.EXTI-外部中斷/事件控制器
第64 頁SAIUR2016
由表7-1 可知,EXTI0 能夠經過AFIO 的外部中斷配置寄存器1(AFIO_EXTICR1)的EXTI0[3:0]位選
擇配置爲PA0、PB0、PC0、PD0、PE0、PF0、PG0、PH0 或者PI0,見圖7-2。其餘EXTI 線(EXTI 中
斷/事件線)使用配置都是相似的。
圖7-2 EXTI0 輸入源選擇
7.6. EXTI 初始化結構體詳解
標準庫函數對每一個外設都創建了一個初始化結構體,好比EXTI_InitTypeDef,結構體成員用於設
置外設工做參數,並由外設初始化配置函數,好比EXTI_Init()調用,這些設定參數將會設置外設相應
的寄存器,達到配置外設工做環境的目的。初始化結構體和初始化庫函數配合使用是標準庫精髓所在,
理解了初始化結構體每一個成員意義基本上就能夠對該外設運用自如了。初始化結構體定義在
stm32f10x_exti.h 文件中,初始化庫函數定義在stm32f10x_exti.c 文件中,編程時咱們能夠結合這兩個
文件內註釋使用。
代碼清單7-1 EXTI 初始化結構體
EXTI_Line:EXTI 中斷/事件線選擇,可選EXTI0 至EXTI19,可參考表7-1 選擇。
EXTI_Mode : EXTI 模式選擇, 可選爲產生中斷(EXTI_Mode_Interrupt) 或者產生事件
(EXTI_Mode_Event)。
EXTI_Trigger:EXTI 邊沿觸發事件,可選上升沿觸發(EXTI_Trigger_Rising)、降低沿觸發
( EXTI_Trigger_Falling) 或者上升沿和降低沿都觸發( EXTI_Trigger_Rising_Falling)。
EXTI_LineCmd:控制是否使能EXTI 線,可選使能EXTI 線(ENABLE)或禁用(DISABLE)。
第7 章.EXTI-外部中斷/事件控制器
SAIUR201 6 第65頁
7.7. 外部中斷控制實驗
中斷在嵌入式應用中佔有很是重要的地位,幾乎每一個控制器都有中斷功能。中斷對保證緊急事件
獲得第一時間處理是很是重要的。咱們設計使用外接的按鍵來做爲觸發源,使得控制器產生中斷,並在
中斷服務函數中實現控制RGB 彩燈的任務。
7.7.1. 硬件設計
輕觸按鍵在按下時會使得引腳接通,經過電路設計能夠使得按下時產生電平變化,見圖7-3。
圖7-3 按鍵電路設計
7.7.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參
考本章配套的工程。咱們建立了兩個文件:bsp_exti.c 和bsp_exti.h 文件用來存放EXTI 驅動程序及相
關宏定義,中斷服務函數放在stm32f10x_it.h 文件中。
7.7.3. 編程要點
1.初始化用來產生中斷的GPIO;
2.初始化EXTI;
3.配置NVIC;
4.編寫中斷服務函數;
7.7.4. 代碼分析
使用宏定義方法指定與硬件電路設計相關配置,這對於程序移植或升級很是有用的。在上面的宏定
義中,咱們除了開GPIO 的端口時鐘外,咱們還打開了AFIO 的時鐘,這是由於等下配置EXTI 信號
源的時候須要用到AFIO 的外部中斷控制寄存器AFIO_EXTICRx,具體見《STM32F10X-中文參考手
冊》8.4 章節AFIO 寄存器描述。嵌套向量中斷控制器NVIC 配置有關NVIC 配置問題可參考《STM32
中斷應用概覽》章節內容,這裏不作過多解釋。這裏咱們配置兩個的中斷軟件優先級同樣,若是出現了
兩個按鍵同時按下的狀況,那怎麼辦,到底該執行哪個中斷?當兩個中斷的軟件優先級同樣的時候,
陳德金老師編著
第7 章.EXTI-外部中斷/事件控制器
第66 頁SAIUR2016
中斷來臨時,具體先執行哪一個中斷服務函數由硬件的中斷編號決定,編號越小,優先級越高。有關外設
的硬件編號可查詢《STM32F10X-中文參考手冊》的中斷和事件章節中的向量表,表中的位置編號即
是每一個外設的硬件中斷優先級。固然,咱們也能夠把搶佔優先級設置成同樣,子優先級設置成不同,
這樣就能夠區別兩個按鍵同時按下的狀況,而不用硬件去對比硬件編號。
代碼清單7-2 按鍵和EXTI 宏定義
代碼清單7-3 NVIC 配置
第7 章.EXTI-外部中斷/事件控制器
SAIUR201 6 第67頁
EXTI 中斷配置
代碼清單7-4 EXTI 中斷配置
首先,使用GPIO_InitTypeDef 和EXTI_InitTypeDef 結構體定義兩個用於GPIO 和EXTI 初始化
配置的變量,關於這兩個結構體前面都已經作了詳細的講解。使用GPIO 以前必須開啓GPIO 端口的
時鐘;用到EXTI 必須開啓AFIO 時鐘。調用NVIC_Configuration 函數完成對按鍵一、按鍵2 優
先級配置並使能中斷通道。做爲中斷/事件輸入線時需把GPIO 配置爲輸入模式,具體爲浮空輸入,由
外部電路徹底決定引腳的狀態。GPIO_EXTILineConfig 函數用來指定中斷/事件線的輸入源,它實際是
陳德金老師編著
第7 章.EXTI-外部中斷/事件控制器
第68 頁SAIUR2016
設定外部中斷配置寄存器的AFIO_EXTICRx 值,該函數接收兩個參數,第一個參數指定GPIO 端口
源,第二個參數爲選擇對應GPIO 引腳源編號。咱們的目的是產生中斷,執行中斷服務函數,EXTI 選
擇中斷模式,按鍵1 使用上升沿觸發方式,並使能EXTI 線。按鍵2 基本上採用與按鍵1 相關參數
配置,只是改成降低沿觸發方式。兩個按鍵的電路是同樣的,可代碼中咱們設置按鍵1 是上升沿中斷,
按鍵2 是降低沿中斷,有人就會問這是否是設置錯了?實際上能夠這麼理解,按鍵1 檢測的是按鍵按
下的狀態,按鍵2 檢測的是按鍵彈開的狀態,那這樣就解釋的通了。
代碼清單7-5 EXTI 中斷服務函數
當中斷髮生時,對應的中斷服務函數就會被執行,咱們能夠在中斷服務函數實現一些控制。通常爲
確保中斷確實發生,咱們會在中斷服務函數中調用中斷標誌位狀態讀取函數讀取外設中斷標誌位並判斷
標誌位狀態。EXTI_GetITStatus 函數用來獲取EXTI 的中斷標誌位狀態,若是EXTI 線有中斷髮生函
數返回「 SET 」 不然返回「 RESET 」 。實際上, EXTI_GetITStatus 函數是經過讀取EXTI_PR
寄存器值來判斷EXTI 線狀態的。按鍵1 的中斷服務函數咱們讓LED1 翻轉其狀態,按鍵2 的中斷
服務函數咱們讓LED2 翻轉其狀態。執行任務後須要調用EXTI_ClearITPendingBit 函數清除EXTI 線
的中斷標誌位。主函數
代碼清單7-6 主函數
主函數很是簡單,只有兩個任務函數。LED_GPIO_Config 函數定義在bsp_led.c 文件內,完成RGB
第7 章.EXTI-外部中斷/事件控制器
SAIUR201 6 第69頁
彩燈的GPIO 初始化配置。EXTI_Key_Config 函數完成兩個按鍵的GPIO 和EXTI 配置。
7.7.5. 下載驗證
保證開發板相關硬件鏈接正確,把編譯好的程序下載到開發板。此時RGB 彩色燈是暗的,若是
咱們按下開發板上的按鍵1,RGB 彩燈變亮,再按下按鍵1,RGB 彩燈又變暗;若是咱們按下開發
板上的按鍵2 並彈開,RGB 彩燈變亮,再按下開發板上的KEY2 並彈開,RGB 彩燈又變暗。按鍵
按下表示上升沿,按鍵彈開表示降低沿,這跟咱們軟件設置是同樣的。
7.8. 課後練習
一、是否能夠同時使用PA0 和PB0 中斷?若是不能夠,有什麼解決方法。
二、從硬件角度結合程序分析,爲何按下按鍵1RGB 彩燈就立刻變化,而按鍵2 卻須要按下
按鍵再彈開以後RGB 彩燈才變化?
第8 章.SysTick 系統定時器
第70 頁SAIUR2016
第8 章. SysTick 系統定時器
8.1. 課前預習
在書上找到答案。
1. SysTIck 和系統時鐘有什麼區別?
8.2. 概述
本章所講內容:
(1)SysTick 的說明和使用
8.3. SysTick 簡介
SysTick—系統定時器是屬於CM3 內核中的一個外設,內嵌在NVIC 中。系統定時器是一個24bit
的向下遞減的計數器,計數器每計數一次的時間爲1/SYSCLK,通常咱們設置系統時鐘SYSCLK 等於
72M。當重裝載數值寄存器的值遞減到0 的時候,系統定時器就產生一次中斷,以此循環往復。由於
SysTick 是屬於CM3 內核的外設,因此全部基於CM3 內核的單片機都具備這個系統定時器,使得
軟件在CM3 單片機中能夠很容易的移植。系統定時器通常用於操做系統,用於產生時基,維持操做
系統的心跳。
8.4. SysTick 寄存器介紹
SysTick—系統定時器有4 個寄存器,簡要介紹以下。在使用SysTick 產生定時的時候,須要配置
前三個寄存器,最後一個校準寄存器不須要使用。
表8-1 SysTick 寄存器彙總
第8 章.SysTick 系統定時器
SAIUR201 6 第71頁
表8-2 SysTick 控制及狀態寄存器
表8-3 SysTick 重裝載數值寄存器
表8-4 SysTick 當前數值寄存器
第8 章.SysTick 系統定時器
第72 頁SAIUR2016
表8-5 SysTick 當前數值寄存器
系統定時器的校準數值寄存器在定時實驗中不須要用到。有關各個位的描述這裏引用手冊裏面的英
文版本,比較晦澀難懂,暫時不知道這個寄存器用來幹什麼。有研究過的朋友能夠交流,起個拋磚引玉
的做用。
8.5. SysTick 定時實驗
利用SysTick 產生1s 的時基,LED 以1s 的頻率閃爍。
8.5.1. 硬件設計
SysTick 屬於單片機內部的外設,不須要額外的硬件電路,剩下的只需一個LED 燈便可。
8.5.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參
考本章配套的工程。咱們建立了兩個文件:bsp_SysTick.c 和bsp_ SysTick.h 文件用來存放SysTick 驅
動程序及相關宏定義,中斷服務函數放在stm32f10x_it.h 文件中。
8.5.3. 編程要點
一、設置重裝載寄存器的值
二、清除當前數值寄存器的值
三、配置控制與狀態寄存器
第8 章.SysTick 系統定時器
SAIUR201 6 第73頁
8.5.4. 代碼分析
SysTick 屬於內核的外設, 有關的寄存器定義和庫函數都在內核相關的庫文件core_cm3.h 中。
SysTick 配置庫函數
代碼8-1 SysTick 配置庫函數
用固件庫編程的時候咱們只須要調用庫函數SysTick_Config()便可,形參ticks 用來設置重裝載寄
存器的值,最大不能超太重裝載寄存器的值224,當重裝載寄存器的值遞減到0 的時候產生中斷,然
後重裝載寄存器的值又從新裝載往下遞減計數,以此循環往復。緊隨其後設置好中斷優先級,最後配置
系統定時器的時鐘等於AHBCLK=72M,使能定時器和定時器中斷,這樣系統定時器就配置好了,一個
庫函數搞定。SysTick_Config()庫函數主要配置了SysTick 中的三個寄存器:LOAD、VAL 和CTRL,
有關具體的部分看代碼註釋便可。
配置SysTick 中斷優先級
在SysTick_Config()庫函數還調用了固件庫函數NVIC_SetPriority()來配置系統定時器的中斷優先
級,該庫函數也在core_m3.h 中定義,原型以下:
函數首先先判斷形參IRQn 的大小,若是是小於0,則表示這個是系統異常,系統異常的優先級
由內核外設SCB 的寄存器SHPRx 控制,若是大於0 則是外部中斷,外部中斷的優先級由內核外設
NVIC 中的IPx 寄存器控制。由於SysTick 屬於內核外設,跟普通外設的中斷優先級有些區別,並沒
有搶佔優先級和子優先級的說法。在STM32F103 中,內核外設的中斷優先級由內核SCB 這個外設的
第8 章.SysTick 系統定時器
第74 頁SAIUR2016
寄存器:SHPRx(x=1.2.3)來配置。有關SHPRx 寄存器的詳細描述可參考《Cortex-M3 內核編程手冊》
4.4.8 章節。下面咱們簡單介紹下這個寄存器。SPRH1-SPRH3 是一個32 位的寄存器,可是隻能經過
字節訪問,每8 個字段控制着一個內核外設的中斷優先級的配置。在STM32F103 中,只有位7:3 這
高四位有效,低四位沒有用到,因此內核外設的中斷優先級可編程爲:0~15,只有16 個可編程優先
級,數值越小,優先級越高。若是軟件優先級配置相同,那就根據他們在中斷向量表裏面的位置編號來
決定優先級大小,編號越小,優先級越高。
表8-6 系統異常優先級字段
若是要修改內核外設的優先級,只須要修改下面三個寄存器對應的某個字段便可。
圖8-1 SHPR1 寄存器
圖8-2 SHPR2 寄存器
第8 章.SysTick 系統定時器
SAIUR201 6 第75頁
圖8-3 SHPR3 寄存器
系統定時器中, 配置優先級爲(1UL << __NVIC_PRIO_BITS) - 1UL) , 其中宏
__NVIC_PRIO_BITS 爲4,那計算結果就等於15,能夠看出系統定時器此時設置的優先級在內核外設
中是最低的,若是要修改優先級則修改這個值便可,範圍爲:0~15。
systick 和片上外設呢?並且片上外設也恰好須要使用中斷,那systick 的中斷優先級跟外設的中
斷優先級怎麼設置?會不會由於systick 是內核裏面的外設,因此它的中斷優先級就必定比內核以外的
外設的優先級高?
從《STM32 中斷應用概覽》這章咱們知道,外設在設置中斷優先級的時候,首先要分組,而後
設置搶佔優先級和子優先級。而systick 這類內核的外設在配置的時候,只須要配置一個寄存器便可,
取值範圍爲0~15。既然配置方法不一樣,那如何區分二者的優先級?下面舉例說明。好比配置一個外設
的中斷優先級分組爲2,搶佔優先級爲1,子優先級也爲1,systick 的優先級爲固件庫默認配置的15。
當咱們比較內核外設和片上外設的中斷優先級的時候,咱們只須要抓住NVIC 的中斷優先級分組不只
對片上外設有效,一樣對內核的外設也有效。咱們把systick 的優先級15 轉換成二進制值就是
1111(0b),又由於NVIC 的優先級分組2,那麼前兩位的11(0b)就是3,後兩位的11(0b)也是3。無
論從搶佔仍是子優先級都比咱們設定的外設的優先級低。若是當兩個的軟件優先級都配置成同樣,那麼
就比較他們在中斷向量表中的硬件編號,編號越小,優先級越高。
第8 章.SysTick 系統定時器
第76 頁SAIUR2016
SysTick 初始化函數
代碼8-2 SysTick 初始化函數
SysTick 初始化函數由用戶編寫,裏面調用了SysTick_Config()這個固件庫函數,經過設置該固件
庫函數的形參,就決定了系統定時器通過多少時間就產生一次中斷。
SysTick 中斷時間的計算
SysTick 定時器的計數器是向下遞減計數的,計數一次的時間TDEC=1/CLKAHB,當重裝載寄存
器中的值VALUELOAD 減到0 的時候, 產生中斷, 可知中斷一次的時間TINT=VALUELOAD *
TDEC= VALUELOAD/CLKAHB , 其中CLKAHB =72MHZ 。若是設置VALUELOAD 爲72,
那中斷一次的時間TINT=72/72M=1us。不過1us 的中斷沒啥意義,整個程序的重心都花在進出中斷上
了,根本沒有時間處理其餘的任務。
SysTick_Config()的形咱們配置爲SystemCoreClock / 100000=72M/100000=720,從剛剛分析我
們知道這個形參的值最終是寫到重裝載寄存器LOAD 中的,從而可知咱們如今把SysTick 定時器中斷
一次的時間TINT=720/72M=10us。
SysTick 定時時間的計算
當設置好中斷時間TINT 後,咱們能夠設置一個變量t,用來記錄進入中斷的次數,那麼變量t 乘
以中斷的時間TINT 就能夠計算出須要定時的時間。
第8 章.SysTick 系統定時器
SAIUR201 6 第77頁
SysTick 定時函數
如今咱們定義一個微秒級別的延時函數,形參爲nTime,當用這個形參乘以中斷時間TINT 就得
出咱們須要的延時時間,其中TINT 咱們已經設置好爲10us。關於這個函數的具體調用看註釋便可。
函數Delay_us()中咱們等待TimingDelay 爲0,當TimingDelay 爲0 的時候表示延時時間到。變
量TimingDelay 在中斷函數中遞減,即SysTick 每進一次中斷即10us 的時間TimingDelay 遞減一次。
SysTick 中斷服務函數
中斷復位函數調用了另一個函數TimingDelay_Decrement(),原型以下:
TimingDelay 的值等於延時函數中傳進去的nTime 的值,好比nTime=100000,則延時的時間等於
100000*10us=1s。
第8 章.SysTick 系統定時器
第78 頁SAIUR2016
主函數中初始化了LED 和SysTick,而後在一個while 循環中以1s 的頻率讓LED 閃爍。另
外一種更簡潔的定時編程上面的實驗,咱們是使用了中斷,並且通過多個函數的調用,還使用了全局變
量,理解起來挺費勁的,其實還有另一種更簡潔的寫法。咱們知道,systick 的counter 從reload 值
往下遞減到0 的時候,CTRL 寄存器的位16:countflag 會置1,且讀取該位的值可清0,全部咱們可
以使用軟件查詢的方法來實現延時。具體代碼見代碼8-3 和代碼8-4,我敢確定這樣的寫法,初學者
確定會更喜歡,由於它直接,套路淺。
代碼8-3 systick 微秒級延時
在這兩個微秒和毫秒級別的延時函數中,咱們仍是調用了SysTick_Config 這個固件庫函數, 有關
這個函數的說明具體見代碼19-5 。配套代碼註釋理解便可。其中SystemCoreClock 是一個宏,大
小爲72000000,若是不想使用這個宏,也能夠直接改爲數字。
第8 章.SysTick 系統定時器
SAIUR201 6 第79頁
8.6. 課後練習
一、若是修改SysTick 的中斷優先級?
二、如何計算SysTick 進入一次中斷的時間?
三、如何利用SysTick 實現一個1ms 的延時?
第9 章.USART-串口通信
第80 頁SAIUR2016
第9 章. USART—串口通信
9.1. 課前預習
在書上找到答案。
1. 同步和異步的區別?
2. USART 有多少個引腳?
9.2. 概述
本章所講內容:
(1)USART 的介紹
(2)使用串口發送和接收數據
9.3. 串口通信協議簡介
串口通信(Serial Communication)是一種設備間很是經常使用的串行通信方式,由於它簡單便捷,所以
大部分電子設備都支持該通信方式,電子工程師在調試設備時也常用該通信方式輸出調試信息。
在計算機科學裏,大部分複雜的問題均可以經過分層來簡化。如芯片被分爲內核層和片上外設;STM32
標準庫則是在寄存器與用戶代碼之間的軟件層。對於通信協議,咱們也以分層的方式來理解,最基本
的是把它分爲物理層和協議層。物理層規定通信系統中具備機械、電子功能部分的特性,確保原始數
據在物理媒體的傳輸。協議層主要規定通信邏輯, 統一收發雙方的數據打包、解包標準。簡單來講物
理層規定咱們用嘴巴仍是用肢體來交流, 協議層則規定咱們用中文仍是英文來交流。下面咱們分別對
串口通信協議的物理層及協議層進行講解。
9.3.1. 物理層
串口通信的物理層有不少標準及變種,咱們主要講解RS-232 標準,RS-232 標準主要規定了信
號的用途、通信接口以及信號的電平標準。使用RS-232 標準的串口設備間常見的通信結構見圖9-1。
第9 章.USART-串口通信
SAIUR201 6 第81頁
圖9-1 串口通信結構圖
在上面的通信方式中,兩個通信設備的「DB9 接口」之間經過串口信號線創建起鏈接, 串口信號線
中使用「RS-232 標準」傳輸數據信號。因爲RS-232 電平標準的信號不能直接被控制器直接識別,因此
這些信號會通過一個「電平轉換芯片」轉換成控制器能識別的「TTL 標準」的電平信號,才能實現通信。
電平標準
根據通信使用的電平標準不一樣,串口通信可分爲TTL 標準及RS-232 標準,見表9-1。
表9-1 TTL 電平標準與RS232 電平標準
咱們知道常見的電子電路中常使用TTL 的電平標準,理想狀態下,使用5V 表示二進制邏輯1,
使用0V 表示邏輯0;而爲了增長串口通信的遠距離傳輸及抗干擾能力,它使用-15V 表示邏輯1,+15V
表示邏輯0。使用RS232 與TTL 電平校準表示同一個信號時的對比見圖8-2。
圖9-2 RS-232 與TTL 電平標準下表示同一個信號
由於控制器通常使用TTL 電平標準,因此經常會使用MA3232 芯片對TTL 及RS-232 電平的信
第9 章.USART-串口通信
第82 頁SAIUR2016
號進行互相轉換。
RS-232 信號線
在最初的應用中,RS-232 串口標準經常使用於計算機、路由與調製調解器(MODEN,俗稱「貓」)之間的
通信,在這種通信系統中,設備被分爲數據終端設備DTE(計算機、路由)和數據通信設備DCE(調製
調解器)。咱們以這種通信模型講解它們的信號線鏈接方式及各個信號線的做用。在舊式的臺式計算機
中通常會有RS-232 標準的COM 口(也稱DB9 接口),見圖9-3。
圖9-3 電腦主板上的COM 口及串口線
其中接線口以針式引出信號線的稱爲公頭,以孔式引出信號線的稱爲母頭。在計算機中通常引出
公頭接口,而在調製調解器設備中引出的通常爲母頭,使用上圖中的串口線便可把它與計算機鏈接起
來。通信時,串口線中傳輸的信號就是使用前面講解的RS-232 標準調製的。在這種應用場合下,DB9
接口中的公頭及母頭的各個引腳的標準信號線接法見圖9-4 及表9-2。
第9 章.USART-串口通信
SAIUR201 6 第83頁
圖9-4 DB9 標準的公頭及母頭接法
表9-2 DB9 信號線說明(公頭,爲方便理解,可把DTE 理解爲計算機,DCE 理解爲調製調解
器)
上表中的是計算機端的DB9 公頭標準接法,因爲兩個通信設備之間的收發信號(RXD 與TXD)應
交叉相連,因此調製調解器端的DB9 母頭的收發信號接法通常與公頭的相反,兩個設備之間鏈接時,
只要使用「直通型」的串口線鏈接起來便可,見圖9-5。
第9 章.USART-串口通信
第84 頁SAIUR2016
圖9-5 計算機與調製調解器的信號線鏈接
串口線中的RTS、CTS、DSR、DTR 及DCD 信號,使用邏輯1 表示信號有效,邏輯0 表示信
號無效。例如,當計算機端控制DTR 信號線表示爲邏輯1 時,它是爲了告知遠端的調製調解器,本
機已準備好接收數據,0 則表示還沒準備就緒。在目前的其它工業控制使用的串口通信中,通常只使用
RXD、TXD 以及GND 三條信號線,直接傳輸數據信號,而RTS、CTS、DSR、DTR 及DCD 信號
都被裁剪掉了。
9.3.2. 協議層
串口通信的數據包由發送設備經過自身的TXD 接口傳輸到接收設備的RXD 接口。在串口通信
的協議層中,規定了數據包的內容,它由啓始位、主體數據、校驗位以及中止位組成,通信雙方的數據
包格式要約定一致才能正常收發數據,其組成見圖9-6。
圖9-6 串口數據包的基本組成
波特率
本章中主要講解的是串口異步通信,異步通信中因爲沒有時鐘信號(如前面講解的DB9 接口中是沒
有時鐘信號的),因此兩個通信設備之間須要約定好波特率,即每一個碼元的長度,以便對信號進行解碼,
圖21-6 中用虛線分開的每一格就是表明一個碼元。常見的波特率爲4800、9600、115200 等。
通信的起始和中止信號
串口通信的一個數據包從起始信號開始,直到中止信號結束。數據包的起始信號由一個邏輯0 的
數據位表示,而數據包的中止信號可由0.五、一、1.5 或2 個邏輯1 的數據位表示,只要雙方約定一致
便可。
有效數據
在數據包的起始位以後緊接着的就是要傳輸的主體數據內容,也稱爲有效數據,有效數據的長度常
被約定爲五、六、7 或8 位長。
第9 章.USART-串口通信
SAIUR201 6 第85頁
數據校驗
在有效數據以後,有一個可選的數據校驗位。因爲數據通訊相對更容易受到外部干擾致使傳輸數據
出現誤差,能夠在傳輸過程加上校驗位來解決這個問題。校驗方法有奇校驗(odd)、偶校驗(even)、0 校
驗(space)、1 校驗(mark)以及無校驗(noparity)。奇校驗要求有效數據和校驗位中「1」的個數爲奇數,好比
一個8 位長的有效數據爲:01101001,此時總共有4 個「1」,爲達到奇校驗效果,校驗位爲「1」,最後
傳輸的數據將是8 位的有效數據加上1 位的校驗位總共9 位。偶校驗與奇校驗要求恰好相反,要求
幀數據和校驗位中「1」的個數爲偶數,好比數據幀:11001010,此時數據幀「1」的個數爲4 個,因此偶
校驗位爲「0」。0 校驗是無論有效數據中的內容是什麼,校驗位總爲「0」,1 校驗是校驗位總爲「1」。
9.4. STM32 的USART 簡介
通用同步異步收發器(Universal Synchronous Asynchronous Receiver and Transmitter)是一個串行通訊
設備,能夠靈活地與外部設備進行全雙工數據交換。有別於USART 還有一個UART(Universal
Asynchronous Receiver and Transmitter),它是在USART 基礎上裁剪掉了同步通訊功能,只有異步通訊。
簡單區分同步和異步就是看通訊時需不須要對外提供時鐘輸出,咱們平時用的串口通訊基本都是
UART。串行通訊通常是以幀格式傳輸數據,便是一幀一幀的傳輸,每幀包含有起始信號、數據信息、
中止信息,可能還有校驗信息。USART 就是對這些傳輸參數有具體規定,固然也不是隻有惟一一個
參數值,不少參數值均可以自定義設置,只是加強它的兼容性。USART 知足外部設備對工業標準NRZ
異步串行數據格式的要求,而且使用了小數波特率發生器,能夠提供多種波特率,使得它的應用更加
普遍。USART 支持同步單向通訊和雙工單線通訊;還支持局域互連網絡LIN、智能卡(SmartCard)協議
與lrDA(紅外線數據協會) SIR ENDEC 規範。USART 支持使用DMA,可實現高速數據通訊,有關
DMA 具體應用將在DMA 章節做具體講解。USART 在STM32 應用最多莫過於「打印」程序信息,一
般在硬件設計時都會預留一個USART 通訊接口鏈接電腦,用於在調試程序是能夠把一些調試信息
「打印」在電腦端的串口調試助手工具上,從而瞭解程序運行是否正確、若是出錯哪具體哪裏出錯等等。
9.5. USART 功能框圖
USART 的功能框圖包含了USART 最核心內容,掌握了功能框圖,對USART 就有一個總體的
把握,在編程時就思路就很是清晰。USART 功能框圖見圖9-7。
第9 章.USART-串口通信
第86 頁SAIUR2016
圖9-7 USART 功能框圖
功能引腳
TX:發送數據輸出引腳。
RX:接收數據輸入引腳。
SW_RX:數據接收引腳,只用於單線和智能卡模式,屬於內部引腳,沒有具體外部引腳。
nRTS:請求以發送(Request To Send),n 表示低電平有效。若是使能RTS 流控制,當
USART 接收器準備好接收新數據時就會將nRTS 變成低電平;當接收寄存器已滿時,nRTS 將被
設置爲高電平。該引腳只適用於硬件流控制。
nCTS:清除以發送(Clear To Send),n 表示低電平有效。若是使能CTS 流控制,發送器在發送下
一幀數據以前會檢測nCTS 引腳,若是爲低電平,表示能夠發送數據,若是爲高電平則在發送完當前
數據幀以後中止發送。該引腳只適用於硬件流控制。
SCLK:發送器時鐘輸出引腳。這個引腳僅適用於同步模式。
USART 引腳在STM32F103ZET6 芯片具體分佈見表21-3。
表9-3 STM32F103VET6 芯片的USART 引腳
第9 章.USART-串口通信
SAIUR201 6 第87頁
STM32F103VET6 系統控制器有三個USART 和兩個UART,其中USART1 和時鐘來源於
APB2 總線時鐘,其最大頻率爲72MHz,其餘四個的時鐘來源於APB1 總線時鐘,其最大頻率爲
36MHz。UART 只是異步傳輸功能,因此沒有SCLK、nCTS 和nRTS 功能引腳。
數據寄存器
USART 數據寄存器(USART_DR)只有低9 位有效,而且第9 位數據是否有效要取決於USART
控制寄存器1(USART_CR1)的M 位設置,當M 位爲0 時表示8 位數據字長,當M 位爲1 表示9
位數據字長,咱們通常使用8 位數據字長。USART_DR 包含了已發送的數據或者接收到的數據。
USART_DR 實際是包含了兩個寄存器,一個專門用於發送的可寫TDR,一個專門用於接收的可讀
RDR。當進行發送操做時, 往USART_DR 寫入數據會自動存儲在TDR 內;當進行讀取操做時,向
USART_DR 讀取數據會自動提取RDR 數據。TDR 和RDR 都是介於系統總線和移位寄存器之間。
串行通訊是一個位一個位傳輸的, 發送時把TDR 內容轉移到發送移位寄存器,而後把移位寄存器數
據每一位發送出去,接收時把接收到的每一位順序保存在接收移位寄存器內而後才轉移到RDR。
USART 支持DMA 傳輸,能夠實現高速數據傳輸,具體DMA 使用將在DMA 章節講解。
控制器
USART 有專門控制發送的發送器、控制接收的接收器,還有喚醒單元、中斷控制等等。
使用USART 以前須要向USART_CR1 寄存器的UE 位置1 使能USART,UE 位用來開啓供
給給串口的時鐘。發送或者接收數據字長可選8 位或9 位,由USART_CR1 的M 位控制。發送器
當USART_CR1 寄存器的發送使能位TE 置1 時,啓動數據發送,發送移位寄存器的數據會在TX
引腳輸出,低位在前,高位在後。若是是同步模式SCLK 也輸出時鐘信號。一個字符幀發送須要三個
部分:起始位+數據幀+中止位。起始位是一個位週期的低電平,位週期就是每一位佔用的時間;數據
幀就是咱們要發送的8 位或9 位數據,數據是從最低位開始傳輸的;中止位是必定時間週期的高電
平。中止位時間長短是能夠經過USART 控制寄存器2(USART_CR2)的STOP[1:0]位控制,可選0.5
個、1 個、1.5 個和2 箇中止位。默認使用1 箇中止位。2 箇中止位適用於正常USART 模式、單線
模式和調制解調器模式。0.5 個和1.5 箇中止位用於智能卡模式。當選擇8 位字長,使用1 箇中止位
時,具體發送字符時序圖見圖9-8。
第9 章.USART-串口通信
第88 頁SAIUR2016
圖9-8 字符發送時序圖
當發送使能位TE 置1 以後,發送器開始會先發送一個空閒幀(一個數據幀長度的高電平),接下
來就能夠往USART_DR 寄存器寫入要發送的數據。在寫入最後一個數據後,須要等待USART 狀
態寄存器(USART_SR) 的TC 位爲1 , 表示數據傳輸完成, 若是USART_CR1 寄存器的TCIE
位置1,將產生中斷。在發送數據時,編程的時候有幾個比較重要的標誌位咱們來總結下。
接收器
若是將USART_CR1 寄存器的RE 位置1,使能USART 接收,使得接收器在RX 線開始搜
索起始位。在肯定到起始位後就根據RX 線電平狀態把數據存放在接收移位寄存器內。接收完成後
就把接收移位寄存器數據移到RDR 內,並把USART_SR 寄存器的RXNE 位置1,同時若是
USART_CR2 寄存器的RXNEIE 置1 的話能夠產生中斷。在接收數據時,編程的時候有幾個比較
重要的標誌位咱們來總結下。
小數波特率生成
波特率指數據信號對載波的調製速率,它用單位時間內載波調製狀態改變次數來表示, 單位爲波
特。比特率指單位時間內傳輸的比特數,單位bit/s(bps)。對於USART 波特率與比特率相等,之後不
區分這兩個概念。波特率越大,傳輸速率越快。USART 的發送器和接收器使用相同的波特率。計算公
式以下:
公式9-1 波特率計算
其中,fPLCK 爲USART 時鐘, USARTDIV 是一個存放在波特率寄存器(USART_BRR)的一個無
符號定點數。其中DIV_Mantissa[11:0] 位定義USARTDIV 的整數部分,DIV_Fraction[3:0]位定義
第9 章.USART-串口通信
SAIUR201 6 第89頁
USARTDIV 的小數部分。例如: DIV_Mantissa=24(0x18) , DIV_Fraction=10(0x0A) , 此時
USART_BRR 值爲0x18A;那麼USARTDIV 的小數位10/16=0.625;整數位24,最終USARTDIV 的
值爲24.625。若是知道USARTDIV 值爲27.68,那麼DIV_Fraction=16*0.68=10.88,最接近的正整數
爲11,因此DIV_Fraction[3:0]爲0xB;DIV_Mantissa=整數(27.68)=27,即爲0x1B。波特率的經常使用值
有2400、9600、19200、115200。下面以實例講解如何設定寄存器值獲得波特率的值。咱們知道USART1
使用APB2 總線時鐘,最高可達72MHz,其餘USART 的最高頻率爲36MHz。咱們選取USART1 做
爲實例講解,即fPLCK=72MHz。爲獲得115200bps 的波特率,此時:
解得USARTDIV=39.0625,可算得DIV_Fraction=0.0625*16=1=0x01,DIV_Mantissa=39=0x17,即
應該設置USART_BRR 的值爲0x171。
校驗控制
STM32F103 系列控制器USART 支持奇偶校驗。當使用校驗位時,串口傳輸的長度將是8 位的
數據幀加上1 位的校驗位總共9 位,此時USART_CR1 寄存器的M 位須要設置爲1,即9 數據位。
將USART_CR1 寄存器的PCE 位置1 就能夠啓動奇偶校驗控制,奇偶校驗由硬件自動完成。啓動
了奇偶校驗控制以後,在發送數據幀時會自動添加校驗位,接收數據時自動驗證校驗位。接收數據時
若是出現奇偶校驗位驗證失敗,會見USART_SR 寄存器的PE 位置1,並能夠產生奇偶校驗中斷。
使能了奇偶校驗控制後,每一個字符幀的格式將變成:起始位+數據幀+校驗位+中止位。
中斷控制
USART 有多箇中斷請求事件,具體見表9-4。
表9-4 USART 中斷請求
第9 章.USART-串口通信
第90 頁SAIUR2016
9.6. USART 初始化結構體詳解
標準庫函數對每一個外設都創建了一個初始化結構體,好比USART_InitTypeDef,結構體成員用於
設置外設工做參數,並由外設初始化配置函數,好比USART_Init()調用,這些設定參數將會設置外設
相應的寄存器,達到配置外設工做環境的目的。初始化結構體和初始化庫函數配合使用是標準庫精髓所
在,理解了初始化結構體每一個成員意義基本上就能夠對該外設運用自如了。初始化結構體定義在
stm32f10x_usart.h 文件中,初始化庫函數定義在stm32f10x_usart.c 文件中,編程時咱們能夠結合這兩
個文件內註釋使用。
USART_BaudRate:波特率設置。通常設置爲2400、9600、19200、115200。標準庫函數會根據
設定值計算獲得USARTDIV 值,從而設置USART_BRR 寄存器值。
USART_WordLength:數據幀字長,可選8 位或9 位。它設定USART_CR1 寄存器的M 位的
值。若是沒有使能奇偶校驗控制,通常使用8 數據位;若是使能了奇偶校驗則通常設置爲9 數據位。
USART_StopBits:中止位設置,可選0.5 個、1 個、1.5 個和2 箇中止位,它設定USART_CR2
寄存器的STOP[1:0]位的值,通常咱們選擇1 箇中止位。
USART_Parity : 奇偶校驗控制選擇, 可選USART_Parity_No( 無校驗) 、
USART_Parity_Even( 偶校驗) 以及USART_Parity_Odd( 奇校驗) , 它設定USART_CR1
寄存器的PCE 位和PS 位的值。
USART_Mode:USART 模式選擇,有USART_Mode_Rx 和USART_Mode_Tx,容許使用邏輯或
運算選擇兩個,它設定USART_CR1 寄存器的RE 位和TE 位。
USART_HardwareFlowControl:硬件流控制選擇,只有在硬件流控制模式纔有效, 可選有⑴使能
RTS、⑵使能CTS、⑶同時使能RTS 和CTS、⑷不使能硬件流。當使用同步模式時須要配置SCLK 引
腳輸出脈衝的屬性,標準庫使用一個時鐘初始化結構體USART_ClockInitTypeDef 來設置,該結構體內
容也只有在同步模式才須要設置。
第9 章.USART-串口通信
SAIUR201 6 第91頁
USART_Clock : 同步模式下SCLK 引腳上時鐘輸出使能控制, 可選禁止時鐘輸出
(USART_Clock_Disable)或開啓時鐘輸出(USART_Clock_Enable);若是使用同步模式發送,通常都須要
開啓時鐘。它設定USART_CR2 寄存器的CLKEN 位的值。
USART_CPOL:同步模式下SCLK 引腳上輸出時鐘極性設置,可設置在空閒時SCLK 引腳爲低
電平(USART_CPOL_Low)或高電平(USART_CPOL_High)。它設定USART_CR2 寄存器的CPOL 位的
值。
USART_CPHA:同步模式下SCLK 引腳上輸出時鐘相位設置,可設置在時鐘第一個變化沿捕獲數
據(USART_CPHA_1Edge)或在時鐘第二個變化沿捕獲數據。它設定USART_CR2 寄存器的CPHA 位
的值。USART_CPHA 與USART_CPOL 配合使用能夠得到多種模式時鐘關係。
USART_LastBit:選擇在發送最後一個數據位的時候時鐘脈衝是否在SCLK 引腳輸出, 能夠
是不輸出脈衝(USART_LastBit_Disable) 、輸出脈衝(USART_LastBit_Enable)。它設定
USART_CR2 寄存器的LBCL 位的值。
9.7. USART1 接發通訊實驗
USART 只需兩根信號線便可完成雙向通訊,對硬件要求低,使得不少模塊都預留USART 接口來
實現與其餘模塊或者控制器進行數據傳輸,好比GSM 模塊,WIFI 模塊、藍牙模塊等等。在硬件設
計時,注意還須要一根「共地線」。咱們常用USART 來實現控制器與電腦之間的數據傳輸。這使
得咱們調試程序很是方便,好比咱們能夠把一些變量的值、函數的返回值、寄存器標誌位等等經過
USART 發送到串口調試助手,這樣咱們能夠很是清楚程序的運行狀態,當咱們正式發佈程序時再把
這些調試信息去除便可。咱們不只僅能夠將數據發送到串口調試助手,咱們還能夠在串口調試助手發
送數據給控制器,控制器程序根據接收到的數據進行下一步工做。首先,咱們來編寫一個程序實現開
發板與電腦通訊,在開發板上電時經過USART 發送一串字符串給電腦,而後開發板進入中斷接收等
待狀態,若是電腦有發送數據過來,開發板就會產生中斷,咱們在中斷服務函數接收數據,並立刻把
數據返回發送給電腦。
第9 章.USART-串口通信
第92 頁SAIUR2016
9.7.1. 硬件設計
爲利用USART 實現開發板與電腦通訊,須要用到一個USB 轉USART 的IC,咱們選擇
CH340G 芯片來實現這個功能,CH340G 是一個USB 總線的轉接芯片,實現USB 轉USART、USB
轉lrDA 紅外或者USB 轉打印機接口,咱們使用其USB 轉USART 功能。具體電路設計見圖9-9。
咱們將CH340G 的TXD 引腳與USART1 的RX 引腳鏈接,CH340G 的RXD 引腳與USART1 的
TX 引腳鏈接。CH340G 芯片集成在開發板上,其地線(GND)已與控制器的GND 連通。
圖9-9 USB 轉串口硬件設計
9.7.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參
考本章配套的工程。咱們建立了兩個文件:bsp_usart.c 和bsp _usart.h 文件用來存放USART 驅動程
序及相關宏定義。
9.7.3. 編程要點
1.使能RX 和TX 引腳GPIO 時鐘和USART 時鐘;
2.初始化GPIO,並將GPIO 複用到USART 上;
3.配置USART 參數;
4.配置中斷控制器並使能USART 接收中斷;
5.使能USART;
6.在USART 接收中斷服務函數實現數據接收和發送。
第9 章.USART-串口通信
SAIUR201 6 第93頁
9.7.4. 代碼分析
代碼清單9-1 GPIO 和USART 宏定義
使用宏定義方便程序移植和升級。開發板中的CH340G 的收發引腳默認經過跳帽鏈接到
USART1,若是想使用其餘串口,能夠把CH340G 跟USART1 直接的鏈接跳帽拔掉,而後再把其餘
串口的IO 用杜邦線接到CH340G 的收發引腳便可。這裏咱們使用USART1,設定波特率爲115200,
選定USART 的GPIO 爲PA9 和PA10。嵌套向量中斷控制器NVIC 配置。
代碼清單9-2 中斷控制器NVIC 配置
第9 章.USART-串口通信
第94 頁SAIUR2016
代碼清單9-3 USART 初始化配置
第9 章.USART-串口通信
SAIUR201 6 第95頁
使用GPIO_InitTypeDef 和USART_InitTypeDef 結構體定義一個GPIO 初始化變量以及一個
USART 初始化變量,這兩個結構體內容咱們以前已經有詳細講解。調用RCC_APB2PeriphClockCmd
函數開啓GPIO 端口時鐘, 使用GPIO 以前必須開啓對應端口的時鐘。使用
RCC_APB2PeriphClockCmd 函數開啓USART 時鐘。使用GPIO 以前都須要初始化配置它,而且還要
添加特殊設置,由於咱們使用它做爲外設的引腳,通常都有特殊功能。咱們在初始化時須要把它的模式
設置爲複用功能。這裏把串口的Tx 引腳配置爲複用推輓輸出,Rx 引腳爲浮空輸入,數據徹底由外部
輸入決定。接下來,咱們配置USART1 通訊參數爲:波特率115200,字長爲8,1 箇中止位,沒有
校驗位,不使用硬件流控制,收發一體工做模式,而後調用USART 初始化函數完成配置。程序用到
USART 接收中斷,須要配置NVIC,這裏調用NVIC_Configuration 函數完成配置。配置完NVIC 之
後調用USART_ITConfig 函數使能USART 接收中斷。
最後調用USART_Cmd 函數使能USART,這個函數最終配置的是USART_CR1 的UE 位,具體
的做用是開啓USART 的工做時鐘,沒有時鐘那USART 這個外設天然就工做不了。
代碼清單9-4 字符發送函數
Usart_SendByte 函數用來在指定USART 發送一個ASCLL 碼值字符,它有兩個形參,第一個爲
USART,第二個爲待發送的字符。它是經過調用庫函數USART_SendData 來實現的,而且增長了等待
發送完成功能。經過使用USART_GetFlagStatus 函數來獲取USART 事件標誌來實現發送完成功能等
待,它接收兩個參數,一個是USART,一個是事件標誌。這裏咱們循環檢測發送數據寄存器爲空這個
標誌,當跳出while 循環時說明發送數據寄存器爲空這個事實。Usart_SendString 函數用來發送一個字
符串,它實際是調用Usart_SendByte 函數發送每一個字符,直到遇到空字符才中止發送。最後使用循環
檢測發送完成的事件標誌TC 來實現保證數據發送完成後才退出函數。
第9 章.USART-串口通信
第96 頁SAIUR2016
USART 中斷服務函數
代碼清單21-5 USART 中斷服務函數
這段代碼是存放在stm32f10x_it.c 文件中的,該文件用來集中存放外設中斷服務函數。當咱們使
能了中斷而且中斷髮生時就會執行這裏的中斷服務函數。咱們在代碼清單21-3 使能了USART 接收
中斷,當USART 有接收到數據就會執行USART_IRQHandler 函數。USART_GetITStatus 函數與
USART_GetFlagStatus 函數相似用來獲取標誌位狀態,但USART_GetITStatus 函數是專門用來獲取中
斷事件標誌的,並返回該標誌位狀態。使用if 語句來判斷是不是真的產生USART 數據接收這個中斷
事件,若是是真的就使用USART 數據讀取函數USART_ReceiveData 讀取數據到指定存儲區。而後
再調用USART 數據發送函數USART_SendData 把數據又發送給源設備,即PC 端的串口調試助手。
主函數
代碼清單9-6 主函數
首先咱們須要調用USART_Config 函數完成USART 初始化配置,包括GPIO 配置,USART 配
置,接收中斷使能等等信息。接下來就能夠調用字符發送函數把數據發送給串口調試助手了。最後主函
數什麼都不作,只是靜靜地等待USART 接收中斷的產生,並在中斷服務函數把數據回傳。
第9 章.USART-串口通信
SAIUR201 6 第97頁
9.7.5. 下載驗證
保證開發板相關硬件鏈接正確,用USB 線鏈接開發板的USB 轉串口跟電腦,在電腦端打開串口
調試助手並配置好相關參數:115200 8-N-1,把編譯好的程序下載到開發板,此時串口調試助手便可收
到開發板發過來的數據。咱們在串口調試助手發送區域輸入任意字符,點擊發送按鈕,立刻在串口調試
助手接收區便可看到相同的字符。
圖9-10 實驗現象
9.8. 課後練習
1.使用Usart 控制RGB 彩燈
第10 章.DMA 直接存儲區訪問
第98 頁SAIUR2016
第10 章.DMA 直接存儲區訪問
10.1.課前預習
在書上找到答案。
1. 什麼是DMA
10.2.概述
本章所講內容:
(1)DMA 功能和配置
(2)使用DMA 讀寫存儲器數據
10.3. DMA 簡介
DMA(Direct Memory Access)—直接存儲器存取,是單片機的一個外設,它的主要功能是用來搬數
據,可是不須要佔用CPU,即在傳輸數據的時候,CPU 能夠幹其餘的事情,好像是多線程同樣。數據
傳輸支持從外設到存儲器或者存儲器到存儲器,這裏的存儲器能夠是SRAM 或者是FLASH。DMA 控
制器包含了DMA1 和DMA2,其中DMA1 有7 個通道,DMA2 有5 個通道,這裏的通道能夠理
解爲傳輸數據的一種管道。要注意的是DMA2 只存在於大容量的單片機中。
10.4. DMA 功能框圖
DMA 控制器獨立於內核,屬於一個單獨的外設,結構比較簡單,從編程的角度來看,咱們只需掌
握功能框圖中的三部份內容便可,具體見圖10-1:DMA 控制器的框圖。
第10 章.DMA 直接存儲區訪問
SAIUR201 6 第99頁
圖10-1 DMA 框圖
DMA 請求
若是外設要想經過DMA 來傳輸數據,必須先給DMA 控制器發送DMA 請求,DMA 收到請求
信號以後,控制器會給外設一個應答信號,當外設應答後且DMA 控制器收到應答信號以後,就會啓
動DMA 的傳輸,直到傳輸完畢。DMA 有DMA1 和DMA2 兩個控制器,DMA1 有7 個通道,DMA2
有5 個通道,不一樣的DMA 控制器的通道對應着不一樣的外設請求,這決定了咱們在軟件編程上該怎麼
設置,具體見DMA 請求映像表。
圖10-2 DMA1 各個通道的請求映像
第10 章.DMA 直接存儲區訪問
第100 頁SAIUR2016
圖10-3 DMA2 各個通道的請求映像
其中ADC三、SDIO 和TIM8 的DMA 請求只在大容量產品中存在,這個在具體項目時要注意。
通道
DMA 具備12 個獨立可編程的通道,其中DMA1 有7 個通道,DMA2 有5 個通道,每一個通道
對應不一樣的外設的DMA 請求。雖然每一個通道能夠接收多個外設的請求,可是同一時間只能接收一個,
不能同時接收多個。
仲裁器
當發生多個DMA 通道請求時,就意味着有前後響應處理的順序問題,這個就由仲裁器也管理。
仲裁器管理DMA 通道請求分爲兩個階段。第一階段屬於軟件階段,能夠在DMA_CCRx 寄存器中設
置,有4 個等級:很是高、高、中和低四個優先級。第二階段屬於硬件階段,若是兩個或以上的DMA
通道請求設置的優先級同樣,則他們優先級取決於通道編號,編號越低優先權越高,好比通道0 高於
通道1。在大容量產品和互聯型產品中,DMA1 控制器擁有高於DMA2 控制器的優先級。
10.5. DMA 數據配置
使用DMA,最核心就是配置要傳輸的數據,包括數據從哪裏來,要到哪裏去,傳輸的數據的單位
是什麼,要傳多少數據,是一次傳輸仍是循環傳輸等等。
從哪裏來到哪裏去
咱們知道DMA 傳輸數據的方向有三個:從外設到存儲器,從存儲器到外設,從存儲器到存儲器。
具體的方向DMA_CCR 位4 DIR 配置:0 表示從外設到存儲器,1 表示從存儲器到外設。這裏面涉
及到的外設地址由DMA_CPAR 配置,存儲器地址由DMA_CMAR 配置。外設到存儲器當咱們使用
從外設到存儲器傳輸時,以ADC 採集爲例。DMA 外設寄存器的地址對應的就是ADC 數據寄存器的
地址,DMA 存儲器的地址就是咱們自定義的變量(用來接收存儲AD 採集的數據)的地址。方向我
第10 章.DMA 直接存儲區訪問
SAIUR201 6 第101頁
們設置外設爲源地址。存儲器到外設當咱們使用從存儲器到外設傳輸時,以串口向電腦端發送數據爲
例。DMA 外設寄存器的地址對應的就是串口數據寄存器的地址,DMA 存儲器的地址就是咱們自定
義的變量(至關於一個緩衝區,用來存儲經過串口發送到電腦的數據)的地址。方向咱們設置外設爲目
標地址。存儲器到存儲器當咱們使用從存儲器到存儲器傳輸時,之內部FLASH 向內部SRAM 複製數
據爲例。DMA 外設寄存器的地址對應的就是內部FLASH(咱們這裏把內部FALSH 看成一個外設來
看)的地址,DMA 存儲器的地址就是咱們自定義的變量(至關於一個緩衝區,用來存儲來自內部FLASH
的數據)的地址。方向咱們設置外設(即內部FLASH)爲源地址。跟上面兩個不同的是,這裏須要
把DMA_CCR 位14:MEM2MEM:存儲器到存儲器模式配置爲1,啓動M2M 模式。
要傳多少,單位是什麼
當咱們配置好數據要從哪裏來到哪裏去以後,咱們還須要知道咱們要傳輸的數據是多少,數據的
單位是什麼。以串口向電腦發送數據爲例,咱們能夠一次性給電腦發送不少數據,具體多少由
DMA_CNDTR 配置,這是一個32 位的寄存器,一次最多隻能傳輸65535 個數據。要想數據傳輸正
確,源和目標地址存儲的數據寬度還必須一致,串口數據寄存器是8 位的,因此咱們定義的要發送的
數據也必須是8 位。外設的數據寬度由DMA_CCR 的PSIZE[1:0]配置,能夠是8/16/32 位,存儲器
的數據寬度由DMA_CCR 的MSIZE[1:0]配置, 能夠是8/16/32 位。
在DMA 控制器的控制下,數據要想有條不紊的從一個地方搬到另一個地方,還必須正確設置
兩邊數據指針的增量模式。外設的地址指針由DMA_CCRx 的PINC 配置,存儲器的地址指針由
MINC 配置。以串口向電腦發送數據爲例,要發送的數據不少,每發送完一個,那麼存儲器的地址指
針就應該加1,而串口數據寄存器只有一個,那麼外設的地址指針就固定不變。具體的數據指針的增量
模式由實際狀況決定。
何時傳輸完成
數據何時傳輸完成,咱們能夠經過查詢標誌位或者經過中斷的方式來鑑別。每一個DMA 通道
在DMA 傳輸過半、傳輸完成和傳輸錯誤時都會有相應的標誌位,若是使能了該類型的中斷後,則會
產生中斷。有關各個標誌位的詳細描述請參考DMA 中斷狀態寄存器DMA_ISR 的詳細描述。傳輸完
成還分兩種模式,是一次傳輸仍是循環傳輸,一次傳輸很好理解,便是傳輸一次以後就中止,要想再傳
輸的話,必須關斷DMA 使能後再從新配置後才能繼續傳輸。循環傳輸則是一次傳輸完成以後又恢復
第一次傳輸時的配置循環傳輸,不斷的重複。具體的DMA_CCR 寄存器的CIRC 循環模式位控制。
10.6. DMA 初始化結構體詳解
標準庫函數對每一個外設都創建了一個初始化結構體xxx_InitTypeDef(xxx 爲外設名稱),結構體成
員用於設置外設工做參數,並由標準庫函數xxx_Init()調用這些設定參數進入設置外設相應的寄存器,
達到配置外設工做環境的目的。結構體xxx_InitTypeDef 和庫函數xxx_Init 配合使用是標準庫精髓所
第10 章.DMA 直接存儲區訪問
第102 頁SAIUR2016
在, 理解告終構體xxx_InitTypeDef 每一個成員意義基本上就能夠對該外設運用自如。結構體
xxx_InitTypeDef 定義在stm32f10x_xxx.h(後面xxx 爲外設名稱)文件中,庫函數xxx_Init 定義在
stm32f10x_xxx.c 文件中,編程時咱們能夠結合這兩個文件內註釋使用。
DMA_PeripheralBaseAddr:外設地址,設定DMA_CPAR 寄存器的值;通常設置爲外設的數據
寄存器地址,若是是存儲器到存儲器模式則設置爲其中一個存儲器地址。
DMA_Memory0BaseAddr:存儲器地址,設定DMA_CMAR 寄存器值;通常設置爲咱們自定義
存儲區的首地址。
DMA_DIR : 傳輸方向選擇, 可選外設到存儲器、存儲器到外設。它設定DMA_CCR 寄存器
的DIR[1:0]位的值。這裏並無存儲器到存儲器的方向選擇, 當使用存儲器到存儲器時,只須要把其
中一個存儲器看成外設使用便可。
DMA_BufferSize:設定待傳輸數據數目,初始化設定DMA_CNDTR 寄存器的值。
DMA_PeripheralInc:若是配置爲DMA_PeripheralInc_Enable,使能外設地址自動遞增功能,它
設定DMA_CCR 寄存器的PINC 位的值;通常外設都是隻有一個數據寄存器,因此通常不會使能該
位。
DMA_MemoryInc:若是配置爲DMA_MemoryInc_Enable,使能存儲器地址自動遞增功能,它設
定DMA_CCR 寄存器的MINC 位的值;咱們自定義的存儲區通常都是存放多個數據的,因此要使能
存儲器地址自動遞增功能。
DMA_PeripheralDataSize:外設數據寬度,可選字節(8 位)、半字(16 位)和字(32 位), 它設定
DMA_CCR 寄存器的PSIZE[1:0]位的值。
DMA_MemoryDataSize:存儲器數據寬度,可選字節(8 位)、半字(16 位)和字(32 位),它設定
DMA_CCR 寄存器的MSIZE[1:0]位的值。當外設和存儲器之間傳數據時,兩邊的數據寬度應該設置
爲一致大小。
DMA_Mode : DMA 傳輸模式選擇, 可選一次傳輸或者循環傳輸, 它設定DMA_CCR 寄存
第10 章.DMA 直接存儲區訪問
SAIUR201 6 第103頁
器的CIRC 位的值。例程咱們的ADC 採集是持續循環進行的,因此使用循環傳輸模式。
DMA_Priority:軟件設置通道的優先級,有4 個可選優先級分別爲很是高、高、中和低,它設
定DMA_CCR 寄存器的PL[1:0]位的值。DMA 通道優先級只有在多個DMA 通道同時使用時纔有意
義,若是是單個通道,優先級能夠隨便設置。
DMA_M2M : 存儲器到存儲器模式, 使用存儲器到存儲器時用到, 設定DMA_CCR 的位14
MEN2MEN 便可啓動存儲器到存儲器模式。
10.7. DMA 存儲器到存儲器模式實驗
本章只講解存儲器到存儲器和存儲器到外設這兩種模式,其餘功能模式在其餘章節使用到的時候再
講。存儲器到存儲器模式能夠實現數據在兩個內存的快速拷貝。咱們先定義一個靜態的源數據,存放在
內部FLASH,而後使用DMA 傳輸把源數據拷貝到目標地址上(內部SRAM),最後對比源數據和
目標地址的數據,看看是否傳輸準確。
10.7.1. 硬件設計
DMA 存儲器到存儲器實驗不須要其餘硬件要求,只用到RGB 彩色燈用於指示程序狀態。
10.7.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參
考本章配套的工程。這個實驗代碼比較簡單,主要程序代碼都在main.c 文件中。
10.7.3. 編程要點
1.使能DMA 時鐘;
2.配置DMA 數據參數;
3.使能DMA,進行傳輸;
4.等待傳輸完成,並對源數據和目標地址數據進行比較。
第10 章.DMA 直接存儲區訪問
第104 頁SAIUR2016
10.7.4. 代碼分析
DMA 宏定義及相關變量定義
代碼清單10-1 DMA 數據流和相關變量定義
使用宏定義設置外設配置方便程序修改和升級。存儲器到存儲器傳輸通道沒有硬性規定,能夠隨意
選擇。aSRC_Const_Buffer[BUFFER_SIZE]定義用來存放源數據,而且使用了const 關鍵字修飾,即常
量類型,使得變量是存儲在內部flash 空間上。
第10 章.DMA 直接存儲區訪問
SAIUR201 6 第105頁
DMA 數據配置
代碼清單10-2 DMA 傳輸參數配置
使用DMA_InitTypeDef 結構體定義一個DMA 初始化變量,這個結構體內容咱們以前已經有詳細
講解。調用RCC_AHBPeriphClockCmd 函數開啓DMA 時鐘,使用DMA 控制器以前必須開啓對應
的時鐘。源地址和目標地址使用以前定義的數組首地址,傳輸的數據量爲宏BUFFER_SIZE 決定,源
和目標地址指針地址遞增,使用一次傳輸模式不能循環傳輸,由於只有一個DMA 通道,優先級隨便
設置,最後調用DMA_Init 函數完成DMA 的初始化配置。
DMA_ClearFlag 函數用於清除DMA 標誌位,代碼用到傳輸完成標誌位,使用以前先清除傳輸完
成標誌位以避免產生沒必要要干擾。DMA_ClearFlag 函數須要1 個形參,即事件標誌位,可選有傳輸完成
標誌位、半傳輸標誌位、FIFO 錯誤標誌位、傳輸錯誤標誌位等等,很是多,咱們這裏選擇傳輸完成標
志位,由宏DMA_FLAG_TC 定義。
DMA_Cmd 函數用於啓動或者中止DMA 數據傳輸,它接收兩個參數,第一個是DMA 通道,另
外一個是開啓ENABLE 或者中止DISABLE。存儲器數據對比
第10 章.DMA 直接存儲區訪問
第106 頁SAIUR2016
代碼清單10-3 源數據與目標地址數據對比
判斷指定長度的兩個數據源是否徹底相等,若是徹底相等返回1;只要其中一對數據不相等返回0。
它須要三個形參,前兩個是兩個數據源的地址,第三個是要比較數據長度。
主函數
代碼清單10-4 存儲器到存儲器模式主函數
第10 章.DMA 直接存儲區訪問
SAIUR201 6 第107頁
首先定義一個變量用來保存存儲器數據比較結果。RGB 彩色燈用來指示程序進程,使用以前須要
初始化它,LED_GPIO_Config 定義在bsp_led.c 文件中。開始設置RGB 彩色燈爲紫色,LED_PURPLE
是定義在bsp_led.h 文件的一個宏定義。Delay 函數只是一個簡單的延時函數。調用DMA_Config 函
數完成DMA 數據流配置並啓動DMA 數據傳輸。DMA_GetFlagStatus 函數獲取DMA 事件標誌位的
當前狀態,這裏獲取DMA 數據傳輸完成這個標誌位,使用循環持續等待直到該標誌位被置位,即
DMA 傳輸完成這個事件發生,而後退出循環,運行以後程序。肯定DMA 傳輸完成以後就能夠調用
Buffercmp 函數比較源數據與DMA 傳輸後目標地址的數據是否一一對應。TransferStatus 保存比較結
果,若是爲1 表示兩個數據源一一對應相等說明DMA 傳輸成功;相反,若是爲0 表示兩個數據源
數據存在不等狀況,說明DMA 傳輸出錯。若是DMA 傳輸成功設置RGB 彩色燈爲藍色,若是DMA
傳輸出錯設置RGB 彩色燈爲紅色。
10.7.5. 下載驗證
確保開發板供電正常,編譯程序並下載。觀察RGB 彩色燈變化狀況。正常狀況下RGB 彩色燈先
爲紫色,而後變成藍色。若是DMA 傳輸出錯纔會爲紅色。
10.8.課後練習
1. 根據存儲器至外設模式實驗編寫一個外設到存儲器程序,實現USART 的DMA 接收請求功能,
在接收數據的同時LED 不斷的亮滅,至關於兩個任務在執行。
第11 章.TIM 基本定時器
第108 頁SAIUR2016
第11 章. TIM 基本定時器
11.1.課前預習
在書上找到答案。
1. 什麼是TIM 基本定時器?
11.2.概述
本章所講內容:
(1)定時器的分類
(2)定時器功能框圖
(3)使用基本定時器編寫程序
11.3.定時器分類
STM32F1 系列中,除了互聯型的產品,共有8 個定時器,分爲基本定時器,通用定時器和高級
定時器。基本定時器TIM6 和TIM7 是一個16 位的只能向上計數的定時器,只能定時,沒有外部
IO。通用定時器TIM2/3/4/5 是一個16 位的能夠向上/下計數的定時器,能夠定時,能夠輸出比較,可
以輸入捕捉,每一個定時器有四個外部IO。高級定時器TIM1/8 是一個16 位的能夠向上/下計數的定時
器,能夠定時,能夠輸出比較,能夠輸入捕捉,還能夠有三相電機互補輸出信號,每一個定時器有8 個
外部IO。更加具體的分類詳情見圖11-1。
第11 章.TIM 基本定時器
SAIUR201 6 第109頁
圖11-1 定時器分類
11.4.基本定時器功能框圖講解
基本定時器的核心是時基,不只基本定時器有,通用定時器和高級定時器也有。學習定時器時,我
們先從簡單的基本定時器學起,到了後面的通用和高級定時器的學習中,咱們直接跳過期基部分的講解
便可。基本定時器的功能框圖見圖11-2。
圖11-2 基本定時器功能框圖
時鐘源
定時器時鐘TIMxCLK,即內部時鐘CK_INT,經APB1 預分頻器後分頻提供,若是APB1 預分
頻係數等於1,則頻率不變,不然頻率乘以2,庫函數中APB1 預分頻的係數是2,即PCLK1=36M,
因此定時器時鐘TIMxCLK=36*2=72M。
計數器時鐘
定時器時鐘通過PSC 預分頻器以後,即CK_CNT,用來驅動計數器計數。PSC 是一個16 位的
預分頻器,能夠對定時器時鐘TIMxCLK 進行1~65536 之間的任何一個數進行分頻。具體計算方式
第11 章.TIM 基本定時器
第110 頁SAIUR2016
爲:CK_CNT=TIMxCLK/(PSC+1)。
計數器
計數器CNT 是一個16 位的計數器,只能往上計數,最大計數值爲65535。當計數達到自動重
裝載寄存器的時候產生更新事件,並清零從頭開始計數。
自動重裝載寄存器
自動重裝載寄存器ARR 是一個16 位的寄存器,這裏面裝着計數器能計數的最大數值。當計數
到這個值的時候,若是使能了中斷的話,定時器就產生溢出中斷。
定時時間的計算
定時器的定時時間等於計數器的中斷週期乘以中斷的次數。計數器在CK_CNT 的驅動下,計一
個數的時間則是CK_CLK 的倒數,等於:1/(TIMxCLK/(PSC+1)),產生一次中斷的時間則等於:1/
(CK_CLK * ARR)。若是在中斷服務程序裏面設置一個變量time,用來記錄中斷的次數, 那麼就
能夠計算出咱們須要的定時時間等於: 1/CK_CLK * (ARR+1)*time。
11.5.定時器初始化結構體詳解
在標準庫函數頭文件stm32f10x_tim.h 中對定時器外設創建了四個初始化結構體,基本定時器只用
到其中一個即TIM_TimeBaseInitTypeDef,具體的見代碼清單11-1,其餘三個咱們在高級定時器章節講
解。
代碼清單11-1 定時器基本初始化結構體
TIM_Prescaler:定時器預分頻器設置,時鐘源經該預分頻器纔是定時器時鐘,它設定TIMx_PSC 寄
存器的值。可設置範圍爲0 至65535,實現1 至65536 分頻。
TIM_CounterMode:定時器計數方式,但是在爲向上計數、向下計數以及三種中心對齊模式。基
本定時器只能是向上計數,即TIMx_CNT 只能從0 開始遞增,而且無需初始化。TIM_Period:定時
器週期,實際就是設定自動重載寄存器的值,在事件生成時更新到影子寄存器。可設置範圍爲0 至
65535。
TIM_ClockDivision:時鐘分頻,設置定時器時鐘CK_INT 頻率與數字濾波器採樣時鐘頻率分頻
第11 章.TIM 基本定時器
SAIUR201 6 第111頁
比,基本定時器沒有此功能,不用設置。
TIM_RepetitionCounter:重複計數器,屬於高級控制寄存器專用寄存器位,利用它能夠很是容易
控制輸出PWM 的個數。這裏不用設置。雖然定時器基本初始化結構體有5 個成員,但對於基本定時
器只需設置其中兩個就能夠,想一想使用基本定時器就是簡單。
11.6.基本定時器定時實驗
11.6.1. 硬件設計
本實驗利用基本定時器TIM6/7 定時1s,1s 時間到LED 翻轉一次。基本定時器是單片機內部
的資源,沒有外部IO,不須要接外部電路,現只須要一個LED 便可。
11.6.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到, 完整的代碼請參
考本章配套的工程。咱們編寫兩個定時器驅動文件,bsp_TiMbase.h 和bsp_TiMbase.h,用來配置定時
器中斷優先級和和初始化定時器。
11.6.3. 編程要點
1.開定時器時鐘TIMx_CLK, x[6,7];
2.初始化時基初始化結構體;
3.使能TIMx, x[6,7] update 中斷;
4.打開定時器;
5.編寫中斷服務程序
通用定時器和高級定時器的定時編程要點跟基本定時器差很少,只是還要再選擇下計數器的計數模
式,是向上仍是向下。由於基本定時器只能向上計數,且沒有配置計數模式的寄存器,默認是向上。
11.6.4. 軟件分析
基本定時器宏
第11 章.TIM 基本定時器
第112 頁SAIUR2016
代碼清單11-2 宏定義
基本定時器有TIM6 和TIM7,咱們能夠有選擇的使用,爲了提升代碼的可移植性,咱們把當需
要修改定時器時須要修改的代碼定義成宏,默認使用的是定時器6,若是想修改爲定時器7,只須要把
宏BASIC_TIM6 註釋掉便可。
基本定時器配置
代碼清單11-3 基本定時器模式配置
第11 章.TIM 基本定時器
SAIUR201 6 第113頁
咱們把定時器設置自動重裝載寄存器ARR 的值爲1000,設置時鐘預分頻器爲71,則驅動計數器
的時鐘:CK_CNT = CK_INT / (71+1)=1M,則計數器計數一次的時間等於:1/CK_CNT=1us,當計數器
計數到ARR 的值1000 時,產生一次中斷,則中斷一次的時間爲:1/CK_CNT*ARR=1ms。在初始化
定時器的時候, 咱們定義了一個結構體: TIM_TimeBaseInitTypeDef , TIM_TimeBaseInitTypeDef 結
構體裏面有5 個成員,TIM6 和TIM7 的寄存器裏面只有TIM_Prescaler 和TIM_Period,另外三個成
員基本定時器是沒有的,因此使用TIM6 和TIM7 的時候只需初始化這兩個成員便可, 另外三個成員
是通用定時器和高級定時器纔有,具體說明以下:
其中TIM15/16/17 只存在與互聯型產品中,在F1 大/中/小容量型號中沒有。
定時器中斷優先級配置
咱們設置中斷分組爲0,主優先級爲0,搶佔優先級爲3。
定時器中斷服務程序
定時器中斷一次的時間是1ms,咱們定義一個全局變量time,每當進一次中斷的時候,讓time 來
記錄進入中斷的次數。若是咱們想實現一個1s 的定時,咱們只須要判斷time 是否等於1000 便可,
1000 個1ms 就是1s。而後把time 清0,從新計數,以此循環往復。在中斷服務程序的最後,要把
相應的中斷標誌位清除掉,切記。
第11 章.TIM 基本定時器
第114 頁SAIUR2016
主函數
主函數作一些必須的初始化,而後在一個死循環中不斷的判斷time 的值,time 的值在定時器中
斷改變,每加一次表示定時器過了1ms,當time 等於1000 時,1s 時間到,LED1 翻轉一次,並把time
清0。
11.6.5. 下載驗證
把編寫好的程序下載到開發板,能夠看到LED1 以1s 的頻率閃爍一次。
11.7.課後練習
1.計算基本定時器一次最長定時時間,若是須要使用基本定時器產生100s 週期事件有什麼辦法實
現?
2.修改實驗程序,在保使其每0.5s 翻轉一次LED1 的同時在每10s 翻轉LED2。
第12 章.TIM 高級定時器
SAIUR201 6 第115頁
第12 章.TIM 高級定時器
12.1.課前預習
在書上找到答案。
1. 什麼是TIM 高級定時器?
12.2.概述
本章所講內容:
(1)高級定時器功能框圖
(2)使用高級定時器編寫程序
12.3.高級控制定時器
高級控制定時器(TIM1 和TIM8)和通用定時器在基本定時器的基礎上引入了外部引腳,能夠實現
輸入捕獲和輸出比較功能。高級控制定時器比通用定時器增長了可編程死區互補輸出、重複計數器、帶
剎車(斷路)功能,這些功能都是針對工業電機控制方面。這幾個功能在本書不作詳細的介紹,主要介紹
經常使用的輸入捕獲和輸出比較功能。高級控制定時器時基單元包含一個16 位自動重裝載寄存器ARR,
一個16 位的計數器CNT,可向上/下計數,一個16 位可編程預分頻器PSC,預分頻器時鐘源有多種
可選,有內部的時鐘、外部時鐘。還有一個8 位的重複計數器RCR,這樣最高可實現40 位的可編程
定時。STM32F103ZET6 的高級/通用定時器的IO 分配具體見表12-1。配套開發板由於IO 資源緊缺,
定時器的IO 不少已經複用它途,故下表中的IO 只有部分可用於定時器的實驗。
第12 章.TIM 高級定時器
第116 頁SAIUR2016
表12-1 高級控制和通用定時器通道引腳分佈
12.4. 高級控制定時器功能框圖
高級控制定時器功能框圖包含了高級控制定時器最核心內容,掌握了功能框圖,對高級控制定時器
就有一個總體的把握,在編程時思路就很是清晰,見,圖中有些寄存器是帶影子的,表示其有影子寄存
器。
圖12-1 高級控制定時器功能框圖
第12 章.TIM 高級定時器
SAIUR201 6 第117頁
12.4.1. 時鐘源
高級控制定時器有四個時鐘源可選:
1.內部時鐘源CK_INT
2.外部時鐘模式1:外部輸入引腳TIx(x=1,2,3,4)
3.外部時鐘模式2:外部觸發輸入ETR
4.內部觸發輸入(ITRx)
5.內部時鐘源(CK_INT)
內部時鐘CK_INT 即來自於芯片內部,等於72M,通常狀況下,咱們都是使用內部時鐘。當從模
式控制寄存器TIMx_SMCR 的SMS 位等於000 時,則使用內部時鐘。
12.4.2. 外部時鐘模式1
圖12-2 外部時鐘模式1 框圖
①:時鐘信號輸入引腳
當使用外部時鐘模式1 的時候,時鐘信號來自於定時器的輸入通道,總共有4 個,分別爲
TI1/2/3/4,即TIMx_CH1/2/3/4。具體使用哪一路信號,由TIM_CCMRx 的位CCxS[1:0]配置,其中
CCMR1 控制TI1/2,CCMR2 控制TI3/4。
②:濾波器
若是來自外部的時鐘信號的頻率太高或者混雜有高頻干擾信號的話,咱們就須要使用濾波器對信號
從新採樣,來達到降頻或者去除高頻干擾的目的,具體的由TIMx_CCMRx 的位ICxF[3:0]配置。
③:邊沿檢測
邊沿檢測的信號來自於濾波器的輸出,在成爲觸發信號以前,須要進行邊沿檢測,決定是上升沿有
效仍是降低沿有效,具體的由TIMx_CCER 的位CCxP 和CCxNP 配置。
第12 章.TIM 高級定時器
第118 頁SAIUR2016
④:觸發選擇
當使用外部時鐘模式1 時,觸發源有兩個,一個是濾波後的定時器輸入1(TI1FP1)和濾波後的
定時器輸入2(TI2FP2),具體的由TIMxSMCR 的位TS[2:0]配置。
⑤:從模式選擇
選定了觸發源信號後,最後咱們需把信號鏈接到TRGI 引腳,讓觸發信號成爲外部時鐘模式1 的
輸入,最終等於CK_PSC,而後驅動計數器CNT 計數。具體的配置TIMx_SMCR 的位SMS[2:0]爲000
便可選擇外部時鐘模式1。
⑥:使能計數器
通過上面的5 個步驟以後,最後咱們只需使能計數器開始計數,外部時鐘模式1 的配置就算完成。
使能計數器由TIMx_CR1 的位CEN 配置。
12.4.3. 外部時鐘模式2
圖12-3 外部時鐘模式2 框圖
①:時鐘信號輸入引腳
當使用外部時鐘模式2 的時候,時鐘信號來自於定時器的特定輸入通道TIMx_ETR,只有1 個。
②:外部觸發極性
來自ETR 引腳輸入的信號能夠選擇爲上升沿或者降低沿有效,具體的由TIMx_SMCR 的位ETP
配置。
③:外部觸發預分頻器
因爲ETRP 的信號的頻率不能超過TIMx_CLK(72M)的1/4,當觸發信號的頻率很高的狀況下,
就必須使用分頻器來降頻,具體的由TIMx_SMCR 的位ETPS[1:0]配置。
④:濾波器
若是ETRP 的信號的頻率太高或者混雜有高頻干擾信號的話,咱們就須要使用濾波器對ETRP
信號從新採樣,來達到降頻或者去除高頻干擾的目的。具體的由TIMx_SMCR 的位ETF[3:0]配置,其
中的fDTS 是由內部時鐘CK_INT 分頻獲得,具體的由TIMx_CR1 的位CKD[1:0]配置。
第12 章.TIM 高級定時器
SAIUR201 6 第119頁
⑤:從模式選擇
通過濾波器濾波的信號鏈接到ETRF 引腳後,觸發信號成爲外部時鐘模式2 的輸入, 最終等於
CK_PSC,而後驅動計數器CNT 計數。具體的配置TIMx_SMCR 的位ECE 爲1 便可選擇外部時鐘
模式2。
⑥:使能計數器
通過上面的5 個步驟以後,最後咱們只需使能計數器開始計數,外部時鐘模式2 的配置就算完成。
使能計數器由TIMx_CR1 的位CEN 配置。
12.4.4. 內部觸發輸入
內部觸發輸入是使用一個定時器做爲另外一個定時器的預分頻器。硬件上高級控制定時器和通用定
時器在內部鏈接在一塊兒,能夠實現定時器同步或級聯。主模式的定時器能夠對從模式定時器執行復位、
啓動、中止或提供時鐘。
控制器
高級控制定時器控制器部分包括觸發控制器、從模式控制器以及編碼器接口。觸發控制器用來針對
片內外設輸出觸發信號,好比爲其它定時器提供時鐘和觸發DAC/ADC 轉換。編碼器接口專門針對編
碼器計數而設計。從模式控制器能夠控制計數器復位、啓動、遞增/遞減、計數。有關控制器部分只需
熟練閱讀寄存器描述便可。
時基單元
圖12-4 高級定時器時基單元
高級控制定時器時基單元功能包括四個寄存器,分別是計數器寄存器(CNT)、預分頻器寄存器
(PSC)、自動重載寄存器(ARR)和重複計數器寄存器(RCR)。其中重複計數器RCR 是高級定時器獨有,
通用和基本定時器沒有。前面三個寄存器都是16 位有效,TIMx_RCR 寄存器是8 位有效。
預分頻器PSC
預分頻器PSC ,有一個輸入時鐘CK_PSC 和一個輸出時鐘CK_CNT 。輸入時鐘CK_PSC 就是
上面時鐘源的輸出,輸出CK_CNT 則用來驅動計數器CNT 計數。經過設置預分頻器PSC 的值能夠
第12 章.TIM 高級定時器
第120 頁SAIUR2016
獲得不一樣的CK_CNT,實際計算爲:fCK_CNT 等於fCK_PSC/(PSC[15:0]+1),能夠實現1 至65536 分
頻。
計數器CNT
高級控制定時器的計數器有三種計數模式,分別爲遞增計數模式、遞減計數模式和遞增/遞減(中心
對齊)計數模式。
1. 遞增計數模式下,計數器從0 開始計數,每來一個CK_CNT 脈衝計數器就增長1,直到計數器
的值與自動重載寄存器ARR 值相等,而後計數器又從0 開始計數並生成計數器上溢事件,計
數器老是如此循環計數。若是禁用重複計數器,在計數器生成上溢事件就立刻生成更新事件
(UEV);若是使能重複計數器,每生成一次上溢事件重複計數器內容就減1,直到重複計數器內
容爲0 時纔會生成更新事件。
2. 遞減計數模式下,計數器從自動重載寄存器ARR 值開始計數,每來一個CK_CNT 脈衝計數器
就減1,直到計數器值爲0,而後計數器又從自動重載寄存器ARR 值開始遞減計數並生成計數
器下溢事件,計數器老是如此循環計數。若是禁用重複計數器,在計數器生成下溢事件就立刻生
成更新事件;若是使能重複計數器,每生成一次下溢事件重複計數器內容就減1,直到重複計數
器內容爲0 時纔會生成更新事件。
3. 中心對齊模式下,計數器從0 開始遞增計數,直到計數值等於(ARR-1)值生成計數器上溢事件,
而後從ARR 值開始遞減計數直到1 生成計數器下溢事件。而後又從0 開始計數,如此循環。
每次發生計數器上溢和下溢事件都會生成更新事件。
自動重載寄存器ARR
自動重載寄存器ARR 用來存放與計數器CNT 比較的值,若是兩個值相等就遞減重計數器。能夠
經過TIMx_CR1 寄存器的ARPE 位控制自動重載影子寄存器功能,若是ARPE 位置1,自動重載影
子寄存器有效,只有在事件更新時才把TIMx_ARR 值賦給影子寄存器。若是ARPE 位爲0,則修改
TIMx_ARR 值立刻有效。
重複計數器RCR
在基本/通用定時器發生上/下溢事件時直接就生成更新事件,但對於高級控制定時器卻不是這樣,
高級控制定時器在硬件結構上多出了重複計數器,在定時器發生上溢或下溢事件是遞減重複計數器的
值,只有當重複計數器爲0 時纔會生成更新事件。在發生N+1 個上溢或下溢事件(N 爲RCR 的值)
時產生更新事件。
第12 章.TIM 高級定時器
SAIUR201 6 第121頁
12.4.5. 輸入捕獲
圖12-5 輸入捕獲功能框圖
輸入捕獲能夠對輸入的信號的上升沿,降低沿或者雙邊沿進行捕獲,經常使用的有測量輸入信號的脈寬
和測量PWM 輸入信號的頻率和佔空比這兩種。輸入捕獲的大概的原理就是,當捕獲到信號的跳變沿
的時候,把計數器CNT 的值鎖存到捕獲寄存器CCR 中,把先後兩次捕獲到的CCR 寄存器中的值相
減,就能夠算出脈寬或者頻率。若是捕獲的脈寬的時間長度超過你的捕獲定時器的週期,就會發生溢出,
這個咱們須要作額外的處理。
①輸入通道
須要被測量的信號從定時器的外部引腳TIMx_CH1/2/3/4 進入,一般叫TI1/2/3/4,在後面的捕獲
講解中對於要被測量的信號咱們都以TIx 爲標準叫法。
②輸入濾波器和邊沿檢測器
當輸入的信號存在高頻干擾的時候,咱們須要對輸入信號進行濾波,即進行從新採樣, 根據採樣
定律,採樣的頻率必須大於等於兩倍的輸入信號。好比輸入的信號爲1M,又存在高頻的信號干擾,
那麼此時就頗有必要進行濾波,咱們能夠設置採樣頻率爲2M,這樣能夠在保證採樣到有效信號的基
礎上把高於2M 的高頻干擾信號過濾掉。濾波器的配置由CR1 寄存器的位CKD[1:0]和CCMR1/2 的
位ICxF[3:0]控制。從ICxF 位的描述可知,採樣頻率fSAMPLE 能夠由fCK_INT 和fDTS 分頻後的
時鐘提供,其中是fCK_INT 內部時鐘,fDTS 是fCK_INT 通過分頻後獲得的頻率,分頻因子由
CKD[1:0]決定,能夠是不分頻,2 分頻或者是4 分頻。邊沿檢測器用來設置信號在捕獲的時候是什
麼邊沿有效,能夠是上升沿,降低沿,或者是雙邊沿,具體的由CCER 寄存器的位CCxP 和CCxNP
決定。
③捕獲通道
第12 章.TIM 高級定時器
第122 頁SAIUR2016
捕獲通道就是圖中的IC1/2/3/4,每一個捕獲通道都有相對應的捕獲寄存器CCR1/2/3/4,當發生捕獲
的時候,計數器CNT 的值就會被鎖存到捕獲寄存器中。這裏咱們要搞清楚輸入通道和捕獲通道的區
別,輸入通道是用來輸入信號的,捕獲通道是用來捕獲輸入信號的通道,一個輸入通道的信號能夠同時
輸入給兩個捕獲通道。好比輸入通道TI1 的信號通過濾波邊沿檢測器以後的TI1FP1 和TI1FP2 能夠
進入到捕獲通道IC1 和IC2,其實這就是咱們後面要講的PWM 輸入捕獲,只有一路輸入信號(TI1)
卻佔用了兩個捕獲通道(IC1 和IC2)。當只須要測量輸入信號的脈寬時候,用一個捕獲通道便可。輸
入通道和捕獲通道的映射關係具體由寄存器CCMRx 的位CCxS[1:0]配置。
④預分頻器
ICx 的輸出信號會通過一個預分頻器,用於決定發生多少個事件時進行一次捕獲。具體的由寄存
器CCMRx 的位ICxPSC 配置,若是但願捕獲信號的每個邊沿,則不分頻。
⑤捕獲寄存器
通過預分頻器的信號ICxPS 是最終被捕獲的信號,當發生捕獲時(第一次),計數器CNT 的值
會被鎖存到捕獲寄存器CCR 中,還會產生CCxI 中斷,相應的中斷位CCxIF(在SR 寄存器中)會
被置位,經過軟件或者讀取CCR 中的值能夠將CCxIF 清0。若是發生第二次捕獲(即重複捕獲:CCR
寄存器中已捕獲到計數器值且CCxIF 標誌已置1),則捕獲溢出標誌位CCxOF(在SR 寄存器中)
會被置位,CCxOF 只能經過軟件清零。
12.4.6. 輸出比較
圖12-6 輸出比較功能框圖
第12 章.TIM 高級定時器
SAIUR201 6 第123頁
輸出比較就是經過定時器的外部引腳對外輸出控制信號, 有凍結、將通道X(x=1,2,3,4)設置
爲匹配時輸出有效電平、將通道X 設置爲匹配時輸出無效電平、翻轉、強制變爲無效電平、強制變爲
有效電平、PWM1 和PWM2 這八種模式,具體使用哪一種模式由寄存器CCMRx 的位OCxM[2:0]配置。
其中PWM 模式是輸出比較中的特例,使用的也最多。
①比較寄存器
當計數器CNT 的值跟比較寄存器CCR 的值相等的時候,輸出參考信號OCxREF 的信號的極
性就會改變,其中OCxREF=1(高電平)稱之爲有效電平,OCxREF=0(低電平) 稱之爲無效電平,
而且會產生比較中斷CCxI,相應的標誌位CCxIF(SR 寄存器中)會置位。而後OCxREF 再通過一
系列的控制以後就成爲真正的輸出信號OCx/OCxN。
②死區發生器
在生成的參考波形OCxREF 的基礎上,能夠插入死區時間,用於生成兩路互補的輸出信號OCx
和OCxN,死區時間的大小具體由BDTR 寄存器的位DTG[7:0]配置。死區時間的大小必須根據與輸
出信號相鏈接的器件及其特性來調整。下面咱們簡單舉例說明下帶死區的PWM 信號的應用,咱們以
一個板橋驅動電路爲例。
圖12-7 半橋驅動電路
在這個半橋驅動電路中,Q1 導通,Q2 截止,此時我想讓Q1 截止Q2 導通,確定是要先讓Q1 截
止一段時間以後,再等一段時間才讓Q2 導通,那麼這段等待的時間就稱爲死區時間,由於Q1 關閉
須要時間(由MOS 管的工藝決定)。若是Q1 關閉以後,立刻打開Q2,那麼此時一段時間內至關
於Q1 和Q2 都導通了,這樣電路會短路。圖12-8 是針對上面的半橋驅動電路而畫的帶死區插入的
PWM 信號,圖中的死區時間要根據MOS 管的工藝來調節。
第12 章.TIM 高級定時器
第124 頁SAIUR2016
圖12-8 帶死區插入的互補輸出
圖12-9 輸出比較(通道1~3)的輸出控制框圖
③輸出控制
在輸出比較的輸出控制中,參考信號OCxREF 在通過死區發生器以後會產生兩路帶死區的互補信
號OCx_DT 和OCxN_DT(通道1~3 纔有互補信號,通道4 沒有,其他跟通道1~3 同樣),這兩路
帶死區的互補信號而後就進入輸出控制電路,若是沒有加入死區控制, 那麼進入輸出控制電路的信號
就直接是OCxREF。進入輸出控制電路的信號會被分紅兩路,一路是原始信號,一路是被反向的信號,
具體的由寄存器CCER 的位CCxP 和CCxNP 控制。通過極性選擇的信號是否由OCx 引腳輸出到外
部引腳CHx/CHxN 則由寄存器CCER 的位CxE/CxNE 配置。若是加入了斷路(剎車)功能,則斷路
和死區寄存器BDTR 的MOE、OSSI 和OSSR 這三個位會共同影響輸出的信號。
④輸出引腳
輸出比較的輸出信號最終是經過定時器的外部IO 來輸出的,分別爲CH1/2/3/4,其中前面三個
通道還有互補的輸出通道CH1/2/3N。更加詳細的IO 說明還請查閱相關的數據手冊。
第12 章.TIM 高級定時器
SAIUR201 6 第125頁
12.4.7. 斷路功能
斷路功能就是電機控制的剎車功能,使能斷路功能時,根據相關控制位狀態修改輸出信號電平。
在任何狀況下,OCx 和OCxN 輸出都不能同時爲有效電平,這關係到電機控制經常使用的H 橋電路結構
緣由。斷路源能夠是時鐘故障事件,由內部復位時鐘控制器中的時鐘安全系統(CSS)生成,也能夠是外
部斷路輸入IO,二者是或運算關係。系統復位啓動都默認關閉斷路功能,將斷路和死區寄存器
(TIMx_BDTR)的BKE 爲置1,使能斷路功能。可經過TIMx_BDTR 寄存器的BKP 位設置設置斷路
輸入引腳的有效電平, 設置爲1 時輸入BRK 爲高電平有效,不然低電平有效。
發送斷路時,將產生如下效果:
1. TIMx_BDTR 寄存器中主輸出模式使能(MOE)位被清零,輸出處於無效、空閒或復位狀態;
2. 根據相關控制位狀態控制輸出通道引腳電平;當使能通道互補輸出時,會根據狀況自動控制輸出
通道電平;
3. 將TIMx_SR 寄存器中的BIF 位置1,並可產生中斷和DMA 傳輸請求。
4. 若是TIMx_BDTR 寄存器中的自動輸出使能(AOE)位置1,則MOE 位會在發生下一個UEV
事件時自動再次置1。
12.5.輸入捕獲應用
輸入捕獲通常應用在兩個方面,一個方面是脈衝跳變沿時間測量,另外一方面是PWM 輸入測量。
圖12-10 脈寬/頻率測量示意圖
第12 章.TIM 高級定時器
第126 頁SAIUR2016
12.5.1. 測量頻率
當捕獲通道TIx 上出現上升沿時,發生第一次捕獲,計數器CNT 的值會被鎖存到捕獲寄存器
CCR 中,並且還會進入捕獲中斷,在中斷服務程序中記錄一次捕獲(能夠用一個標誌變量來記錄),
並把捕獲寄存器中的值讀取到value1 中。當出現第二次上升沿時,發生第二次捕獲,計數器CNT 的
值會再次被鎖存到捕獲寄存器CCR 中,並再次進入捕獲中斷,在捕獲中斷中,把捕獲寄存器的值讀取
到value3 中,並清除捕獲記錄標誌。利用value3 和value1 的差值咱們就能夠算出信號的週期(頻率)。
12.5.2. 測量脈寬
當捕獲通道TIx 上出現上升沿時,發生第一次捕獲,計數器CNT 的值會被鎖存到捕獲寄存器
CCR 中,並且還會進入捕獲中斷,在中斷服務程序中記錄一次捕獲(能夠用一個標誌變量來記錄),
並把捕獲寄存器中的值讀取到value1 中。而後把捕獲邊沿改變爲降低沿捕獲,目的是捕獲後面的降低
沿。當降低沿到來的時候,發生第二次捕獲,計數器CNT 的值會再次被鎖存到捕獲寄存器CCR 中,
並再次進入捕獲中斷,在捕獲中斷中,把捕獲寄存器的值讀取到value3 中,並清除捕獲記錄標誌。然
後把捕獲邊沿設置爲上升沿捕獲。
在測量脈寬過程當中須要來回的切換捕獲邊沿的極性,若是測量的脈寬時間比較長,定時器就會發生
溢出,溢出的時候會產生更新中斷,咱們能夠在中斷裏面對溢出進行記錄處理。
12.6. PWM 輸入模式
測量脈寬和頻率還有一個更簡便的方法就是使用PWM 輸入模式,該模式是輸入捕獲的特例,只
能使用通道1 和通道2,通道3 和通道4 使用不了。與上面那種只使用一個捕獲寄存器測量脈寬和
頻率的方法相比,PWM 輸入模式須要佔用兩個捕獲寄存器。
圖12-11 輸入通道和捕獲通道的關係映射圖
第12 章.TIM 高級定時器
SAIUR201 6 第127頁
當使用PWM 輸入模式的時候,由於一個輸入通道(TIx)會佔用兩個捕獲通道(ICx),因此一個定時
器在使用PWM 輸入的時候最多隻能使用兩個輸入通道(TIx)。咱們以輸入通道TI1 工做在PWM 輸
入模式爲例來說解下具體的工做原理,其餘通道以此類推便可。
PWM 信號由輸入通道TI1 進入,由於是PWM 輸入模式的緣故,信號會被分爲兩路, 一路是
TI1FP1,另一路是TI2FP2。其中一路是週期,另外一路是佔空比,具體哪一路信號對應週期仍是佔
空比,得從程序上設置哪一路信號做爲觸發輸入,做爲觸發輸入的哪一路信號對應的就是週期,另外一
路就是對應占空比。做爲觸發輸入的那一路信號還須要設置極性,是上升沿仍是降低沿捕獲,一旦設
置好觸發輸入的極性,另一路硬件就會自動配置爲相反的極性捕獲,無需軟件配置。一句話歸納就
是:選定輸入通道,肯定觸發信號,而後設置觸發信號的極性便可,由於是PWM 輸入的緣故,另外一
路信號則由硬件配置,無需軟件配置。當使用PWM 輸入模式的時候必須將從模式控制器配置爲復位
模式(配置寄存器SMCR 的位SMS[2:0]來實現),即當咱們啓動觸發信號開始進行捕獲的時候,同時
把計數器CNT 復位清零。下面咱們以一個更加具體的時序圖來分析下PWM 輸入模式。
圖12-12 PWM 輸入模式時序
PWM 信號由輸入通道TI1 進入,配置TI1FP1 爲觸發信號,上升沿捕獲。當上升沿的時候IC1 和
IC2 同時捕獲,計數器CNT 清零,到了降低沿的時候,IC2 捕獲,此時計數器CNT 的值被鎖存到捕
獲寄存器CCR2 中,到了下一個上升沿的時候,IC1 捕獲,計數器CNT 的值被鎖存到捕獲寄存器
CCR1 中。其中CCR2+1 測量的是脈寬,CCR1+1 測量的是週期。這裏要注意的是CCR2 和CCR1
的值在計算佔空比和頻率的時候都必須加1,由於計數器是從0 開始計數的。從軟件上來講,用PWM
輸入模式測量脈寬和週期更容易,付出的代價是須要佔用兩個捕獲寄存器。
第12 章.TIM 高級定時器
第128 頁SAIUR2016
12.7.輸出比較應用
輸出比較模式總共有8 種,具體的由寄存器CCMRx 的位OCxM[2:0]配置。咱們這裏只講解最
經常使用的PWM 模式,其餘幾種模式具體的看數據手冊便可。
12.7.1. PWM 輸出模式
PWM 輸出就是對外輸出脈寬(即佔空比)可調的方波信號,信號頻率由自動重裝寄存器ARR 的
值決定,佔空比由比較寄存器CCR 的值決定。PWM 模式分爲兩種,PWM1 和PWM2,總得來講是
差很少,就看你怎麼用而已,具體的區別見表格12-1。
表格12-1 PWM1 與PWM2 模式的區別
下面咱們以PWM1 模式來說解,以計數器CNT 計數的方向不一樣還分爲邊沿對齊模式和中心對齊
模式。PWM 信號主要都是用來控制電機,通常的電機控制用的都是邊沿對齊模式,FOC 電機通常用
中心對齊模式。咱們這裏只分析這兩種模式在信號感官上(即信號波形)的區別,具體在電機控制中的
區別不作討論,到了你真正須要使用的時候就會知道了。
12.7.2. PWM 邊沿對齊模式
在遞增計數模式下,計數器從0 計數到自動重載值( TIMx_ARR 寄存器的內容),而後從新從0
開始計數並生成計數器上溢事件
圖12-13 PWM1 模式的邊沿對齊波形
在邊沿對齊模式下,計數器CNT 只工做在一種模式,遞增或者遞減模式。這裏咱們以CNT 工做
在遞增模式爲例,在中,ARR=8,CCR=4,CNT 從0 開始計數,當CNT<CCR 的值時, OCxREF 爲
有效的高電平, 於此同時, 比較中斷寄存器CCxIF 置位。當CCR=<CNT<=ARR 時,OCxREF 爲
第12 章.TIM 高級定時器
SAIUR201 6 第129頁
無效的低電平。而後CNT 又從0 開始計數並生成計數器上溢事件,以此循環往復。
12.7.3. PWM 中心對齊模式
圖12-14 PWM1 模式的中心對齊波形
在中心對齊模式下,計數器CNT 是工做作遞增/遞減模式下。開始的時候,計數器CNT 從0 開
始計數到自動重載值減1(ARR-1),生成計數器上溢事件;而後從自動重載值開始向下計數到1 並生
成計數器下溢事件。以後從0 開始從新計數。圖12-14 是PWM1 模式的中心對齊波形,ARR=8,
CCR=4。第一階段計數器CNT 工做在遞增模式下,從0 開始計數,當CNT<CCR 的值時,OCxREF
爲有效的高電平,當CCR=<CNT<<ARR 時,OCxREF 爲無效的低電平。第二階段計數器CNT 工做
在遞減模式,從ARR 的值開始遞減,當CNT>CCR 時,OCxREF 爲無效的低電平,當CCR=>CNT>=1
時,OCxREF 爲有效的高電平。
在波形圖上咱們把波形分爲兩個階段,第一個階段是計數器CNT 工做在遞增模式的波形,這個
階段咱們又分爲①和②兩個階段,第二個階段是計數器CNT 工做在遞減模式的波形,這個階段咱們
又分爲③和④兩個階段。要說中心對齊模式下的波形有什麼特徵的話, 那就是①和③階段的時間相等,
②和④階段的時間相等。中心對齊模式又分爲中心對齊模式1/2/3 三種,具體由寄存器CR1 位
CMS[1:0]配置。具體的區別就是比較中斷中斷標誌位CCxIF 在什麼時候置1:中心模式1 在CNT 遞減
計數的時候置1,中心對齊模式2 在CNT 遞增計數時置1,中心模式3 在CNT 遞增和遞減計數時
都置1。
12.8.定時器初始化結構體詳解
在標準庫函數頭文件stm32f10x_tim.h 中對定時器外設創建了四個初始化結構體,分別爲時基
初始化結構體TIM_TimeBaseInitTypeDef 、輸出比較初始化結構體
TIM_OCInitTypeDef 、輸入捕獲初始化結構體TIM_ICInitTypeDef 和斷路和死區初始化結構體
TIM_BDTRInitTypeDef , 高級控制定時器能夠用到全部初始化結構體, 通用定時器不能使用
TIM_BDTRInitTypeDef 結構體,基本定時器只能使用時基結構體。接下來咱們具體講解下這四個結構
第12 章.TIM 高級定時器
第130 頁SAIUR2016
體。
12.8.1. TIM_TimeBaseInitTypeDef
時基結構體TIM_TimeBaseInitTypeDef 用於定時器基礎參數設置,與TIM_TimeBaseInit 函數配合
使用完成配置。
代碼清單12-1 定時器基本初始化結構體
TIM_Prescaler:定時器預分頻器設置,時鐘源經該預分頻器纔是定時器計數時鐘CK_CNT,它設定
PSC 寄存器的值。計算公式爲:計數器時鐘頻率(fCK_CNT) 等於fCK_PSC / (PSC[15:0] + 1),可實現
1 至65536 分頻。
TIM_CounterMode:定時器計數方式,可設置爲向上計數、向下計數以及中心對齊。高級控制定時器
容許選擇任意一種。
TIM_Period:定時器週期,實際就是設定自動重載寄存器ARR 的值,ARR 爲要裝載到實際自動重
載寄存器(即影子寄存器)的值,可設置範圍爲0 至65535。
TIM_ClockDivision:時鐘分頻,設置定時器時鐘CK_INT 頻率與死區發生器以及數字濾波器採樣時
鍾頻率分頻比。能夠選擇一、二、4 分頻。
TIM_RepetitionCounter:重複計數器,只有8 位,只存在於高級定時器。
12.8.2. TIM_OCInitTypeDef
輸出比較結構體TIM_OCInitTypeDef 用於輸出比較模式,與TIM_OCxInit 函數配合使用完成指
定定時器輸出通道初始化配置。高級控制定時器有四個定時器通道,使用時都必須單獨設置。
代碼清單12-2 定時器比較輸出初始化結構體
TIM_OCMode:比較輸出模式選擇,總共有八種,經常使用的爲PWM1/PWM2。它設定CCMRx 寄存器
第12 章.TIM 高級定時器
SAIUR201 6 第131頁
OCxM[2:0]位的值。
TIM_OutputState:比較輸出使能,決定最終的輸出比較信號OCx 是否經過外部引腳輸出。它設定
TIMx_CCER 寄存器CCxE/CCxNE 位的值。
TIM_OutputNState:比較互補輸出使能,決定OCx 的互補信號OCxN 是否經過外部引腳輸出。它設
定CCER 寄存器CCxNE 位的值。
TIM_Pulse:比較輸出脈衝寬度,實際設定比較寄存器CCR 的值,決定脈衝寬度。可設置範圍爲0 至
65535。
TIM_OCPolarity:比較輸出極性,可選OCx 爲高電平有效或低電平有效。它決定着定時器通道有效
電平。它設定CCER 寄存器的CCxP 位的值。
TIM_OCNPolarity : 比較互補輸出極性, 可選OCxN 爲高電平有效或低電平有效。它設定
TIMx_CCER 寄存器的CCxNP 位的值。
TIM_OCIdleState:空閒狀態時通道輸出電平設置,可選輸出1 或輸出0,即在空閒狀態(BDTR_MOE
位爲0)時,通過死區時間後定時器通道輸出高電平或低電平。它設定CR2 寄存器的OISx 位的值。
TIM_OCNIdleState:空閒狀態時互補通道輸出電平設置,可選輸出1 或輸出0,即在空閒狀態
(BDTR_MOE 位爲0)時,通過死區時間後定時器互補通道輸出高電平或低電平,設定值必須與
TIM_OCIdleState 相反。它設定是CR2 寄存器的OISxN 位的值。
12.8.3. TIM_ICInitTypeDef
輸入捕獲結構體TIM_ICInitTypeDef 用於輸入捕獲模式,與TIM_ICInit 函數配合使用完成定時器
輸入通道初始化配置。若是使用PWM 輸入模式須要與TIM_PWMIConfig 函數配合使用完成定時器
輸入通道初始化配置。
代碼清單12-3 定時器輸入捕獲初始化結構體
TIM_Channel:捕獲通道ICx 選擇,可選TIM_Channel_一、TIM_Channel_二、TIM_Channel_3 或
TIM_Channel_4 四個通道。它設定CCMRx 寄存器CCxS 位的值。
TIM_ICPolarity:輸入捕獲邊沿觸發選擇,可選上升沿觸發、降低沿觸發或邊沿跳變觸發。它設定
CCER 寄存器CCxP 位和CCxNP 位的值。
TIM_ICSelection : 輸入通道選擇, 捕獲通道ICx 的信號可來自三個輸入通道, 分別爲
第12 章.TIM 高級定時器
第132 頁SAIUR2016
TIM_ICSelection_DirectTI 、TIM_ICSelection_IndirectTI 或TIM_ICSelection_TRC , 具體的區別見圖
33-15。若是是普通的輸入捕獲,4 個通道均可以使用,若是是PWM 輸入則只能使用通道1 和通道
2。它設定CCRMx 寄存器的CCxS[1:0]位的值。
圖12-15 輸入通道與捕獲通道IC 的映射圖
TIM_ICPrescaler:輸入捕獲通道預分頻器,可設置一、二、四、8 分頻,它設定CCMRx 寄存器的
ICxPSC[1:0]位的值。若是須要捕獲輸入信號的每一個有效邊沿,則設置1 分頻便可。IM_ICFilter:輸
入捕獲濾波器設置,可選設置0x0 至0x0F。它設定CCMRx 寄存器ICxF[3:0]位的值。通常咱們不使
用濾波器,即設置爲0。
12.8.4. TIM_BDTRInitTypeDef
斷路和死區結構體TIM_BDTRInitTypeDef 用於斷路和死區參數的設置,屬於高級定時器專用,用
於配置斷路時通道輸出狀態,以及死區時間。它與TIM_BDTRConfig 函數配置使用完成參數配置。這
個結構體的成員只對應BDTR 這個寄存器,有關成員的具體使用配置請參考手冊BDTR 寄存器的詳
細描述。
代碼清單12-4 斷路和死區初始化結構體
TIM_OSSRState:運行模式下的關閉狀態選擇,它設定BDTR 寄存器OSSR 位的值。
TIM_OSSIState:空閒模式下的關閉狀態選擇,它設定BDTR 寄存器OSSI 位的值。
TIM_LOCKLevel:鎖定級別配置, BDTR 寄存器LOCK[1:0]位的值。
TIM_DeadTime:配置死區發生器,定義死區持續時間,可選設置範圍爲0x0 至0xFF。它設定BDTR
寄存器DTG[7:0]位的值。
第12 章.TIM 高級定時器
SAIUR201 6 第133頁
TIM_Break:斷路輸入功能選擇,可選使能或禁止。它設定BDTR 寄存器BKE 位的值。
TIM_BreakPolarity:斷路輸入通道BRK 極性選擇,可選高電平有效或低電平有效。它設定BDTR 寄
存器BKP 位的值。
TIM_AutomaticOutput:自動輸出使能,可選使能或禁止,它設定BDTR 寄存器AOE 位的值。
12.9. PWM 互補輸出實驗
輸出比較模式比較多,這裏咱們以PWM 輸出爲例講解,並經過示波器來觀察波形。實驗中不只
在主輸出通道輸出波形,還在互補通道輸出與主通道互補的的波形,而且添加了斷路和死區功能。
12.9.1. 硬件設計
根據開發板引腳使用狀況,而且參考表12-1 中定時器引腳信息,使用高級定時器TIM1 的通道1
及其互補通道做爲本實驗的波形輸出通道,對應選擇PA8 和PB13 引腳。將示波器的兩個輸入通道分
別與PA8 和PB13 引腳鏈接,用於觀察波形,還有注意共地。爲增長斷路功能,須要用到TIM1_BKIN
引腳,這裏選擇PB12 引腳。程序咱們設置該引腳爲高電平有效,當BKIN 引腳被置高低電平的時候,
兩路互補的PWM 輸出就被中止,就好像是剎車同樣。
12.9.2. 軟件設計
這裏只講解核心的部分代碼,有些變量的設置,頭文件的包含等並無涉及到,完整的代碼請參
考本章配套的工程。咱們建立了兩個文件: bsp_AdvanceTim.c 和bsp_AdvanceTim.h 文件用來存定時
器驅動程序及相關宏定義。
12.9.3. 編程要點
1. 定時器用到的GP IO 初始化
2. 定時器時基結構體TIM_TimeBaseInitTypeDef 初始化
3. 定時器輸出比較結構體TIM_OCInitTypeDef 初始化
4. 定時器剎車和死區結構體TIM_BDTRInitTypeDef 初始化
第12 章.TIM 高級定時器
第134 頁SAIUR2016
12.9.4. 軟件分析
代碼清單12-5 宏定義
使用宏定義很是方便程序升級、移植。有關每一個宏的具體含義看程序註釋便可。
代碼清單12-6 定時器複用功能引腳初始化
第12 章.TIM 高級定時器
SAIUR201 6 第135頁
ADVANCE_TIM_GPIO_Config()函數初始化了定時器用到的相關的GPIO,當使用不一樣的GPIO 的
時候,只須要修改頭文件裏面的宏定義便可,而不須要修改這個函數。
代碼清單12-7 定時器模式配置
第12 章.TIM 高級定時器
第136 頁SAIUR2016
ADVANCE_TIM_Mode_Config()函數中初始化了三個結構體,有關這三個結構體成員的具體含義可
參考「定時器初始化結構體詳解」小節,剩下的程序參考註釋閱讀便可。若是須要修改PWM 的週期
和佔空比, 修改頭文件裏面的ADVANCE_TIM_PERIOD ADVANCE_TIM_PSC 和
ADVANCE_TIM_PULSE 這三個宏便可。PWM 信號的頻率的計算公司爲: F =
TIM_CLK/{(ARR+1)*(PSC+1)},其中TIM_CLK 等於72MHZ,ARR 即自動重裝載寄存器的值,對
應ADVANCE_TIM_PERIOD 這個宏,PSC 即計數器時鐘的分頻因子,對應ADVANCE_TIM_PSC 這
個宏。
代碼清單12-8 main 函數
Main 函數很簡單,調用了ADVANCE_TIM_Init() 函數, 該函數調用了
ADVANCE_TIM_GPIO_Config()和ADVANCE_TIM_Mode_Config()這兩個函數完成了定時器GPIO 引
腳和工做模式的初始化,這時,相應的GPIO 引腳上就能夠檢測到互補輸出的PWM 信號,並且帶死
區時間,若是程序運行的過程當中,BKIN 引腳被拉高的話,PWM 輸出會被禁止,就好像是斷路或者剎
車同樣。
12.9.5. 下載驗證
根據實驗的硬件設計內容接好示波器輸入通道和開發板引腳鏈接,,編譯實驗程序並下載到開發
板上,調整示波器到合適參數,在示波器顯示屏和看到一路互補的帶死區時間的PWM 波形,參考圖
33-16。至於圖中的信號有毛刺是由於信號的輸出引腳還接了其餘的芯片,受到了影響。
第12 章.TIM 高級定時器
SAIUR201 6 第137頁
圖12-16 PWM 互補帶死區時間波形輸出
BKIN 引腳接高電平時,PWM 輸出被禁止,就好像是剎車同樣,具體見圖12-17。
圖33-17 PWM 剎車輸出
第13 章.I2C 通信
第138 頁SAIUR2016
第13 章.I2C 通信
13.1.課前預習
在書上找到答案。
1. 什麼是SDA?
2. 什麼是數據有效協議?
13.2.概述
本章所講內容:
(1)I2C通訊協議
(2)使用I2C讀寫EEPROM
13.3. I2C 協議簡介
I2C 通信協議(Inter-Integrated Circuit)是由Phiilps 公司開發的,因爲它引腳少,硬件實現簡單,
可擴展性強,不須要USART、CAN 等通信協議的外部收發設備,如今被普遍地使用在系統內多個集
成電路(IC)間的通信。在計算機科學裏,大部分複雜的問題均可以經過分層來簡化。如芯片被分爲內核
層和片上外設;STM32 標準庫則是在寄存器與用戶代碼之間的軟件層。對於通信協議,咱們也以分
層的方式來理解,最基本的是把它分爲物理層和協議層。物理層規定通信系統中具備機械、電子功能
部分的特性,確保原始數據在物理媒體的傳輸。協議層主要規定通信邏輯, 統一收發雙方的數據打包、
解包標準。簡單來講物理層規定咱們用嘴巴仍是用肢體來交流, 協議層則規定咱們用中文仍是英文來
交流。下面咱們分別對I2C 協議的物理層及協議層進行講解。
第13 章.I2C 通信
SAIUR201 6 第139頁
13.3.1. I2C 物理層
I2C 通信設備之間的經常使用鏈接方式見圖13-1。
圖13-1 常見的I2C 通信系統
它的物理層有以下特色:
1. 它是一個支持設備的總線。「總線」指多個設備共用的信號線。在一個I2C 通信總線中,可鏈接多
個I2C 通信設備,支持多個通信主機及多個通信從機。
2. 一個I2C 總線只使用兩條總線線路,一條雙向串行數據線(SDA) ,一條串行時鐘線(SCL)。數據
線即用來表示數據,時鐘線用於數據收發同步。
3. 每一個鏈接到總線的設備都有一個獨立的地址,主機能夠利用這個地址進行不一樣設備之間的訪問。
4. 總線經過上拉電阻接到電源。當I2C 設備空閒時,會輸出高阻態,而當全部設備都空閒,都輸出
高阻態時,由上拉電阻把總線拉成高電平。
5. 多個主機同時使用總線時,爲了防止數據衝突,會利用仲裁方式決定由哪一個設備佔用總線。
6. 具備三種傳輸模式:標準模式傳輸速率爲100kbit/s ,快速模式爲400kbit/s ,高速模式下可達
3.4Mbit/s,但目前大多I2C 設備尚不支持高速模式。
7. 鏈接到相同總線的IC 數量受到總線的最大電容400pF 限制。
第13 章.I2C 通信
第140 頁SAIUR2016
13.3.2. 協議層
I2C 的協議定義了通信的起始和中止信號、數據有效性、響應、仲裁、時鐘同步和地址廣播等環節。
I2C 基本讀寫過程
先看看I2C 通信過程的基本結構,它的通信過程見圖13-二、圖13-3 及圖13-4。
圖13-2 主機寫數據到從機
圖13-3 主機由從機中讀數據
圖13-4 I2C 通信複合格式
陰影部分數據由主機傳輸至從機S : 傳輸開始信號SLAVE_ADDRESS: 從機地址
空白部分數據由從機傳輸至主機R/W: 傳輸方向選擇位,1 爲讀,0 爲寫A/ A : 應答(ACK)
或非應答(NACK)信號P : 中止傳輸信號
這些圖表示的是主機和從機通信時,SDA 線的數據包序列。
其中S 表示由主機的I2C 接口產生的傳輸起始信號(S),這時鏈接到I2C 總線上的全部從機都
會接收到這個信號。
起始信號產生後, 全部從機就開始等待主機緊接下來廣播的從機地址信號(SLAVE_ADDRESS)。
在I2C 總線上,每一個設備的地址都是惟一的,當主機廣播的地址與某個設備地址相同時,這個設備就
被選中了,沒被選中的設備將會忽略以後的數據信號。根據I2C 協議,這個從機地址能夠是7 位或10
第13 章.I2C 通信
SAIUR201 6 第141頁
位。
在地址位以後,是傳輸方向的選擇位,該位爲0 時,表示後面的數據傳輸方向是由主機傳輸至從
機,即主機向從機寫數據。該位爲1 時,則相反,即主機由從機讀數據。
從機接收到匹配的地址後,主機或從機會返回一個應答(ACK)或非應答(NACK)信號, 只有接收到
應答信號後,主機才能繼續發送或接收數據。
寫數據
若配置的方向傳輸位爲「寫數據」方向,即第一幅圖的狀況,廣播完地址,接收到應答信號後,主
機開始正式向從機傳輸數據(DATA),數據包的大小爲8 位,主機每發送完一個字節數據,都要等待
從機的應答信號(ACK),重複這個過程,能夠向從機傳輸N 個數據,這個N 沒有大小限制。當數據
傳輸結束時,主機向從機發送一箇中止傳輸信號(P),表示再也不傳輸數據。
讀數據
若配置的方向傳輸位爲「讀數據」方向,即第二幅圖的狀況,廣播完地址,接收到應答信號後,從
機開始向主機返回數據(DATA),數據包大小也爲8 位,從機每發送完一個數據,都會等待主機的應
答信號(ACK),重複這個過程,能夠返回N 個數據,這個N 也沒有大小限制。當主機但願中止接收
數據時,就向從機返回一個非應答信號(NACK),則從機自動中止數據傳輸。
讀和寫數據
除了基本的讀寫,I2C 通信更經常使用的是複合格式,即第三幅圖的狀況,該傳輸過程有兩次起始信
號(S)。通常在第一次傳輸中,主機經過SLAVE_ADDRESS 尋找到從設備後,發送一段「數據」,這段
數據一般用於表示從設備內部的寄存器或存儲器地址(注意區分它與SLAVE_ADDRESS 的區別);在第
二次的傳輸中,對該地址的內容進行讀或寫。也就是說,第一次通信是告訴從機讀寫地址,第二次則是
讀寫的實際內容。
以上通信流程中包含的各個信號分解以下:
13.3.3. 通信的起始和中止信號
前文中提到的起始(S)和中止(P)信號是兩種特殊的狀態,見圖24-5。當SCL 線是高電平時SDA
線從高電平向低電平切換,這個狀況表示通信的起始。當SCL 是高電平時SDA 線由低電平向高電平
切換,表示通信的中止。起始和中止信號通常由主機產生。
第13 章.I2C 通信
第142 頁SAIUR2016
圖13-5 起始和中止信號
數據有效性
I2C 使用SDA 信號線來傳輸數據,使用SCL 信號線進行數據同步。見圖24-6。SDA 數據線在
SCL 的每一個時鐘週期傳輸一位數據。傳輸時,SCL 爲高電平的時候SDA 表示的數據有效,即此時
的SDA 爲高電平時表示數據「1」,爲低電平時表示數據「0」。當SCL 爲低電平時,SDA 的數據無效,
通常在這個時候SDA 進行電平切換,爲下一次表示數據作好準備。
圖13-6 數據有效性
每次數據傳輸都以字節爲單位,每次傳輸的字節數不受限制。
地址及數據方向
I2C 總線上的每一個設備都有本身的獨立地址,主機發起通信時,經過SDA 信號線發送設備地址
(SLAVE_ADDRESS)來查找從機。I2C 協議規定設備地址能夠是7 位或10 位,實際中7 位的地址應
用比較普遍。緊跟設備地址的一個數據位用來表示數據傳輸方向,它是數據方向位(R/W),第8 位或
第11 位。數據方向位爲「1」時表示主機由從機讀數據,該位爲「0」時表示主機向從機寫數據。見圖
12-7。
第13 章.I2C 通信
SAIUR201 6 第143頁
圖13-7 設備地址(7 位)及數據傳輸方向
讀數據方向時,主機會釋放對SDA 信號線的控制,由從機控制SDA 信號線,主機接收信號,寫
數據方向時,SDA 由主機控制,從機接收信號。
響應
I2C 的數據和地址傳輸都帶響應。響應包括「應答(ACK)」和「非應答(NACK)」兩種信號。做爲數據
接收端時,當設備(不管主從機)接收到I2C 傳輸的一個字節數據或地址後, 若但願對方繼續發送數據,
則須要向對方發送「應答(ACK)」信號,發送方會繼續發送下一個數據;若接收端但願結束數據傳輸,
則向對方發送「非應答(NACK)」信號,發送方接收到該信號後會產生一箇中止信號,結束信號傳輸。見
圖13-8。
圖13-8 響應與非響應信號
傳輸時主機產生時鐘,在第9 個時鐘時,數據發送端會釋放SDA 的控制權,由數據接收端控制SDA,
若SDA 爲高電平,表示非應答信號(NACK),低電平表示應答信號(ACK)。
第13 章.I2C 通信
第144 頁SAIUR2016
13.4. STM32 的I2C 特性及架構
若是咱們直接控制STM32 的兩個GPIO 引腳,分別用做SCL 及SDA,按照上述信號的時序要
求,直接像控制LED 燈那樣控制引腳的輸出(如果接收數據時則讀取SDA 電平),就能夠實現I2C 通
訊。一樣,假如咱們按照USART 的要求去控制引腳,也能實現USART 通信。因此只要遵照協議,
就是標準的通信,無論您如何實現它,無論是ST 生產的控制器仍是ATMEL 生產的存儲器, 都能
按通信標準交互。因爲直接控制GPIO 引腳電平產生通信時序時,須要由CPU 控制每一個時刻的引腳
狀態, 因此稱之爲「軟件模擬協議」方式。相對地,還有「硬件協議」方式,STM32 的I2C 片上外設專
門負責實現I2C 通信協議, 只要配置好該外設,它就會自動根據協議要求產生通信信號,收發數據並
緩存起來,CPU 只要檢測該外設的狀態和訪問數據寄存器,就能完成數據收發。這種由硬件外設處理
I2C 協議的方式減輕了CPU 的工做,且使軟件設計更加簡單。
13.4.1. STM32 的I2C 外設簡介
STM32 的I2C 外設可用做通信的主機及從機,支持100Kbit/s 和400Kbit/s 的速率,支7 位、
10 位設備地址,支持DMA 數據傳輸,並具備數據校驗功能。它的I2C 外設還支SMBus2.0 協議,
SMBus 協議與I2C 相似,主要應用於筆記本電腦的電池管理中,本教程不展開,感興趣的讀者可參
考《SMBus20》文檔瞭解。
第13 章.I2C 通信
SAIUR201 6 第145頁
13.4.2. STM32 的I2C 架構剖析
圖13-9 I2C 架構圖
通信引腳
I2C 的全部硬件架構都是根據圖中左側SCL 線和SDA 線展開的(其中的SMBA 線用於SMBUS
的警告信號,I2C 通信沒有使用)。STM32 芯片有多個I2C 外設,它們的I2C 通信信號引出到不一樣的
GPIO 引腳上,使用時必須配置到這些指定的引腳,見圖13-1。關於GPIO 引腳的複用功能,以規格
書爲準。
表13-1 STM32F10x 的I2C 引腳
第13 章.I2C 通信
第146 頁SAIUR2016
時鐘控制邏輯
SCL 線的時鐘信號,由I2C 接口根據時鐘控制寄存器(CCR)控制,控制的參數主要爲時鐘頻率。
配置I2C 的CCR 寄存器可修改通信速率相關的參數:
1. 可選擇I2C 通信的「標準/快速」模式,這兩個模式分別I2C 對應100/400Kbit/s 的通信速率。
2. 在快速模式下可選擇SCL 時鐘的佔空比,可選Tlow/Thigh=2 或Tlow/Thigh=16/9 模式,咱們知
道I2C 協議在SCL 高電平時對SDA 信號採樣,SCL 低電平時SDA 準備下一個數據,修改
SCL 的高低電平比會影響數據採樣,但其實這兩個模式的比例差異並不大,若不是要求很是嚴格,
這裏隨便選就能夠了。
3. CCR 寄存器中還有一個12 位的配置因子CCR,它與I2C 外設的輸入時鐘源共同做用,產生
SCL 時鐘,STM32 的I2C 外設都掛載在APB1 總線上,使用APB1 的時鐘源PCLK1,SCL 信
號線的輸出時鐘公式以下:
計算結果得出CCR 爲30,向該寄存器位寫入此值則能夠控制IIC 的通信速率爲400KHz,其實
即便配置出來的SCL 時鐘不徹底等於標準的400KHz,IIC 通信的正確性也不會受到影響,由於全部
數據通信都是由SCL 協調的,只要它的時鐘頻率不遠高於標準便可。
第13 章.I2C 通信
SAIUR201 6 第147頁
數據控制邏輯
I2C 的SDA 信號主要鏈接到數據移位寄存器上,數據移位寄存器的數據來源及目標是數據寄存
器(DR)、地址寄存器(OAR)、PEC 寄存器以及SDA 數據線。當向外發送數據的時候,數據移位寄存
器以「數據寄存器」爲數據源,把數據一位一位地經過SDA 信號線發送出去;當從外部接收數據的時候,
數據移位寄存器把SDA 信號線採樣到的數據一位一位地存儲到「數據寄存器」中。若使能了數據校驗,
接收到的數據會通過PCE 計算器運算,運算結果存儲在「PEC 寄存器」中。當STM32 的I2C 工做在
從機模式的時候,接收到設備地址信號時,數據移位寄存器會把接收到的地址與STM32 的自身的「I2C
地址寄存器」的值做比較,以便響應主機的尋址。STM32 的自身I2C 地址可經過修改「自身地址寄存器」
修改,支持同時使用兩個I2C 設備地址,兩個地址分別存儲在OAR1 和OAR2 中。
總體控制邏輯
總體控制邏輯負責協調整個I2C 外設,控制邏輯的工做模式根據咱們配置的「控制寄存器
(CR1/CR2)」的參數而改變。在外設工做時,控制邏輯會根據外設的工做狀態修改「狀態寄存器(SR1 和
SR2)」,咱們只要讀取這些寄存器相關的寄存器位,就能夠了解I2C 的工做狀態。除此以外,控制邏輯
還根據要求,負責控制產生I2C 中斷信號、DMA 請求及各類I2C 的通信信號(起始、中止、響應信
號等)。
13.4.3. 通信過程
使用I2C 外設通信時,在通信的不一樣階段它會對「狀態寄存器(SR1 及SR2)」的不一樣數據位寫入參
數,咱們經過讀取這些寄存器標誌來了解通信狀態。
主發送器
見圖13-10。圖中的是「主發送器」流程,即做爲I2C 通信的主機端時,向外發送數據時的過程。
圖13-10 主發送器通信過程
主發送器發送流程及事件說明以下:
1. 控制產生起始信號(S),當發生起始信號後,它產生事件「EV5」,並會對SR1 寄存器的「SB」位置1,
表示起始信號已經發送;
第13 章.I2C 通信
第148 頁SAIUR2016
2. 緊接着發送設備地址並等待應答信號,如有從機應答,則產生事件「EV6」及「EV8」,這時SR1 寄
存器的「ADDR」位及「TXE」位被置1,ADDR 爲1 表示地址已經發送,TXE 爲1 表示數據寄存
器爲空;
3. 以上步驟正常執行並對ADDR 位清零後,咱們往I2C 的「數據寄存器DR」寫入要發送的數據,
這時TXE 位會被重置0,表示數據寄存器非空,I2C 外設經過SDA 信號線一位位把數據發送出
去後,又會產生「EV8」事件,即TXE 位被置1,重複這個過程,就能夠發送多個字節數據了;
4. 當咱們發送數據完成後,控制I2C 設備產生一箇中止信號(P),這個時候會產生EV8_2 事件,SR1
的TXE 位及BTF 位都被置1,表示通信結束。假如咱們使能了I2C 中斷,以上全部事件產生
時,都會產生I2C 中斷信號,進入同一個中斷服務函數,到I2C 中斷服務程序後,再經過檢查
寄存器位來判斷是哪個事件。
主接收器
再來分析主接收器過程,即做爲I2C 通信的主機端時,從外部接收數據的過程,見圖13-11。
圖13-11 主接收器過程
主接收器接收流程及事件說明以下:
1. 同主發送流程,起始信號(S)是由主機端產生的,控制發生起始信號後,它產生事件「EV5」,並會
對SR1 寄存器的「SB」位置1,表示起始信號已經發送;
2. 緊接着發送設備地址並等待應答信號,如有從機應答,則產生事件「EV6」這時SR1 寄存器的
「ADDR」位被置1,表示地址已經發送。
3. 從機端接收到地址後,開始向主機端發送數據。當主機接收到這些數據後,會產生「EV7」事件,
SR1 寄存器的RXNE 被置1,表示接收數據寄存器非空,咱們讀取該寄存器後,可對數據寄存
器清空,以便接收下一次數據。此時咱們能夠控制I2C 發送應答信號(ACK)或非應答信號(NACK),
若應答,則重複以上步驟接收數據,若非應答,則中止傳輸;
4. 發送非應答信號後,產生中止信號(P),結束傳輸。在發送和接收過程當中,有的事件不僅是標誌了
咱們上面提到的狀態位,還可能同時標誌主機狀態之類的狀態位,並且讀了以後還須要清除標誌
位,比較複雜。咱們可以使用STM32 標準庫函數來直接檢測這些事件的複合標誌,下降編程難度。
第13 章.I2C 通信
SAIUR201 6 第149頁
13.5. I2C 初始化結構體詳解
跟其它外設同樣,STM32 標準庫提供了I2C 初始化結構體及初始化函數來配置I2C 外設。初始
化結構體及函數定義在庫文件「stm32f10x_i2c.h」及「stm32f10x_i2c.c」中,編程時咱們能夠結合這兩個文
件內的註釋使用或參考庫幫助文檔。瞭解初始化結構體後咱們就能對I2C 外設運用自如了,見代碼清
單13-1。
代碼清單13-1 I2C 初始化結構體
這些結構體成員說明以下,其中括號內的文字是對應參數在STM32 標準庫中定義的宏:
1. 2C_ClockSpeed
本成員設置的是I2C 的傳輸速率,在調用初始化函數時,函數會根據咱們輸入的數值通過運算後
把時鐘因子寫入到I2C 的時鐘控制寄存器CCR。而咱們寫入的這個參數值不得高於400KHz。實際
上因爲CCR 寄存器不能寫入小數類型的時鐘因子,影響到SCL 的實際頻率可能會低於本成員設置
的參數值,這時除了通信稍慢一點之外,不會對I2C 的標準通信形成其它影響。
2. I2C_Mode
本成員是選擇I2C 的使用方式, 有I2C 模式(I2C_Mode_I2C ) 和SMBus 主、從模式
(I2C_Mode_SMBusHost、I2C_Mode_SMBusDevice ) 。I2C 不須要在此處區分主從模式,直接設置
I2C_Mode_I2C 便可。
3. I2C_DutyCycle
本成員設置的是I2C 的SCL 線時鐘的佔空比。該配置有兩個選擇,分別爲低電平時間比高電平
時間爲2:1 ( I2C_DutyCycle_2)和16:9 (I2C_DutyCycle_16_9)。其實這兩個模式的比例差異並不大,
通常要求都不會如此嚴格,這裏隨便選就能夠。
4. I2C_OwnAddress1
本成員配置的是STM32 的I2C 設備本身的地址,每一個鏈接到I2C 總線上的設備都要有一個自
己的地址, 做爲主機也不例外。地址可設置爲7 位或10 位( 受下面I2C_AcknowledgeAddress 成員
決定),只要該地址是I2C 總線上惟一的便可。STM32 的I2C 外設可同時使用兩個地址,即同時對兩
第13 章.I2C 通信
第150 頁SAIUR2016
個地址做出響應,這個結構成員I2C_OwnAddress1 配置的是默認的、OAR1 寄存器存儲的地址,若需
要設置第二個地址寄存器OAR2,可以使用I2C_OwnAddress2Config 函數來配置,OAR2 不支持10 位
地址,只有7 位。
5. I2C_Ack_Enable
本成員是關於I2C 應答設置,設置爲使能則能夠發送響應信號。本實驗配置爲容許應答
(I2C_Ack_Enable),這是絕大多數遵循I2C 標準的設備的通信要求,改成禁止應答(I2C_Ack_Disable)
每每會致使通信錯誤。
6. I2C_AcknowledgeAddress
本成員選擇I2C 的尋址模式是7 位仍是10 位地址。這須要根據實際鏈接到I2C 總線上設備的
地址進行選擇,這個成員的配置也影響到I2C_OwnAddress1 成員,只有這裏設置成10 位模式時,
I2C_OwnAddress1 才支持10 位地址。配置完這些結構體成員值,調用庫函數I2C_Init 便可把結構體
的配置寫入到寄存器中。
13.6. I2C—讀寫EEPROM 實驗
EEPROM 是一種掉電後數據不丟失的存儲器,經常使用來存儲一些配置信息,以便系統從新上電的時
候加載之。EEPOM 芯片最經常使用的通信方式就是I2C 協議,本小節以EEPROM 的讀寫實驗爲你們講
解STM32 的I2C 使用方法。實驗中STM32 的I2C 外設採用主模式,分別用做主發送器和主接收
器,經過查詢事件的方式來確保正常通信。
13.6.1. 硬件設計
圖13-12 EEPROM 硬件鏈接圖
本實驗板中的EEPROM 芯片(型號:AT24C02)的SCL 及SDA 引腳鏈接到了STM32 對應的
第13 章.I2C 通信
SAIUR201 6 第151頁
I2C 引腳中,結合上拉電阻,構成了I2C 通信總線,它們經過I2C 總線交互。EEPROM 芯片的設備
地址一共有7 位,其中高4 位固定爲:1010 b,低3 位則由A0/A1/A2 信號線的電平決定,見圖
13-13,圖中的R/W 是讀寫方向位,與地址無關。
圖13-13 EEPROM 設備地址(摘自《AT24C02》規格書)
按照咱們此處的鏈接,A0/A1/A2 均爲0,因此EEPROM 的7 位設備地址是:101 0000b ,即
0x50。因爲I2C 通信時經常是地址跟讀寫方向連在一塊兒構成一個8 位數,且當R/W 位爲0 時,表
示寫方向,因此加上7 位地址,其值爲「0xA0」,常稱該值爲I2C 設備的「寫地址」;當R/W 位爲1 時,
表示讀方向,加上7 位地址,其值爲「0xA1」,常稱該值爲「讀地址」。
EEPROM 芯片中還有一個WP 引腳,具備寫保護功能,當該引腳電平爲高時,禁止寫入數據,當
引腳爲低電平時,可寫入數據,咱們直接接地,不使用寫保護功能。
13.6.2. 軟件設計
爲了使工程更加有條理,咱們把讀寫EEPROM 相關的代碼獨立分開存儲,方便之後移植。在「工
程模板」之上新建「bsp_i2c_ee.c」及「bsp_i2c_ee.h」文件,這些文件也可根據您的喜愛命名,它們不屬於
STM32 標準庫的內容,是由咱們本身根據應用須要編寫的。
13.6.3. 編程要點
1. 配置通信使用的目標引腳爲開漏模式;
2. 使能I2C 外設的時鐘;
3. 配置I2C 外設的模式、地址、速率等參數並使能I2C 外設;
4. 編寫基本I2C 按字節收發的函數;
5. 編寫讀寫EEPROM 存儲內容的函數;
6. 編寫測試程序,對讀寫數據進行校驗。
第13 章.I2C 通信
第152 頁SAIUR2016
8.
13.6.4. 代碼分析
咱們把I2C 硬件相關的配置都以宏的形式定義到「bsp_i2c_ee.h」文件中,見代碼清單13-2。
代碼清單13-2 I2C 硬件配置相關的宏
以上代碼根據硬件鏈接,把與EEPROM 通信使用的I2C 號、引腳號都以宏封裝起來,而且定
義了自身的I2C 地址及通信速率,以便配置模式的時候使用。
利用上面的宏,編寫I2C GPIO 引腳的初始化函數,見代碼清單13-2。
代碼清單13-3 I2C GPIO 初始化函數
開啓相關的時鐘並初始化GPIO 引腳,函數執行流程以下:
1. 使用GPIO_InitTypeDef 定義GPIO 初始化結構體變量,以便下面用於存儲GPIO 配置;
2. 調用庫函數RCC_APB1PeriphClockCmd(代碼中爲宏EEPROM_I2C_APBxClock_FUN) 使能
第13 章.I2C 通信
SAIUR201 6 第153頁
I2C 外設時鐘, 調用RCC_APB2PeriphClockCmd ( 代碼中爲宏
EEPROM_I2C_GPIO_APBxClock_FUN)來使能I2C 引腳使用的GPIO 端口時鐘,調用時咱們使
用「|」操做同時配置兩個引腳。
3. 向GPIO 初始化結構體賦值,把引腳初始化成複用開漏模式,要注意I2C 的引腳必須使用這種
模式。
4. 使用以上初始化結構體的配置,調用GPIO_Init 函數向寄存器寫入參數,完成GPIO 的初始化。
以上只是配置了I2C 使用的引腳,還不算對I2C 模式的配置,見代碼清單13-4。
第13 章.I2C 通信
第154 頁SAIUR2016
代碼清單13-4 配置I2C 模式
熟悉STM32 I2C 結構的話,這段初始化程序就十分好理解,它把I2C 外設通信時鐘SCL 的低
/高電平比設置爲2,使能響應功能,使用7 位地址I2C_OWN_ADDRESS7 以及速率配置爲
I2C_Speed(前面在bsp_i2c_ee.h 定義的宏)。最後調用庫函數I2C_Init 把這些配置寫入寄存器,並調用
I2C_Cmd 函數使能外設。爲方便調用,咱們把I2C 的GPIO 及模式配置都用I2C_EE_Init 函數封裝
起來。向EEPROM 寫入一個字節的數據
初始化好I2C 外設後,就能夠使用I2C 通信,咱們看看如何向EEPROM 寫入一個字節的數據,
見代碼清單13-5。
第13 章.I2C 通信
SAIUR201 6 第155頁
代碼清單13-5 向EEPROM 寫入一個字節的數據
第13 章.I2C 通信
第156 頁SAIUR2016
先來分析I2C_TIMEOUT_UserCallback 函數, 它的函數體裏只調用了宏
EEPROM_ERROR,這個宏封裝了printf 函數,方便使用串口向上位機打印調試信息,閱讀代碼時把
它當成printf 函數便可。在I2C 通信的不少過程,都須要檢測事件,當檢測到某事件後才能繼續下一
步的操做,但有時通信錯誤或者I2C 總線被佔用,咱們不能無休止地等待下去,因此咱們設定每一個事
件檢測都有等待的時間上限,若超過這個時間,咱們就調用I2C_TIMEOUT_UserCallback 函數輸出調
試信息(或能夠本身加其它操做),並終止I2C 通信。
瞭解了這個機制,再來分析I2C_EE_ByteWrite 函數,這個函數實現了前面講的I2C
主發送器通信流程:
1. 使用庫函數I2C_GenerateSTART 產生I2C 起始信號,其中的EEPROM_I2C 宏是前面硬件定義
相關的I2C 編號;
2. 對I2CTimeout 變量賦值爲宏I2CT_FLAG_TIMEOUT,這個I2CTimeout 變量在下面的while
循環中每次循環減1,該循環經過調用庫函數I2C_CheckEvent 檢測事件,若檢測到事件,則進
入通信的下一階段,若未檢測到事件則停留在此處一直檢測,當檢測I2CT_FLAG_TIMEOUT 次
都還沒等待到事件則認爲通信失敗,調用前面的I2C_TIMEOUT_UserCallback 輸出調試信息,並
退出通信;
3. 調用庫函數I2C_Send7bitAddress 發送EEPROM 的設備地址,並把數據傳輸方向設置爲
I2C_Direction_Transmitter(即發送方向),這個數據傳輸方向就是經過設置I2C 通信中緊跟地址後面
的R/W 位實現的。發送地址後以一樣的方式檢測EV6 標誌;
4. 調用庫函數I2C_SendData 向EEPROM 發送要寫入的內部地址, 該地址是I2C_EE_ByteWrite
函數的輸入參數,發送完畢後等待EV8 事件。要注意這個內部地址跟上面的EEPROM 地址不
同樣,上面的是指I2C 總線設備的獨立地址,而此處的內部地址是指EEPROM 內數據組織的
地址,也可理解爲EEPROM 內存的地址或I2C 設備的寄存器地址;
5. 調用庫函數I2C_SendData 向EEPROM 發送要寫入的數據,該數據是I2C_EE_ByteWrite 函
數的輸入參數,發送完畢後等待EV8 事件;
6. 一個I2C 通信過程完畢,調用I2C_GenerateSTOP 發送中止信號。在這個通信過程當中,STM32 實
際上經過I2C 向EEPROM 發送了兩個數據,但爲什麼第一個數據被解釋爲EEPROM 的內存地
址?這是由EEPROM 的本身定義的單字節寫入時序,見圖13-14。
第13 章.I2C 通信
SAIUR201 6 第157頁
圖13-14 EEPROM 單字節寫入時序(摘自《AT24C02》規格書)
EEPROM 的單字節時序規定,向它寫入數據的時候,第一個字節爲內存地址,第二個字節是要寫
入的數據內容。因此咱們須要理解:命令、地址的本質都是數據,對數據的解釋不一樣,它就有了不一樣的
功能。
多字節寫入及狀態等待
單字節寫入通信結束後,EEPROM 芯片會根據這個通信結果擦寫該內存地址的內容, 這須要一
段時間,因此咱們在屢次寫入數據時,要先等待EEPROM 內部擦寫完畢。多個數據寫入過程見代碼
清單13-6。
代碼清單13-6 多字節寫入
這段代碼比較簡單,直接使用for 循環調用前面定義的I2C_EE_ByteWrite 函數一個字節一個字節
地向EEPROM 發送要寫入的數據。在每次數據寫入通信前調用了I2C_EE_WaitEepromStandbyState
函數等待EEPROM 內部擦寫完畢,該函數的定義見代碼清單13-7。
第13 章.I2C 通信
第158 頁SAIUR2016
代碼清單13-7 等待EEPROM 處於準備狀態
函數主要實現是向EEPROM 發送它設備地址, 檢測EEPROM 的響應, 若EEPROM 接收到地
址後返回應答信號,則表示EEPROM 已經準備好,能夠開始下一次通信。函數中檢測響應是經過讀
取STM32 的SR1 寄存器的ADDR 位及AF 位來實現的,當I2C 設備響應了地址的時候,ADDR 會
置1,若應答失敗,AF 位會置1。
EEPROM 的頁寫入
在以上的數據通信中,每寫入一個數據都須要向EEPROM 發送寫入的地址,咱們但願向連續地
址寫入多個數據的時候,只要告訴EEPROM 第一個內存地址address1,後面的數據按次序寫入到
address二、address3… 這樣能夠節省通信的時間,加快速度。爲應對這種需求,EEPROM 定義了一種
頁寫入時序,見圖13-15。
圖13-15 EEPROM 頁寫入時序(摘自《AT24C02》規格書)
根據頁寫入時序,第一個數據被解釋爲要寫入的內存地址address1,後續可連續發送n 個數據,
這些數據會依次寫入到內存中。其中AT24C02 型號的芯片頁寫入時序最多能夠一次發送8 個數據(即
n = 8 ),該值也稱爲頁大小,某些型號的芯片每一個頁寫入時序最多可傳輸16 個數據。EEPROM 的頁
寫入代碼實現見代碼清單13-8。
第13 章.I2C 通信
SAIUR201 6 第159頁
代碼清單13-8 EEPROM 的頁寫入
這段頁寫入函數主體跟單字節寫入函數是同樣的,只是它在發送數據的時候,使用for 循環控制
發送多個數據,發送完多個數據後才產生I2C 中止信號,只要每次傳輸的數據小於等於EEPROM 時
第13 章.I2C 通信
第160 頁SAIUR2016
序規定的頁大小,就能正常傳輸。快速寫入多字節利用EEPROM 的頁寫入方式,能夠改進前面的「多
字節寫入」函數,加快傳輸速度,見代碼清單13-9。
代碼清單13-9 快速寫入多字節函數
第13 章.I2C 通信
SAIUR201 6 第161頁
不少讀者以爲這段代碼的運算很複雜,看不懂,其實它的主旨就是對輸入的數據進行分頁( 本型
號芯片每頁8 個字節) , 見表24-2 。經過「 整除」 計算要寫入的數據NumByteToWrite 能寫滿多
少「完整的頁」,計算得的值存儲在NumOfPage 中,但有時數據不是恰好能寫滿完整頁的,會多一點
出來,經過「求餘」計算得出「不滿一頁的數據個數」就存儲在NumOfSingle 中。計算後經過按頁傳輸
NumOfPage 次整頁數據及最後的NumOfSing 個數據,使用頁傳輸,比以前的單個字節數據傳輸要快
不少。除了基本的分頁傳輸,還要考慮首地址的問題,見表24-3。若首地址不是恰好對齊到頁的首地
址,會須要一個count 值,用於存儲從該首地址開始寫滿該地址所在的頁,還能寫多少個數據。實際
傳輸時,先把這部分count 個數據先寫入,填滿該頁,而後把剩餘的數據(NumByteToWrite-count),再
重複上述求出NumOPage 及NumOfSingle 的過程,按頁傳輸到EEPROM。
1. 若writeAddress=16,計算得Addr=16%8= 0 ,count=8-0= 8;
2. 同時,若NumOfPage=22,計算得NumOfPage=22/8= 2,NumOfSingle=22%8= 6。
3. 數據傳輸狀況如表13-2
第13 章.I2C 通信
第162 頁SAIUR2016
表13-2 首地址對齊到頁時的狀況
4. 若writeAddress=17,計算得Addr=17%8= 1,count=8-1= 7;
5. 同時,若NumByteToWrite =22,
6. 先把count 去掉,特殊處理,計算得新的NumByteToWrite =22-7= 1,
7. 計算得NumOfPage=15/8= 1,NumOfSingle=15%8= 7。
8. 數據傳輸狀況如表13-3
表13-3 首地址未對齊到頁時的狀況
最後,強調一下,EEPROM 支持的頁寫入只是一種加速的I2C 的傳輸時序,實際上並不要求每
次都以頁爲單位進行讀寫,EEPROM 是支持隨機訪問的(直接讀寫任意一個地址),如前面的單個字節
寫入。在某些存儲器,如NAND FLASH,它是必須按照Block 寫入的,例如每一個Block 爲512 或
4096 字節,數據寫入的最小單位是Block,寫入前都須要擦除整個Block;NOR FLASH 則是寫入前
必須以Sector/Block 爲單位擦除,而後才能夠按字節寫入。而咱們的EEPROM 數據寫入和擦除的最
小單位是「字節」而不是「頁」,數據寫入前不須要擦除整頁。
EEPROM 讀取數據
EEPROM 讀取數據是一個複合的I2C 時序,它實際上包含一個寫過程和一個讀過程,見圖
13-16。
第13 章.I2C 通信
SAIUR201 6 第163頁
圖13-16 EEPROM 數據讀取時序
讀時序的第一個通信過程當中,使用I2C 發送設備地址尋址(寫方向),接着發送要讀取的「內存地
址」;第二個通信過程當中,再次使用I2C 發送設備地址尋址,但這個時候的數據方向是讀方向;在這
個過程以後,EEPROM 會向主機返回從「內存地址」開始的數據,一個字節一個字節地傳輸,只要主機
的響應爲「應答信號」,它就會一直傳輸下去,主機想結束傳輸時,就發送「非應答信號」,並以「中止信
號」結束通信,做爲從機的EEPROM 也會中止傳輸。實現代碼見代碼清單13-10。
代碼清單13-10 從EEPROM 讀取數據
第13 章.I2C 通信
第164 頁SAIUR2016
第13 章.I2C 通信
SAIUR201 6 第165頁
這段中的寫過程跟前面的寫字節函數相似, 而讀過程當中接收數據時, 須要使用庫函數
I2C_ReceiveData 來讀取。響應信號則經過庫函數I2C_AcknowledgeConfig 來發送,DISABLE
時爲非響應信號,ENABLE 爲響應信號。
main 文件
EEPROM 讀寫測試函數
完成基本的讀寫函數後,接下來咱們編寫一個讀寫測試函數來檢驗驅動程序,見代碼清單13-11。
代碼清單13-11 EEPROM 讀寫測試函數
第13 章.I2C 通信
第166 頁SAIUR2016
代碼中先填充一個數組,數組的內容爲1,2,3 至N,接着把這個數組的內容寫入到EEPROM 中,
寫入時能夠採用單字節寫入的方式或頁寫入的方式。寫入完畢後再從EEPROM 的地址中讀取數據,把
讀取獲得的與寫入的數據進行校驗,若一致說明讀寫正常, 不然讀寫過程有問題或者EEPROM 芯片
不正常。其中代碼用到的EEPROM_INFO 跟EEPROM_ERROR 宏相似,都是對printf 函數的封裝,
使用和閱讀代碼時把它直接當成printf 函數就好。具體的宏定義在「bsp_i2c_ee.h 文件中」,在之後的代
碼咱們經常會用相似的宏來輸出調試信息。
main 函數
最後編寫main 函數,函數中初始化串口、I2C 外設,而後調用上面的I2C_Test 函數進行讀寫測
試,見代碼清單13-12。
第13 章.I2C 通信
SAIUR201 6 第167頁
代碼清單13-12 main 函數
13.6.5. 下載驗證
用USB 線鏈接開發板「USB TO UART」接口跟電腦,在電腦端打開串口調試助手,把編譯好的程
序下載到開發板。在串口調試助手可看到EEPROM 測試的調試信息。
圖13-17 EEPROM 測試成功
第13 章.I2C 通信
第168 頁SAIUR2016
13.7.課後練習
1. 在EEPROM 測試程序中,分別使用單字節寫入及頁寫入函數寫入數據,對比它們消耗的時間。
2. 嘗試使用EEPROM 存儲int 整型變量,float 型浮點變量,編寫程序寫入數據,並讀出校驗。
3. 嘗試把I2C 通信引腳的模式改爲非開漏模式,測試是否還能正常通信,爲何?
4. 查看「bsp_i2c_ee.h」文件中EEPROM_ERROR、EEPROM_INFO、EEPROM_DEBUG 宏,解釋爲什麼
要使用這樣的宏輸出調試信息,而不直接使用printf 函數。
第14 章.SPI 通信
SAIUR201 6 第169頁
第14 章.SPI 通信
14.1.課前預習
在書上找到答案。
1. SPI和I2C 有什麼區別?
14.2.概述
本章所講內容:
(1)SPI 通訊協議
(2)使用I2C讀寫串行FLASH
14.3. SPI 協議簡介
SPI 協議是由摩托羅拉公司提出的通信協議(Serial Peripheral Interface),即串行外圍設備接口,是
一種高速全雙工的通訊總線。它被普遍地使用在ADC、LCD 等設備與MCU 間,要求通信速率較高
的場合。學習本章時,可與I2C 章節對比閱讀,體會兩種通信總線的差別以及EEPROM 存儲器FLASH
存儲器的區別。下面咱們分別對SPI 協議的物理層及協議層進行講解。
14.3.1. SPI 物理層
SPI 通信設備之間的經常使用鏈接方式見圖14-1。
第14 章.SPI 通信
第170 頁SAIUR2016
圖14-1 常見的SPI 通信系統
SPI 通信使用3 條總線及片選線,3 條總線分別爲SCK、MOSI、MISO,片選線爲SS ,它們的
做用介紹以下:
1. S S ( Slave Select):從設備選擇信號線,常稱爲片選信號線,也稱爲NSS、CS,如下用NSS 表示。
當有多個SPI 從設備與SPI 主機相連時,設備的其它信號線SCK、MOSI 及MISO 同時並聯到
相同的SPI 總線上,即不管有多少個從設備,都共同只使用這3 條總線;而每一個從設備都有獨立
的這一條NSS 信號線,本信號線獨佔主機的一個引腳,即有多少個從設備,就有多少條片選信號
線。I2C 協議中經過設備地址來尋址、選中總線上的某個設備並與其進行通信;而SPI 協議中沒
有設備地址,它使用NSS 信號線來尋址,當主機要選擇從設備時,把該從設備的NSS 信號線設
置爲低電平,該從設備即被選中,即片選有效,接着主機開始與被選中的從設備進行SPI 通信。
因此SPI 通信以NSS 線置低電平爲開始信號,以NSS 線被拉高做爲結束信號。
2. SCK (Serial Clock):時鐘信號線,用於通信數據同步。它由通信主機產生,決定了通信的速率,
不一樣的設備支持的最高時鐘頻率不同,如STM32 的SPI 時鐘頻率最大爲fpclk/2,兩個設備之
間通信時,通信速率受限於低速設備。
3. MOSI (Master Output, Slave Input):主設備輸出/從設備輸入引腳。主機的數據從這條信號線輸
出,從機由這條信號線讀入主機發送的數據,即這條線上數據的方向爲主機到從機。
4. MISO(Master Input,,Slave Output):主設備輸入/從設備輸出引腳。主機從這條信號線讀入數據,
從機的數據由這條信號線輸出到主機,即在這條線上數據的方向爲從機到主機。
第14 章.SPI 通信
SAIUR201 6 第171頁
14.3.2. 協議層
與I2C 的相似,SPI 協議定義了通信的起始和中止信號、數據有效性、時鐘同步等環節。
SPI 基本通信過程
先看看SPI 通信的通信時序,見圖14-2。
圖14-2 SPI 通信時序
這是一個主機的通信時序。NSS、SCK、MOSI 信號都由主機控制產生,而MISO 的信號由從機
產生,主機經過該信號線讀取從機的數據。MOSI 與MISO 的信號只在NSS 爲低電平的時候纔有效,
在SCK 的每一個時鐘週期MOSI 和MISO 傳輸一位數據。
以上通信流程中包含的各個信號分解以下:
通信的起始和中止信號
在圖14-2 中的標號①處,NSS 信號線由高變低,是SPI 通信的起始信號。NSS 是每一個從機各自
獨佔的信號線,當從機在本身的NSS 線檢測到起始信號後,就知道本身被主機選中了,開始準備與主
機通信。在圖中的標號⑥處,NSS 信號由低變高,是SPI 通信的中止信號,表示本次通信結束,從機
的選中狀態被取消。
數據有效性
SPI 使用MOSI 及MISO 信號線來傳輸數據,使用SCK 信號線進行數據同步。MOSI 及MISO
數據線在SCK 的每一個時鐘週期傳輸一位數據,且數據輸入輸出是同時進行的。數據傳輸時,MSB 先
行或LSB 先行並無做硬性規定,但要保證兩個SPI 通信設備之間使用一樣的協定,通常都會採用
圖14-2 中的MSB 先行模式。
觀察圖中的②③④⑤標號處,MOSI 及MISO 的數據在SCK 的上升沿期間變化輸出,在SCK 的
降低沿時被採樣。即在SCK 的降低沿時刻,MOSI 及MISO 的數據有效,高電平時表示數據「1」,
爲低電平時表示數據「0」。在其它時刻,數據無效,MOSI 及MISO 爲下一次表示數據作準備。SPI 每
次數據傳輸能夠8 位或16 位爲單位,每次傳輸的單位數不受限制。
第14 章.SPI 通信
第172 頁SAIUR2016
CPOL/CPHA 及通信模式
上面講述的圖14-2 中的時序只是SPI 中的其中一種通信模式,SPI 一共有四種通信模式,它們
的主要區別是總線空閒時SCK 的時鐘狀態以及數據採樣時刻。爲方便說明,在此引入「時鐘極性
CPOL」和「時鐘相位CPHA」的概念。時鐘極性CPOL 是指SPI 通信設備處於空閒狀態時,SCK 信號
線的電平信號(即SPI 通信開始前、NSS 線爲高電平時SCK 的狀態)。CPOL=0 時, SCK 在空閒狀
態時爲低電平,CPOL=1 時,則相反。時鐘相位CPHA 是指數據的採樣的時刻,當CPHA=0 時,MOSI
或MISO 數據線上的信號將會在SCK 時鐘線的「奇數邊沿」被採樣。當CPHA=1 時,數據線在SCK
的「偶數邊沿」採樣。見圖14-3 及圖14-4。
圖14-3 CPHA=0 時的SPI 通信模式
咱們來分析這個CPHA=0 的時序圖。首先,根據SCK 在空閒狀態時的電平,分爲兩種狀況。SCK
信號線在空閒狀態爲低電平時,CPOL=0;空閒狀態爲高電平時,CPOL=1。不管CPOL=0 仍是=1,因
爲咱們配置的時鐘相位CPHA=0,在圖中能夠看到,採樣時刻都是在SCK 的奇數邊沿。注意當
CPOL=0 的時候,時鐘的奇數邊沿是上升沿,而CPOL=1 的時候,時鐘的奇數邊沿是降低沿。因此SPI
的採樣時刻不是由上升/降低沿決定的。MOSI 和MISO 數據線的有效信號在SCK 的奇數邊沿保持不
變,數據信號將在SCK 奇數邊沿時被採樣,在非採樣時刻,MOSI 和MISO 的有效信號才發生切換。
相似地,當CPHA=1 時,不受CPOL 的影響,數據信號在SCK 的偶數邊沿被採樣,見圖14-4。
第14 章.SPI 通信
SAIUR201 6 第173頁
圖14-4 CPHA=1 時的SPI 通信模式
由CPOL 及CPHA 的不一樣狀態,SPI 分紅了四種模式,見表25-1,主機與從機須要工做在相同
的模式下才能夠正常通信,實際中採用較多的是「模式0」與「模式3」。
表14-1 SPI 的四種模式
14.4. STM32 的SPI 特性及架構
與I2C 外設同樣,STM32 芯片也集成了專門用於SPI 協議通信的外設。
14.4.1. STM32 的SPI 外設簡介
STM32 的SPI 外設可用做通信的主機及從機,支持最高的SCK 時鐘頻率爲fpclk/2(STM32F103
型號的芯片默認fpclk1 爲72MHz,fpclk2 爲36MHz),徹底支持SPI 協議的4 種模式,數據幀長度
可設置爲8 位或16 位,可設置數據MSB 先行或LSB 先行。它還支持雙線全雙工(前面小節說明的
SPI 模式CPOL CPHA 空閒時SCK 時鐘採樣時刻
0 0 0 低電平奇數邊沿
1 0 1 低電平偶數邊沿
2 1 0 高電平奇數邊沿
3 1 1 高電平偶數邊沿
第14 章.SPI 通信
第174 頁SAIUR2016
都是這種模式)、雙線單向以及單線模式。其中雙線單向模式能夠同時使用MOSI 及MISO 數據線向
一個方向傳輸數據,能夠加快一倍的傳輸速度。而單線模式則能夠減小硬件接線,固然這樣速率會受到
影響。咱們只講解雙線全雙工模式。
14.4.2. TM32 的SPI 架構剖析
圖14-5 SPI 架構圖
通信引腳
SPI 的全部硬件架構都從圖14-5 中左側MOSI、MISO、SCK 及NSS 線展開的。STM32 芯片有
多個SPI 外設,它們的SPI 通信信號引出到不一樣的GPIO 引腳上,使用時必須配置到這些指定的引
腳,見表14-2。
表14-2 STM32F10x 的SPI 引腳
其中SPI1 是APB2 上的設備,最高通訊速率達36Mbtis/s,SPI二、SPI3 是APB1 上的設備,最
高通訊速率爲18Mbits/s。除了通信速率,在其它功能上沒有差別。其中SPI3 用到了下載接口的引腳,
這幾個引腳默認功能是下載,第二功能纔是IO 口,若是想使用SPI3 接口,則程序上必須先禁用掉這
第14 章.SPI 通信
SAIUR201 6 第175頁
幾個IO 口的下載功能。通常在資源不是十分緊張的狀況下,這幾個IO 口是專門用於下載和調試程
序,不會複用爲SPI3。
時鐘控制邏輯
SCK 線的時鐘信號,由波特率發生器根據「控制寄存器CR1」中的BR[0:2]位控制,該位是對fpclk
時鐘的分頻因子,對fpclk 的分頻結果就是SCK 引腳的輸出時鐘頻率,計算方法見表14-3。
表14-3 BR 位對fpclk 的分頻
其中的fpclk 頻率是指SPI 所在的APB 總線頻率,APB1 爲fpclk1,APB2 爲fpckl2。經過配
置「控制寄存器CR」的「CPOL 位」及「CPHA」位能夠把SPI 設置成前面分析的4 種SPI 模式。
數據控制邏輯
SPI 的MOSI 及MISO 都鏈接到數據移位寄存器上,數據移位寄存器的數據來源及目標接收、
發送緩衝區以及MISO、MOSI 線。當向外發送數據的時候,數據移位寄存器以「發送緩衝區」爲數據源,
把數據一位一位地經過數據線發送出去;當從外部接收數據的時候, 數據移位寄存器把數據線採樣到
的數據一位一位地存儲到「接收緩衝區」中。經過寫SPI 的「數據寄存器DR」把數據填充到發送F 緩衝
區中,通信讀「數據寄存器DR」,能夠獲取接收緩衝區中的內容。其中數據幀長度能夠經過「控制寄存
器CR1」的「DFF 位」配置成8 位及16 位模式;配置「LSBFIRST 位」可選擇MSB 先行仍是LSB 先
行。
總體控制邏輯
總體控制邏輯負責協調整個SPI 外設,控制邏輯的工做模式根據咱們配置的「控制寄存器
(CR1/CR2)」的參數而改變,基本的控制參數包括前面提到的SPI 模式、波特率、LSB 先行、主從模式、
單雙向模式等等。在外設工做時,控制邏輯會根據外設的工做狀態修改「狀態寄存器(SR)」,咱們只要讀
取狀態寄存器相關的寄存器位,就能夠了解SPI 的工做狀態了。除此以外,控制邏輯還根據要求,負
責控制產生SPI 中斷信號、DMA 請求及控制NSS 信號線。實際應用中,咱們通常不使用STM32 SPI
外設的標準NSS 信號線,而是更簡單地使用普通的GPIO,軟件控制它的電平輸出,從而產生通信
起始和中止信號。
14.4.3. 通信過程
STM32 使用SPI 外設通信時,在通信的不一樣階段它會對「狀態寄存器SR」的不一樣數據位寫入參
數,咱們經過讀取這些寄存器標誌來了解通信狀態。圖14-6 中的是「主模式」流程,即STM32 做爲SPI
通信的主機端時的數據收發過程。
第14 章.SPI 通信
第176 頁SAIUR2016
圖14-6 主發送器通信過程
主模式收發流程及事件說明以下:
1. 控制NSS 信號線,產生起始信號(圖中沒有畫出);
2. 把要發送的數據寫入到「數據寄存器DR」中,該數據會被存儲到發送緩衝區;
3. 通信開始,SCK 時鐘開始運行。MOSI 把發送緩衝區中的數據一位一位地傳輸出去;MISO 則把
數據一位一位地存儲進接收緩衝區中;
4. 當發送完一幀數據的時候,「狀態寄存器SR」中的「TXE 標誌位」會被置1,表示傳輸完一幀,發
送緩衝區已空;相似地,當接收完一幀數據的時候,「RXNE 標誌位」會被置1,表示傳輸完一幀,
接收緩衝區非空;
5. 等待到「TXE 標誌位」爲1 時,若還要繼續發送數據,則再次往「數據寄存器DR」 寫入數據便可;
等待到「RXNE 標誌位」爲1 時,經過讀取「數據寄存器DR」能夠獲取接收緩衝區中的內容。
假如咱們使能了TXE 或RXNE 中斷,TXE 或RXNE 置1 時會產生SPI 中斷信號,進入同
一箇中斷服務函數,到SPI 中斷服務程序後,可經過檢查寄存器位來了解是哪個事件,再分別進行
處理。也能夠使用DMA 方式來收發「數據寄存器DR」中的數據。
第14 章.SPI 通信
SAIUR201 6 第177頁
14.5. SPI 初始化結構體詳解
跟其它外設同樣,STM32 標準庫提供了SPI 初始化結構體及初始化函數來配置SPI 外設。初始
化結構體及函數定義在庫文件「stm32f10x_spi.h」及「stm32f10x_spi.c」中,編程時咱們能夠結合這兩個文
件內的註釋使用或參考庫幫助文檔。瞭解初始化結構體後咱們就能對SPI 外設運用自如了,見代碼清
單14-1。
代碼清單14-1 SPI 初始化結構體
這些結構體成員說明以下,其中括號內的文字是對應參數在STM32 標準庫中定義的宏:
1. SPI_Direction
本成員設置SPI 的通信方向,可設置爲雙線全雙工(SPI_Direction_2Lines_FullDuplex),雙線只接
收(SPI_Direction_2Lines_RxOnly) , 單線只接收(SPI_Direction_1Line_Rx) 、單線只發送模式
(SPI_Direction_1Line_Tx)。
2. SPI_Mode
本成員設置SPI 工做在主機模式(SPI_Mode_Master)或從機模式(SPI_Mode_Slave ),這兩個模式
的最大區別爲SPI 的SCK 信號線的時序,SCK 的時序是由通信中的主機產生的。若被配置爲從機
模式,STM32 的SPI 外設將接受外來的SCK 信號。
3. SPI_DataSize
本成員能夠選擇SPI 通信的數據幀大小是爲8 位(SPI_DataSize_8b) 仍是16 位
(SPI_DataSize_16b)。
4. SPI_CPOL 和SPI_CPHA
這兩個成員配置SPI 的時鐘極性CPOL 和時鐘相位CPHA,這兩個配置影響到SPI 的通信模
式,關於CPOL 和CPHA 的說明參考前面「通信模式」小節。時鐘極性CPOL 成員,可設置爲高電平
(SPI_CPOL_High)或低電平(SPI_CPOL_Low )。時鐘相位CPHA 則能夠設置爲SPI_CPHA_1Edge(在
第14 章.SPI 通信
第178 頁SAIUR2016
SCK 的奇數邊沿採集數據) 或SPI_CPHA_2Edge (在SCK 的偶數邊沿採集數據) 。
5. SPI_NSS
本成員配置NSS 引腳的使用模式, 能夠選擇爲硬件模式(SPI_NSS_Hard ) 與軟件模式
(SPI_NSS_Soft ),在硬件模式中的SPI 片選信號由SPI 硬件自動產生,而軟件模式則須要咱們親自把
相應的GPIO 端口拉高或置低產生非片選和片選信號。實際中軟件模式應用比較多。
6. SPI_BaudRatePrescaler
本成員設置波特率分頻因子,分頻後的時鐘即爲SPI 的SCK 信號線的時鐘頻率。這個成員參數
可設置爲fpclk 的二、四、六、八、1六、3二、6四、12八、256 分頻。
7. SPI_FirstBit
全部串行的通信協議都會有MSB 先行(高位數據在前)仍是LSB 先行(低位數據在前)的問題,而
STM32 的SPI 模塊能夠經過這個結構體成員,對這個特性編程控制。
8. SPI_CRCPolynomial
這是SPI 的CRC 校驗中的多項式,若咱們使用CRC 校驗時,就使用這個成員的參數(多項式),
來計算CRC 的值。配置完這些結構體成員後,咱們要調用SPI_Init 函數把這些參數寫入到寄存器中,
實現SPI 的初始化,而後調用SPI_Cmd 來使能SPI 外設。
14.6. SPI—讀寫串行FLASH 實驗
FLSAH 存儲器又稱閃存,它與EEPROM 都是掉電後數據不丟失的存儲器,但FLASH 存儲器容
量廣泛大於EEPROM,如今基本取代了它的地位。咱們生活中經常使用的U 盤、SD 卡、SSD 固態硬盤
以及咱們STM32 芯片內部用於存儲程序的設備,都是FLASH 類型的存儲器。在存儲控制上,最主
要的區別是FLASH 芯片只能一大片一大片地擦寫,而在「I2C 章節」中咱們瞭解到EEPROM 能夠單個
字節擦寫。本小節以一種使用SPI 通信的串行FLASH 存儲芯片的讀寫實驗爲你們講解STM32 的
SPI 使用方法。實驗中STM32 的SPI 外設採用主模式,經過查詢事件的方式來確保正常通信。
第14 章.SPI 通信
SAIUR201 6 第179頁
14.6.1. 硬件設計
圖14-7 SPI 串行FLASH 硬件鏈接圖
本實驗板中的FLASH 芯片(型號:W25Q64)是一種使用SPI 通信協議的NOR FLASH 存儲器,
它的CS/CLK/DIO/DO 引腳分別鏈接到了STM32 對應的SPI 引腳
NSS/SCK/MOSI/MISO 上,其中STM32 的NSS 引腳雖然是其片上SPI 外設的硬件引腳,但實際上
後面的程序只是把它當成一個普通的GPIO,使用軟件的方式控制NSS 信號,因此在SPI 的硬件設
計中,NSS 能夠隨便選擇普通的GPIO,沒必要糾結於選擇硬件NSS 信號。FLASH 芯片中還有WP 和
HOLD 引腳。WP 引腳可控制寫保護功能,當該引腳爲低電平時,禁止寫入數據。咱們直接接電源,
不使用寫保護功能。HOLD 引腳可用於暫停通信,該引腳爲低電平時,通信暫停,數據輸出引腳輸出
高阻抗狀態,時鐘和數據輸入引腳無效。咱們直接接電源,不使用通信暫停功能。關於FLASH 芯片
的更多信息,可參考其數據手冊《W25Q64》來了解。若您使用的實驗板FLASH 的型號或控制引腳不
同樣,只需根據咱們的工程修改便可,程序的控制原理相同。
14.6.2. 軟件設計
爲了使工程更加有條理,咱們把讀寫FLASH 相關的代碼獨立分開存儲,方便之後移植。在「工程
模板」之上新建「bsp_spi_flash.c」及「bsp_spi_ flash.h」文件,這些文件也可根據您的喜愛命名,它們不屬於
STM32 標準庫的內容,是由咱們本身根據應用須要編寫的。
第14 章.SPI 通信
第180 頁SAIUR2016
14.6.3. 編程要點
1. 初始化通信使用的目標引腳及端口時鐘;
2. 使能SPI 外設的時鐘;
3. 配置SPI 外設的模式、地址、速率等參數並使能SPI 外設;
4. 編寫基本SPI 按字節收發的函數;
5. 編寫對FLASH 擦除及讀寫操做的的函數;
6. 編寫測試程序,對讀寫數據進行校驗。
14.6.4. 代碼分析
咱們把SPI 硬件相關的配置都以宏的形式定義到「bsp_spi_ flash.h」文件中,見代碼清單14-2。
代碼清單14-2 SPI 硬件配置相關的宏
以上代碼根據硬件鏈接,把與FLASH 通信使用的SPI 號、GPIO 等都以宏封裝起來,而且定義
了控制CS(NSS)引腳輸出電平的宏,以便配置產生起始和中止信號時使用。初始化SPI 的GPIO 利用
上面的宏,編寫SPI 的初始化函數,見代碼清單14-3。
第14 章.SPI 通信
SAIUR201 6 第181頁
代碼清單14-3 SPI 的初始化函數(GPIO 初始化部分)
與全部使用到GPIO 的外設同樣,都要先把使用到的GPIO 引腳模式初始化,配置好複用功能。
GPIO 初始化流程以下:
1. 使用GPIO_InitTypeDef 定義GPIO 初始化結構體變量,以便下面用於存儲GPIO 配置;
2. 調用庫函數RCC_APB2PeriphClockCmd 來使能SPI 引腳使用的GPIO 端口時鐘。
3. 向GPIO 初始化結構體賦值,把SCK/MOSI/MISO 引腳初始化成複用推輓模式。而CS(NSS)引
腳因爲使用軟件控制,咱們把它配置爲普通的推輓輸出模式。
4. 使用以上初始化結構體的配置,調用GPIO_Init 函數向寄存器寫入參數,完成GPIO 的初始化。
配置SPI 的模式
以上只是配置了SPI 使用的引腳,對SPI 外設模式的配置。在配置STM32 的SPI 模式前,我
第14 章.SPI 通信
第182 頁SAIUR2016
們要先了解從機端的SPI 模式。根據FLASH 芯片的說明,它支持SPI 模式0 及模式3,支持雙線
全雙工,使用MSB 先行模式,支持最高通信時鐘爲104MHz,數據幀長度爲8 位。咱們要把STM32
的SPI 外設中的這些參數配置一致。見代碼清單14-4。
代碼清單14-4 配置SPI 模式
這段代碼中,把STM32 的SPI 外設配置爲主機端,雙線全雙工模式,數據幀長度爲8 位,使用
SPI 模式3(CPOL=1,CPHA=1),NSS 引腳由軟件控制以及MSB 先行模式。代碼中把SPI 的時鐘頻
率配置成了4 分頻,實際上能夠配置成2 分頻以提升通信速率,讀者可親自嘗試一下。最後一個成員
爲CRC 計算式,因爲咱們與FLASH 芯片通信不須要CRC 校驗,並無使能SPI 的CRC 功能,
這時CRC 計算式的成員值是無效的。賦值結束後調用庫函數SPI_Init 把這些配置寫入寄存器,並調
用SPI_Cmd 函數使能外設。
使用SPI 發送和接收一個字節的數據
初始化好SPI 外設後,就能夠使用SPI 通信了,複雜的數據通信都是由單個字節數據收發組成
的,咱們看看它的代碼實現,見代碼清單14-5。
第14 章.SPI 通信
SAIUR201 6 第183頁
代碼清單14-5 使用SPI 發送和接收一個字節的數據
SPI_FLASH_SendByte 發送單字節函數中包含了等待事件的超時處理,這部分原理跟I2C 中的一
樣,在此再也不贅述。SPI_FLASH_SendByte 函數實現了前面講解的「SPI 通信過程」:
1. 本函數中不包含SPI 起始和中止信號,只是收發的主要過程,因此在調用本函數先後要作好起始
和中止信號的操做;
2. 對SPITimeout 變量賦值爲宏SPIT_FLAG_TIMEOUT。這個SPITimeout 變量在下面的while 循
環中每次循環減1,該循環經過調用庫函數SPI_I2S_GetFlagStatus 檢測事件,若檢測到事件,則
進入通信的下一階段,若未檢測到事件則停留在此處一直檢測,當檢測SPIT_FLAG_TIMEOUT
次都還沒等待到事件則認爲通信失敗, 調用的SPI_TIMEOUT_UserCallback 輸出調試信息,並退
出通信;
3. 經過檢測TXE 標誌,獲取發送緩衝區的狀態,若發送緩衝區爲空,則表示可能存在的上一個數
據已經發送完畢;
第14 章.SPI 通信
第184 頁SAIUR2016
4. 等待至發送緩衝區爲空後,調用庫函數SPI_I2S_SendData 把要發送的數據「byte」 寫入到SPI 的
數據寄存器DR,寫入SPI 數據寄存器的數據會存儲到發送緩衝區,SPI 外設發送出去;
5. 寫入完畢後等待RXNE 事件,即接收緩衝區非空事件。因爲SPI 雙線全雙工模式下MOSI 與
MISO 數據傳輸是同步的(請對比「SPI 通信過程」閱讀),當接收緩衝區非空時,表示上面的數據
發送完畢,且接收緩衝區也收到新的數據;
6. 等待至接收緩衝區非空時,經過調用庫函數SPI_I2S_ReceiveData 讀取SPI 的數據寄存器DR,
就能夠獲取接收緩衝區中的新數據了。代碼中使用關鍵字「return」 把接收到的這個數據做爲
SPI_FLASH_SendByte 函數的返回值,因此咱們能夠看到在下面定義的SPI 接收數據函數
SPI_FLASH_ReadByte,它只是簡單地調用了SPI_FLASH_SendByte 函數發送數據「Dummy_Byte」,
而後獲取其返回值(由於不關注發送的數據,因此此時的輸入參數「Dummy_Byte」能夠爲任意值)。
能夠這樣作的緣由是SPI 的接收過程和發送過程實質是同樣的,收發同步進行,關鍵在於咱們
的上層應用中,關注的是發送仍是接收的數據。
控制FLASH 的指令
搞定SPI 的基本收發單元后,還須要瞭解如何對FLASH 芯片進行讀寫。FLASH 芯片自定義了
不少指令,咱們經過控制STM32 利用SPI 總線向FLASH 芯片發送指令,FLASH 芯片收到後就會
執行相應的操做。而這些指令,對主機端(STM32)來講,只是它遵照最基本的SPI 通信協議發送出的
數據,但在設備端(FLASH 芯片)把這些數據解釋成不一樣的意義,因此才成爲指令。見表14-4。
第14 章.SPI 通信
SAIUR201 6 第185頁
表14-4 FLASH 經常使用芯片指令表
該表中的第一列爲指令名,第二列爲指令編碼,第三至第N 列的具體內容根據指令的不一樣而有不
同的含義。其中帶括號的字節參數,方向爲FLASH 向主機傳輸,即命令響應,不帶括號的則爲主機
向FLASH 傳輸。表中「A0~A23」 指FLASH 芯片內部存儲器組織的地址; 「M0~M7」 爲廠商號
(MANUFACTURER ID);「ID0-ID15」爲FLASH 芯片的ID;「dummy」指該處可爲任意數據;「D0~D7」
爲FLASH 內部存儲矩陣的內容。在FLSAH 芯片內部,存儲有固定的廠商編號(M7-M0)和不一樣類型
FLASH 芯片獨有的編號(ID15-ID0),見表14-5。
第14 章.SPI 通信
第186 頁SAIUR2016
表14-5 FLASH 數據手冊的設備ID 說明
經過指令表中的讀ID 指令「JEDEC ID」能夠獲取這兩個編號,該指令編碼爲「9F h」,其中「9F h」是
指16 進制數「9F」 (至關於C 語言中的0x9F)。緊跟指令編碼的三個字節分別爲FLASH 芯片輸出的
「(M7-M0)」、「(ID15-ID8)」及「(ID7-ID0)」 。此處咱們以該指令爲例,配合其指令時序圖進行講解,見圖
14-8。
圖14-8 FLASH 讀ID 指令「JEDEC ID」的時序
主機首先經過MOSI 線向FLASH 芯片發送第一個字節數據爲「9F h」,當FLASH 芯片收到該數
據後,它會解讀成主機向它發送了「JEDEC 指令」,而後它就做出該命令的響應:經過MISO 線把它的
廠商ID(M7-M0)及芯片類型(ID15-0)發送給主機,主機接收到指令響應後可進行校驗。常見的應用是主
機端經過讀取設備ID 來測試硬件是否鏈接正常,或用於識別設備。對於FLASH 芯片的其它指令,
都是相似的,只是有的指令包含多個字節,或者響應包含更多的數據。
實際上,編寫設備驅動都是有必定的規律可循的。首先咱們要肯定設備使用的是什麼通信協議。如
FLASH 型號廠商號(M7-M0) FLASH 型號(ID15-ID0)
W25Q64 EF h 4017 h
W25Q128 EF h 4018 h
第14 章.SPI 通信
SAIUR201 6 第187頁
上一章的EEPROM 使用的是I2C,本章的FLASH 使用的是SPI。那麼咱們就先根據它的通信協議,
選擇好STM32 的硬件模塊,並進行相應的I2C 或SPI 模塊初始化。接着,咱們要了解目標設備的相
關指令,由於不一樣的設備,都會有相應的不一樣的指令。如EEPROM 中會把第一個數據解釋爲內部存儲
矩陣的地址(實質就是指令)。而FLASH 則定義了更多的指令,有寫指令,讀指令,讀ID 指令等等。
最後,咱們根據這些指令的格式要求,使用通信協議向設備發送指令,達到控制設備的目標。
定義FLASH 指令編碼表
爲了方便使用,咱們把FLASH 芯片的經常使用指令編碼使用宏來封裝起來,後面須要發送指令編碼
的時候咱們直接使用這些宏便可,見代碼清單14-6。
代碼清單14-6 FLASH 指令編碼表
讀取FLASH 芯片ID
根據「JEDEC」指令的時序,咱們把讀取FLASH ID 的過程編寫成一個函數,見代碼清單14-7。
代碼清單14-7 讀取FLASH 芯片ID
第14 章.SPI 通信
第188 頁SAIUR2016
這段代碼利用控制CS 引腳電平的宏「SPI_FLASH_CS_LOW/HIGH」以及前面編寫的單字節收發函
數SPI_FLASH_SendByte, 很清晰地實現了「JEDEC ID」指令的時序:發送一個字節的指令編碼
「W25X_JedecDeviceID」,而後讀取3 個字節,獲取FLASH 芯片對該指令的響應,最後把讀取到的這
3 個數據合併到一個變量Temp 中,而後做爲函數返回值,把該返回值與咱們定義的宏「sFLASH_ID」
對比,便可知道FLASH 芯片是否正常。
FLASH 寫使能以及讀取當前狀態
在向FLASH 芯片存儲矩陣寫入數據前,首先要使能寫操做,經過「Write Enable」命令便可寫使能,
見代碼清單14-8。
代碼清單14-8 寫使能命令
EEPROM 同樣,因爲FLASH 芯片向內部存儲矩陣寫入數據須要消耗必定的時間,並非在總線
通信結束的一瞬間完成的,因此在寫操做後須要確認FLASH 芯片「空閒」時才能進行再次寫入。爲了
表示本身的工做狀態,FLASH 芯片定義了一個狀態寄存器,見圖14-9。
第14 章.SPI 通信
SAIUR201 6 第189頁
圖14-9 FLASH 芯片的狀態寄存器
咱們只關注這個狀態寄存器的第0 位「BUSY」,當這個位爲「1」時,代表FLASH 芯片處於忙碌狀
態,它可能正在對內部的存儲矩陣進行「擦除」或「數據寫入」的操做。利用指令表中的「Read Status
Register」指令能夠獲取FLASH 芯片狀態寄存器的內容,其時序見圖14-10。
圖14-10 讀取狀態寄存器的時序
只要向FLASH 芯片發送了讀狀態寄存器的指令,FLASH 芯片就會持續向主機返回最新的狀態
寄存器內容,直到收到SPI 通信的中止信號。據此咱們編寫了具備等待FLASH 芯片寫入結束功能的
函數,見代碼清單14-9。
代碼清單14-9 經過讀狀態寄存器等待FLASH 芯片空閒
第14 章.SPI 通信
第190 頁SAIUR2016
這段代碼發送讀狀態寄存器的指令編碼「W25X_ReadStatusReg」後,在while 循環裏持續獲取寄存
器的內容並檢驗它的「WIP_Flag 標誌」(即BUSY 位),一直等待到該標誌表示寫入結束時才退出本函
數,以便繼續後面與FLASH 芯片的數據通信。
FLASH 扇區擦除
因爲FLASH 存儲器的特性決定了它只能把原來爲「1」的數據位改寫成「0」,而原來爲「0」的數據位
不能直接改寫爲「1」。因此這裏涉及到數據「擦除」的概念,在寫入前, 必需要對目標存儲矩陣進行擦除
操做,把矩陣中的數據位擦除爲「1」,在數據寫入的時候,若是要存儲數據「1」,那就不修改存儲矩陣,
在要存儲數據「0」時,才更改該位。一般,對存儲矩陣擦除的基本操做單位都是多個字節進行,如本例
子中的FLASH 芯片支持「扇區擦除」、「塊擦除」以及「整片擦除」,見表14-6。
表14-6 本實驗FLASH 芯片的擦除單位
FLASH 芯片的最小擦除單位爲扇區(Sector),而一個塊(Block)包含16 個扇區,其內部存儲矩陣分
布見圖14-11。。
第14 章.SPI 通信
SAIUR201 6 第191頁
圖14-11 FLASH 芯片的存儲矩陣
使用扇區擦除指令「Sector Erase」可控制FLASH 芯片開始擦寫,其指令時序見圖14-14。
圖14-12 扇區擦除時序
扇區擦除指令的第一個字節爲指令編碼,緊接着發送的3 個字節用於表示要擦除的存儲矩陣地址。要
注意的是在扇區擦除指令前,還須要先發送「寫使能」指令,發送扇區擦除指令後,經過讀取寄存器
狀態等待扇區擦除操做完畢,代碼實現見代碼清單14-10。
第14 章.SPI 通信
第192 頁SAIUR2016
代碼清單25-10 擦除扇區
這段代碼調用的函數在前面都已講解,只要注意發送擦除地址時高位在前便可。調用扇區擦除指令
時注意輸入的地址要對齊到4KB。
FLASH 的頁寫入
目標扇區被擦除完畢後,就能夠向它寫入數據了。與EEPROM 相似,FLASH 芯片也有頁寫入命
令,使用頁寫入命令最多能夠一次向FLASH 傳輸256 個字節的數據,咱們把這個單位爲頁大小。
FLASH 頁寫入的時序見圖14-13。
圖14-13 FLASH 芯片頁寫入
第14 章.SPI 通信
SAIUR201 6 第193頁
從時序圖可知,第1 個字節爲「頁寫入指令」編碼,2-4 字節爲要寫入的「地址A」,接着的是要寫
入的內容,最多個能夠發送256 字節數據,這些數據將會從「地址A」開始,按順序寫入到FLASH 的
存儲矩陣。若發送的數據超出256 個,則會覆蓋前面發送的數據。與擦除指令不同,頁寫入指令的
地址並不要求按256 字節對齊,只要確認目標存儲單元是擦除狀態便可(即被擦除後沒有被寫入過)。
因此,若對「地址x」執行頁寫入指令後,發送了200 個字節數據後終止通信,下一次再執行頁寫入指
令,從「地址(x+200)」開始寫入200 個字節也是沒有問題的(小於256 都可)。只是在實際應用中因爲
基本擦除單元是4KB,通常都以扇區爲單位進行讀寫,想深刻了解,可學習咱們的「FLASH 文件系統」
相關的例子。把頁寫入時序封裝成函數,其實現見代碼清單14-11。
代碼清單14-11 FLASH 的頁寫入
第14 章.SPI 通信
第194 頁SAIUR2016
這段代碼的內容爲:先發送「寫使能」命令,接着纔開始頁寫入時序,而後發送指令編碼、地址,
再把要寫入的數據一個接一個地發送出去,發送完後結束通信,檢查FLASH 狀態寄存器,等待FLASH
內部寫入結束。不定量數據寫入應用的時候咱們經常要寫入不定量的數據,直接調用「頁寫入」函數並
不是特別方便, 因此咱們在它的基礎上編寫了「不定量數據寫入」的函數,基實現見代碼清單14-12。
代碼清單14-12 不定量數據寫入
第14 章.SPI 通信
SAIUR201 6 第195頁
這段代碼與EEPROM 章節中的「快速寫入多字節」函數原理是同樣的,運算過程在此再也不贅述。
區別是頁的大小以及實際數據寫入的時候,使用的是針對FLASH 芯片的頁寫入函數,且在實際調用
這個「不定量數據寫入」函數時,還要注意確保目標扇區處於擦除狀態。
從FLASH 讀取數據
相對於寫入,FLASH 芯片的數據讀取要簡單得多,使用讀取指令「Read Data」便可,其指令時序見
圖14-14。
第14 章.SPI 通信
第196 頁SAIUR2016
圖14-14 SPI FLASH 讀取數據時序
發送了指令編碼及要讀的起始地址後,FLASH 芯片就會按地址遞增的方式返回存儲矩陣的內容,
讀取的數據量沒有限制,只要沒有中止通信,FLASH 芯片就會一直返回數據。代碼實現見代碼清單
14-13。
代碼清單14-13 從FLASH 讀取數據
因爲讀取的數據量沒有限制,因此發送讀命令後一直接收NumByteToRead 個數據到結束便可。
第14 章.SPI 通信
SAIUR201 6 第197頁
main 函數
最後咱們來編寫main 函數,進行FLASH 芯片讀寫校驗,見代碼清單14-14。
代碼清單14-14 main 函數
第14 章.SPI 通信
第198 頁SAIUR2016
函數中初始化了LED、串口、SPI 外設,而後讀取FLASH 芯片的ID 進行校驗,若ID 校驗通
過則向FLASH 的特定地址寫入測試數據,而後再從該地址讀取數據,測試讀寫是否正常。
注意:因爲實驗板上的FLASH 芯片默認已經存儲了特定用途的數據,如擦除了這些數據會影響
到某些程序的運行。因此咱們預留了FLASH 芯片的「第0 扇區(0-4096 地址)」專用於本實驗,如非
必要,請勿擦除其它地址的內容。如已擦除,可在配套資料裏找到「刷外部FLASH 內容」程序,根據其
說明給FLASH 從新寫入出廠內容。
14.6.5. 下載驗證
用USB 線鏈接開發板「USB TO UART」接口跟電腦,在電腦端打開串口調試助手,把編譯好的程
序下載到開發板。在串口調試助手可看到FLASH 測試的調試信息。
14.7.課後練習
1. 在SPI 外設初始化部分,MISO 引腳能夠設置爲輸入模式嗎?爲何?實際測試現象如何?
2. 嘗試使用FLASH 芯片存儲int 整型變量,float 型浮點變量,編寫程序寫入數據,並讀出校驗。
3. 若是扇區未經擦除就寫入,會有什麼後果?請作實驗驗證。
4. 簡述FLASH 存儲器與EEPROM 存儲器的區別。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第199頁
第15 章.陀螺儀姿態檢測
15.1.課前預習
在書上找到答案。
1. MPU6050 模塊由什麼功能?
15.2.概述
本章所講內容:
(1)MPU6050 模塊介紹
(2)使用MPU6050 模塊進行姿態檢測
15.3.姿態檢測
15.3.1. 基本認識
在飛行器中,飛行姿態是很是重要的參數,見圖50-1,以飛機自身的中心創建座標系, 當飛機繞
座標軸旋轉的時候,會分別影響偏航角、橫滾角及俯仰角。
第15 章.陀螺儀姿態檢測
第200 頁SAIUR2016
圖15-1 表示飛機姿態的偏航角、橫滾角及俯仰角
假如咱們知道飛機初始時是左上角的狀態,只要想辦法測量出基於原始狀態的三個姿態角的變化
量,再進行疊加,就能夠獲知它的實時姿態了。
15.3.2. 座標系
抽象來講,姿態是「載體座標系」與「地理座標系」之間的轉換關係。
圖15-2 地球座標系、地理座標系與載體座標系
咱們先來了解三種經常使用的座標系:
1. 地球座標系:以地球球心爲原點,Z 軸沿地球自轉軸方向,X、Y 軸在赤道平面內的座標系。
2. 地理座標系:它的原點在地球表面(或運載體所在的點),Z 軸沿當地地理垂線的方向(重力加速度
第15 章.陀螺儀姿態檢測
SAIUR201 6 第201頁
方向),XY 軸沿當地經緯線的切線方向。根據各個軸方向的不一樣,可選爲「東北天」、「東南天」、
「西北天」等座標系。這是咱們平常生活中使用的座標系,平時說的東南西北方向與這個座標系東
南西北的概念一致。
3. 載體座標系:載體座標系以運載體的質心爲原點,通常根據運載體自身結構方向構成座標系,如Z
軸上由原點指向載體頂部,Y 軸指向載體頭部,X 軸沿載體兩側方向。上面說基於飛機創建的坐
標系就是一種載體座標系,可類比到汽車、艦船、人體、動物或手機等各類物體。
地理座標系與載體座標系都以載體爲原點,因此它們能夠通過簡單的旋轉進行轉換, 載體的姿態
角就是根據載體座標系與地理座標系的夾角來肯定的。配合圖50-1,發揮您的空間想象力,假設初始
狀態中,飛機的Z 軸、X 軸及Y 軸分別與地理座標系的天軸、北軸、東軸平行。如當飛機繞自身的
「Z」軸旋轉,它會使自身的「Y」軸方向與地理座標系的「南北」方向偏離必定角度,該角度就稱爲偏航角
(Yaw);當載體繞自身的「X」軸旋轉,它會使自身的「Z」軸方向與地理座標系的「天地」方向偏離必定角度,
該角度稱爲俯仰角(Pitch);當載體繞自身的「Y」軸旋轉,它會使自身的「X」軸方向與地理座標系的「東西」
方向偏離必定角度,該角度稱爲橫滾角。
表50-1 姿態角的關係
這些角度也稱歐拉角,是用於描述姿態的很是直觀的角度。
15.4.利用陀螺儀檢測角度
最直觀的角度檢測器就是陀螺儀了,見圖50-3,它能夠檢測物體繞座標軸轉動的「角速度」,如同
將速度對時間積分能夠求出路程同樣,將角速度對時間積分就能夠計算出旋轉的「角度」。
圖15-3 陀螺儀檢測示意圖
第15 章.陀螺儀姿態檢測
第202 頁SAIUR2016
陀螺儀檢測的缺陷
因爲陀螺儀測量角度時使用積分,會存在積分偏差,見圖50-4,若積分時間Dt 越小, 偏差就越
小。這十分容易理解,例如計算路程時,假設行車時間爲1 小時,咱們隨機選擇行車過程某個時刻的
速度Vt 乘以1 小時,求出的路程偏差是極大的,由於行車的過程當中並非每一個時刻都等於該時刻速
度的,若是咱們每5 分鐘檢測一次車速,可獲得Vt一、Vt二、Vt3-Vt12 這12 個時刻的車速,對各個
時刻的速度乘以時間間隔(5 分鐘),並對這12 個結果求和,就可得出一個相對精確的行車路程了,
不斷提升採樣頻率,就能夠使積分時間Dt 變小,下降偏差。
圖15-4 積分偏差
一樣地,提升陀螺儀傳感器的採樣頻率,便可減小積分偏差,目前很是普通的陀螺儀傳感器的採
樣頻率均可以達到8KHz,已能知足大部分應用的精度要求。更難以解決的是器件自己偏差帶來的問題。
例如,某種陀螺儀的偏差是0.1 度/秒,當陀螺儀靜止不動時,理想的角速度應爲0,不管它靜止多久,
對它進行積分測量得的旋轉角度都是0,這是理想的狀態;而因爲存在0.1 度/秒的偏差,當陀螺儀
靜止不動時,它採樣得的角速度一直爲0.1 度/秒,若靜止了1 分鐘,對它進行積分測量得的旋轉角
度爲6 度,若靜止了1 小時,陀螺儀進行積分測量得的旋轉角度就是360 度,即轉過了一整圈,這
就變得沒法忍受了。只有當正方向偏差和負方向偏差能正好互相抵消的時候,才能消除這種累計偏差。
15.5. 利用加速度計檢測角度
因爲直接用陀螺儀測量角度在長時間測量時會產生累計偏差,於是咱們又引入了檢測傾角的傳感
器。
圖15-5 T 字型水平儀
第15 章.陀螺儀姿態檢測
SAIUR201 6 第203頁
測量傾角最多見的例子是建築中使用的水平儀,在重力的影響下,水平儀內的氣泡能大體反映水柱
所在直線與重力方向的夾角關係,利用圖15-5 中的T 字型水平儀,能夠檢測出圖15-1 中說明的橫
滾角與俯仰角,可是偏航角是沒法以這樣的方式檢測的。在電子設備中,通常使用加速度傳感器來檢測
傾角,它經過檢測器件在各個方向的形變狀況而採樣獲得受力數據,根據F=ma 轉換,傳感器直接輸
出加速度數據,於是被稱爲加速度傳感器。因爲地球存在重力場,因此重力在任什麼時候刻都會做用於傳
感器,當傳感器靜止的時候(實際上加速度爲0),傳感器會在該方向檢測出加速度g,不能認爲重力
方向測出的加速度爲g,就表示傳感器在該方向做加速度爲g 的運動。當傳感器的姿態不一樣時,它在
自身各個座標軸檢測到的重力加速度是不同的,利用各方向的測量結果,根據力的分解原理,可求
出各個座標軸與重力之間的夾角,見圖15-6。
圖15-6 重力檢測
由於重力方向是與地理座標系的「天地」軸固連的,因此經過測量載體座標系各軸與重力方向的夾
角便可求得它與地理座標系的角度旋轉關係,從而獲知載體姿態。加速度傳感器檢測的缺陷因爲這種
傾角檢測方式是利用重力進行檢測的,它沒法檢測到偏航角(Yaw),原理跟T 字型水平儀同樣,不管如
何設計水平儀,水泡都沒法指示這樣的角度。另外一個缺陷是加速度傳感器並不會區分重力加速度與外
力加速度,當物體運動的時候,它也會在運動的方向檢測出加速度,特別在震動的狀態下,傳感器的數
據會有很是大的數據變化,此時難以反應重力的實際值。
15.6.利用磁場檢測角度
爲了彌補加速度傳感器沒法檢測偏航角(Yaw)的問題,咱們再引入磁場檢測傳感器, 它能夠檢測出
各個方向上的磁場大小,經過檢測地球磁場,它可實現指南針的功能,因此也被稱爲電子羅盤。因爲
地磁場與地理座標系的「南北」軸固聯,利用磁場檢測傳感器的指南針功能,就能夠測量出偏航角(Yaw)
了。磁場檢測器的缺陷與指南針的缺陷同樣,使用磁場傳感器會受到外部磁場干擾,如載體自己的電
第15 章.陀螺儀姿態檢測
第204 頁SAIUR2016
磁場干擾,不一樣地理環境的磁鐵礦干擾等等。
15.7.利用GPS 檢測角度
使用GPS 能夠直接檢測出載體在地球上的座標,假如載體在某時刻測得座標爲A,另外一時刻測得
座標爲B,利用兩個座標便可求出它的航向,便可以肯定偏航角,且不受磁場的影響,但這種檢測方
式只有當載體產生大範圍位移的時候纔有效(GPS 民用精度大概爲10 米級)。
15.8. 姿態融合與四元數
能夠發現,使用陀螺儀檢測角度時,在靜止狀態下存在缺陷,且受時間影響,而加速度傳感器檢測
角度時,在運動狀態下存在缺陷,且不受時間影響,恰好互補。假如咱們同時使用這兩種傳感器,並設
計一個濾波算法,當物體處於靜止狀態時,增大加速度數據的權重,當物體處於運動狀時,增大陀螺儀
數據的權重,從而得到更準確的姿態數據。同理,檢測偏航角,當載體在靜止狀態時,可增大磁場檢測
器數據的權重,當載體在運動狀態時,增大陀螺儀和GPS 檢測數據的權重。這些採用多種傳感器數據
來檢測姿態的處理算法被稱爲姿態融合。在姿態融合解算的時候經常使用「四元數」來表示姿態,它由
三個實數及一個虛數組成,於是被稱之爲四元數。使用四元數表示姿態並不直觀,但由於使用歐拉角(即
前面說的偏航角、橫滾角及俯仰角)表示姿態的時候會有「萬向節死鎖」問題,且運算比較複雜,因此
通常在數據處理的時候會使用四元數,處理完畢後再把四元數轉換成歐拉角。在這裏咱們只要瞭解四元
數是姿態的另外一種表示方式便可,感興趣的話可自行查閱相關資料。
15.9.MPU6050 模塊簡介
15.9.1. MPU6050 模塊功能及外觀
接下來咱們使用傳感器實例來說解如何檢測物體的姿態。在咱們的開發板上有引出I2C 總線接口,
方便用於擴展使用I2C 協議通信的傳感器模塊,本節中咱們將在板子上擴展MPU6050 陀螺儀模塊,
見圖50-9。它是一種六軸傳感器模塊,採用InvenSense 公司的MPU6050 做爲主芯片,能同時檢測三
軸加速度、三軸陀螺儀(三軸角速度)的運動數據以及溫度數據。利用MPU6050 芯片內部的DMP 模塊
(Digital Motion Processor 數字運動處理器),可對傳感器數據進行濾波、融合處理,它直接經過I2C
接口向主控器輸出姿態解算後的姿態數據,下降主控器的運算量。其姿態解算頻率最高可達200Hz,
很是適合用於對姿態控制實時要求較高的領域。常見應用於手機、智能手環、四軸飛行器及計步器等的
姿態檢測。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第205頁
圖15-9 MPU6050 模塊外觀
15.9.2. MPU6050 模塊的引腳功能說明
該模塊引出的8 個引腳功能說明見表15-3。
其中的SDA/SCL、XDA/XCL 通信引腳分別爲兩組I2C 信號線。當模塊與外部主機通信時,使用
SDA/SCL,如與STM32 芯片通信;而XDA/XCL 則用於MPU6050 芯片與其它I2C 傳感器通信時使
用,例如使用它與磁場傳感器鏈接,MPU6050 模塊能夠把從主機SDA/SCL 接收的數據或命令經過
XDA/XCL 引腳轉發到磁場傳感器中。但實際上這種功能比較雞肋,控制麻煩且效率低,通常會直接把
磁場傳感器之類的I2C 傳感器直接與MPU6050 掛載在同一條總線上(即都鏈接到SDA/SCL),使
用主機直接控制。
15.9.3. MPU6050 模塊的硬件原理圖
MPU6050 模塊的硬件原理圖見圖15-10。
圖15-10 MPU6050 模塊原理圖
它的硬件很是簡單,SDA 與SCL 被引出方便與外部I2C 主機鏈接,看圖中的右上角,可知該模
第15 章.陀螺儀姿態檢測
第206 頁SAIUR2016
塊的I2C 通信引腳SDA 及SCL 已經鏈接了上拉電阻,所以它與外部I2C 通信主機通信時直接使用
導線鏈接起來便可;而MPU6050 模塊與其它傳感器通信使用的XDA、XCL 引腳沒有接上拉電阻,
要使用時須要注意。模塊自身的I2C 設備地址可經過AD0 引腳的電平控制,當AD0 接地時,設備
地址爲0x68(七位地址),當AD0 接電源時,設備地址爲0x69(七位地址)。另外,當傳感器有新數據的
時候會經過INT 引腳通知STM32。因爲MPU6050 檢測時是基於自身中心座標系的,見圖50-11,
它表示的座標系及旋轉符號標出了MPU6050 傳感器的XYZ 軸的加速度有角速度的正方向。因此在
安裝模塊時,您須要考慮它與所在設備的座標系統的關係。
圖15-11 MPU6050 傳感器的座標及方向
15.10. MPU6050 模塊的特性參數
MPU6050 傳感器模塊的參數見表15-4。
表15-4 MPU6050 的特性參數
第15 章.陀螺儀姿態檢測
SAIUR201 6 第207頁
該表說明,加速度與陀螺儀傳感器的ADC 均爲16 位,它們的量程及分辨率可選多種模式,見
圖15-13,量程越大,分辨率越低。
圖50-12 加速度配置跟量程的關係
圖15-13 陀螺儀的幾種量程配置
從表中還可瞭解到傳感器的加速度及陀螺儀的採樣頻率分別爲1000Hz 及8000Hz,它們是指加速
度及角速度數據的採樣頻率,咱們能夠使用STM32 控制器把這些數據讀取出來而後進行姿態融合解
算,以求出傳感器當前的姿態(即求出偏航角、橫滾角、俯仰角)。而若是咱們使用傳感器內部的DMP 單
元進行解算,它能夠直接對採樣獲得的加速度及角速度進行姿態解算,解算獲得的結果再輸出給
STM32 控制器,即STM32 無需本身計算,可直接獲取偏航角、橫滾角及俯仰角,該DMP 每秒可輸
出200 次姿態數據。
15.11. MPU6050—獲取原始數據實驗
這一小節咱們學習如何使用STM32 控制MPU6050 傳感器讀取加速度、角速度及溫度數據。在
控制傳感器時,使用到了STM32 的I2C 驅動,就如同控制STM32 同樣,對MPU6050 傳感器的不
同寄存器寫入不一樣內容能夠實現不一樣模式的控制,從特定的寄存器讀取內容則可獲取測量數據,這部分
關於MPU6050 具體寄存器的內容咱們再也不展開,請您查閱《MPU-60X0 寄存器》手冊獲知。
15.11.1. 硬件設計
在實驗前,咱們先用杜邦線把STM32 開發板與該MPU6050 模塊鏈接起來,見圖15-14 及表
15-5。
第15 章.陀螺儀姿態檢測
第208 頁SAIUR2016
圖15-14 STM32 與MPU6050 的硬件鏈接
表15-5 MPU6050 模塊引腳說明
15.11.2. 配套程序簡介
本章的MPU6050 模塊一共配套了四個例程,用戶可根據需求選擇相應的程序來學習,各個例程
的基本功能介紹見表15-6。
表15-6 MPU6050 模塊配套程序基本功能介紹
第15 章.陀螺儀姿態檢測
SAIUR201 6 第209頁
其中,例程1 和2 的功能相似,都是簡單地獲取數據,但因爲硬件I2C 不支持同時使用液晶屏,
因此後面的二、三、4 例程都默認使用軟件I2C 來驅動MPU6050,底層的軟件I2C 驅動跟EEPROM 基
本本一致,本章中重點講述上層的MPU6050 應用及接口。
15.11.3. 軟件設計
本小節講解的是「硬件STM32-MPU6050」實驗,請打開配套的代碼工程閱讀理解。爲了方便展現
及移植,咱們把STM32 的I2C 驅動相關的代碼都編寫到「bsp_i2c.c」及「bsp_i2c.h」文件中,與
MPU6050 傳感器相關的代碼都寫到「mpu6050.c」及「mpu6050.h」文件中,這些文件是咱們本身編寫的,
不屬於標準庫的內容,可根據您的喜愛命名文件。
15.11.4. 程序設計要點
1. 初始化STM32 的I2C;
2. 使用I2C 向MPU6050 寫入控制參數;
3. 定時讀取加速度、角速度及溫度數據。
15.11.5. 代碼分析
本實驗中的I2C 驅動與MPU6050 驅動分開主要是考慮到擴展其它傳感器時的通用性,如使用磁
場傳感器、氣壓傳感器均可以使用一樣一個I2C 驅動,這個驅動只要給出針對不一樣傳感器時的不一樣讀
寫接口便可。本章講解的I2C 驅動主要針對接口封裝講解,細節再也不贅述。本實驗中的I2C 硬件定義
見代碼清單15-1。
代碼清單15-1 I2C 的硬件定義(bsp_i2c.h 文件)
這些宏根據傳感器使用的I2C 硬件封裝起來了。初始化I2C 接下來利用這些宏對I2C 進行初始
化,初始化過程與I2C 讀寫EEPROM 中的無異,見代碼清單15-2。
第15 章.陀螺儀姿態檢測
第210 頁SAIUR2016
代碼清單15-2 初始化I2C(bsp_i2c.c 文件)
對讀寫函數的封裝初始化完成後就是編寫I2C 讀寫函數了,這部分跟EERPOM 的同樣,主要是
調用STM32 標準庫函數讀寫數據寄存器及標誌位, 本實驗的這部分被編
寫進ST_Sensors_I2C_WriteRegister 及ST_Sensors_I2C_ReadRegister 中了,在它們之上,再封裝成
了Sensors_I2C_WriteRegister 及Sensors_I2C_ReadRegister,見代碼清單15-3。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第211頁
代碼清單15-3 對讀寫函數的封裝(i2c.c 文件)
第15 章.陀螺儀姿態檢測
第212 頁SAIUR2016
封裝後的函數主要是增長了錯誤重試機制,若讀寫出現錯誤,則會進行屢次嘗試,屢次嘗試均失敗
後會返回錯誤代碼。這個函數做爲I2C 驅動對外的接口,其它使用I2C 的傳感器調用這個函數進行
讀寫寄存器。
MPU6050 的寄存器定義
MPU6050 有各類各樣的寄存器用於控制工做模式,咱們把這些寄存器的地址、寄存器位使用宏定
義到了mpu6050.h 文件中了,見代碼清單15-4。
代碼清單15-4MPU6050 的寄存器定義(mpu6050.h)
初始化MPU6050
根據MPU6050 的寄存器功能定義,咱們使用I2C 往寄存器寫入特定的控制參數,見代碼清單
15-5。
代碼清單15-5 初始化MPU6050(mpu6050.c)
第15 章.陀螺儀姿態檢測
SAIUR201 6 第213頁
這段代碼首先使用MPU6050_ReadData 及MPU6050_WriteRed 函數封裝了I2C 的底層讀寫驅
動,接下來用它們在MPU6050_Init 函數中向MPU6050 寄存器寫入控制參數,設置了MPU6050 的
採樣率、量程(分辨率)。讀傳感器ID 初始化後,可經過讀取它的「WHO AM I」寄存器內容來檢測硬件
是否正常,該寄存器存儲了ID 號0x68,見代碼清單15-6。
代碼清單15-6 讀取傳感器ID(mpu6050.c)
讀取原始數據
若傳感器檢測正常,就能夠讀取它數據寄存器獲取採樣數據了,見代碼清單15-7。
代碼清單15-7 讀取傳感器數據(mpu6050.c)
第15 章.陀螺儀姿態檢測
第214 頁SAIUR2016
其中前以上三個函數分別用於讀取三軸加速度、角速度及溫度值,這些都是原始的ADC 數值(16
位長),對於加速度和角速度,把讀取得的ADC 值除以分辨率,便可求得實際物理量數值。最後一個
函數MPU6050_ReturnTemp 展現了溫度ADC 值與實際溫度值間的轉換,它是根據MPU6050 的說
明給出的轉換公式進行換算的,注意陀螺儀檢測的溫度會受自身芯片發熱的影響,嚴格來講它測量的
是自身芯片的溫度,因此用它來測量氣溫是不太準確的。對於加速度和角速度值咱們沒有進行轉換,
在下一小節中咱們直接利用這些數據交給DMP 單元,求解出姿態角。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第215頁
main 函數
最後咱們來看看本實驗的main 函數,見代碼清單15-8。
代碼清單15-8 main 函數
本實驗中控制MPU6050 並無使用中斷檢測,咱們是利用Systick 定時器進行計時,隔一段時
間讀取MPU6050 的數據寄存器獲取採樣數據的,代碼中使用Task_Delay 變量來控制定時時間,在
Systick 中斷裏會每隔1ms 對該變量值減1,因此當它的值爲0 時表示定時時間到。
在main 函數裏,調用I2C_Bus_Init、MPU6050_Init 及MPU6050ReadID 函數後,就在whlie 循
環裏判判定時時間,定時時間到後就讀取加速度、角速度及溫度值,並使用串口打印信息到電腦端。
15.11.6. 下載驗證
使用杜邦線鏈接好開發板和模塊,用USB 線鏈接開發板「USB TO UART」接口跟電腦,在電腦端
第15 章.陀螺儀姿態檢測
第216 頁SAIUR2016
打開串口調試助手,把編譯好的程序下載到開發板。在串口調試助手可看到MPU6050 採樣獲得的調試
信息。
15.12. MPU6050—利用DMP 進行姿態解算
上一小節咱們僅利用MPU6050 採集了原始的數據,若是您對姿態解算的算法深有研究,能夠自
行編寫姿態解算的算法,並利用這些數據,使用STM32 進行姿態解算,解算後輸出姿態角。而因爲
MPU6050 內部集成了DMP,不須要STM32 參與解算,可直接輸出姿態角, 也不須要對解算算法做
深刻研究,很是方便,本章講解如何使用DMP 進行解算。實驗中使用的代碼主體是從MPU6050 官
方提供的驅動《motion_driver_6.12》移植過來的,該資料包裏提供了基於STM32F4 控制器的源代碼
(本工程正是利用該代碼移植到STM32F1 上的)及使用python 語言編寫的上位機,資料中還附帶了
說明文檔,請您充分利用官方自帶的資料學習。
15.12.1. 硬件設計
硬件設計與上一小節實驗中的徹底同樣,且軟件中使用了INT 引腳產生的中斷信號,本小節中的
代碼默認使用軟件I2C。
15.12.2. 軟件設計
本小節講解的是「MPU6050_python 上位機」實驗,請打開配套的代碼工程閱讀理解。本工程是從
官方代碼移植過來的(IAR 工程移植至MDK),改動並很少,咱們主要給讀者講解一下該驅動的設計思
路,方便應用。因爲本工程的代碼十分龐大,在講解到某些函數時,請善用MDK 的搜索功能,從而
在工程中查找出對應的代碼。
15.12.3. 程序設計要點
1. 提供I2C 讀寫接口、定時服務及INT 中斷處理;
2. 從陀螺儀中獲取原始數據並處理;
3. 更新數據並輸出。
15.12.4. 代碼分析
官方的驅動主要是了MPL 軟件庫(Motion Processing Library),要移植該軟件庫咱們須要爲它提供
I2C 讀寫接口、定時服務以及MPU6050 的數據更新標誌。若須要輸出調試信息到上位機,還須要提
供串口接口。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第217頁
I2C 讀寫接口
MPL 庫的內部對I2C 讀寫時都使用i2c_write 及i2c_read 函數,在文件「inv_mpu.c」中給出了它
們的接口格式,見代碼清單15-1。
代碼清單15-9 I2C 讀寫接口(inv_mpu.c 文件)
這些接口的格式與咱們上一小節寫的I2C 讀寫函數Sensors_I2C_ReadRegister 及
Sensors_I2C_WriteRegister 一致,因此可直接使用宏替換。提供定時服務MPL 軟件庫中使用到了延時
及時間戳功能,要求須要提供delay_ms 函數實現毫秒級延時,提供get_ms 獲取毫秒級的時間戳,
它們的接口格式也在「inv_mpu.c」文件中給出,見代碼清單15-2。
代碼清單15-10 定時服務接口(inv_mpu.c 文件)
咱們爲接口提供的Delay_ms 及get_tick_count 函數定義在bsp_SysTick.c 文件,咱們使用
SysTick 每毫秒產生一次中斷,進行計時,見代碼清單15-11。
第15 章.陀螺儀姿態檢測
第218 頁SAIUR2016
代碼清單15-11 使用Systick 進行定時(bsp_SysTick.c)
上述代碼中的TimingDelay_Decrement 和TimeStamp_Increment 函數是在Systick 的中斷服務函
數中被調用的,見代碼清單50-12。systick 被配置爲每毫秒產生一次中斷,而每次中斷中會對
TimingDelay 變量減1,對g_ul_ms_ticks 變量加1。它們分別用於Delay_ms 函數利用TimingDelay
的值進行阻塞延遲,而get_tick_count 函數獲取的時間戳即g_ul_ms_ticks 的值。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第219頁
代碼清單15-12 Systick 的中斷服務函數(stm32f10x_it.c 文件)
提供串口調試接口
MPL 代碼庫的調試信息輸出函數都集中到了log_stm32.c 文件中,咱們能夠爲這些函數提供串口
輸出接口,以便把這些信息輸出到上位機,見代碼清單15-3。
代碼清單15-13 串口調試接口(log_stm32.c 文件)
第15 章.陀螺儀姿態檢測
第220 頁SAIUR2016
上述代碼中的fputcc 函數是咱們本身編寫的串口輸出接口,它與咱們重定向printf 函數定義的
fputc 函數功能很相似。下面的eMPL_send_quat 函數是MPL 庫中的原函數,它用於打印「四元數信
息」,在這個log_stm32.c 文件中還有輸出日誌信息的_MLPrintLog 函數,輸出原始信息到專用上位機
的eMPL_send_data 函數,它們都調用了fputcc 進行輸出。MPU6050 的中斷接口
與上一小節中的基礎實驗不一樣,爲了高效處理採樣數據,MPL 代碼庫使用了MPU6050 的INT 中
斷信號,爲此咱們要給提供中斷接口,見代碼清單15-4。
代碼清單15-14 中斷接口(stm32f10x_it.c 文件)
在工程中咱們把MPU6050 與STM32 相連的引腳配置成了中斷模式,上述代碼是該引腳的中斷
服務函數, 在中斷裏調用了MPL 代碼庫的gyro_data_ready_cb 函數, 它設置了標誌變量
hal.new_gyro,以通知MPL 庫有新的數據,其函數定義見代碼清單15-15。
代碼清單15-15 設置標誌變量(main.c 文件)
main 函數執行流程
瞭解MPL 移植須要提供的接口後,咱們直接看main 函數了解如何利用MPL 庫獲取姿態數據,
見代碼清單15-5。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第221頁
代碼清單15-16 使用MPL 進行姿態解算的過程
第15 章.陀螺儀姿態檢測
第222 頁SAIUR2016
第15 章.陀螺儀姿態檢測
SAIUR201 6 第223頁
第15 章.陀螺儀姿態檢測
第224 頁SAIUR2016
如您所見,main 函數很是長,並且咱們只是摘抄了部分,在原工程代碼中還有不少代碼,以及不
同模式下的條件判斷分支,例如加入磁場數據使用9 軸數據進行解算的功能(這是MPU9150 的功能,
MPU6050 不支持)以及其它工做模式相關的控制示例。上述main 函數的主要執行流程歸納以下:
1. 初始化STM32 的硬件,如Systick、LED、調試串口、INT 中斷引腳以及I2C 外設的初始化;
2. 調用MPL 庫函數mpu_init 初始化傳感器的基本工做模式(如下過程調用的大部分都是MPL 庫
函數,再也不強調);
3. 調用inv_init_mpl 函數初始化MPL 軟件庫,初始化後才能正常進行解算;
4. 設置各類運算參數, 如四元數運算(inv_enable_quaternion) 、6 軸或9 軸數據融合
(inv_enable_9x_sensor_fusion)等等;
5. 設置傳感器的工做模式(mpu_set_sensors) 、採樣率(mpu_set_sample_rate) 、分辨率
(inv_set_gyro_orientation_and_scale)等等;
6. 當STM32 驅動、MPL 庫、傳感器工做模式、DMP 工做模式等全部初始化工做都完成後進行
while 循環;
7. 在while 循環中檢測串口的輸入,若串口有輸入,則調用handle_input 根據串口輸入的字符(命
令),切換工做方式。這部分主要是爲了支持上位機經過輸入命令, 根據進行不一樣的處理,如開、
關加速度信息的採集或調試信息的輸出等;
8. 在while 循環中檢測是否有數據更新(if (hal.new_gyro && hal.dmp_on)),當有數據更新的時候產
生INT 中斷,會使hal.new_gyro 置1 的,從而執行if 裏的條件代碼;
9. 使用dmp_read_fifo 把數據讀取到FIFO,這個FIFO 是指MPL 軟件庫定義的一個緩衝區,用
來緩衝最新採集得的數據;
10. 調用inv_build_gyro、inv_build_temp、inv_build_accel 及inv_build_quat 函數處理數據角速度、
溫度、加速度及四元數數據,並對標誌變量new_data 置1;
11. 在while 循環中檢測new_data 標誌位,當有新的數據時執行if 裏的條件代碼;
12. 調用inv_execute_on_data 函數更新全部數據及狀態;
13. 調用read_from_mpl 函數向主機輸出最新的數據。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第225頁
數據輸出接口
在上面main 中最後調用的read_from_mpl 函數演示瞭如何調用MPL 數據輸出接口,經過這些
接口咱們能夠得到想要的數據,其函數定義見代碼清單15-17。
代碼清單15-17 MPL 的數據輸出接口(main.c)
第15 章.陀螺儀姿態檢測
第226 頁SAIUR2016
上述代碼展現了使用inv_get_sensor_type_quat 、inv_get_sensor_type_accel 、
inv_get_sensor_type_gyro、inv_get_sensor_type_euler 及dmp_get_pedometer_step_count 函數分別獲取四
元數、加速度、角速度、歐拉角及計步器數據。代碼中的eMPL_send_data 函數是使用串口按照
PYTHON 上位機格式進行提交數據,上位機根據這些數據對三維模型做相應的旋轉。另外咱們本身在
代碼中加入了液晶顯示的代碼(#ifdef USE_LCD_DISPLAY 宏內的代碼),它把這些數據輸出到實驗板上
的液晶屏上。您可根據本身的數據使用需求,參考這個read_from_mpl 函數對數據輸出接口的調用方
式,編寫本身的應用。
15.12.5. 下載驗證
直接下載本程序到開發板,在液晶屏上會觀察到姿態角、溫度、計步器數據,改變開發板的姿態,
數據會更新(計步器數據要模擬走路纔會更新),若直接鏈接串口調試助手, 會接收到一系列的亂碼信
息,這是正常的,這些數據須要使用上位機解碼。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第227頁
15.13. MPU6050—使用第三方上位機
上一小節中的實驗必須配合使用官方提供的上位機才能看到三維模型,並且功能比較簡單,因此
在小節中咱們演示如何把數據輸出到第三方的上位機,直觀地觀察設備的姿態。實驗中咱們使用的是「匿
名飛控地面站0512」版本的上位機,關於上位機的通信協議可查閱《飛控通訊協議》文檔,或到他們
的官方網站了解。
15.13.1. 硬件設計
硬件設計與上一小節實驗中的徹底同樣,一樣使用了中斷INT 引腳獲取數據狀態,默認使用軟件
I2C 通信。
15.13.2. 軟件設計
本小節講解的是「MPU6050_DMP 測試例程」實驗,請打開配套的代碼工程閱讀理解。本小節的內
容主體跟上一小節同樣,區別主要是當獲取獲得數據後,本實驗根據「匿名飛控」上位機的數據格式要
求上傳數據。
15.13.3. 程序設計要點
1. 瞭解上位機的通信協議;
2. 根據協議格式上傳數據到上位機;
15.13.4. 代碼分析
通信協議
要按照上位機的格式上傳數據,首先要了解它的通信協議,本實驗中的上位機協議說明見表15-7。
第15 章.陀螺儀姿態檢測
第228 頁SAIUR2016
表15-7 匿名上位機的通信協議(部分)
表中說明了兩種數據幀,分別是STATUS 幀及SENSER 幀,數據幀中包含幀頭、功能字、長度、
主體數據及校驗和。「幀頭」用於表示數據包的開始,均使用兩個字節的0xAA 表示;「功能字」用於區分
數據幀的類型,0x01 表示STATUS 幀,0x02 表示SENSER 幀;「長度」表示後面主體數據內容的字節
數;「校驗和」用於校驗,它是前面全部內容的和。其中的STATUS 幀用於向上位機傳輸橫滾角、俯仰
角及偏航角的值(100 倍),SENSER 幀用於傳輸加速度、角速度及磁場強度的原始數據。發送數據包根
據以上數據格式的要求,咱們定義了兩個函數,分別用於發送STATUS 幀及SENSER 幀,見代碼清
單15-2。
代碼清單15-18 發送數據包(main.c 文件)
第15 章.陀螺儀姿態檢測
SAIUR201 6 第229頁
第15 章.陀螺儀姿態檢測
第230 頁SAIUR2016
函數比較簡單,就是根據輸入的內容,一字節一字節地按格式封裝好,而後調用串口發送到上位
機。
發送數據
與上一小節同樣,咱們使用read_from_mpl 函數輸出數據,因爲使用了不一樣的上位機, 因此咱們
修改了它的具體內容,見代碼清單15-3。
代碼清單15-19 read_from_mpl 函數(main.c 文件)
代碼中調用inv_get_sensor_type_euler 獲取歐拉角,而後調用Data_Send_Status 格式上傳到上位
機,而加速度及角速度的原始數據直接從sensors 結構體變量便可獲取,獲取後調end_Data 發送出去。
第15 章.陀螺儀姿態檢測
SAIUR201 6 第231頁
15.13.5. 下載驗證
直接下載本程序到開發板,在液晶屏上會觀察到姿態角、溫度、計步器數據,改變開發板的姿態,
數據會更新(計步器數據要模擬走路纔會更新),若直接鏈接串口調試助手, 會接收到一系列的亂碼信
息,這是正常的,這些數據須要使用「匿名飛控地面站」上位機解碼。若經過液晶屏的信息瞭解到
MPU6050 模塊已正常工做,則可進一步在電腦上使用「ANO_TC 匿名飛控地面站-0512.exe」(如下簡稱
「匿名上位機」)軟件查看可視化數據。實驗步驟以下:
1. 確認開發板的USB TO USART 接口已與電腦相連,確認電腦端能查看到該串口設備。
2. 打開配套資料裏的「匿名上位機」軟件,在軟件界面打開開發板對應的串口(波特率爲115200),
把「基本收碼」、「高級收碼」、「飛控波形」功能設置爲on 狀態。點擊上方圖中的基本收發、波形顯
示、飛控狀態圖標,會彈出窗口。具體見下文軟件配置圖。
3. 在軟件的「基本收發」、「波形顯示」、「飛控狀態」頁面可看到滾動數據、隨着模塊晃動而變化的波
形以及模塊姿態的3D 可視化圖形。
第15 章.陀螺儀姿態檢測
第232 頁SAIUR2016python

相關文章
相關標籤/搜索