首页资源分类嵌入式系统 > stm32资源文档

stm32资源文档

已有 445117个资源

下载专区

上传者其他资源

    文档信息举报收藏

    标    签:stm32

    分    享:

    文档简介

    stm32资源文档,总线

    文档预览

    ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 STM32 神舟 III 号开发板用户手册 2014 年 1 月 26 日版本 V4.0 作者:WWW.ARMJISHU.COM STM32神舟ARM系列技术开发板产品目录: ●【神舟51单片机开发板(51+ARM)开发板】 ● 神舟I号:STM32F103RBT6 + 2.8"TFT 触摸彩屏 ● 神舟II号:STM32F103VCT6 + 3.2"TFT 触摸彩屏 ● 【神舟III号:STM32F103ZET6 + 3.2"TFT 触摸彩屏】 ● 神舟IV号:STM32F103VCT6 + 3.2"TFT 触摸彩屏 ● STM32核心板:四层核心板(STM32F103ZET+207ZGT+407ZGT+407IGT) ● 神舟王103系列(STM32F103ZET核心板) ● 神舟王207系列(STM32F207ZGT核心板) ● 神舟王407系列(STM32F407ZGT/407IGT核心板) ● 神舟王全系列(STM32F103ZET/207ZGT/407ZGT核心板): 全功能底板(支 持MP3,以太网,收音机,无线,SRAM,Nor/Nand Flash,鼠标,键盘,红 外接收,CAN,示波器,电压表,USB HOST,步进电机,RFID物联网等) ●神舟 51 开发板(STC 51 单片机+STM32F103C8T6 核心板):全功能底板(支 持音频播放,无线,鼠标,键盘,红外收发,CAN,温度传感器,直流电机, 步进电机,实时时钟,两路 485,两路继电器,小喇叭,热敏光敏电阻,RFID 物联网等) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 1 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 2 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 声明 本 手 册 版 权 归 属 ARMJISHU.COM 所 有 , 并 保 留 一 切 权 利 。 非 经 ARMJISHU.COM 书面同意,任何单位或个人不得擅自摘录本手册部分或全 部内容,违者我们将追究其法律责任。 本文档为 ARMJISHU.COM 网站推出的神舟 III 号 STM32 开发板配套用 户手册,详细介绍 STM32 的开发过程和神舟 III 号的使用指导。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 3 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 目录 第一篇 硬件篇....................................................................................................................................................... 18 1.1. 神舟III号STM32 开发板简介 ............................................................................................................... 18 1.2. 神舟III号开发板硬件详解 .................................................................................................................... 26 1.2.1. 处理器最小系统............................................................................................................................ 26 1.2.2. LED指示灯 .................................................................................................................................... 34 1.2.3. 按键................................................................................................................................................ 34 1.2.4. USB接口与电源............................................................................................................................. 34 1.2.5. 液晶显示模块................................................................................................................................ 35 1.2.6. Nor Flash ....................................................................................................................................... 36 1.2.7. SRAM.............................................................................................................................................. 37 1.2.8. Nand Flash ..................................................................................................................................... 38 1.2.9. 串口与RS485 接口 ........................................................................................................................ 39 1.2.10. 收音机模块.................................................................................................................................... 40 1.2.11. 音频解码电路................................................................................................................................ 40 1.2.12. SPI Flash........................................................................................................................................ 41 1.2.13. EEPROM........................................................................................................................................ 41 1.2.14. CAN总线接口 ................................................................................................................................ 42 1.2.15. SD卡............................................................................................................................................... 42 1.2.16. 无线模块........................................................................................................................................ 42 1.2.17. 以太网............................................................................................................................................ 43 第二章 软件篇....................................................................................................................................................... 45 2.1 RVMDK简介.......................................................................................................................................... 45 2.2 MDK 4.12 集成开发环境的组成 .......................................................................................................... 45 2.3 MDK工程的编辑................................................................................................................................... 45 2.3.1 新建RVMDK工程 .......................................................................................................................... 45 2.3.2 建立文件........................................................................................................................................ 49 2.3.3 添加文件到工程............................................................................................................................ 50 2.3.4 管理工程目录以及源文件 ............................................................................................................ 52 2.3.5 编译和连接工程............................................................................................................................ 55 2.3.6 打开旧工程.................................................................................................................................... 58 2.4 RVMDK使用技巧.................................................................................................................................. 59 2.4.1 快速定位函数/变量被定义的地方 ............................................................................................... 59 2.4.2 快速注释与快速消注释 ................................................................................................................ 61 2.4.3 快速打开头文件............................................................................................................................ 61 2.5 JLINK V8 仿真器的安装与应用........................................................................................................... 63 2.5.1 JLINK V8 仿真器简介................................................................................................................... 63 2.5.2 JLINK ARM主要特点 .................................................................................................................... 63 2.5.3 如何安装JLINK软件 ..................................................................................................................... 64 2.5.4 JLINK V8 仿真器配置(MDK KEIL环境)................................................................................. 66 2.5.5 使用KEIL的DOWNLOAD功能 ..................................................................................................... 69 2.6 在MDK开发环境中JLINK V8 的调试技巧 ......................................................................................... 69 2.7 在MDK开发环境中调试....................................................................................................................... 71 2.7.1 KEIL仿真的应用 ........................................................................................................................... 71 2.7.2 KEIL软件仿真 ............................................................................................................................... 71 2.7.3 硬件仿真........................................................................................................................................ 78 嵌入式专业技术论坛 (www.armjishu.com)出品 第 4 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 第三章 STM32 神舟III号 基本操作篇............................................................................................................... 82 3.1. 如何安装JLINK驱动程序 ..................................................................................................................... 82 3.2. 如何使用JLINK仿真器 ......................................................................................................................... 84 3.2.1. 如何使用J-Flash ARM 烧写固件到芯片Flash............................................................................ 84 3.2.2. 使用J-Link command 设置和查看相关调试信息........................................................................ 87 3.3. 如何给神舟III号板供电 ........................................................................................................................ 87 3.1.1. 使用USB供电................................................................................................................................. 87 3.1.2. 使用外接电源供电........................................................................................................................ 87 3.1.3. 使用JLINK V8 供电....................................................................................................................... 88 3.4. 如何通过串口下载一个固件到神舟III号开发板................................................................................. 88 3.5. 如何在MDK开发环境中使用JLINK在线调试 .................................................................................... 91 3.6. 神舟III号跳线含义 ................................................................................................................................ 95 3.6.1. 启动模式选择跳线........................................................................................................................ 95 3.6.2. RS-232/RS-485 选择跳线 .............................................................................................................. 95 3.6.3. RTC实时时钟跳线......................................................................................................................... 95 3.6.4. Nand Flash访问选择跳线 ............................................................................................................. 95 第四章 STM32 神舟III号 零基础入门篇........................................................................................................... 96 4.1 如何从零开始新建STM32 工程模板 ................................................................................................... 96 4.1.1 如何去官网下载最新的STM32 资料的方法................................................................................ 96 4.1.2 获取ST库源码.............................................................................................................................. 102 4.1.3 开始新建工程.............................................................................................................................. 102 4.1.4 MDK环境设置 ............................................................................................................................. 109 4.1.5 使用JLINK V8 仿真器硬件调试配置 ......................................................................................... 114 4.2 理解芯片控制的原理 ...........................................................................................................................118 4.3 芯片管脚控制LED灯原理图解释........................................................................................................119 4.4 STM32 相关的芯片手册有哪些?我们如何阅读这些资料 ............................................................. 120 4.5 STM32 芯片各个管脚是怎么控制以及被管理的?(如何阅读芯片手册).................................. 121 4.6 STM32 芯片单个管脚是怎么被控制以及被管理的?(如何阅读芯片寄存器).......................... 125 4.7 分析一个最简单的例程 ...................................................................................................................... 128 4.7.1 硬件原理图分析.......................................................................................................................... 128 4.7.2 例程环境搭建.............................................................................................................................. 131 4.7.3 实验现象...................................................................................................................................... 138 4.7.4 代码详细分析:.......................................................................................................................... 138 4.7.5 程序代码详细说明...................................................................................................................... 144 4.7.6 代码如何映射到芯片内部的寄存器 .......................................................................................... 147 4.7.7 Main函数寄存器级分析(重点).............................................................................................. 148 4.7.8 函数与我们这个例程之间的关系 .............................................................................................. 153 4.8 STM32 重映射功能 ............................................................................................................................. 153 4.8.1 什么是STM32 的重映射 ............................................................................................................. 153 4.8.2 所有的管脚都可以重映射吗 ...................................................................................................... 153 4.8.3 为什么要有STM32 重映射这个功能.......................................................................................... 153 4.8.4 举例说明...................................................................................................................................... 154 4.8.5 深入分析STM32 重映射内部架构原理...................................................................................... 154 4.8.6 STM32 重映射关键指点 ............................................................................................................. 156 4.9 STM32 的内存管理研究(KEIL编程环境下) ................................................................................ 156 4.9.1 研究意义...................................................................................................................................... 156 4.9.2 举例说明并详细分析 .................................................................................................................. 156 4.9.3 举例分析...................................................................................................................................... 157 4.9.4 观察堆栈...................................................................................................................................... 159 4.10 STM32 芯片加密解密 ......................................................................................................................... 161 4.10.1 关于芯片加密的定义 .................................................................................................................. 161 嵌入式专业技术论坛 (www.armjishu.com)出品 第 5 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4.10.2 关于芯片解密方法的理论总结 .................................................................................................. 161 4.10.3 常规芯片解密过程...................................................................................................................... 162 4.10.4 增加芯片解密难度的一些建议总结 .......................................................................................... 163 4.10.5 STM32 加密思路-01 串口ISP设置加密..................................................................................... 164 4.10.6 STM32 加密思路-02 软件加密 .................................................................................................. 164 4.10.7 STM32 加密思路-03 外置ID芯片 .............................................................................................. 165 4.10.8 STM32 加密思路-04 程序自毁 .................................................................................................. 165 4.10.9 STM32 加密思路-05 磨IC型号 .................................................................................................. 165 4.10.10 STM32 加密思路-06 高端硬件加密 .......................................................................................... 165 4.10.11 STM32 加密思路-07 AES加密 .................................................................................................... 165 4.11 STM32 低功耗经验总结 ..................................................................................................................... 166 4.11.1 STM32 低功耗实战项目案例故事(转载).............................................................................. 166 4.11.2 STM32 低功耗三种模式 ............................................................................................................. 169 4.11.3 STM32 低功耗需注意的地方 ..................................................................................................... 169 4.12 STM32 的中断与事件关系的区别 ..................................................................................................... 170 第五章 STM32 神舟III号 实战篇(寄存器版本)......................................................................................... 172 5.1 通用输入/输出(GPIO).................................................................................................................... 172 5.1.1 脚特性.......................................................................................................................................... 172 5.1.2 GPIO应用领域 ............................................................................................................................ 172 5.1.3 管脚分配...................................................................................................................................... 172 5.1.4 GPIO管脚内部硬件电路原理剖析............................................................................................. 173 5.1.5 STM32 的GPIO管脚深入分析 .................................................................................................... 176 5.1.6 在STM32 中如何配置片内外设使用的IO端口 ......................................................................... 180 5.1.7 例程 01 单个LED点灯闪烁程序................................................................................................ 180 5.1.8 例程 02 LED双灯闪烁实验 ..................................................................................................... 184 5.1.9 例程 03 LED三个灯同时亮同时灭.......................................................................................... 185 5.1.10 例程 04 LED流水灯程序 ............................................................................................................ 186 5.2 时钟 ...................................................................................................................................................... 187 5.2.1 什么是时钟.................................................................................................................................. 187 5.2.2 STM32 的时钟 ............................................................................................................................. 188 5.2.3 STM32 的时钟深入分析 ............................................................................................................. 189 5.2.4 例程 01 STM32 芯片 32MHZ频率下跑点灯程序 ...................................................................... 192 5.2.5 例程 02 STM32 芯片 40MHZ频率下跑点灯程序 ...................................................................... 197 5.2.6 例程 03 STM32 芯片 72MHZ频率下跑点灯程序 ...................................................................... 197 5.3 独立按键 .................................................................................................................................................... 199 5.3.1 键的分类 ............................................................................................................................................ 199 5.3.2 按键属性...................................................................................................................................... 199 5.3.3 STM32 的位带操作 ..................................................................................................................... 201 5.3.4 例程 01 STM32 芯片按键点灯(无防抖)................................................................................ 205 5.3.5 例程 02 STM32 芯片按键点灯-增加了防抖的代码 .................................................................. 210 5.4 串口通信的收与发 .....................................................................................................................................211 5.4.1 什么是串口通信................................................................................................................................. 211 5.4.2 串口通信的属性.......................................................................................................................... 211 5.4.3 什么是单片机的TTL电平? ....................................................................................................... 215 5.4.4 关于NPN和PNP的三极管基础知识?....................................................................................... 216 5.4.5 RS-232 电平与TTL电平的转换................................................................................................... 217 5.4.6 串口波特率的理解...................................................................................................................... 219 5.4.7 STM32 神舟III号独特的USB转串口的TTL电平模块设计........................................................ 220 5.4.8 例程 01 最简单串口打印$字符 ................................................................................................. 220 5.4.9 例程 02 单串口打印www.armjishu.com字符-初级 ................................................................... 228 5.4.10 例程 03 单串口打印www.armjishu.com字符-中级 ................................................................... 229 5.4.11 例程 04 单串口打印www.armjishu.com字符-高级 ................................................................... 231 嵌入式专业技术论坛 (www.armjishu.com)出品 第 6 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 5.4.12 5.4.13 5.4.14 例程 05 USART-COM1 串口接收与发送实验-初级版 .............................................................. 232 例程 06 USART-COM1 串口接收与发送实验-中级版 .............................................................. 234 例程 05 USART-COM1 串口接收与发送实验-高级版 .............................................................. 235 第六章 STM32 库函数架构剖析 ....................................................................................................................... 237 6.1 STM32 库函数到底是什么 ................................................................................................................. 238 6.2 STM32 库函数的好处 ......................................................................................................................... 238 6.3 千人大项目如何分配工作 .................................................................................................................. 238 6.4 STM32 库结构剖析 ............................................................................................................................. 239 6.4.1 CMSIS标准 .................................................................................................................................. 239 6.4.2 库目录,文件简介...................................................................................................................... 240 6.4.3 关于core_cm3.c文件.................................................................................................................... 241 6.4.4 system_stm32f10x.c文件 .............................................................................................................. 242 6.4.5 stm32f10x.c文件........................................................................................................................... 243 6.4.6 启动文件...................................................................................................................................... 243 6.4.7 STM32F10x_StdPeriph_DrIer文件夹 ......................................................................................... 244 6.4.8 stm32f10x_it.c、 stm32f10x_conf.h文件 .................................................................................... 246 6.4.9 库各文件间的关系...................................................................................................................... 247 6.4.10 常用官方资料.............................................................................................................................. 249 6.4.11 库函数帮助文档使用 .................................................................................................................. 249 第七章 STM32 神舟III号 实战篇..................................................................................................................... 251 7.1 LED流水灯实验 .................................................................................................................................. 251 7.1.1 流水灯试验的意义与作用 .......................................................................................................... 251 7.1.2 实验原理...................................................................................................................................... 251 7.1.3 硬件设计...................................................................................................................................... 252 7.1.4 软件设计...................................................................................................................................... 253 7.1.5 下载与验证.................................................................................................................................. 257 7.1.6 实验现象...................................................................................................................................... 258 7.2 蜂鸣器实验 .......................................................................................................................................... 259 7.2.1 蜂鸣器的简介.............................................................................................................................. 259 7.2.2 蜂鸣器的结构.............................................................................................................................. 259 7.2.3 意义与作用.................................................................................................................................. 260 7.2.4 实验原理...................................................................................................................................... 260 7.2.5 硬件设计...................................................................................................................................... 260 7.2.6 软件设计...................................................................................................................................... 261 7.2.7 下载与验证.................................................................................................................................. 264 7.2.8 实验现象...................................................................................................................................... 264 7.3 按键检测实验 ...................................................................................................................................... 266 7.3.1 按键的介绍.................................................................................................................................. 266 7.3.2 单片机检测小弹性按键的原理 .................................................................................................. 267 7.3.3 意义与作用.................................................................................................................................. 268 7.3.4 实验原理...................................................................................................................................... 268 7.3.5 硬件设计...................................................................................................................................... 268 7.3.6 软件设计...................................................................................................................................... 271 7.3.7 下载与验证.................................................................................................................................. 279 7.3.8 实验现象...................................................................................................................................... 280 7.4 BITBAND按键扫描检测实验 ............................................................................................................... 281 7.4.1 什么是位带操作.......................................................................................................................... 281 7.4.2 为什么要用位带操作 .................................................................................................................. 281 7.4.3 如何设计和实现位带操作的 ...................................................................................................... 281 7.4.4 STM32 中位带操作的具体部署情况.......................................................................................... 282 7.4.5 如何用代码来实现位带操作 ...................................................................................................... 283 嵌入式专业技术论坛 (www.armjishu.com)出品 第 7 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.4.6 软件设计...................................................................................................................................... 285 7.4.7 下载与验证.................................................................................................................................. 289 7.4.8 实验现象...................................................................................................................................... 289 7.5 EXTI外部按键中断实验 ..................................................................................................................... 290 7.5.1 什么是中断.................................................................................................................................. 291 7.5.2 什么是单片机的中断? .............................................................................................................. 291 7.5.3 STM32 中断的初步理解 ............................................................................................................. 291 7.5.4 STM32 中断的初始化过程以及手册的查询.............................................................................. 294 7.5.5 STM32 中断优先级 ..................................................................................................................... 296 7.5.6 硬件设计...................................................................................................................................... 297 7.5.7 软件设计...................................................................................................................................... 299 7.5.8 下载与验证.................................................................................................................................. 306 7.5.9 实验现象...................................................................................................................................... 306 7.6 SYSTICK系统滴答实验........................................................................................................................ 306 7.6.1 基本概念和原理.......................................................................................................................... 306 7.6.2 实验原理...................................................................................................................................... 308 7.6.3 硬件设计...................................................................................................................................... 308 7.6.4 软件设计...................................................................................................................................... 308 7.6.5 下载与验证.................................................................................................................................. 312 7.6.6 实验现象...................................................................................................................................... 312 7.7 USART串口 1 通信实验 ..................................................................................................................... 313 7.7.1 STM32 的异步串口通讯协议 ..................................................................................................... 313 7.7.2 交叉线和直连线.......................................................................................................................... 313 7.7.3 串口工作流程.............................................................................................................................. 314 7.7.4 例程 01 UART串口 1 Printf打印输出字符................................................................................ 315 7.7.5 软件设计...................................................................................................................................... 315 7.7.6 下载与验证.................................................................................................................................. 322 7.7.7 实验现象...................................................................................................................................... 322 7.7.8 例程 02 UART串口 1-带SYSTICK中断Printf().......................................................................... 324 7.7.9 软件设计...................................................................................................................................... 324 7.7.10 实验现象...................................................................................................................................... 324 7.7.11 例程 03 UART串口 1Printf输出和scanf输入 ............................................................................ 324 7.7.12 软件设计...................................................................................................................................... 324 7.7.13 实验现象...................................................................................................................................... 325 7.8 USART串口 2 通信实验 ..................................................................................................................... 328 7.8.1 意义与作用.................................................................................................................................. 328 7.8.2 串口 2 与串口 1 的区别 .............................................................................................................. 328 7.8.3 多个串口如何同时接收源源不断发送给每个串口的数据 ...................................................... 328 7.8.4 两个串口同时来数据了 这个时候只能进入一个中断,会丢失数据吗................................. 329 7.8.5 硬件设计...................................................................................................................................... 330 7.8.6 例程 01 UART串口 2Printf()打印.......................................................................................... 333 7.8.7 软件设计...................................................................................................................................... 333 7.8.8 下载与验证.................................................................................................................................. 333 7.8.9 实验现象...................................................................................................................................... 333 7.8.10 例程 02 UART串口 2-带SYSTICK中断Printf().......................................................................... 335 7.8.11 例程 03 UART串口 2Printf输出和scanf输入 ............................................................................ 335 7.9 UART串口 1 和串口 2 同时格式化输出输入.................................................................................... 335 7.9.1 下载与验证.................................................................................................................................. 335 7.9.2 实验现象...................................................................................................................................... 335 7.10 串口高级例程之PRINTF中断收发实验............................................................................................... 339 7.10.1 意义与作用.................................................................................................................................. 339 7.10.2 实验原理...................................................................................................................................... 339 7.10.3 硬件设计...................................................................................................................................... 340 嵌入式专业技术论坛 (www.armjishu.com)出品 第 8 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.10.4 软件设计...................................................................................................................................... 340 7.10.5 下载与验证.................................................................................................................................. 345 7.10.6 实验现象...................................................................................................................................... 345 7.11 RS-485 总线收发实验 ......................................................................................................................... 346 7.11.1 485 简介....................................................................................................................................... 346 7.11.2 RS485 的通信概念 ...................................................................................................................... 347 7.11.3 RS485 的连接方式 ...................................................................................................................... 348 7.11.4 RS485 通信电缆中的信号反射................................................................................................... 348 7.11.5 RS485 的接地问题 ...................................................................................................................... 349 7.11.6 RS485 的应用 .............................................................................................................................. 349 7.11.7 原理图的连接.............................................................................................................................. 351 7.11.8 实验现象...................................................................................................................................... 352 7.11.9 软件设计...................................................................................................................................... 353 7.11.10 下载与验证.................................................................................................................................. 360 7.11.11 实验现象...................................................................................................................................... 360 7.12 产品唯一身份标识(UNIQUE DEVICE ID)实验................................................................................ 365 7.12.1 意义与作用.................................................................................................................................. 365 7.12.2 实验原理...................................................................................................................................... 365 7.12.3 硬件设计...................................................................................................................................... 365 7.12.4 软件设计...................................................................................................................................... 366 7.12.5 下载与验证.................................................................................................................................. 368 7.12.6 实验现象...................................................................................................................................... 368 7.13 ADC模数转换实验.............................................................................................................................. 370 7.13.1 意义与作用.................................................................................................................................. 370 7.13.2 实验原理...................................................................................................................................... 370 7.13.3 硬件设计...................................................................................................................................... 372 7.13.4 软件设计...................................................................................................................................... 373 7.13.5 下载与验证.................................................................................................................................. 377 7.13.6 实验现象...................................................................................................................................... 377 7.14 ADC数据多路采集.............................................................................................................................. 378 7.14.1 意义与作用.................................................................................................................................. 378 7.14.2 实验原理...................................................................................................................................... 378 7.14.3 硬件设计...................................................................................................................................... 378 7.14.4 软件设计...................................................................................................................................... 378 7.14.5 下载与验证.................................................................................................................................. 378 7.14.6 实验现象...................................................................................................................................... 378 7.15 RTC实时时钟实验............................................................................................................................... 379 7.15.1 意义与作用.................................................................................................................................. 379 7.15.2 实验原理...................................................................................................................................... 379 7.15.3 硬件设计...................................................................................................................................... 381 7.15.4 软件设计...................................................................................................................................... 382 7.15.5 下载与验证.................................................................................................................................. 388 7.15.6 实验现象...................................................................................................................................... 388 7.16 CALENDAR实时时钟与农历年月日实验 ............................................................................................ 391 7.16.1 意义与作用.................................................................................................................................. 391 7.16.2 实验原理...................................................................................................................................... 391 7.16.3 硬件设计...................................................................................................................................... 393 7.16.4 软件设计...................................................................................................................................... 394 7.16.5 下载与验证.................................................................................................................................. 400 7.16.6 实验现象...................................................................................................................................... 400 7.17 EEPROM读写测试实验 ...................................................................................................................... 402 7.17.1 意义与作用.................................................................................................................................. 402 7.17.2 I2C的介绍.................................................................................................................................... 402 嵌入式专业技术论坛 (www.armjishu.com)出品 第 9 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.17.3 实验原理...................................................................................................................................... 404 7.17.4 硬件设计...................................................................................................................................... 404 7.17.5 软件设计...................................................................................................................................... 406 7.18 TIMER定时器中断实验...................................................................................................................... 419 7.18.1 意义与作用.................................................................................................................................. 419 7.18.2 实验原理...................................................................................................................................... 419 7.18.3 硬件设计...................................................................................................................................... 421 7.18.4 软件设计...................................................................................................................................... 421 7.18.5 下载与验证.................................................................................................................................. 423 7.18.6 实验现象...................................................................................................................................... 424 7.19 IWDG独立看门狗 ............................................................................................................................... 425 7.19.1 什么是看门狗.............................................................................................................................. 425 7.19.2 为什么是独立看门狗呢 .............................................................................................................. 425 7.19.3 怎么使用独立看门狗IWDG........................................................................................................ 426 7.19.4 启动STM32 的独立看门狗 ......................................................................................................... 428 7.19.5 软件设计...................................................................................................................................... 429 7.19.6 下载与验证.................................................................................................................................. 429 7.19.7 实验现象...................................................................................................................................... 430 7.20 窗口看门狗 .......................................................................................................................................... 431 7.20.1 什么是窗口看门狗...................................................................................................................... 431 7.20.2 窗口看门狗的特性...................................................................................................................... 431 7.20.3 窗口看门狗的计算公式: .......................................................................................................... 432 7.20.4 窗口看门狗要用到哪些寄存器 .................................................................................................. 433 7.20.5 窗口看门狗与独立看门狗的区别 .............................................................................................. 435 7.20.6 怎么使用窗口看门狗 .................................................................................................................. 435 7.20.7 硬件设计...................................................................................................................................... 435 7.20.8 软件设计...................................................................................................................................... 436 7.20.9 实验现象...................................................................................................................................... 438 7.21 输入捕获实验 ...................................................................................................................................... 439 7.21.1 意义与作用.................................................................................................................................. 439 7.21.2 输入捕获介绍.............................................................................................................................. 439 7.21.3 实验原理...................................................................................................................................... 439 7.21.4 与输入捕获相关的寄存器 .......................................................................................................... 440 7.21.5 输入捕获配置的步骤 .................................................................................................................. 443 7.21.6 硬件设计...................................................................................................................................... 444 7.21.7 软件设计...................................................................................................................................... 444 7.21.8 实验现象...................................................................................................................................... 448 7.22 315M无线模块扫描实验..................................................................................................................... 449 7.22.1 意义与作用.................................................................................................................................. 449 7.22.2 实验原理...................................................................................................................................... 450 7.22.3 硬件设计...................................................................................................................................... 450 7.22.4 软件设计...................................................................................................................................... 453 7.22.5 下载与验证.................................................................................................................................. 460 7.22.6 实验现象...................................................................................................................................... 460 7.24 CAN总线实验...................................................................................................................................... 463 7.24.1 什么是CAN总线 .......................................................................................................................... 463 7.24.2 CAN总线的特点 .......................................................................................................................... 464 7.24.3 CAN总线技术介绍 ...................................................................................................................... 464 7.24.4 CAN总线关键特性参数 .............................................................................................................. 466 7.24.5 CAN总线的三种工作模式 .......................................................................................................... 467 7.24.6 实验原理...................................................................................................................................... 468 7.24.7 硬件设计...................................................................................................................................... 472 7.24.4 软件设计...................................................................................................................................... 473 嵌入式专业技术论坛 (www.armjishu.com)出品 第 10 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.24.5 下载与测试.................................................................................................................................. 481 7.24.6 实验现象...................................................................................................................................... 481 7.25 SPI FLASH读写实验........................................................................................................................... 481 7.25.1 SPI FLASH(W25X16)读写程序实验的意义与作用.............................................................. 481 7.25.2 SPI的介绍 .................................................................................................................................... 481 7.25.3 硬件设计...................................................................................................................................... 485 7.25.4 软件设计...................................................................................................................................... 486 7.25.5 下载与测试.................................................................................................................................. 490 7.25.6 实验现象...................................................................................................................................... 491 7.26 SRAM 访问实验 ................................................................................................................................. 491 7.26.1 SRAM访问实验的意义与作用.................................................................................................... 491 7.26.2 IS62WV25616 简介...................................................................................................................... 491 7.26.3 STM32 处理器FSMC总线简介 ................................................................................................... 494 7.26.4 实验原理...................................................................................................................................... 497 7.26.5 硬件设计...................................................................................................................................... 498 7.26.6 软件设计...................................................................................................................................... 499 7.26.7 下载与测试.................................................................................................................................. 503 7.26.8 实验现象...................................................................................................................................... 503 7.27 NOR FLASH访问程序实验.................................................................................................................... 504 7.27.1 Nor Flash与Nand Flash的区别 ................................................................................................... 504 7.27.2 FSMC扩展Nor Flash配置 ........................................................................................................... 506 7.27.3 Nor Flash访问实验的意义与作用.............................................................................................. 507 7.27.4 实验原理...................................................................................................................................... 507 7.27.5 硬件设计...................................................................................................................................... 508 7.27.6 软件设计...................................................................................................................................... 510 7.27.7 下载与测试.................................................................................................................................. 515 7.27.8 实验现象...................................................................................................................................... 515 7.28 NAND FLASH访问实验 ......................................................................................................................... 516 7.28.1 Nand Flash访问实验的意义与作用 ........................................................................................... 516 7.28.2 实验原理...................................................................................................................................... 516 7.28.3 硬件设计...................................................................................................................................... 518 7.28.4 软件设计...................................................................................................................................... 520 7.28.5 下载与测试.................................................................................................................................. 527 7.28.6 实验现象...................................................................................................................................... 527 7.29 2.4G无线模块实验 .............................................................................................................................. 528 7.29.1 2.4G无线模块通讯实验的意义与作用 ...................................................................................... 528 7.29.2 试验原理...................................................................................................................................... 528 7.29.3 硬件设计...................................................................................................................................... 529 7.29.4 软件设计...................................................................................................................................... 531 7.29.5 下载与测试.................................................................................................................................. 534 7.29.6 实验现象...................................................................................................................................... 535 7.30 收音机实验 .......................................................................................................................................... 536 7.30.1 收音机实验的意义与作用 .......................................................................................................... 536 7.30.2 实验原理...................................................................................................................................... 537 7.30.3 硬件设计...................................................................................................................................... 542 7.30.4 软件设计...................................................................................................................................... 543 7.30.5 下载与测试.................................................................................................................................. 548 7.30.6 实验现象...................................................................................................................................... 549 7.31 网口程序实验 ...................................................................................................................................... 551 7.31.1 ENC28J60 网口程序实验的意义与作用.................................................................................... 551 7.31.2 实验原理...................................................................................................................................... 551 7.31.4 硬件设计...................................................................................................................................... 552 7.31.4 软件设计...................................................................................................................................... 554 嵌入式专业技术论坛 (www.armjishu.com)出品 第 11 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.31.5 下载与测试.................................................................................................................................. 558 7.31.6 实验现象...................................................................................................................................... 559 7.32 TFT彩色液晶屏只显示红色 ............................................................................................................... 560 7.32.1 术语解释...................................................................................................................................... 560 7.32.2 液晶彩屏原理简介...................................................................................................................... 560 7.32.3 液晶彩屏图像像素分析 .............................................................................................................. 561 7.32.4 控制器命令分析.......................................................................................................................... 562 7.32.5 FSMC介绍 ................................................................................................................................... 565 7.32.6 FSMC函数初始化 ....................................................................................................................... 569 7.32.7 硬件设计...................................................................................................................................... 571 7.32.8 软件分析...................................................................................................................................... 572 7.32.9 下载与测试.................................................................................................................................. 577 7.32.10 实验现象...................................................................................................................................... 577 7.33 TFT彩色液晶屏显示蓝色 ................................................................................................................... 578 7.33.1 硬件设计...................................................................................................................................... 578 7.33.2 软件分析...................................................................................................................................... 578 7.33.3 下载与测试.................................................................................................................................. 579 7.33.4 实验现象...................................................................................................................................... 579 7.34 TFT彩色液晶屏如何显示一个点 ....................................................................................................... 580 7.34.1 扫描的简要分析.......................................................................................................................... 580 7.34.2 硬件设计...................................................................................................................................... 580 7.34.3 软件分析...................................................................................................................................... 580 7.34.4 下载与测试.................................................................................................................................. 583 7.34.5 实验现象...................................................................................................................................... 583 7.35 TFT彩色液晶屏显示一个数字 1 ........................................................................................................ 583 7.35.1 扫描的简要分析.......................................................................................................................... 583 7.35.2 什么是字模.................................................................................................................................. 583 7.35.3 ASCII码的字符解释 .................................................................................................................... 584 7.35.4 硬件设计...................................................................................................................................... 587 7.35.5 软件分析...................................................................................................................................... 587 7.35.6 下载与测试.................................................................................................................................. 591 7.35.7 实验现象...................................................................................................................................... 591 7.36 TFT彩色液晶屏显示变异的数字 1 .................................................................................................... 592 7.36.1 简要分析...................................................................................................................................... 592 7.36.2 软件分析...................................................................................................................................... 592 7.36.3 软件分析...................................................................................................................................... 593 7.37 TFT彩色液晶屏显示数字 9 ................................................................................................................ 593 7.37.1 简要分析...................................................................................................................................... 593 7.37.2 软件分析...................................................................................................................................... 593 7.37.3 下载测试...................................................................................................................................... 594 7.37.4 实验现象...................................................................................................................................... 595 7.38 TFT彩色液晶屏显示一个英文 ........................................................................................................... 595 7.38.1 简要分析...................................................................................................................................... 595 7.38.2 硬件设计...................................................................................................................................... 595 7.38.3 软件分析...................................................................................................................................... 595 7.38.4 下载与测试.................................................................................................................................. 596 7.38.5 实验现象...................................................................................................................................... 596 7.39 TFT彩色液晶屏显示 26 个英文字母 ................................................................................................. 597 7.39.1 简要分析...................................................................................................................................... 597 7.39.2 硬件设计...................................................................................................................................... 597 7.39.3 软件分析...................................................................................................................................... 597 7.39.4 下载与测试.................................................................................................................................. 598 7.39.5 实验现象...................................................................................................................................... 599 嵌入式专业技术论坛 (www.armjishu.com)出品 第 12 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.40 TFT彩色液晶屏显示图片 ................................................................................................................... 599 7.40.1 图片格式介绍.............................................................................................................................. 599 7.40.2 深入了解BMP图片...................................................................................................................... 599 7.40.3 使用工具将图片转换成二进制码 .............................................................................................. 600 7.40.4 硬件设计...................................................................................................................................... 601 7.40.5 软件分析...................................................................................................................................... 602 7.40.6 下载与测试.................................................................................................................................. 604 7.40.7 实验现象...................................................................................................................................... 605 7.41 TFT彩色液晶屏显示图片并刷屏【未更新】 ................................................................................... 605 7.41.1 硬件设计...................................................................................................................................... 605 7.41.2 软件设计...................................................................................................................................... 605 7.41.3 下载与测试.................................................................................................................................. 606 7.41.4 实验现象...................................................................................................................................... 606 7.42 开机TFT液晶屏图片自动左右移动实验 ........................................................................................... 607 7.42.1 简要分析...................................................................................................................................... 607 7.42.2 硬件设计...................................................................................................................................... 607 7.42.3 软件分析...................................................................................................................................... 607 7.42.4 下载与测试.................................................................................................................................. 607 7.42.5 实验现象...................................................................................................................................... 607 7.43 TFT触摸屏实验 ................................................................................................................................... 608 7.43.1 实验的意义与作用...................................................................................................................... 609 7.43.2 实验原理...................................................................................................................................... 609 7.43.3 硬件设计...................................................................................................................................... 609 7.43.4 软件设计...................................................................................................................................... 610 7.43.5 下载与现象.................................................................................................................................. 614 7.44 图片跟触摸点移动实验 ...................................................................................................................... 615 7.44.1 简要分析...................................................................................................................................... 615 7.44.2 硬件设计...................................................................................................................................... 615 7.44.3 软件分析...................................................................................................................................... 615 7.44.4 下载与测试.................................................................................................................................. 615 7.44.5 实验现象...................................................................................................................................... 615 7.45 点击图片小图标显示小图标外框实验 .............................................................................................. 616 7.45.1 简要分析...................................................................................................................................... 616 7.45.2 硬件设计...................................................................................................................................... 616 7.45.3 软件分析...................................................................................................................................... 616 7.45.4 下载与测试.................................................................................................................................. 617 7.45.5 实验现象...................................................................................................................................... 617 7.46 点击图片小图标触发事件实验 .......................................................................................................... 617 7.46.1 简要分析...................................................................................................................................... 617 7.46.2 硬件设计...................................................................................................................................... 617 7.46.3 软件分析...................................................................................................................................... 617 7.46.4 下载与测试.................................................................................................................................. 618 7.46.5 实验现象...................................................................................................................................... 618 7.47 双击小图标触发实验 .......................................................................................................................... 619 7.47.1 简要分析...................................................................................................................................... 619 7.47.2 硬件设计...................................................................................................................................... 619 7.47.3 软件分析...................................................................................................................................... 619 7.47.4 实验现象...................................................................................................................................... 620 7.48 TFT彩色液晶屏显示英文字 ............................................................................................................... 621 7.48.1 什么是字模.................................................................................................................................. 621 7.48.2 ASCII码的字符解释 .................................................................................................................... 621 7.48.3 硬件设计...................................................................................................................................... 624 7.48.4 软件分析...................................................................................................................................... 624 嵌入式专业技术论坛 (www.armjishu.com)出品 第 13 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.48.5 下载与测试.................................................................................................................................. 627 7.48.6 实验现象...................................................................................................................................... 628 7.49 TFT彩色液晶屏显示中文字 ............................................................................................................... 628 7.49.1 使用工具将中文字转换成二进制码 .......................................................................................... 628 7.49.2 硬件设计...................................................................................................................................... 629 7.49.3 软件分析...................................................................................................................................... 629 7.49.4 下载与测试.................................................................................................................................. 631 7.49.5 实验现象...................................................................................................................................... 631 7.50 TFT彩色液晶屏显示中英文字 ........................................................................................................... 632 7.50.1 硬件设计...................................................................................................................................... 632 7.50.2 软件分析...................................................................................................................................... 632 7.50.3 下载与测试.................................................................................................................................. 632 7.50.4 实验现象...................................................................................................................................... 632 7.51 SD卡读卡器实验 ................................................................................................................................. 633 7.51.1 SD卡读卡器实验的意义与作用 ................................................................................................. 633 7.51.2 试验原理...................................................................................................................................... 633 7.51.3 硬件设计...................................................................................................................................... 633 7.51.4 软件设计...................................................................................................................................... 639 7.51.5 下载与测试.................................................................................................................................. 643 7.51.6 实验现象...................................................................................................................................... 644 7.52 音频播放试验 ...................................................................................................................................... 646 7.52.1 实验原理...................................................................................................................................... 646 7.52.2 硬件设计...................................................................................................................................... 646 7.52.3 软件设计...................................................................................................................................... 649 7.52.4 下载与测试.................................................................................................................................. 653 7.52.5 试验现象...................................................................................................................................... 653 7.53 硬件CRC循环冗余检验实验 .............................................................................................................. 654 7.53.1 意义与作用.................................................................................................................................. 654 7.53.2 实验原理...................................................................................................................................... 654 7.53.3 硬件设计...................................................................................................................................... 655 7.53.4 软件设计...................................................................................................................................... 655 7.53.5 下载与验证.................................................................................................................................. 657 7.53.6 实验现象...................................................................................................................................... 657 7.54 PVD电源电压监测实验 ...................................................................................................................... 659 7.54.1 意义与作用.................................................................................................................................. 659 7.54.2 实验原理...................................................................................................................................... 659 7.54.3 硬件设计...................................................................................................................................... 660 7.54.4 软件设计...................................................................................................................................... 660 7.54.5 下载与验证.................................................................................................................................. 663 7.54.6 实验现象...................................................................................................................................... 663 7.55 STM32 低功耗之--STANDBY待机模式 ............................................................................................ 664 7.55.1 意义与作用.................................................................................................................................. 664 7.55.2 STM32 低功耗模式介绍 ............................................................................................................. 664 7.55.3 待机模式...................................................................................................................................... 664 7.55.4 进入待机模式.............................................................................................................................. 665 7.55.5 待机模式寄存器介绍 .................................................................................................................. 665 7.55.6 待机唤醒步骤.............................................................................................................................. 667 7.55.7 硬件设计...................................................................................................................................... 668 7.55.8 软件设计...................................................................................................................................... 668 7.55.9 下载与验证.................................................................................................................................. 673 7.55.10 实验现象...................................................................................................................................... 674 7.56 STM32 低功耗之--STOP停止模式实验............................................................................................. 674 7.56.1 意义与作用.................................................................................................................................. 674 嵌入式专业技术论坛 (www.armjishu.com)出品 第 14 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.56.2 7.56.3 7.56.4 7.56.5 7.56.6 实验原理...................................................................................................................................... 674 硬件设计...................................................................................................................................... 675 软件设计...................................................................................................................................... 675 下载与验证.................................................................................................................................. 683 实验现象...................................................................................................................................... 683 7.57 DMA传输实验..................................................................................................................................... 683 7.57.1 STM32 DMA简介......................................................................................................................... 683 7.57.2 实验原理...................................................................................................................................... 684 7.57.3 硬件设计...................................................................................................................................... 685 7.57.4 软件设计...................................................................................................................................... 685 7.57.5 下载验证...................................................................................................................................... 688 7.58 STM32 内部温度传感器实验 ............................................................................................................. 689 7.58.1 STM32 内部温度传感器简介 ..................................................................................................... 689 7.58.2 实验原理...................................................................................................................................... 689 7.58.3 硬件设计...................................................................................................................................... 690 7.58.4 软件设计...................................................................................................................................... 691 7.58.5 下载验证...................................................................................................................................... 694 7.59 温度传感器(DS18B20)实验........................................................................................................... 694 7.59.1 意义与作用.................................................................................................................................. 694 7.59.2 温度传感器的介绍...................................................................................................................... 695 7.59.3 DS18B20 温度传感器的使用...................................................................................................... 698 7.59.4 软件设计...................................................................................................................................... 701 7.59.5 硬件设计与实验现象 .................................................................................................................. 709 7.60 DHT11 数字温湿度传感器实验 ......................................................................................................... 710 7.60.1 简介.............................................................................................................................................. 710 7.60.2 DHT11 的工作原理 ..................................................................................................................... 710 7.60.3 硬件连接与温度协议分析 .......................................................................................................... 711 7.60.4 实验现象...................................................................................................................................... 713 7.61 三轴加速度模块实验 .......................................................................................................................... 714 7.61.1 三轴加速传感器有什么用 .......................................................................................................... 714 7.61.2 ADXL345 简介............................................................................................................................. 714 7.61.3 ADXL345 工作原理..................................................................................................................... 715 7.61.4 ADXL345 的通信方式实验原理 ................................................................................................. 716 7.61.5 ADXL345 的寄存器说明 ............................................................................................................. 717 7.61.6 ADXL345 内部结构与管脚连接 ................................................................................................. 718 7.61.7 实验原理...................................................................................................................................... 720 7.61.8 硬件设计...................................................................................................................................... 720 7.61.9 软件设计...................................................................................................................................... 720 7.61.10 实验现象...................................................................................................................................... 725 7.62 红外遥控器实验 .................................................................................................................................. 726 7.62.1 什么是红外?红外的历史 .......................................................................................................... 726 7.62.2 红外的特点和用途...................................................................................................................... 727 7.62.3 红外的功能参数.......................................................................................................................... 727 7.62.4 红外的工作原理.......................................................................................................................... 727 7.62.5 实验原理...................................................................................................................................... 730 7.62.6 硬件设计...................................................................................................................................... 730 7.62.7 代码分析...................................................................................................................................... 731 7.62.8 下载与测试.................................................................................................................................. 734 7.62.9 实验现象...................................................................................................................................... 734 7.63 UCOSII操作系统之单任务运行 ......................................................................................................... 735 7.63.1 UCOSII简单介绍......................................................................................................................... 735 7.63.2 UCOSII的学习方法..................................................................................................................... 736 7.63.3 神舟官方团队点破操作系统的学习精妙之处 .......................................................................... 737 嵌入式专业技术论坛 (www.armjishu.com)出品 第 15 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.63.4 实验原理...................................................................................................................................... 737 7.63.5 硬件设计...................................................................................................................................... 737 7.63.6 软件设计...................................................................................................................................... 738 7.63.7 下载与测试.................................................................................................................................. 740 7.64 UCOSII操作系统多任务运行 ............................................................................................................. 740 7.64.1 SYSTICK时钟介绍....................................................................................................................... 740 7.64.2 实验原理...................................................................................................................................... 740 7.64.3 硬件设计...................................................................................................................................... 740 7.64.4 软件设计...................................................................................................................................... 741 7.64.5 下载与测试.................................................................................................................................. 742 7.65 UCOS_UCGUI_DEMO实验................................................................................................................ 742 7.66 4.3 寸液晶屏模块 ................................................................................................................................ 742 7.66.1 神舟III号_TFT绘图API(4.3')实验现象 ........................................................................................... 742 7.66.2 神舟III号_刷屏测试(4.3') 实验现象 .............................................................................................. 743 7.66.3 神舟III号_触摸测试(4.3') 实验现象 .............................................................................................. 743 7.66.4 神舟III号_电子相框(4.3'卡在屏上)实验现象 ................................................................................ 743 7.66.5 神舟III号_HZK16(4.3'卡在屏上) 实验现象................................................................................... 744 7.67 7 寸液晶屏模块 ................................................................................................................................... 745 7.67.1 神舟III号_TFT绘图API(7 寸) 实验现象 ........................................................................................ 745 7.67.2 神舟III号_TFT刷屏测试(7 寸) 实验现象 ...................................................................................... 745 7.67.3 神舟III号_触摸屏测试(7 寸) 实验现象 ......................................................................................... 746 7.67.4 神舟III号_电子相框_BIN(7'卡在屏上) 实验现象 ......................................................................... 747 7.67.5 神舟III号_HZK16(7'卡在屏上) 实验现象...................................................................................... 748 附件 1:如何从单片机零基础到嵌入式高手.................................................................................................... 749 附件 2:STM32 神舟系列其他开发板介绍 ...................................................................................................... 752 1.神舟 51+ARM(STM32F103C8T)单片机开发板....................................................................................... 752 2.STM32 神舟I号(STM32F103RBT)开发板................................................................................................ 753 3.STM32 神舟III号(STM32F103ZET)开发板............................................................................................. 755 4.STM32 神舟III号(STM32F103ZET)开发板............................................................................................. 759 5.STM32 神舟王 103 开发板(STM32F103ZET) ......................................................................................... 761 6.STM32 神舟王 207 开发板(STM32F207ZGT)......................................................................................... 764 7.STM32 神舟王 407 开发板(STM32F407ZGT)......................................................................................... 766 8.STM32 神舟王 407IGT开发板+130W摄像头(STM32F407IGT)............................................................ 767 9.STM32 神舟王 417IGT开发板+130W摄像头(STM32F417IGT)............................................................ 768 10.STM32 神舟王 439IGT开发板+130W摄像头(STM32F439IGT).......................................................... 769 11.STM32F103/207/407/439 多个核心板共同神舟王底板---真正一板变多板 ............................................... 772 附件 3:STM32 神舟团队 20 年工作经验心得总结 ........................................................................................ 772 1)需求定义..................................................................................................................................................... 773 2)处理器的选择 ............................................................................................................................................ 775 3)开发成本的预测和估计 ............................................................................................................................ 780 4)产品开发设计文档(需要包括硬件和软件两个方面)......................................................................... 780 5)嵌入式高手对技术的理解(含辛茹苦这么多年的精华体验) ............................................................. 782 附件 4:PCB设计建议........................................................................................................................................ 783 1.PCB设计干扰的相关基础知识........................................................................................................................ 783 嵌入式专业技术论坛 (www.armjishu.com)出品 第 16 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.电磁干扰三要素................................................................................................................................................ 783 3.印制电路板........................................................................................................................................................ 784 3.器件位置............................................................................................................................................................ 785 4.接地和供电(VSS,VDD)............................................................................................................................ 785 5.数字电路与模拟电路的供地处理.................................................................................................................... 785 6.信号线布在电或地层上.................................................................................................................................... 785 7.焊盘与产品良品率质量的关系........................................................................................................................ 786 8.其他信号的注意事项........................................................................................................................................ 786 9.未用到的I/O管脚 .............................................................................................................................................. 786 附件 5:项目合作与技术支持联系方式............................................................................................................ 786 嵌入式专业技术论坛 (www.armjishu.com)出品 第 17 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 第一篇 硬件篇 本章将详细介绍神舟III号STM32开发板的硬件,从神舟III号的整体硬件资源,产品特点到各个硬 件模块,进行详细的介绍。通过本章节,使大家对该开发板的整个功能特点有所了解,同时熟悉各个 功能模块的硬件实现方案。 本章主要分为如下几个部分: 1.1.神舟III号STM32开发板简介; 1.2.神舟III号STM32开发板硬件详解; 1.3.神舟III号STM32开发板使用注意事项; 1.1. 神舟III号STM32开发板简介 神舟III号是一款基于STM32F103ZET6处理器的STM32开发板,面向广大的企业客户和STM32爱 好者。开发板功能强大,外围资源齐全。此外,还预留了丰富的扩展接口,可以灵活的扩展各种功能。 而整板尺寸仅仅110mm*150mm,非常小巧,方便携带。 神舟III号STM32开发板的产品外观及对应各功能模块说明如图表1所示: USB 接口 扩展接口 DC 电 源 输入接口 电源 开关 电源芯片 与指示灯 JTAG/SWD 接口 2.4G 无线模 块接口座 收音机接口 音频接口 2M bit EEPROM 串口 2 2.8/3.2 寸 LCD 接口 串口 1 4M bit SPI Flash 1G bit Nand Flash 以太网 接口 STM32F103ZET6 高性能处理器 315M 无线 模块接口 收音模块 功能按键 复位按键 4M bit SRAM SD 卡座 (背面) LED 灯 RTC 实时 时钟电池 蜂鸣 器 232/485 选 择跳线 485 接口 CAN 总 线接口 AD、DA 与 PWM 接口 电位 器 启动模 式配置 16Mbit Nor Flash 图表 1 神舟 III 号开发板外观与功能 嵌入式专业技术论坛 (www.armjishu.com)出品 第 18 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 神舟 III 号开发板板载硬件资源如下: ◆ STM32F103系列最高端配置芯片STM32F103ZET6。Cortex-M3内核32位处理器,72M主频, LQFP144封装,片内Flash容量:512K,片内SRAM容量:64K ◆ 标配1G比特容量的Nand Flash ◆ 标配16M比特容量的Nor Flash,最大支持128M比特容量Nor Flash ◆ 标配4M比特容量的SRAM ◆ 标配2M比特容量的I2C接口的EEPROM芯片 ◆ 标配16M比特容量的SPI Flash芯片 ◆ 采用主流收音机模块,提供收音机功能 ◆ 采用专用I2S音频DA芯片,提供音频播放功能 ◆ 1个USB SLAVE接口,支持USB过流保护与USB接口静电防护,符合ESD防护标注 IEC61000-4-2(ESD 15kV air, 8kV Contact) ◆ 1个10M以太网接口,用于以太网通信 ◆ 1个SD卡接口 ◆ 1个标准的2.8/3.2寸LCD接口,支持触摸屏,分辨率320X240, 26万色 ◆ 1个复位按钮,控制整板硬件复位 ◆ 4个功能按钮,包括WAKEUP与TAMPER按键 ◆ 4个状态指示灯(DS1~DS4:绿色) ◆ 1个电源指示灯(绿色) ◆ 1个5V外部电源输入接口(内正外负) ◆ 1个电源开关,控制整个板的电源开关 ◆ 1个标准的JTAG/SWD调试下载口,支持JLINK供电 ◆ 2个串行接口(DB9 公头) ◆ 1个485总线接口 ◆ 1个CAN总线接口 ◆ 1个电位器接口 ◆ 1路蜂鸣器 ◆ 1个启动模式选择配置接口 ◆ 支持2.4G无线通信模块 ◆ 支持315M无线通信模块 ◆ 1个RTC后备电池座,支持CR1220纽扣电池 ◆ 除晶振占用的IO口外,其余所有IO口全部引出 ◆ 预留AD,DC,PWM接口 从上面的板载资源可以看出,神舟III号开发板板载资源非常丰富,即包括STM32爱好者常用的硬 件资源,又包括各种工业接口。此外,开发板还将处理器所有GPIO接口通过双排插针接口引出,非 常方便产品的功能扩展和其他功能模块调试,让你的开发变得更加简单。 神舟III号开发板的特点包括: 1) 外观大气。整个板子尺寸为110mm*150mm*20mm(包括液晶,但不计算铜柱的高度)。 2) 设计灵活。板上除晶振外的所有的IO口全部引出,可以极大的方便大家扩展及使用。 3) 资源丰富。板载十多种外设及接口,让你畅游STM32。 4) 调试方便。和主流调试仿真工具JLINK V8完美结合,让您快速找到代码的BUG。 5) 触摸彩屏。320X240分辨率, 26万色TFT LCD,带触摸功能,让您设计出迷人的GUI。 6) 畅游网络。支持10M以太网,支持Ping、HTTP等,缩短您的开发周期,而且支持网络固件 更新,降低您的维护成本。 7) 教程齐全。共计近二十个实例,使用ST标准库,方便用户修改升级。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 19 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 接下来我们详细介绍神舟III号开发板的各个功能模块。 1) STM32F103ZET6 处理器 开发板使用了STMF103系列中的最高配置的Cortex-M3内核32位处理器STM32F103ZET6,72M主 频,LQFP144封装,片内Flash容量:512K,片内SRAM容量:64K。 STM32家族主要产品系列家谱如下图所示,STM32F103ZET6与同系列的其他处理器相比,增加 了ETM,FSMC总线,SDIO接口和2个I2S接口。 图表 2 STM32 家族主要产品系列家谱 STM32F103的产品列表出下图所示,神舟III号开发板选用的是外设资源和管脚资源最丰富的144 脚LQFP封装的STM32F103ZET6芯片,充分满足企业和广大爱好者的评估开发需求。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 20 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 图表 3 STM32F103 产品列表 2) Nor Flash Nor的特点是芯片内执行,这样应用程序可以直接在flash闪存内运行,不必再把代码读到系统 RAM中。另外,Nor的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入 和擦除速度大大影响了它的性能。 神舟III号通过FSMC总线扩展了16M比特容量的Nor Flash,最大支持128M比特容量Nor Flash。可 用于保存操作系统及一些重要数据。 3) Nand Flash Nand Flash和NorFlash都是Flash的一种,都是闪存,但是Nand Flash一般比较大,而Nor Flash比较 小,并且NorFlash比较贵,并且Nor Flash写的速度比较慢,但读的速度比较快,而Nand Flash读的速 度比较慢,写的速度比较快 Nand Flash一般是用来存储数据,而Nor Flash是用来执行程序。同时,Nor Flash读取速度稍微快 与Nand Flash,而Nand Flash在写入速度和擦除速度比Nor 快很多。 神舟III号通过FSMC总线扩展了1个2G比特的Nand Flash, 可用于图片及其他数据的保存。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 21 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4) SRAM SRAM是Static Random Access Memory的缩写,中文含义为静态随机访问存储器,它是一种类型 的半导体存储器。“静态”是指只要不掉电,存储在SRAM中的数据就不会丢失。这一点与动态RAM (DRAM)不同,DRAM需要进行周期性的刷新操作。 神舟III号通过FSMC总线扩展了8M比特容量的SRAM,可用于系统或程序运行过程中的临时数据 的存取。 5) SPI Flash SPI Flash存储器它具有掉电数据不丢失、快速数据存取速度、电可擦除、容量大、在线可编程、 价格低廉以及足够多的擦写次数(一百万次)和较高的可靠性等诸多优点,在嵌入式应用得到广泛引 用。 神舟III号板载了一片16M比特容量的SPI Flash芯片W25X16,非常适合我们存储一些不常修改的 数据。 6) SD 卡接口 除了前面提到的SPI Flash以外,神舟III号还自带SD卡接口。SD卡作最常见的存储设备,是很多 数码设备的存储媒介,比如数码相框、数码相机、MP5等。有了它,我们的开发板就相当于拥有了一 个大容量的外部存储器,不单可以用来提供数据,也可以用来存储数据,使得我们的板子可以完成更 多的功能。 7) I2C EEPROM 嵌入式专业技术论坛 (www.armjishu.com)出品 第 22 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 用于掉电数据保存,因为STM32内部没有EEPROM,我们这里外扩了24C02,可用于设备的一些 配置数据,或一些不需要经常修改的数据保存。 8) 音频播放电路 神舟III号STM32开发板具有音频播放功能,可以将保存在Flash中的音频文件通过专用的解码芯 片播放出来,在STM32上也可以听到美妙的歌声,或者给产品播放提示音。 9) 收音机 采用主流的收音机模块,TEA5767实现收音机功能,通过这个模块,可了解收音机的基本原理与 TEA5767芯片的配置与访问。 10) 以太网口 神舟III号开发板提供了一个标准的10M以太网接口。通过这个接口,我们可以将神舟III号也接如 到以太网中,与其他网络设备进行号通信。 11) 2.8/3.2LCD 接口 该接口是一个目前比较通用的LCD液晶触摸屏接口,一个32芯LCD接口引出了LCD控制器和触摸 屏的全部信号,它的线序兼容市面上在售的主流触摸屏模块,比如ARMJISHU.COM推出的液晶模块、 红牛开发板使用的液晶模块、STMSKY开发板使用的液晶模块等。 320 X 240的显示分辨率64万色可以逼真的显示图片、文字和菜单等,配合触摸功能实现灵活的 控制,我们提供已经调试成功的LCD液晶屏和触摸屏的示例代码。 该 接 口 是 一 个 目 前 比 较 通 用 的 LCD接 口 , 可 以 用 来 接 很 多 市 面 上 再 售 的 液 晶 模 块 , 比 如 ARMJISHU.COM推出的液晶模块、红牛开发板使用的液晶模块、STMSKY开发板使用的液晶模块等 都可以使用这个接口。 12) BOOT 选择跳帽 STM32F10x处理器一共有三种启动模式,可以通过这一跳线进行选择,具体的跳帽设置与启动模 式选择关系如下表。 BOOT1(J9) BOOT0(J10) 功能 嵌入式专业技术论坛 (www.armjishu.com)出品 第 23 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ANY 2-3 User Boot(默认) 2-3 1-2 System Boot 1-2 1-2 SRAM Boot 13) RTC 实时时钟 STM32内部RTC功能非常实用,它的供电和时钟是独立于内核的,可以说是STM32内部独立的外 设模块,RTC内部寄存器不受系统复位掉电的影响。 在神舟III号STM32开发板上,我们采用外部电池供电和32768表振晶体来实现真正RTC(实时时 钟)功能。同时,如果RTC电池没有安装的情况下,可以通过跳线帽来去掉RTC时钟功能,而不影响 系统正常运行。 14) CAN 总线接口 CAN 是Controller Area Network 的缩写(以下称为CAN),是ISO国际标准化的串行通信协议。 它 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。 CAN总线当今自动化领域技术发展的热点之一,被誉为自动化领域的计算机局域网。它的出现为分布 式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。 在神舟III号STM32开发板中,通过VP230这一款3.3VCAN总线收发器将STM32的CAN总线接口引 出,VP230芯片的管脚视图如下: 15) 蜂鸣器 蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、报警 器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。用于产品的声音提醒或者 告警。 神舟III号STM32开发板,板载一个蜂鸣器。当接通蜂鸣器两端的电源时,蜂鸣器发出固定频率的 声音。 16) 电位器 神舟III号STM32开发板,提供了一路电位器,通过这一路电位器可以学习STM32处理器的AD功 能。 17) LED 灯 神舟III号提供了4路LED指示灯,分别与GPIOF6-9四个管脚连接,当管脚为低电平时,对应的LED 指示灯亮。4路LED灯可以用于STM32开发板的状态指示。 18) 复位按钮 该按钮是神舟III号的整板硬件复位按钮,当按键按下时,STM32处理器,液晶,以太网,以及音 频解码芯片都将复位。 19) 通用按钮 神舟III号,除了前面提到的复位按键这一特殊功能按键外,还提供四个按键,其中两个按键分别 为WAKEUP唤醒按键,以及TAMPER按键,另两个为用户可自定义功能的通用按键USER1和USER2。 (说明:这四个按键,可依据实际产品,定义成产品的功能按键,包括WAKEUP按键与TAMPER按键) 20) JTAG/SWD 接口 标准的20针JTAG,直接可以和ULINK或者JLINK连接的,同时支持SWD(因为STM32支持SWD)。 可以用于调试STM32,更方便的开发软件。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 24 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 21) 电源开关 控制3.3V供电,如果通过选择由USB供电或外部电源输入,实现电源的通断。 22) 电源芯片与电源指示灯 由于STM32F103ZET6是3.3V的工作电压,因此,我们需要将外部电源输入或者USB提供的5V电 源转换成3.3V的工作电压。在神舟III号这一块开发板上,采用了ASM1117-3.3V这一常用电源转换芯 片来实现这一功能。另外,为了方便用户确认电源是否已经正常提供,开发板还提供了一个绿色的电 源指示灯,当开发板上3.3V电源正常时,指示灯亮。 23) 5V 直流电源输入接口 DC电源座符合常见电源适配器接口标准,DC电源座的里面为电源正极,外面为电源负极。 24) USB 接口 标准的USB SLAVE接口,其他主设备,如PC电脑可通过此接口与神舟III号通讯,另外,该接口 也可以作为神舟III的电源输入,由PC或其他USB主设备提供电源。为了保证设备可以正常工作,USB 接口具有一个500自恢复保险丝,当工作电流大于500mA时,以及ESD防护器件,符合ESD防护标注 IEC61000-4-2(ESD 15kV air, 8kV Contact) 。 25) 串口 1 此处将STM32F103ZET6的USART12通过MAX3232转换成232电平的串口,接口方式为DB9公头, 实现了一个3线串口。管脚定义如下: 管脚 信号 2 RXD 3 TXD 5 GND 26) 串口 2 串口2与串口1的实现方式相同,主要的差别在于,我们可以通过跳帽选择处理器的USART2实现 的是串口2还是485总线接口。 27) RS-485 接口 RS-485总线接口,采用SP3485VP230接口芯片实现。 28) RS-232 与 RS-485 选择跳帽 神舟III号STM32开发板串口2可以选择实现RS-232接口或者RS-485接口。具体选择关系如下表。 J12 J14 功能 1-2 1-2 RS-485接口 2-3 2-3 RS-232接口 29) 特殊功能接口 神舟III号STM32开发板,将STM32处理器部分具有特殊功能的管脚连接到预留接口,提供一些可 扩展的功能。预留接口的管脚定义如下。 管脚号 功能 管脚号 功能 1 GND 6 DAC1 2 ADC_IN11 7 GND 3 ADC_IN10 8 TIM3_CH4 4 GND 9 TIM3_CH3 5 DAC2 10 GND 30) 扩展接口 嵌入式专业技术论坛 (www.armjishu.com)出品 第 25 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 神舟III号将所有的GPIO的使用标准双排插针引出,方便大家的实验和测试,调试其他模块或功 能扩展。 31) 2.4G 无线模块(可选配件) 神舟III号提供了1个2.4G模块接口,可以直接支持深圳云佳科技的NRF24l01模块。本模块作为选 配件。产品图片如下。 32) 315M 无线模块(可选配件) 神舟III号提供了1个315M模块接口,可通过遥控控制进行远程控制,相关产品和模块如下所示。 1.2. 神舟III号开发板硬件详解 详细介绍神舟III号各功能模块的硬件实现与原理。 1.2.1. 处理器最小系统 神舟III号处理器选择的是STM32F103ZET6,STM32F103的型号众多,作为一款中高端开发板, 我们选择了其中最高配置的型号,让用户可以使用STM32F103系列的所有外设,和体验它的强悍功能。 MCU部分原理图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 26 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 图1.2.1.1 MCU部分原理图 ‹ JTAG/SWD接口 JTAG(Joint Test Action Group)联合测试行动小组)是一种国际标准测试协议(IEEE 1149.1兼容)。 标准的JTAG接口包括TMS、TCK、TDI和TDO,通过JTAG接口,我们可以烧录和调试程序,神舟III 号的JTAG接口的硬件连接如下图所示,可以与目前主流的JLINK V8仿真器配合使用。另外STMM32 还有SWD接口,SWD只需要最少2跟线(SWCLK和SWDIO)就可以下载并调试代码了,它与JTAG 接口是共用的,只要接上JTAG,你就可以使用SWD模式了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 27 页,共 788 页 JTAG/SWD接口的信号定义如下: ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ‹ 滤波电容 为STM32F103ZET6及神舟III号开发板上其他芯片提供必要的储能电容,滤波和退耦。为整个系 统提供一个干净的电源,保证整个系统的稳定可靠运行。 ‹ 实时时钟 STM32的VBAT采用CR1220纽扣电池和VCC3.3混合供电的方式,在有外部电源(VCC3.3)的时 候,CR1220不给VBAT供电,而在外部电源断开的时候,则由CR1220给VBAT供电。这样,VBAT总 是有电的,以保证RTC的走时以及后备寄存器的内容不丢失。 相关电路如下: 当安装了电池后,将J11的2,3脚使用跳线帽短接。VBAT管脚由电池供电,如没有安装电池,将 J11的1,2脚使用跳线帽短接,VBAT管脚由+3.3V系统电源供电。 ‹ VDDA与VREF电源 VDDA与VREF是STM32处理器数字/模拟转换(ADC)电路需要使用到的模拟参考电源和模拟电 源输入。 相关管脚定义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 28 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 在神舟III号板上,VREF和VDDA电源相关电路如下图所示: ‹ STM32F103ZET6处理器 STM32F103ZET6处理器的GPIO口和其他的功能接口分别与神舟III号板的各功能模块连接,处理 器部分电路如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 29 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 30 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 STM32F103ZET6的资源与管脚分配如下表所示。 管脚 号 信号名 功能接口 10 FSMC_A0 RS 信号 11 FSMC_A1 12 FSMC_A2 13 FSMC_A3 14 FSMC_A4 15 FSMC_A5 50 FSMC_A6 53 FSMC_A7 54 FSMC_A8 55 FSMC_A9 56 FSMC_A10 57 FSMC_A11 Nor Flash 87 FSMC_A12 88 FSMC_A13 89 FSMC_A14 90 FSMC_A15 80 FSMC_A16 81 FSMC_A17 82 FSMC_A18 2 FSMC_A19 3 FSMC_A20 4 FSMC_A21 5 FSMC_A22 1 FSMC_A23 128 FSMC_A24 129 FSMC_A25 85 FSMC_D0 2.8/3.2 LCD Nor Flash SRAM 86 FSMC_D1 114 FSMC_D2 115 FSMC_D3 58 FSMC_D4 59 FSMC_D5 60 FSMC_D6 63 FSMC_D7 64 FSMC_D8 65 FSMC_D9 66 FSMC_D10 67 FSMC_D11 68 FSMC_D12 嵌入式专业技术论坛 (www.armjishu.com)出品 Nand Flash 第 31 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 77 FSMC_D13 78 FSMC_D14 79 FSMC_D15 92 FSMC_INT3 127 FSMC_NE4 73 SPI2_NSS 74 SPI2_SCK 75 SPI2_MISO SPI 接口 76 SPI2_MOSI 35 PA1 LCD 背光 93 PG8 BUSY 信号 126 PG11 Flash CS 132 PG15 SD 卡 CS 69 PB10 70 PB11 44 PC4 SPI 片选 45 PC5 USB 上拉 96 PC6 SD 卡 118 FSMC_NOE 119 FSMC_NWE 122 FSMC_NWAIT 123 FSMC_NCE2 91 FSMC_INT2 124 FSMC_NE2 125 FSMC_NE3 141 FSMC_NBL0 142 FSMC_NBL1 34 WKUP WAKE UP 按键 7 TAMPER-RTC TAMPER 按键 100 PA8 USER1 按键 117 PD3 USER2 按键 22 PF10 101 USART1_TX 102 USART1_RX 串口 1 36 USART2_TX 37 USART2_RX 串口 2 PCM1770 2.4G 模块 2.4G 模块片选 2.4G SPICS 2.4G 模块中断 无线模块 485 接口 49 PF11 40 SPI1_NSS 41 42 SPI1_SCK SPI1_MISO SPI AT45DB161 网口模块 43 SPI1_MOSI 28 PC2 中断输入 485 方向 DAC_OUT1 DAC_OUT2 嵌入式专业技术论坛 (www.armjishu.com)出品 第 32 页,共 788 页 103 USB_DM 104 USB_DP 135 I2S_SD 105 TMS-SWDIO 109 TCK-SWCLK 110 TDI 133 TDO 134 NTRST 46 TIM3_CH3 47 TIM3_CH4 26 ADC123_IN10 27 ADC123_IN11 USB 接口 JTAG 接口 PWM 接口 ADC 输入 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 I2S3_WS I2S_CK 29 ADC123_IN13 电位器 48 BOOT1 138 BOOT0 启动模式 136 I2C_SCL 137 I2C_SDA I2C 24C02 收音机 139 CAN_RX 140 CAN_TX CAN 总线 97 I2S3_MCK 98 SDIO_D0 99 SDIO_D1 111 SDIO_D2 SD 卡 112 SDIO_D3 113 SDIO_CK 116 SDIO_CMD 18 PF6 19 PF7 20 PF8 LED 灯 21 PF9 说明:功能接口中同一填充颜色表示相同的接口,如上表中的淡绿色表示2.8/3.2寸LCD接口。 ‹ 启动模式设置 上图中右下角的BOOT0, BOOT1用于设置STM32的启动方式,其对应启动模式如下表所示: BOOT1(J9) BOOT0(J10) 功能 说明 ANY 2-3 User Boot(默认) 用主闪存存储器,即Flash启动 2-3 1-2 System Boot 系统存储器启动,用于串口下载 1-2 1-2 SRAM Boot SRAM启动,用于SRAM中调试代码 — 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它 原来的地址(0x0800 0000)访问它,即闪存存储器的内容可以在两个地址区域访问,0x0000 嵌入式专业技术论坛 (www.armjishu.com)出品 第 33 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 0000或0x0800 0000。 — 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的 地址(0x1FFF F000)访问它。 — 从内置SRAM启动:只能在0x2000 0000开始的地址区访问SRAM。 1.2.2. LED指示灯 在神舟 III 号中,除了电源指示灯外,还有 4 个 LED 指示灯,由 GPIO 管脚控制 LED 灯的亮灭, 当 GPIO 管脚输出低电平时,LED 指示灯亮。反之,当 GPIO 管脚输出高电平时,LED 指示灯灭。 这四个 LED 指示灯分别由 PF6~9 控制。 1.2.3. 按键 神舟 III 号 STM32 开发板板载 4 个功能按键,分别是 WAKEUP 按键和 TAMPER 按键及两个用于 自定义功能按键,在不使用第二功能的情况下,这四个按键都可以作为通用的按键,由用户自定义其 功能。按键分别与 PA0,PC13,PA8 和 PD3 四个 GPIO 管脚连接,当按键按下时,对应的 GPIO 管脚 为低电平,反之,当没有按键按下时,对应的 GPIO 管脚为高电平。 1.2.4. USB接口与电源 神舟 III 号 STM32 开发板支持的供电方式主要有三种,分别是: ¾ USB 接口供电,最大 500mA ¾ 外部直流 5V 供电 嵌入式专业技术论坛 (www.armjishu.com)出品 第 34 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ¾ JLINK V8 供电,包括 5V 和 3.3V 两种方式 如上图所示,为神舟III号的USB接口与电源部分电路。 当CON1电源开关拨到1-2位置时,神舟III号由外部接口供电。板上的电源转换芯片将USB接口输 入的5V电源转换成3.3V的电源,作为处理器和相关外围电路的工作电源。。 当CON1电源开关拨到2-3位置时,神舟III号由USB接口供电。板上的电源转换芯片将USB接口输 入的5V电源转换成3.3V的电源,作为处理器和相关外围电路的工作电源。在上图中,U11为USB接口 的ESD防护电路,满足ESD防护标准IEC61000-4-2(ESD 15kV air, 8kV Contact) 。 1.2.5. 液晶显示模块 神舟III号开发板载有目前比较通用2.8/3.2寸液晶显示模块接口。其原理图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 35 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 图表 4 液晶显示模块原理图 神舟III号通过FSMC总线对屏进行进行访问操作实现图形界面的显示。神舟系列的2.8/3.2寸LCD 触摸屏支持触摸功能,LCD模块上有触摸芯片,将电阻式触摸屏的模拟信号转化为数字信号,处理器 通过SPI接口读取芯片转换后的数字,支持查询方式和中断方式。 此外,2.8/3.2寸LCD屏模块上还集成了SPI Flash和SPI接口的SD卡座(神舟III号板载了一个SDIO 接口的SD卡座),在这里由于资源有限,神舟III号只支持2.8/3.2寸屏和SD卡,不支持2.8/3.2寸LCD 屏模块上的SPI Flash。 1.2.6. Nor Flash 神舟III号板载了16M比特的Nor Flash, 最大支持128M比特容量Nor Flash。如下图所示,为128M Nor Flash的连接原理图,STM32F103ZET通过FSMC访问Nor Flash 嵌入式专业技术论坛 (www.armjishu.com)出品 第 36 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.7. SRAM 神舟III号板载了4M比特的SRAM,如下图所示,为SRAM部分理图,STM32F103ZET通过FSMC访 问SRAM。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 37 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.8. Nand Flash 神舟III号板载了1G比特的的Nand Flash,如下图所示,为Nand Flash部分的原理图,STM32F103ZET 通过FSMC访问Nand Flash。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 38 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.9. 串口与RS485接口 神舟III号板载了2个串口,串口1和串口2,位置分别如下图所示。 其中串口2可通过跳线选择支持RS-232接口或RS-485接口,跳线定义如下: J14 J12 串口2功能选择 1-2 1-2 串口2 RS-485接口 2-3 2-3 串口2 RS-232接口 请按照上表设置跳线,选择串口2作为RS-232串口或RS-485接口。串口1和串口2的原理图如下图 所示,串口1和串口2都可作为3线RS-232串口使用,其中串口2还可作为RS-485接口使用。注意,当 串口2作为RS-485使用时,神舟III号默认是安装了RS-485接口的120欧终端匹配电阻。对应下图的 R82,请依据实际应用选择是否安装此匹配电阻。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 39 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.10. 收音机模块 神舟 III 号 STM32 开发板上使用目前主流的 TEA5767 收音机模块提供收音功能,STM32F103ZET6 处理器通过 I2C 接口访问和配置 TEA5767 模块。 1.2.11. 音频解码电路 神舟 III 号 STM32 开发板上使用了 PCM1770 这款具有耳机放大器的 24 位低功耗立体声音频 DAC 芯片提供音频播放功能。处理器通过 I2S3 传送音频信号到 PCM1770,由它进行解码输出到 J2 音频座。 而 PCM1770 的配置接口与处理器的 SPI2 连接,处理器通过 SPI 接口访问 PCM1770。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 40 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.12. SPI Flash 神舟III号开发板载有SPI Flash芯片W25X16,该芯片的容量为2M字节,与AT45DB161属于同一级 别,其原理图如下: W25X16也是与处理器的SPI1接口相连,注意由于神舟III号上有W25X16和网口共用了SPI1,通过 不同的CS进行区分,请勿同时使这两个接口的CS有效,否则,可能引起芯片读写访问失败。 1.2.13. EEPROM 神舟III号自带了24C02的EEPROM芯片,该芯片的容量为2K比特,也就是256个字节,对于我们 普通应用来说是足够了的。你也可以选择换大的芯片,因为在原理上是兼容24C02~24C256全系列的 EEPROM芯片的。其原理图如下: 这里我们把A0~A2均接地,对24C02来说也就是把地址位设置成0了,在进行程序设计时,请确认 EEPROM的地址与之对应。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 41 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.2.14. CAN总线接口 STM32F103ZET6 这一款处理器集成了 CAN 总体接口,在开发板上我们使用了 TI 公司的 3.3V 电压的 CAN 总线收发器来实现 CAN 总线,如下图所示。CAN 总线收发器型号为 VP230。 1.2.15. SD卡 神舟III号开发板载标准的SD卡接口,有了这个接口,我们就可以外扩大容量存储设备,可以用 来记录数据。其原理图如下: 一般SD卡可通过SPI接口或者SDIO接口来通信,其中SDIO模式通信速率更高,在这里我们即是 使用的SDIO模式进行通信。 1.2.16. 无线模块 神舟III号开发板板载了2款无线模块的接口,分别是315M无线模块和NRF24L01+这一款2.4G无线 模块。 其中315M无线模块,可以接受遥控器的信号,当遥控的一个按键按下时,对应的无线模块的D0~3 嵌入式专业技术论坛 (www.armjishu.com)出品 第 42 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 管脚变为有效。需要指出的是,无线模块当输出为高电平有效。而神舟III号通过三极管将315M无线 模块与板上的按键进行了资源复用。 当无线模块的VT脚有效(低电平)时,表示无线模块接收到遥控的按键信号;当VT管脚无效(高 电平)时,表示无线模块没有接收到遥控的按键信号,与无线模块连接的几个管脚的电平变化是按键 引起的。 图1.2.10.1 无线模块接口原理图 下图为NRF24L01+模块的连接示意图,NRF24L01+无线模块通过SPI2与STM32F103ZET6相连。 注意,NRF24L01+的IRQ管脚与3.2寸屏模块上集成的SD卡CS信号进行了复用,当需要使用3.2寸屏模 块上集成的SD卡时,不能使用NRF24L01+模块。 1.2.17. 以太网 神舟三号选用的是 ENC28J60 这一款 SPI 接口的以太网控制器实现 10M 以太网,如下图所示, STM32F103 通过 SPI1 访问 ENC28J60,包括内部寄存器的读写访问。HR911105A 是 HANRUN 公司 推出的一款集成变压器的 RJ45 接口,两者配合实现了 10M 以太网。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 43 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 至此,整个开发板的硬件就介绍完了,在接下来的章节中,将继续详细介绍原开发环境和具体的 实验例程。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 44 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 第二章 软件篇 本章以目前最新的RVMDK 4.12版本为例,详细介绍RVMDK(以下简称MDK)这一主流的开发 环境的使用。包括MDK工程的建立,代码的编译和调试,以及程序下载等。通过这一章节,我们将 了解MDK的基本操作,熟悉基于MDK软件的STM32开发流程。 2.1 RVMDK简介 RVMDK源自德国的KEIL公司,是RealView MDK的简称,RealView MDK集成了业内最领先的 技术,包括μVision4集成开发环境与 RealView编译器。支持ARM7、ARM9和最新的Cortex-M3核处 理器,自动配置启动代码,集成Flash烧写模块,强大的Simulation设备模拟,性能分析等功能,与ARM 之前的工具包ADS等相比,RealView编译器的最新版本可将性能改善超过20%。 2.2 MDK 4.12集成开发环境的组成 MDK又称叫RVMDK,源自德国的KEIL公司,是RealView MDK的简称,RealView MDK集成了 业内最领先的技术,包括μVision4集成开发环境与 RealView编译器。支持ARM7、ARM9和最新的 Cortex-M3核处理器,自动配置启动代码,集成Flash烧写模块,强大的Simulation设备模拟,性能分析 等功能,与ARM之前的工具包ADS等相比,RealView编译器的最新版本可将性能改善超过20%。 2.3 MDK工程的编辑 2.3.1 新建RVMDK工程 1)点击 WINDOWS 操作系统的【开始】Æ【程序】Æ【Keil uVision4】启动 Keil uVision 或在桌 面双击【Keil uVision4】快捷方式启动。启动 MDK4.12 如图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 45 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2)点击之后,出现启动画面: 1) 点击“project---New uVision Project”新建一个工程 嵌入式专业技术论坛 (www.armjishu.com)出品 第 46 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2) 在对话框,选择放在刚才建立的“新建文件夹”下,给这个工程取个名后保存,不需要填后缀: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 47 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3) 弹出一个框,在 CPU 类型下我们找到并选中“STMicroelectronics”下的 STM32F103ZET: 4) 出现一个提示框,是否复制 STM32 启动代码到工程文件夹,我们选择【是】,就可以看到 STM32 的启动代码自动添加进来了: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 48 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 5) 到这里工程全部建立完毕 2.3.2 建立文件 建立一个文本文件,以便输入用户程序。点击【File】Æ【New…】图标按钮, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 49 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 然后在新建的文件中编写程序,点击“Save”图标按钮将文件存盘,输入文件全名,如 demo.c。 注意,请将文件保存到相应工程的目录下,以便于管理和查找。 当然,您也可以使用其他文本编辑器建立或编辑源文件。 2.3.3 添加文件到工程 选择 Target1 下面的组,这里是“Source Group1”,单击右键,选择【Add File to Group….】,选 定想要添加到文件,确认即可。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 50 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 51 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.3.4 管理工程目录以及源文件 当我们的项目比较庞大时,我们就需要一个管理平台来管理我们的工程文件,以及将一些同类型 的工程文件分好类,放入相对应的文件夹中,而这个管理工程文件以及目录的平台就是下面介绍到的: 1. 右击工程窗口中的 Target1 选择“Manage Components……” 嵌入式专业技术论坛 (www.armjishu.com)出品 第 52 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2. 在 Project Target 中把 Target1 改成你想要的名字,可以不改,这里改为 project,然后在 groups 单 击新建按钮,这些组对应我们实实在在的文件夹,方便源文件的分类和管理,例如我们这里新建 User Source,Library,CMSIS,和 readme 四个组: 3. 先选中一个组之后,在 Files 点击 Add Files,例如在 User Source 组添加 User 文件夹中的源文件, 添加完成该文件就成功添加到工程中了: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 53 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 54 页,共 788 页 2.3.5 编译和连接工程 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1.编译的几个选项介绍: 下面是编译程序的三种情况,具体请看上图: ¾ 编译当前文件:如果只是确认当前文件是否存在问题,可以选择这个按键 ¾ 编译修改过的文件并链接:如果只是确认最近的修改是否存在问题,可以选择这个按键 ¾ 编译所有文件:选择这个按键将将重新编译链接整个工程文件。 1、关于工程设置框: 上面还有个红框是工程设置相关的,例如工程设置,如地址设置,输出文件设置,编译选项等; 如果我们点击它,就会出现下面的图框,我们可以在这里面根据需要进行一系列详细的设置。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 55 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2、 调试时输出的错误: 对于简单的软件调试,可以不进行连接地址的设置,直接点击工程窗口的“build”图标按钮, 即可完成编译连接。若编译出错,会有相应的出错提示,双击出错提示行信息,编辑窗即会使用光标 指出当前出错的源代码行。 4.清除编译之后的垃圾: 重新编译之前,建议将原来生成的目标文件都删除,方法如下,点选“project”下拉选择“Clean Target”,删除所有旧目标文件后再进行编译: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 56 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 5.按 键,编译工程,得到结果如下图所示(不同工程显示内容大同小异): 可以看到没有错误,也没有警告。从编译信息可以看出,我们的代码占用 FLASH 大小为:580 字节(328+252) 这里我们解释一下,编译结果里面的几个数据的意义: Code:表示程序所占用 FLASH 的大小(FLASH) RO-data:即 Read Only-data,表示程序定义的常量(FLASH) RW-data:即 Read Write-data,表示已可以读写的变量(SRAM) ZI-data:即 Zero Init-data,表示已被初始化为 0 的变量(SRAM) 有了这个就可以知道当前使用的 flash 和 sram 大小了,所以,大家不要误解程序的大小就是.hex 文件的大小,这是不对的,程序的大小是编译后的 Code 和 RO-data 之和。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 57 页,共 788 页 ARM 技术论坛 www.armjishu.com 2.3.6 打开旧工程 STM32 神舟 III 号用户手册 V4.0 点击【File】菜单,选择【Open】即弹出”打开”对话框,找到相应的工程文件(*.uvproj),单击【打 开】即可: 在工程窗口中,双击源程序的文件名即可打开该文件进行编辑: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 58 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.4 RVMDK使用技巧 前面介绍了 RVMDK 的基本使用,接下来简单的介绍一下 RVMDK 的几个使用技巧。 2.4.1 快速定位函数/变量被定义的地方 你在调试代码或编写代码的时候,一定有想看看某个函数是在那个地方定义的,具体里面的内容 是怎么样的,也可能想看看某个变量或数组是在哪个地方定义的等。尤其在调试代码或者看别人代码 的时候,如果编译器没有快速定位的功能的时候,你只能慢慢的自己找,代码量比较少还好,如果代 码量一大,那就郁闷了,有时候要花很久的时间来找这个函数到底在哪里。幸好 MDK 提供了这样的 快速定位的功能。只要你把光标放到这个函数/变量的上面,然后右键,如下图所示 : 嵌入式专业技术论坛 (www.armjishu.com)出品 第 59 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 图 2.8.2.3 快速定位 在上图,我们点击 Go To Definition of ‘GPIO_Pin_2’,跳转查看 GPIO_Pin_2 是在何处,如何被定 义的。如下图所示 上面是演示的是一个变量的定义的查找,对于函数,我们也可以按这样的操作快速来定位函数被 定义的地方,大大缩短了你查找代码的时间。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 60 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.4.2 快速注释与快速消注释 接下来,我们介绍一下快速注释与快速消注释的方法。在调试代码的时候,你可能会想注释某一片的 代码,来看看执行的情况,MDK 提供了这样的快速注释/消注释块代码的功能。也是通过右键实现的。 这个操作比较简单,首先选中你要注释的代码区,然后右键,选择 Advanced->Comment Selection 就 可以了。 以 Turn_On_LED 函数为例,比如我要注释掉下图中所选中区域的代码,如下图所示: 我们只要在选中了之后,选择右键,再选择 Advanced->Comment Selection 就可以把这段代码注释掉 了。执行这个操作以后的结果如下图所示: 这样就快速的注释掉了一片代码,而在某些时候,我们又希望这段注释的代码能快速的取消注释, MDK 也提供了这个功能。与注释类似,先选中被注释掉的地方,然后通过右键->Advanced,不过这 里选择的是 Uncomment Selection。 2.4.3 快速打开头文件 将光标放到要打开的引用头文件上,然后右键选择 Open Document“XXX”,就可以快速打开这个文件 了(XXX 是你要打开的头文件名字)。如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 61 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 图 2.8.2.7 快速打开头文件 关于 MDK 软件的使用就介绍到此,如需更深入和全面的了解请用户查看 KEIL 软件用户使用手册。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 62 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.5 JLINK V8仿真器的安装与应用 在代码编译通过后,我们需要验证程序是否与我们的设计预期相符合,一般有几种方式来验证。 第一种,软件仿真。在没有硬件环境的情况下,我们可以使用 MDK 的软件仿真功能来对代码的 功能进行初步验证。关于软件仿真功能的使用,在本文档中不在详细描述,有兴趣的朋友,可以常看 MDK 相关手册和说明文档。 第二种,在线仿真。如果硬件环境允许的情况下,建议使用在线仿真来进行调试,完全与实际应 用相符。神舟 III 号所以实验程序都使用 JLINK 仿真器仿真调试通过。 JLINK 是一款主流的支持 ARM 内核芯片的 JTAG 仿真器,配合 IAR,KEIL,WINARM,RealView 等集成开发环境,支持所有 ARM7/ARM9/Cortex-M3 内核芯片的仿真。在这里,我们以神舟 III 号的 入门程序为例,说明如何在 MDK 开发环境中,搭配 JLINK 仿真器,在线仿真调试程序。 首先按下图,连接 JLINK 仿真器与神舟 III 号开发板。并给神舟 III 号上电。 2.5.1 JLINK V8仿真器简介 J-LINK 是 SEGGER 公司为支持仿真 ARM 内核芯片推出的 JTAG 通用仿真器。配合 IAR EWARM, ADS,KEIL,WINARM,RealView 等集成开发环境,支持所有 ARM7/ARM9/ARM11 和 Cortex-M0/M1/M3 核内核芯片的仿真,通过 RDI 接口和 IAR EWARM,ADS,KEIL,WINARM,RealView 等各集成开发 环境无缝连接,操作方便、连接方便、简单易学,是学习开发 ARM 最好最实用的开发工具。 2.5.2 JLINK ARM主要特点 —   USB 接口符合 USB2.0 规范 —   标准 20 芯 JTAG 接口 —   支持全系列 ARM 7/9/11,Cortex_M0/M1/M3 ARM 核,包括 Thumb 模式 —   IAR EWARM 集成开发环境无缝连接的 JTAG 仿真器 嵌入式专业技术论坛 (www.armjishu.com)出品 第 63 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 —   USB 接口供电,无需外接电源 —   J-LINK 支持对目标板 5V(300mA),3.3V(400mA)供电 —   带 USB 连接线和 20 芯扁平电缆 —   支持 RDI 接口,J-LINK 可用于具有 RDI 接口的开发环境,支持主流的开发环境,包括 ADS,IAR,KEIL,WINARM,REALVIEW 等。 —   下载速度高达 ARM7:600kB/s,ARM9:550kB/s,通过 DCC 最高可达 800 kB/s —   最高 JTAG 速度 12 MHz —   目标板电压范围 1.2V – 3.3V —   自动速度识别功能 —   监测所有 JTAG 信号和目标板电压 —   完全即插即用 —   支持多 JTAG 器件串行连接 —   支持两种下载仿真调试接口:JTAG 接口方式和 SWD 两线接口方式 2.5.3 如何安装JLINK软件 JLINK 仿真器驱动程序可以从配套光盘(文件路径:神舟III号光盘\JLINK驱动 \Setup_JLinkARM_V420p.zip)或SEGGER 网站 (http://www.segger.com/cms/jlink-software.html)获取最新的安装文件(目前最新安装版本 为Software and documentation pack V4.20p ),解压后双击执行,出现下图所示的安装界 面,根据界面安装向导的提示,完成JLINK仿真器驱动程序的安装。 点击Yes继续安装 嵌入式专业技术论坛 (www.armjishu.com)出品 第 64 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 点击Next继续安装 如果你还在以前装了 IAR 的集成开发环境将出现下图提示,提示你选择更新 IAR JLINK 仿真器的动态链接库文件,一般选上后按 OK 完成 JLINK 仿真器的安装。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 65 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.5.4 JLINK V8仿真器配置(MDK KEIL环境) 按下图所示,连接 JLINK 和目标设备。 使用 J-LINK 进行 DEBUG 的设置 打开 KEIL 工程后,选择项目设置的 Debug 菜单。如下图选择“Cortex-M/R J-LINK/J-Trace”,点 击“Settings” 嵌入式专业技术论坛 (www.armjishu.com)出品 第 66 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 67 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 因为 STM32F103ZET 的内部 ROM 大小事 512K 的,所以这里设置 512K 的大小。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 68 页,共 788 页 最后设置好之后,点击’OK’按钮即可 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2.5.5 使用KEIL的DOWNLOAD功能 如果要使用KEIL 提供的 即“DOWNLOAD”功能则在完成 前一步的设置外,还需要在 “Utilities”菜单里面进行和“Debug”一样的设置: 2.6 在MDK开发环境中JLINK V8的调试技巧 接下来,点击 启动在线仿真。软件窗口如下图所示。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 69 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 可以发现,多出了一个工具条,这个工具条对于我们仿真是非常有用的,下面简单介绍一下工具 条相关按钮的功能,工具条部分按钮的功能如下图所示: ¾ 复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。代码重新执行。 ¾ 执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是 想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能。 ¾ 挂起:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入 到单步调试状态。 ¾ 执行一条指令:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于 执行当前行执行过去按钮的。 ¾ 执行当前行:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数 单步执行。 ¾ 跳出当前函数:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余 部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。 ¾ 执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但 是两者是有区别的,断点可以有多个,但是光标所在处只有一个。 ¾ 汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。 ¾ 观看变量窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量 值,也是很常用的一个调试窗口。 ¾ 串口打印窗口:该按钮按下,会弹出一个串口调试助手界面的窗口,用来显示从串口打印出来的 内容。 其他几个按钮用的比较少,以上是比较常用的,当然也不是每次都用得着这么多,具体看你程序 调试的时候有没有必要观看这些东西,来决定要不要看。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 70 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 关于如何一步一步进行仿真调试,请查看 MDK 相关资料。 2.7 在MDK开发环境中调试 单片机软件开发过程中,软件调试遇到的各种问题常令初学者感到不知所措。实际上。各种仿真 开发软件的程序调试基本方法和技巧大同小异,掌握正确的程序调试基本技巧。对于排查这些程序错 误问题可以起到举一反三、事半功倍的效果。软件调试是单片机技术人员必须掌握的重要基本技能。 在这一节里,我们将学习 STM32 在 MDK 下的软件仿真与利用 JLINK 对 STM32 进行在线调试。 2.7.1 KEIL仿真的应用 MDK 的一个强大的功能就是仿真功能,分为硬件仿真与软件仿真。通过软件仿真,我们可以发 现很多将要出现的问题,避免了下载到 STM32 里面来查这些错误,这样最大的好处是能很方便的检 查程序存在的问题,因为在 MDK 的仿真下面,你可以查看很多硬件相关的寄存器,通过观察这些寄 存器,你可以知道代码是不是真正有效。而且软件仿真是不必频繁的刷机,从而延长了 STM32 的 FLASH 寿命(STM32 的 FLASH 寿命≥1W 次)。 而硬件仿真是使用附加的硬件来替代用户系统的单片机并完成单片机全部或大部分的功能。使用 了附加硬件后用户就可以对程序的运行进行控制,例如单步,全速,查看资源断点等。硬件仿真是开 发过程中所必须的。 下面我们通过实际的例子来详细来了解下软件仿真与硬件仿真的使用。 2.7.2 KEIL软件仿真 在做软件仿真的时候,我们先打开一个我们的工程,验证我们的工程是否是有问题的,在这里我 们就使用神舟 III 号是最简单的 LED 流水灯的工程来做我们的例子说明。如下图为我们打开工程后的 页面 嵌入式专业技术论坛 (www.armjishu.com)出品 第 71 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 在开始软件仿真之前,先检查一下配置是不是正确,在project里面点击我们的工程选项“Options for Target‘神舟III号’”或者是我们的快捷按钮 ,在“Device”和“Target”选项卡中先看 下处理器与晶振是否是和我们的板子晶振相符的,神舟III号使用的处理器是STM32F103ZET,而外部 晶振是25MHz的,所以我们也要设置为25MHz的,其他的默认即可,如下图所示: 接下来,我们在这个配置选项中点击Debug选项卡,该选项卡是用来配置调试的,调试有两种, 一种是基于软件的模拟调试,另一种是通过仿真器在线调试。我们这节主要就是使用这个选项卡。如 下图所示,这里分左右两部分,左边为软件仿真,右边为硬件仿真,而我们这里要用的是软件仿真, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 72 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 所以选择左部分的“Use Simulator”模拟仿真。其他默认就行,点击OK退出Options for Target对话框。 退出之后就能进入我们的软件模拟仿真的功能了,接下来,我们点击快捷按钮 仿真按钮),开始仿真,出现如下图所示界面: (开始/停止 图中我们可以看到,快捷按钮比我们仿真之前多了一个工具条,这个就是我们Debug仿真的时候 嵌入式专业技术论坛 (www.armjishu.com)出品 第 73 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 用到的工具条,下面我们简单的介绍一下Debug工具条各个按钮的功能。如下图所示: 复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代码会重新从 头开始执行。 全速运行、运行到断点:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的, 而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查看的地 方设置了断点。 停止:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单 步调试状态。 单步进入函数:该按钮用来实现执行到某个函数里面去的功能 单独执行完函数:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数 单步执行。 执行到函数结束:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部 分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。 运行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两 者是有区别的,断点可以有多个,但是光标所在处只有一个。 汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。 观看变量/堆栈窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变 量值,也是很常用的一个调试窗口。 串口打印窗口:该按钮按下,会弹出一个类似串口调试助手界面的窗口,用来显示从串口打印出来的 内容。 逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过SETUP按钮新建一些IO口,就可以观察这 些IO口的电平变化情况,以多种形式显示出来,比较直观。 Debug工具条上的其他几个按钮用的比较少,我们这里就不介绍了。以上介绍的是比较常用的, 当然也不是每次都用得着这么多,具体看你程序调试的时候有没有必要观看这些东西,来决定要不要 看。 断点设置 在要设置断点的地方双击下鼠标左键即可,可以看到在左边会出现了一个红框,即表示设置了一 个断点(也可以通过鼠标右键弹出菜单来加入),再次双击则取消)。然后我们点击 点处,如下图所示: ,执行到该断 嵌入式专业技术论坛 (www.armjishu.com)出品 第 74 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 调试的时候,可以看到对寄存器的修改,但是在实际操作的时候会需要修改某些外设控制寄存器 或者 memoery 中的数据,那么还需要其他的窗口来支持,这些窗口都在 view 菜单下,如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 75 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这里重点介绍下面几个窗口: Command windows 命令窗口 Disassembly windows 反汇编窗口 Symbol windows 符号窗口 Register windows 寄存器窗口 Call Stack windows 函数调用栈显示窗口 Watch windows 变量观察窗口 Memory windows 存储器观察窗口 Serial windows 串行数据输出观察窗口 Analysis windows 分析窗口 Trace 轨迹跟踪观察窗口 这里有这么多的窗口,实际上比较常用的是 Watch 窗口和 Memory 窗口。如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 76 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 在这个 memory 观察窗口下,只要输入地址就可以看到从这个地址之后的若干个地址的数据。 当然观察窗口同样是支持修改对应的值的。 调试是对代码执行的验证过程,所以具体的调试方法每个人有不同的想法,而且实际的问题不同操作 也会不同。 而我们在程序运行的时候,在左边的窗口可以看到寄存器的变化以及运行的时间,方便分析程序 嵌入式专业技术论坛 (www.armjishu.com)出品 第 77 页,共 788 页 ARM 技术论坛 www.armjishu.com 2.7.3 硬件仿真 STM32 神舟 III 号用户手册 V4.0 硬件仿真的话需要用到我们的仿真器进行一个硬件仿真的操作,在这里我使用的是 J-Link 仿真器,打 开我们刚才的 Debug 选项,选择右边的硬件仿真,选择你的仿真器,我这里用的是 J-link 仿真器。 点击 Settings 进入我们的仿真器设置参数,如下图所示 嵌入式专业技术论坛 (www.armjishu.com)出品 第 78 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这里我们能设置仿真模式为 JYAG 仿真还是 SW 模式仿真调试,JTAG 需要占用比 SW 模式多很多的 IO 口,这里我们设置的调试速度为 2Mhz,单击 OK,完成此部分设置,接下来我们还需要在 Utilities 选 项卡里面设置下载时的目标编程器,如图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 79 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 我们选择 J-LINK 来调试 Cortex M3,然后点击 Settings,设置如图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 80 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这里要根据不同的MCU选择FLASH的大小,因为我们开发板使用的是STM32F103ZET,其FLASH大 小为512KB,所以我们点击Add,并在Programming Algorithm里面选择512K型号的STM32。然后选中 Reset and Run选项,以实现在编程后自动启动,其他默认设置即可。在设置完之后,点击OK,然后 再点击OK,回到IDE界面,编译一下工程。再点击 ,开始仿真(如果开发板的代码没被更新过, 则会先更新代码,再仿真,你也可以通过按 ,只下载代码,而不进入仿真)。 其他的则和软件仿真差不多了,只不过硬件仿真能在设备上运行我们执行程序的效果,方便我们的调 试。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 81 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 第三章 STM32神舟III号 基本操作篇 本章节主要介绍使用神舟 III 号 STM32 开发板进行学习与试验的基本操作,包括如何给 STM32 开发板电源供电,如何下载一个编译好的固件等。 3.1. 如何安装JLINK驱动程序 JLINK 仿真器驱动程序可以从配套光盘(文件路径:神舟III号光盘\JLINK驱动 \Setup_JLinkARM_V420p.zip)或SEGGER 网站(http://www.segger.com/cms/jlink-software.html)获取最新 的安装文件(目前最新安装版本为Software and documentation pack V4.20p ),解压后双击执行,出现 下图所示的安装界面,根据界面安装向导的提示,完成JLINK仿真器驱动程序的安装。 点击Yes继续安装 嵌入式专业技术论坛 (www.armjishu.com)出品 第 82 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 点击Next继续安装 如果你还在以前装了 IAR 的集成开发环境将出现下图提示,提示你选择更新 IAR JLINK 仿真器的动 态链接库文件,一般选上后按 OK 完成 JLINK 仿真器的安装。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 83 页,共 788 页 ARM 技术论坛 www.armjishu.com 3.2. 如何使用JLINK仿真器 STM32 神舟 III 号用户手册 V4.0 3.2.1. 如何使用J-Flash ARM 烧写固件到芯片Flash STM32的程序下载有多种方法,可以通过USB、串口、JTAG、SWD等方式下载。这几种方式都 可以用来给神舟III号开发板下载程序,这里详细介绍通过JLINK 仿真器下载固件到神舟III号开发板 的过程。 JLINK V8是目前主流的JTAG仿真器,支持所有的ARM7/9/11和Cortex-M0/M1/M3处理器。而且 与主流的开发环境,如神舟系列STM32开发板采用的IAR,MDK开发环境完美的结合。通过JLINK仿真 器,我们可以方便的下载,和在线调试代码。因此,推荐神舟III号开发板与JLINK V8搭配使用。 神舟III号提供的官方资源,包括源代码,使用的开发环境为MDK 4.12;使用的仿真调试工具为 JLINK V8。 以下详细描述使用JLINK V8下载固件到神舟III号开发板的过程。 第一步,按下图连接好JLINK V8, 神舟III号与PC机。 USB线 20PIN 排线 PC机 JLINK V8 神舟III号 第二步,在PC机上打开J-Flash ARM软件. 运行 J-Flash,界面如下 首次使用的时候应该在 File 菜单,选择 Open Project ,选择你的目标芯片: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 84 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 然后通过“File”菜单下的“Open…”来打开需要烧写的文件,可以是.bin 格式,也可以是.hex 格式, 甚至可以是.mot 格式。注意起始地址。 接下来在“Options”选择“Project settings”在弹出的对话框中,点击 CPU 标签,选择神舟 III 号使用 的处理器 STM32F103ZE。 点击 Target Interface 选择使用 JTAG 还是 SWD 接口,JLINK V8 可以选择用 JTAG 或 SWD 接口 来下载,在线调试,而这两种接口 STM32 处理器也都是支持的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 85 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 设置好之后,就可以到 Target 里面进行操作,一般步骤是先“Connect”,然后“Erase Chip”,然后 “Program”。大部分芯片还可以加密,主要的操作都在 Target 菜单下完成。为了方便操作,我们可以 直接按 F7 快捷键,自动擦除和烧录固件。 烧录完成 关于J-Flash ARM更详细的操作请参阅JLINK的用户手册。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 86 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3.2.2. 使用J-Link command 设置和查看相关调试信息 J-Link command包含了所有设置和查看相关调试信息的命令,它是基于命令行输入方式。打开 J-Link command 界面,显示JLINK的相关版本信息,如果连接了目标板,将显示目标板的状态和目标 CPU内核信息等。如下 J-Link command包含丰富的测试、查看等命令,相关命令的详细信息可在J-Linkcommand 命令行 下输入”?”号然后回车有详细的说明,操作非常方便。JLINK的其他软件暂不详细介绍,请用户自行参 阅JLINK的用户手册即可得到详细的答案。 3.3. 如何给神舟III号板供电 神舟 III 号 STM32 开发板一共支持三种供电方式,分别是: ¾ 使用 USB 供电 ¾ 使用外接电源供电 ¾ 使用 JLINK V8 供电 3.1.1. 使用USB供电 神舟 III 号支持 USB 供电方式,板上自带一个 500mA 自恢复保险丝,当电流大于 500mA 时,自 恢复保险丝起作用,防止神舟 III 号过大的工作电流损坏 PC 机 USB 接口和神舟 III 号开发板。 使用 USB 供电时,请使用随神舟 III 号配置的 USB 电缆连接开发板的 USB 接口(J6)和 PC 机 的 USB 接口,将电源开关(CON1)拨到右边,选择 USB 供电方式。在正常情况下,电源转换芯片 附近的 LED 灯(DS6),将变亮,表示神舟 III 号已经正常供电。 3.1.2. 使用外接电源供电 神舟 III 号也支持使用外接电源供电,通过电源开关 CON1 选择使用 USB 供电还是外接电源供电。 当电源开关拨向左边时,选择外接电源供电,反之,当电源开关拨向右边时,选择 USB 供电。 神舟 III 号,外接电源电压范围为 4.75V~12V,如使用外接电源供电 ,建议使用 5V 电压,1A 电 流输出的电源适配器进行供电,注意电源适配器必须内芯为电源的正极,外侧为电源的负极。如正负 极与之相反 ,可能损坏神舟 III 号开发板。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 87 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3.1.3. 使用JLINK V8供电 除了前面提到的两种供电方式外,神舟 III 号还支持 JLINK V8 供电,以下以 ARMJISHU.COM 推 出的 JLINK V8 为例,说明如何使用 JLINK V8 为神舟 III 号供电。 首先按下图连接神舟 III 号开发板,JLINK V8 与 PC 机。 USB线 20PIN 排线 PC机 JLINK V8 神舟III号 在 PC 机上打开 J-LINK Commander(注:使用 JLINK V8 时,电脑上要求安装相应的驱动,具体 驱动安装说明请见 JLINK V8 用户手册说明文档)。 在弹出的界面中,输入 power On 即可使能 JLINK V8 给 USB 供电。 说明:请勿同时使用这三种供电方式进行供电,以免多组电源同时供电,损坏神舟 III 号 STM32 开发板。 3.4. 如何通过串口下载一个固件到神舟III号开发板 STM32的程序下载有多种方法,可以通过USB、串口、JTAG、SWD等方式下载。这几种方式都 可以用来给神舟III号开发板下载程序,这里详细介绍通过串口下载固件到神舟III号开发板的过程。 硬件设置 第一步神舟III号启动模式设置为SystemBoot。将跳线JP9短接2-3,JP10短接1-2,用于串口下载。 此模式下,STM32在复位后不会执行用户代码,而是等待串口更新程序。 跳线与启动模式设置关系如下: BOOT1(J9) BOOT0(J10) 功能 嵌入式专业技术论坛 (www.armjishu.com)出品 第 88 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ANY 2-3 User Boot(默认) 2-3 1-2 System Boot 1-2 1-2 SRAM Boot STM32的串口下载一般是通过串口1下载的。 第二步,使用神舟III号配套的串口线连接PC机串口与开发板的串口1。 软件使用 接下来,我们介绍如何使用Flash_Loader_Demonstrator软件串口下载过程。 第一步:打开 神舟III号光盘\串口下载软件目录。解压 um0462_Flash_Loader_Demonstrator_V2.0_Setup.zip文件后,双击 Flash_Loader_Demonstrator_V2.0_Setup.exe安装Flash_Loader_Demonstrator软件(按缺省设置进行 安装即可)。 第二步,安装好软件后,运行Flash_Loader_Demonstrator软件, 在弹出界面的中,选择正确的PC机使用的串口号和串行通信波特率。 按上图设置好以后,注意先按开发板的复位按键后,再点击Next按键,此时,如下界面。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 89 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 浏览加载需要下载的HEX文件。 点击Next进行编程。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 90 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 至此,HEX文件已经成功下载了,为了看到程序运行的现象,我们需要将启动模式设置为User Boot 模式,即将J10的2-3脚短接。复位神舟III号开发板即可看到程序运行的实验现象。 3.5. 如何在MDK开发环境中使用JLINK在线调试 利用串口,我们只能下载程序,并不能实时跟踪,而利用调试工具,比如JLINK、ULINK等就可 以实时跟踪程序,使你的开发事半功倍。这里我们以JLINK V8为例,说说如何在线调试。 JLINK V8支持JTAG和SWD,而STM32也支持JTAG和SWD。所以,我们有2种方式可以用来调试, JTAG调试的时候,占用的IO线比较多,而SWD调试的时候占用的IO线很少,只需要2跟即可。 JLINKV8的安装我们这里就不说了,JLINK的光盘里面有详细的资料。在安装了JLINK V8之后,我 们 接 上 JLINK-V8 , 并 把 JTAG 口 插 到 神 舟 III 号 开 发 板 上 , 打 开 神 舟 III 号 光 盘 \ 源 码 \STM32F10x_StdPeriph_Lib_V3.3.0\STM32F10x_StdPeriph_Lib_V3.3.0\Project\01.LED 流 水 灯 ( 神 舟 III 号)\MDK-ARM目录下的工流水灯工程文件Project.uvproj,点击 ,打开Options for Targe‘t 神舟III号’ 选项卡,在Debug栏选择仿真工具为Cortex-M3 J-LINK,如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 91 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 点击右侧的Setting,配置JLINK 下载参数,主要是选择目标处理器的系列,添加目标芯片对应的烧写 算法。 上图中,我们使用J-LINK V8的JTAG模式调试(当然也可以进行SWD模式调试,只要我们在Port处选 择SW即可)。Max Clock,可以点击Auto Clk来自动设置,上图中JLINK自动设置最大时钟为2Mhz(注 意这里不能设置的太大,如果太大,可能导致JTAG使用不了!但SWD模式的时候,可以设置最大 10Mhz)。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 92 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 单击OK,完成此部分设置。接下来,点击Utilities,进行公共参数设置如下图所示: 在设置完之后,点击OK,然后再点击OK,回到IDE界面,编译一下工程。再点击 ,开始仿 真(如果开发板的代码没被更新过,则会先更新代码,再仿真,你也可以通过按 ,只下载代码, 而不进入仿真),如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 93 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 可以看到都是一些汇编码的查看,如果我们要快速运行到main函数,可以在main函数的第一句语句处 放入断点,然后点击 ,来快速执行到该处。如下图所示: 接下来,我们就可以和软件仿真一样的开始仿真了,不过这是真正的在硬件上的仿真,其结果更 可信。如何在MDK开发环境中使用JLINK在线仿真就介绍到这里。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 94 页,共 788 页 3.6. 神舟III号跳线含义 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3.6.1. 启动模式选择跳线 BOOT1(J9) BOOT0(J10) 功能 说明 ANY 2-3 User Boot(默认) 用主闪存存储器,即Flash启动 2-3 1-2 System Boot 系统存储器启动,用于串口下载 1-2 1-2 SRAM Boot SRAM启动,用于SRAM中调试代码 — 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原来的 地址(0x0800 0000)访问它,即闪存存储器的内容可以在两个地址区域访问,0x0000 0000或0x0800 0000。 — 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的 地址(0x1FFF F000)访问它。 — 从内置SRAM启动:只能在0x2000 0000开始的地址区访问SRAM。 使用JLINK调试下载时,请将启动模式设置为User Boot模式。 3.6.2. RS-232/RS-485选择跳线 串口2可通过跳线选择支持RS-232接口或RS-485接口,跳线定义如下: J14 J12 串口2功能选择 1-2 1-2 串口2 RS-485接口 2-3 2-3 串口2 RS-232接口 3.6.3. RTC实时时钟跳线 当安装纽扣电池时,请用跳帽将 J11 的 2-3 脚短接起来,使用 RTC 实时时钟功能; 当没有安装电池时,请用跳帽将 J11 的 1-2 脚短接起来,不使能 RTC 实时时钟功能。 3.6.4. Nand Flash访问选择跳线 当使用中断方式访问 Nand Flash 时,请用跳帽将 J13 的 1-2 脚短接起来; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 95 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 当使用查询方式访问 Nand Flash 时,请用跳帽将 J13 的 2-3 脚短接起来。 第四章 STM32神舟III号 零基础入门篇 4.1 如何从零开始新建STM32工程模板 4.1.1 如何去官网下载最新的STM32资料的方法 1、 打开网页,在百度搜索网页栏中搜索“ST”,如下图 2、点击 st 意法半导体进入 ST 官网 嵌入式专业技术论坛 (www.armjishu.com)出品 第 96 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3、点击微控制器和存储器 嵌入式专业技术论坛 (www.armjishu.com)出品 第 97 页,共 788 页 4、点击微控制器 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 5、选择 STM32-32 位的微控制器中的 F1 系列 嵌入式专业技术论坛 (www.armjishu.com)出品 第 98 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 6、选择你需要的芯片,比如 STM32F103ZET6、STM32F107VCT6,STM32F207ZGT、STM32F407ZGT 等,这 里我们用 STM32F103ZET6 做示范,如下图: 7、打开后选择 Design support 嵌入式专业技术论坛 (www.armjishu.com)出品 第 99 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 100 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 以上都是官网提供的文档资料,具体请大家登陆官网查看,比如我要下载一个最新的库,大家看 下图,这个库文件我找到了,提示说是 3.5.0 版本的库文件: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 101 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4.1.2 获取ST库源码 在新建工程模板之前,我们首先需要获取到 ST 库的源码,源码从上面的流程就可以从 ST 的官方 网站下载到,在这里我们以 V3.5.0 的库来新建我们的工程模板。 可以看到该库的版本为 3.5.0 版本,下载后 解压缩之后,真正的标准库函数就在 Libraries 文件夹中 4.1.3 开始新建工程 点击桌面 UVision4 图标,启动软件,如下图。如果是第一次使用的话会打开一个自带的 工程文件,我们可以通过工具栏 Project->Close Project 选项把它关掉。 在工具栏 Project->New μVision Project…新建我们的工程文件,我们将新建的工程文 件保存在桌面的“STM32 神舟 III 号开发板模板工程”(先在电脑 E 盘上新建一个“STM32 神 舟 III 号开发板模板工程”,在该文件夹里面新建一个 Project 文件夹,当然你也可以在其 它的盘上建,并不一定要在 E 盘),文件名取为神舟 STM32-DEMO(英文 DEMO 的意思是例子), 名字可以随取,点击保存。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 102 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 接下来的窗口是让我们选择公司跟芯片的型号,我们用 STM32 神舟 4 号的板子做举例说 明,因为我们的 STM32 神舟 III 号用的芯片是 ST 公司的 STM32F103ZET6,有 64K SRAM,512K Flash,属于高集成度的芯片。按如下选择即可。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 103 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 接下来的窗口问我们是否需要拷贝 STM32 的启动代码到工程文件中,这份启动代码在 M3 系列中都是适用的,一般情况下我们都点击是,但我们这里用的是 ST 的库,库文件里面也自 带了这一份启动代码,所以为了保持库的完整性,我们就不需要开发环境为我们自带的启动 代码了,稍后我们自己手动添加,这里我们点击否。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 104 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 此时我们的工程新建成功,如下图所示。但我们的工程中还没有任何文件,接下来我们 需要在我们的工程中添加所需文件。 在“STM32 神舟 III 号开发板模板工程”文件夹下,我们新建 3 个文件夹,分别为 Libraries、Output、Project 文件夹以及“删除 MDK 产生的过程文件.bat”文件、“readme.txt” 文件和“stm32f10x_stdperiph_lib.zip”文件;原来新建的 Project 文件夹用来存放工程文 件和用户代码,包括主函数 main.c;Libraries 用来存放 STM32 标准库里面的 CMSIS 和 STM32F10x_StdPeriph_Driver 这两个文件夹。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 105 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 把从 ST 官网下载的 stm32f10x_stdperiph_lib.zip 库函数文件压缩包,解压缩后将 \stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries 的 CMSIS 跟 STM32F10x_StdPeriph_Driver 这两个文件夹拷贝到 STM32 神舟开发板模板工程\Libraries 文件夹中。 把标准库目录下的: stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Templ ate 文件夹下的 main.c、stm32f10x_conf.h、stm32f10x_it.h、 stm32f10x_it.c 拷贝到 STM32 神舟 III 号开发板模板工程\Project 目录下。 stm32f10x_it.h、和 stm32f10x_it.c 这两个文件里面是中 断函数,里面为空,并没有写任何的中断服务程序;stm32f10x_conf.h 是用户需要配置的头文件, 当我们需要用到芯片中的某部分外设的驱动时,我们只需要在该文件下将该驱动的头文件包含进来即 可,片上外设的驱动在 Libraries\STM32F10x_StdPeriph_Driver\src 文件夹中, Libraries\STM32F10x_StdPeriph_Driver\inc 文件夹里面是它们的头文件。 stm32f10x_it.h、stm32f10x_it.c 和 stm32f10x_conf.h 这三个文件是用户在编程时需要 修改的文件,其他库文件一般不需要修改。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 106 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm 文件夹下是用汇编写的启动文件。 STM32 神舟 III 号开发板用的 CPU 是 STM32F103ZET6,有 512K Flash,属于大容量的,所以等下我们 把 startup_stm32f10x_hd.s 添加到我们的工程中。根据 ST 的官方资料:Flash 在 16~32 Kbytes 为 小容量,64~128 Kbytes 为中容量,256~512 Kbytes 为大容量,不同大小的 Flash 对应的启动文件不 一样,这点要注意。 现在我们新建的工程目录如下所示: 回到我们刚刚新建的 MDK 工程中 嵌入式专业技术论坛 (www.armjishu.com)出品 第 107 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 在 STM32-DEMO 上右键选中 Add Group…选项,新建四个组,分别命名为 start_code、project、 libraries、CMSIS。start_code 从名字就可以看得出我们是用它来放我们的启动代码的,project 用 来存放用户自定义的应用程序,libraries 用来存放库文件,CMSIS 用来存放 M3 系列单片机通用的文 件 嵌入式专业技术论坛 (www.armjishu.com)出品 第 108 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 接下来我们往我们这些新建的组中添加文件,双击哪个组就可以往哪个组里面添加文件。我们在 STARTCODE 里面添加 startup_stm32f10x_hd.s,在 project 组里面添加 main.c 文件和 stm32f10x_it.c 这 2 个文件,在 libraries 组里面添加“Libraries\STM32F10x_StdPeriph_Driver\src”里面的全部 驱动文件,当然,src 里面的驱动文件也可以需要哪个就添加哪个,这里将它们全部添加进去是为了 后续开发的方便,况且我们可以通过配置 stm32f10x_conf.h 这个头文件来选择性添加,只有在 stm32f10x_conf.h 文件中配置的文件才会被编译,。 CMSIS 组我们在“Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x”路径下添加 system_stm32f10x.c 文件(system_stm32f10x.c 是 ARM 公司提供的符合 CMSIS 标准的库文件);然后 从 Libraries\CMSIS\CM3\CoreSupport 里添加 core_cm3.c;注意,这些组里面添加的都是汇编文件 跟 C 文件,头文件是不需要添加的。最终效果如下图: 至于有些文件有个锁的图标,是因为这些都是库文件,不需要我们修改,属性为只读。 4.1.4 MDK环境设置 经过以上的一些步骤,我们的工程已经基本建好,下面来配置一下 MDK 的配置选项,点击工具栏中 的魔术棒按钮,在弹出来的窗口中选中 嵌入式专业技术论坛 (www.armjishu.com)出品 第 109 页,共 788 页 然后选择: ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 步骤 1:点击 Select Folder for Objects... 设置编译后输出文件保存的位置,我们选择 Output 文件 夹。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 110 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 步骤 2:把编译好的输出文件名定为 STM32-DEMO 步骤 3:把 Create HEX File 这个选项框也选上,表示编译输出 HEX 文件 选中选项卡,在 Define 里面输入添加 USE_STDPERIPH_DRIVER, STM32F10X_HD。 添加 USE_STDPERIPH_DRIVER 是为了屏蔽编译器的默认搜索路径,转而使用我们添加到工程中的 ST 的库,添加 STM32F10X_HD 是因为我们用的芯片是大容量的,添加了 STM32F10X_HD 这个宏之后, 库文件里面为大容量定义的寄存器我们就可以用了。芯片是小或中容量的时候宏要换成 STM32F10X_LD 或者 STM32F10X_MD。其实不管是什么容量的,我们只要添加上 STM32F10X_HD 这个宏即可,当你用小 或者中容量的芯片时,那些为大容量定义的寄存器我不去访问就是了,反正也访问不了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 111 页,共 788 页 在 Include Paths 栏点击 默认的搜索路径。 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ,在这里添加库文件的搜索路径,这样就可以屏蔽掉 嵌入式专业技术论坛 (www.armjishu.com)出品 第 112 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 但当编译器在我们指定的路径下 搜索不到的话还是会回到标准目录去搜索,就像有些 ANSIC C 的库 文件,如 stdin.h 、stdio.h。 库文件路径修改成功之后如下所示: 至此,我们的工程模板就建成了。学会新建工程,是学习 stm32 的第一步。 1.4.4 在 main.c 里输入代码,并保存,然后编译代码 /***************************************************** * 内容:STM32 神舟开发板模板工程 * 作者:www.armjishu.com * 版本:v1.0 * 日期:2013.1 ******************************************************/ int main(void) { } 嵌入式专业技术论坛 (www.armjishu.com)出品 第 113 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 可以看到编译成功,最后产生了 HEX 文件,我们的模板搭建成功! 4.1.5 使用JLINK V8仿真器硬件调试配置 这个工程默认的是软件仿真,如果开发板要用 J-LINK 调试的话,还需要在开发环境中做如下修改。 实际上,我们开发程序的时候 80%都是在硬件上调试的。 具体配置如下图所示:点击 ,在 Debug 选项里 嵌入式专业技术论坛 (www.armjishu.com)出品 第 114 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 点 Settings 按钮,查看是否识别到了目标板 CPU(注意,此处目标板应该上电,并将 JLINK V8 与模 板连接好,JLINK V8 也需要上电) 设置完点确定 下面选择 Utilities 选项卡 嵌入式专业技术论坛 (www.armjishu.com)出品 第 115 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 在选项卡 Utilities\Setting\Flash download 中我们设置成如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 116 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 因为 STM32F103ZET6 芯片的内部 ROM 大小是 512K 点击 OK 按钮 编译全部代码,然后点 LOAD 下载程序到目标板 嵌入式专业技术论坛 (www.armjishu.com)出品 第 117 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 到了这里就算是大功告成了。如果在新建工程中遇到什么问题,先不要急,可先参考 STM32 神舟系列 的其他相关资料。 4.2 理解芯片控制的原理 如果要说做单片机很难吗?其实并不难,用 3 句话就可以讲明白: 第 1 句话:芯片管脚不是输入,就是输出。 我们所有的程序,用单片机控制的产品,以及外设,无非就是控制芯片的各个管脚输入或者输出 两个状态;例如,芯片发送数据就是输出;芯片驱动一个产品,也是输出;芯片接收数据就是输入; 单片机对一个存储芯片写输入,可以理解为单片机与存储芯片连接的管脚输出状态,输出数据到存储 芯片的管脚上,而存储芯片此时它的芯片对应管脚被配置成输入,将数据写入到芯片内部。 所以说,芯片管脚不是输入,就是输出,当然,如果你不使用这个管脚,也可以将它配置成某一 种中间状态,免得干扰了外界,影响了 PCB 板上的其他元器件状态。 第 2 句话:芯片管脚不是高电平,就是低电平。 芯片管脚不是高电平就是低电平两种状态,当然也有第三种,既不高电平也不是低电平的状态, 这样的管脚状态表示没有任何内容和数据;无论管脚是输入还是输出,它的目的都是传输数据、传输 信息,所以管脚的高电平我们将它表示为“1”,低电平表示“0”,通过 0 和 1 这样的数据来传输它想 传输的内容,这个就是所谓的二进制。 例如:假如复位芯片管脚是低电平进行复位,我们将该管脚一直拉高为高电平“1”的时候,芯 片可以正常工作,如果将管脚拉低至低电平“0”的时候,芯片通过检测这个管脚状态为低电平,芯 嵌入式专业技术论坛 (www.armjishu.com)出品 第 118 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 片内部就会自动进行复位;我们通过控制这个管脚拉高和拉低,从而就可以达到控制芯片的工作;其 他的管脚也是同样的道理。 第 3 句话:传输协议。 什么是传输协议,比如与串口芯片通信,那么就要是串口协议的;如果是 I2C 协议的 EERPOM, 那么就是 I2C 协议;还有其他一些比如 485 协议,CAN 协议,USB 协议,SD 卡的 SDIO 协议……. 等等数不胜数。 而这些协议,无非就是按照预先规定的表达方式进行通信,比如举个例子,我约定先连续发 4 个 1,,然后再发 4 个 0,就表示芯片 A 要开始发数据给芯片 B 了,即芯片 A 通过它的芯片管脚发‘11110000’ 给到芯片 B 的时候,那么芯片 B 就知道芯片 A 要给它真正的数据,它就要做好准备工作,准备好之 后,芯片 B 就会给芯片 A 一个回应,当芯片 A 收到芯片 B 的回应,就正式开始发数据。 这样通信双方之间的协商规定,就构成了协议,经过这么多年,就形成了我们所常见到的串口协 议,CAN 协议,USB 协议(像 USB 协议又分为 USB1.0 协议,USB2.0 协议,USB3.0 协议,版本越 高,速度就越快,协议进行优化后,通信效率也变高了)。 不知道大家理解了没有呢?所以总结下来, 一个芯片最简单的外设莫过于 I/O 口的高低电平控 制,我们这里将详细讲解一下如何用一个 I/O 口去控制一个 LED 灯的亮灭。 4.3 芯片管脚控制LED灯原理图解释 下面有个原理图,这个原理图是用 STM32 的 PF6 管脚连 LED 灯的负极,用正 3.3V 电源端连 LED 灯的正极,再串联一个限流电阻限制电流(电阻的作用就是限流、降压;如果线路上电阻很小,那么 电压不变的情况下,电流就会变得很大,有可能会烧坏 LED 灯,所以这里我们串联一个电阻进行降 压)降压防止 LED 灯被烧掉,这个串联电阻的阻值要计算好,使得在恒定电压的情况下,电流的大 小刚好足够驱动 LED 灯点亮,点亮这个 LED 灯大概需要 10ma~20ma(毫安)的电流。 原理图中 STM32 的 PF6 管脚如何控制这个 LED1 的灯呢?可以看到,PF6 输出高电平的时候, LED 灯不会亮;只有当 PF6 输出低电平的时候,LED 灯才会点亮。所以我们想用 STM32 的管脚 PF6 去驱动 LED1 这个 LED 灯亮,只要使得 PF6 输出低电平就可以,这样就知道如何控制这个 LED 灯了。 为什么这么接呢?为什么不让 PF6 管脚接 LED 的正极,而 LED 灯的负极去接 GND 地呢?这样 嵌入式专业技术论坛 (www.armjishu.com)出品 第 119 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 才是最常规的接法不对吗?答案是当然是,但是在这里这样的接法有助于芯片的长久使用,芯片的总 体驱动能力是有限的,它可以驱动一个 LED 灯,但驱动不了 100 个,1000 个。 在这里需要重复上面已经说过的内容,首先我们要知道 LED 的发光工作条件,不同的 LED 其 额定电压和额定电流不同,一般而言,红或绿颜色的 LED 的工作电压为 1.7V~2.4V,蓝或白颜色的 LED 工作电压为 2.7~4.2V, 直径为 3mm LED 的工作电流 2mA~10mA,在这里采用绿色的 LED; STM32 单片机(如本实验板中所使用的 STM32F103ZET 芯片)的 I/O 口作为输出口时,向外输出电 流的能力是 25mA 左右,勉强是可以点亮一个发光二极管,但是如果我们用 STM32 去点亮很多个 LED 灯的时候,就有可能造成芯片本身输出电流不足(因为芯片能输出的总电流大小是恒定的)。 其次,PF6 的这种接法是一种灌电流(要 VCC 往内输入电流)的方式,这种方式使得 STM32 的 芯片管脚让一个 LED 灯亮非常轻松,利用灌电流的方式驱动发光二极管是比较常见的一种用法,无 论接多少 LED,芯片管脚的负荷都非常轻。当然,现今的一些增强型单片机,是采用拉电流输出的, 只要单片机的输出电流能力足够强即可,不过接多了也是不可取的,单片机的总体驱动电流是有限的; 上图中的电阻用的是 1K 阻值主要为了限制电流,让发光二极管的工作电流限定在 2mA~10mA。 4.4 STM32相关的芯片手册有哪些?我们如何阅读这些资料 STM32 神舟 III 号开发板的主芯片 STM32F103ZE 芯片相关的资料和例程都可以在 ST 的官方网站 上找到,STM32F103ZET6 芯片的中文网址为“ http://www.st.com/cn/mcu/product/164487.jsp”。 首先介绍两个最重要的两个文档,芯片手册和参考手册。 1、芯片手册。芯片手册在网页“DATASHEET”那一栏。芯片手册详细介绍了所选择的芯片型号的 功能规格,内核型号,运行主频,外设资源以及其性能,芯片封装种类信息以及各种封装的管脚定义, 芯片的电气特性,外设的时序要求,订购信息和器件的机械特。这份文档因为芯片型号的不同而不同, 比如 STM32F103ZE 和 STM32F103RB 和 STM32F105 以及 STM32F107 等等,他们的功能外设资源不同,所 以芯片手册都不相同。在芯片的选型阶段,这份文档是判断芯片功能和性能是否满足项目需求的关键 文档。在原理图阶段这份文档更是尤为重要。后续开发调试阶段这份文档也不可或缺。这份文档将伴 随着你从项目开始一直走到项目结束。 2、参考手册。参考手册在网页“REFERENCE MANUALS”那一栏,也称为技术参考手册。这份参考 手册是有关如何使用该产品的具体信息,包含各个功能模块的内部结构、所有可能的功能描述、各种 工作模式的使用和寄存器配置等详细信息。参考手册不涉及某个具体的芯片,他是将一个系列的芯片。 STM32F103ZE 属 于 STM32F10x 这 一 大 类 , 所 以 我 们 下 载 的 文 档 名 为 “ RM0008: STM32F101xx, STM32F102xx、STM32F103xx、STM32F105xx 和 STM32F107xx,ARM 内核 32 位高性能微控制器”。也就 是说无论你在 STM32F103RB 和 STM32F103ZE 和 STM32F105 以及 STM32F107 等芯片的网页页面下载的参 考手册都是相同的。这也注定这份文档介绍的功能资源是 STM32F10x 这一大类芯片所有功能资源的交 集。这份文档包含了 USB 接口和以太网接口的介绍,但并不表示 STM32F103RB 包含这些接口。 这两份文档都很重要,相对来说,硬件开发人员更多关注芯片手册,软件开发人员更多关注参考 手册。 其次介绍芯片相关的一些文档资料。 1、处理器内核相关文档。STM32F103ZE 芯片的性能是 ARM 公司的 Cortex-M3。所以如果需要了解 内核的资料,可以参考 ARM 公司的“Cortex™-M3 技术参考手册”以及其他 Cortex-M3 的技术书籍, 例如“ARM Cotrex-M3 权威指南”等等。 2、ST 的应用笔记“APPLICATION NOTES”。充分利用 ST 网页中的资源,可以加快产品设计调试 进度。 3、外设资源相关资料。例如 TIM 定时器、UART 串口以及 USB 等等。这些接口的资料可以参考 ST 网页中的 STM32 应用文档以及示例程序。由于很多接口都是各自的协议标准,所以可以查阅这些标准 协议的相关资料文献,例如 I2C、SPI、USB 这些都有各自的规范可以查阅。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 120 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4、相关外部芯片资料。STM32 的接口对外连接了什么器件,就需要查阅相关的文档资料。同样 是 I2C 接口,既可以连接 EEPROM 也可以连接温度传感器或其他;同样是 SPI 接口,既可以连接 DATA FLASH 也可以连接 WIFI 模块或者触摸屏等等。这些已经不属于 STM32 的范围了,所以这块资料在 STM32 的网页一般找不到,或者只能找到对应的参考设计。 5、STM32 神舟系列用户手册。 6、www.armjishu.com 论坛帖子。 7、STM32 神舟系列开发板博客:http://blog.sina.com.cn/u/1989261580 8、STM32 神舟系列开发板微博:http://weibo.com/u/1989261580 4.5 STM32芯片各个管脚是怎么控制以及被管理的?(如何阅读芯片手册) 那么我们怎么来访问这些寄存器呢? 如果是通过标准库访问,只要调用相关函数即可。 如果是寄存器操作,首先要得到寄存器的地址,寄存器的地址是芯片厂商一开始就定好了的,固 定的不能改变,大家看下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 121 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 122 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 寄存器的地址是基址+偏移量的和。基址在芯片数据手册“存储器映像”章节,正如上图那样, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 123 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 比如 Port A 的基址是’0x4001 0800’;比如 Port B 的基址是’0x4001 0c00’;比如 SPI1 的基址 是’0x4001 3000’;比如 USART3 的基址是’0x4000 4800’;以此类推。 从芯片上电后工作正常开始,所有寄存器都会有一个默认数值,保证处理器处于确定的状态。这 个初始值正如上图所描述的这样,这个重要内容我们可以在技术参考手册中获得。 现在我们打开参考手册《STM32F107 中文参考手册》 册,我们截图看看: ,可以看到这是一个 754 页的参考手 比如我们要访问 GPIO 管脚 PD2,那么首先就要找到端口 D 的位置,即 Port D,我们首先查看文档 的目录,找到第 8.2 节 GPIO 寄存器描述章节,可以看到从 113 页开始到 116 页都是描述 GPIO 端口的, 我们查看 8.2.1 节查看一下端口配置低寄存器(GPIOx_CRL),这个里的 x=A…E 表示,GPIOx_CRL 可 以是 GPIOA_CRL、GPIOB_CRL、GPIOC_CRL、GPIOD_CRL、GPIOE_CRL 中的任意一个;在这里我只关心端 口 D,就可以把它看成 GPIOD_CRL: 我们可以找到 PortD 在内存中的基地址的 0x4001 1400,控制端口 D 的各个寄存器的偏移地址应 该怎么确定呢?可以查看具体的寄存器描述(PortD 属于 GPIO 端口中的 D 端口): 嵌入式专业技术论坛 (www.armjishu.com)出品 第 124 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 可以看到该文档写了’偏移地址:0x00’,这表示 GPIOD_CRL 这个寄存器的地址等于 Port D 的位 置+偏移地址就可以算出它的地址,即: GPIOD_CRL 寄存器地址:0x40001 1400(PortB 的地址) + 0x00(GPIOx_CRL 的偏移地址) = 0x40001 1400 我们再看一个地址: GPIOD_CRH 寄存器地址:0x4001 1400(PortB 的地址) + 0x04(GPIOx_CRH 的偏移地址) = 0x40001 1404 也就是说,当我们访问 0x40001 1404 这个地址所指向的内容时,实际上就是在访问 GPIOD_CRH 这个 寄存器了,就这么简单。 4.6 STM32芯片单个管脚是怎么被控制以及被管理的?(如何阅读芯片寄存器) 这里主要是如何去查看 CPU 芯片单个管脚的寄存器表。 实际上,点亮这个 LED 灯,只需要使得我们的 STM32 芯片的 PF6 管脚输出低电平就可以了,那 么如何控制一个 PF6 管脚的状态呢? 我们来举个例子,实际上 STM32 的 PF6 管脚的状态是由 STM32 芯片内部的一些寄存器来控制 的,通过这些寄存器,可以控制将管脚配置成输出或者输入,拉高还是拉低。芯片通过获取寄存器不 同的值,对应我们的 STM32 芯片手册寄存器说明书,就可以知道芯片就相当于获得了不同的命令, 获取命令后就开始执行命令,大家可以看下图,还是看这个《STM32F103 中文参考手册》754 页的文 档: (注意:手册可以从 STM32 神舟 III 号开发板的光盘里获得) 可以看到文档的 8.2 节,注意文档目录红框里的这些寄存器,现在我们就开始仔细来研究一下它们, 这是专门描述 GPIO 寄存器的章节,具体内容大家自己打开文档阅读一下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 125 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 我们进入文档,浏览到第 113 页,我们看其中一个寄存器到底写了些什么: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 126 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 我们看到如下内容,我们逐个列出来: 1) GPIOx_CRL 这个寄存器一共是 32 个比特,从 0-31bit,有 32 个位 2) GPIOx_CRL 寄存器的偏移地址是 0x00;表示在 GPIO 端口的基地址加上这个偏移地址 0x00 就可以访问到这个寄存器的内容。 3) GPIOx_CRL 寄存器的复位值是 0x4444 4444 总共 8 个‘4’ 4) GPIOx_CRL 寄存器其中第 0、1 位和 4、5 位和 8、9 位和 12、13 位以此类推到 28、29 每两 个位为一个组,叫做 MODEy 组;主要功能是设置这个管脚是输入模式,还是输出模式(如 果是输出模式,还要确认输出速度是 10MHz、还是 2MHz、还是 50MHz) 5) GPIOx_CRL 寄存器其中第 2、3 位和 6、7 位和 10、11 位和 14、15 位以此类推到 30、31 每 两个位为一个组,叫做 CNFy 组;主要功能是设置具体哪种输入输出的模式;例如如果是管 脚输出,那么要确定是通用推挽输出模式,还是开漏输出模式,还是复用功能推挽输出模式, 还是复用功能开漏输出模式;如果是管脚输入,是模拟输入模式还是浮空输入模式,还是上 拉/下拉输入模式等。 6) 其他的寄存器也是这样查看表和状态,我们寄存器复位值是 0x4444 4444,十六制的 4 转换成 二进制是 0100,即 CNF=01,MODE=00,我们可以查表知道 MODE=00 表示这个管脚复位 后是输入模式,CNF=01 表示是浮空输入模式。 是不是看得有点头晕了,但是没有办法,我们就是通过改变这些寄存器的值来设置芯片管脚的, 使得芯片管脚按照寄存器手册里的规定来进行相应的工作;可以是输出或输入,可以是高电平或是低 电 平 ( 这 个 是 另 外 一 个 寄 存 器 来 控 制 , 大 家 可 以 对 应 看 手 册 里 的 寄 存 器 说 明 ), 从 而 达 到 我 们 嵌入式专业技术论坛 (www.armjishu.com)出品 第 127 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 控制一个 LED 灯亮和灭,像寄存器 GPIOx_CRH、GPIOx_IDR、GPIOx_ODR、GPIOx_BSRR、GPIOx_BRR、 GPIOx_LCKR 都是同样的分析和阅读方法,我们接下来再来举例子详细说明。 4.7 分析一个最简单的例程 4.7.1 硬件原理图分析 例程硬件原理图说明 现在,知道可以访问处理器所有的寄存器了,我们可以通过改写这些寄存器的值,控制芯片做不 同的功能和操作。 下面我们正式写个例程来感受一下.这个例程用 C 语言来修改这个内存地址的内容,从而控制寄 存器,通过寄存器控制 STM32 芯片的 PF6 管脚使得一个灯亮和灭的。 原理图如下,上面已经有介绍: 例程 main.c 源代码(可以直接运行): 以下是 main.c 的源文件,读者可以直接粘贴编译: /***************代码直接拷贝进去可以直接运行 开始 *********************/ #define __IO volatile typedef unsigned int uint32_t; typedef __IO uint32_t vu32; typedef unsigned short int uint16_t; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 128 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 #define GPIO_Pin_0 #define GPIO_Pin_1 #define GPIO_Pin_2 #define GPIO_Pin_3 #define GPIO_Pin_4 #define GPIO_Pin_5 #define GPIO_Pin_6 #define GPIO_Pin_7 #define GPIO_Pin_8 #define GPIO_Pin_9 #define GPIO_Pin_10 #define GPIO_Pin_11 #define GPIO_Pin_12 #define GPIO_Pin_13 #define GPIO_Pin_14 #define GPIO_Pin_15 #define GPIO_Pin_All ((uint16_t)0x0001) /*!< Pin 0 selected */ ((uint16_t)0x0002) /*!< Pin 1 selected */ ((uint16_t)0x0004) /*!< Pin 2 selected */ ((uint16_t)0x0008) /*!< Pin 3 selected */ ((uint16_t)0x0010) /*!< Pin 4 selected */ ((uint16_t)0x0020) /*!< Pin 5 selected */ ((uint16_t)0x0040) /*!< Pin 6 selected */ ((uint16_t)0x0080) /*!< Pin 7 selected */ ((uint16_t)0x0100) /*!< Pin 8 selected */ ((uint16_t)0x0200) /*!< Pin 9 selected */ ((uint16_t)0x0400) /*!< Pin 10 selected */ ((uint16_t)0x0800) /*!< Pin 11 selected */ ((uint16_t)0x1000) /*!< Pin 12 selected */ ((uint16_t)0x2000) /*!< Pin 13 selected */ ((uint16_t)0x4000) /*!< Pin 14 selected */ ((uint16_t)0x8000) /*!< Pin 15 selected */ ((uint16_t)0xFFFF) /*!< All pins selected */ #define RCC_APB2Periph_AFIO #define RCC_APB2Periph_GPIOA #define RCC_APB2Periph_GPIOB #define RCC_APB2Periph_GPIOC #define RCC_APB2Periph_GPIOD #define RCC_APB2Periph_GPIOE #define RCC_APB2Periph_GPIOF ((uint32_t)0x00000001) ((uint32_t)0x00000004) ((uint32_t)0x00000008) ((uint32_t)0x00000010) ((uint32_t)0x00000020) ((uint32_t)0x00000040) ((uint32_t)0x00000080) /************ GPIOB <*************/ typedef struct { __IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 129 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 typedef struct { __IO uint32_t CR; __IO uint32_t CFGR; __IO uint32_t CIR; __IO uint32_t APB2RSTR; __IO uint32_t APB1RSTR; __IO uint32_t AHBENR; __IO uint32_t APB2ENR; __IO uint32_t APB1ENR; __IO uint32_t BDCR; __IO uint32_t CSR; } RCC_TypeDef; /********* GPIOB 管脚的内存对应地址 *******/ #define PERIPH_BASE ((uint32_t)0x40000000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define GPIOF_BASE (APB2PERIPH_BASE + 0x1c00) #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) /************ RCC 时钟 <*************/ #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define RCC_BASE (AHBPERIPH_BASE + 0x1000) #define RCC ((RCC_TypeDef *) RCC_BASE) /************ www.armjishu.com *******/ void Delay(vu32 nCount); int main(void) //main 是程序入口 { /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 130 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0xF0FFFFFF; GPIOF->CRL |= 0x03000000; while (1) { GPIOF->BRR = GPIO_Pin_6; Delay(0x2FFFFF); GPIOF->BSRR = GPIO_Pin_6; Delay(0x2FFFFF); } } void Delay(vu32 nCount) //通过不断 for 循环 nCount 次,达到延时的目的口 { for(; nCount != 0; nCount--); } /************** 此段代码直接拷贝进去可以直接运行 结束 *******************/ 4.7.2 例程环境搭建 1. 点击桌面UVision4图标,启动软件,如下图。如果是第一次使用的话会打开一个自带的工程文件, 我们可以通过工具栏Project->Close Project选项把它关掉。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 131 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 2. 在工具栏Project->New μVision Project…新建我们的工程文件,我们将新建的工程文件保存在 “STM32神舟开发板模板工程”(先在电脑硬盘上新建一个“STM32神舟开发板模板工程”,在该 文件夹里面新建一个Project文件夹),文件名取为神舟STM32-DEMO(英文DEMO的意思是例子), 名字可以随取,点击保存。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 132 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3. 接下来的窗口是让我们选择公司跟芯片的型号,我们用的是 STM32 神舟 III 号的板子,因为我们 的 STM32 神舟 III 号用的芯片是 ST 公司的 STM32F103ZET6,有 64K SRAM,512K Flash,属于高集 成度的芯片。按如下选择即可。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 133 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4. 接下来的窗口问我们是否需要拷贝STM32的启动代码到工程文件中,这份启动代码在M3系列中都是 适用的,一般情况下我们都点击是,但我们这里用的是ST的库,库文件里面也自带了这一份启动 代码,这里我们点击否。 5. 此时我们的工程新建成功,如下图所示。但我们的工程中还没有任何文件,接下来我们需要在我 们的工程中添加所需文件。 6.可以看到目前工程里只有一个文件: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 134 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 7.新建一个 main.c 文件存放在路径 STM32 神舟 III 号开发板第 1 个例程\Project\main.c 下,然后 按照以下图标操作过程把 main.c 文件添加到工程里: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 135 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这个例程,我们将所有的代码都写到了一个 mian.c 文件,不涉及到任何库函数,也没有包含任何 的头文件,下面我们的截图: 8.把 5.61 节的代码直接全盘拷贝到 main.c 文件里 嵌入式专业技术论坛 (www.armjishu.com)出品 第 136 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 9.编译成功,我们可以看到编译后的 HEX 文件,我们可以直接在光盘中找到这个文件,直接进入 Project 文件夹,打开即可:. 嵌入式专业技术论坛 (www.armjishu.com)出品 第 137 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 10.该代码可以直接下载到神舟 III 号开发板中,按一下复位按键,可以看到 LED1 灯一亮一灭,具 体下载方式我们推荐有三种,具体下载设置请参考手册其他章节: 1)JLINK V8 仿真器下载(我们推荐) 2)ULINK2 仿真器下载 3)串口下载 11.或者直接打开我们已经编译好的例程“STM32 神舟III号开发板从零开始建立一个模板工程”,在 http://blog.sina.com.cn/s/blog_7691b90c0101edpx.html链接中,STM32 神舟III号开发板区域可 以找到。 4.7.3 实验现象 可以看到 STM32 神舟 III 号开发板的 LED3 灯一亮一灭的闪烁。 例程软件架构和代码分析(只有一个 main.c 文件) 4.7.4 代码详细分析: 分析 1:volatile 是什么?怎么用? 答:简单的说,就是不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄 存器中读取或者修改,防止从缓存处读取的值是过期了的,所以加了这个 volatile 可以保证每次读的 值绝对是实时的: 一般说来,volatile 用在如下的几个地方: 1.中断服务程序中修改的供其它程序检测的变量需要加 volatile; 2.多任务环境下各任务间共享的标志应该加 volatile; 3.存储器映射的硬件寄存器通常也要加 volatile 说明,因为每次对它的读写都可能由不同意义。 我认为这是区分 C 程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、 中断、RTOS 等等打交道,所有这些都要求用到 volatile 变量。不懂得 volatile 的内容将会带来灾 难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这 家伙是不是直正懂得 volatile 完全的重要性。 分析 2:__I、 __O 、__IO 是什么? 答:如下: __I :输入口。既然是输入,那么寄存器的值就随时会外部修改,那就不能进行优化,每次都要重新 从寄存器中读取。也不能写,即只读,不然就不是输入而是输出了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 138 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 __O :输出口,也不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那 一次输出,假如外部在两次输出中间修改了值,那就影响输出。 __IO:输入输出口,同上。 分析 3:为什么加下划线? 答:原因是避免命名冲突,一般宏定义都是大写,但因为这里的字母比较少,所以再添加下划线来区 分。这样一般都可以避免命名冲突问题,因为很少人这样命名,这样命名的人肯定知道这些是有什么 用的。 经常写大工程时,都会发现老是命名冲突,要不是全局变量冲突,要不就是宏定义冲突,所以我们要 尽量避免这些问题,不然出问题了都不知道问题在哪里。 分析 4:typedef 是什么意思,怎么使用? 答:typedef 为 C 语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部 数据类型(int,char 等)和自定义的数据类型(struct 等);在编程中使用 typedef 目的一般有两个, 一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。 1) typedef 的最简单使用,例如:typedef long byte_4;表示给已知数据类型 long 起个新名字,叫 byte_4 2) typedef 与结构结合使用 例如:typedef struct tagMyStruct { int iNum; long lLength; } MyStruct; 这语句实际上完成两个操作 操作 1:定义一个新的结构类型 tagMyStruct, struct 关键字和 tagMyStruct 一起,构成了这个结 构类型,不论是否有 typedef,这个结构都存在。我们可以用 struct tagMyStruct varName 来定义 变量,但要注意,使用 tagMyStruct varName 来定义变量是不对的,因为 struct 和 tagMyStruct 合 在一起才能表示一个结构类型。 struct tagMyStruct { int iNum; long lLength; }; 操作 2:typedef 为这个新的结构起了一个名字,叫 MyStruct。 typedef struct tagMyStruct MyStruct; 因此,MyStruct 实际上相当于 struct tagMyStruct,我们可以使用 MyStruct varName 来定 义变量。 分析 5:所以具体的 typedef 代码解释如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 139 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1)例:typedef unsigned int uint32_t; 表示使用 uint32_t 符号表示 unsigned int 符号 2)例:typedef __IO uint32_t vu32; 表示使用 vu32 符号表示 typedef __IO 符号 3)例:typedef unsigned short int uint16_t; 表示使用 uint16_t 符号表示 unsigned short int 符号 2.初始化宏定义详细分析分解: 分析 1:可以看出规律,GPIO_Pin_0、GPIO_Pin_1 到 GPIO_Pin_15 总共 16 个 define 定义每个都是 一个 16 比特(uint16_t)的对象。 每个端口都有 16 个 GPIO 管脚,比如 GPIOA,GPIOB,GPIOC 等,我们用 16bit 的位来表示,即 2 个字节,每个 bit 表示 16 个 GPIO 管脚中的一个,可以看下面 2 个寄存器,就是控制 GPIO 对应的具 体管脚是高电平还是低电平的,通过对设置对应位为 0 或为 1,就可以使得管脚的电平为高或低。 每个 GPIO_Pin_x 占用这 16 个比特中的 1 个位,其他剩余的 15 个位都是 0,这 16 个 GPIO_Pin_x 就被用来表示芯片各个不同端口的 16 个管脚,比如 PA0、PA1 一直到 PA15 分别对应 GPIO_Pin_0、 GPIO_Pin_1 到 GPIO_Pin_15,这样定义好之后具体如何使用我们后面还会再说。 #define GPIO_Pin_0 ((uint16_t)0x0001) 0000 0000 0000 0001 嵌入式专业技术论坛 (www.armjishu.com)出品 第 140 页,共 788 页 #define GPIO_Pin_1 #define GPIO_Pin_2 #define GPIO_Pin_3 #define GPIO_Pin_4 #define GPIO_Pin_5 #define GPIO_Pin_6 #define GPIO_Pin_7 #define GPIO_Pin_8 #define GPIO_Pin_9 #define GPIO_Pin_10 #define GPIO_Pin_11 #define GPIO_Pin_12 #define GPIO_Pin_13 #define GPIO_Pin_14 #define GPIO_Pin_15 #define GPIO_Pin_All ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 ((uint16_t)0x0002) 0000 0000 0000 0010 ((uint16_t)0x0004) 0000 0000 0000 0100 ((uint16_t)0x0008) 0000 0000 0000 1000 ((uint16_t)0x0010) 0000 0000 0001 0000 ((uint16_t)0x0020) 0000 0000 0010 0000 ((uint16_t)0x0040) 0000 0000 0100 0000 ((uint16_t)0x0080) 0000 0000 1000 0000 ((uint16_t)0x0100) 0000 0001 0000 0000 ((uint16_t)0x0200) 0000 0010 0000 0000 ((uint16_t)0x0400) 0000 0100 0000 0000 ((uint16_t)0x0800) 0000 1000 0000 0000 ((uint16_t)0x1000) 0001 0000 0000 0000 ((uint16_t)0x2000) 0010 0000 0000 0000 ((uint16_t)0x4000) 0100 0000 0000 0000 ((uint16_t)0x8000) 1000 0000 0000 0000 ((uint16_t)0xFFFF) 1111 1111 1111 1111 分析 2:这里是定义 GPIO 端口 F 的一些初始化变量,后面那些具体的地址需要查看芯片参考手册 嵌入式专业技术论坛 (www.armjishu.com)出品 第 141 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 1)定义总线的基地址(这个需要参考手册) #define PERIPH_BASE ((uint32_t)0x40000000) 2)APB2PERIPH_BASE(APB2 时钟总线)的地址是在总线基地址上加多 0x10000,刚好就是上图的 AFIO 寄存器地址,具体可以看参考手册 #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) 3)定义 GPIO 端口 F 的基地址,该地址是 0x4001 2000。 #define GPIOD_BASE (APB2PERIPH_BASE + 0x2000) 4)定义一个 GPIO_TypeDef 的 struct 结构,从 GPIO 端口 F 的基地址开始进行覆盖 #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) 分析 3:这里是初始化 RCC 时钟总线的基地址,详细分析与上面同原理,具体的地址需要查看芯片参 考手册 分析 4:设置端口的偏移量,后面我们会详细解释 3.定义这两个结构体与芯片参考手册中的寄存器进行对应,芯片参考手册中对应的寄存器都是 32bit 嵌入式专业技术论坛 (www.armjishu.com)出品 第 142 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 的,所以在这个结构体的各个对象都被定义成 uint32_t 类型,并且是__IO 类型,表示每次操作寄存 器都是实时获取数据: 4.下面是 main 函数的剖析,总共来说分为 4 个步骤,下面一一介绍: 步骤 1:使能 APB2 总线的时钟。 对 GPIO 的端口 F 时钟使能,这个是芯片厂家所规定的操作,我们先按照这样来操作就可以,具 体实现方式也是将对应 GPIOF 寄存器使能,同时,也有 RCC,串口接口,CAN 接口,485 接口等时 钟的使能寄存器,使用前都需要先对时钟总线使能的。 使能操作完毕,就相当于我们对要使用的这个接口功能进行使能和激活,每个接口在使用前都必 须要求使能和激活,只有激活后才可以使用。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 143 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 步骤 2:配置 GPIO 端口的状态。 输入还是输出,速度多少,和大家可以参考对应的芯片寄存器手册,可以看到我们将 PB2 设置 成‘00:通用推挽输出模式’并且速度是‘11:输出模式,最大速度 50MHz’ 具体可以参考 GPIOF_CRL 寄存器,我们将这个寄存器设置为了 0x0300 0000。 步骤 3:进入 while 死循环 可以使得我们的点灯程序一直不会退出,达到重复一亮一灭的功能。 步骤 4:GPIO 输入和输出使得灯亮灭 GPIOF_BSRR 对应位设置 1,可以使得对应管脚的 ODR 位为 1;GPIO_BRR 的对应位设置 1,可 以使得对应管脚的 ODR 位为 0 那么 ODR 位是什么呢?这个就是端口输出数据寄存器 GPIOF_ODR,实际上这个寄存器里的对 应位的变化才是真正 GPIO 管脚高低电平的变化;而寄存器 GPIOF_BSRR 和寄存器 GPIOF_BRR 则可 以间接影响到它。 当然上面程序,我们也可以改成直接操作 GPIOF_ODR 的代码,这个留个大家来做练习吧。 4.7.5 程序代码详细说明 代码的定义和声明如何与芯片内部资源挂钩 C 语言程序代码如何真正访问芯片内部寄存器的呢?大家看下面这些定义: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 144 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 通过这几个 define 可以算出来一下地址: GPIOF= 0x4000 0000 + 0x1 0000 + 0x1C00 = 0x4001 1C00 刚好与 PortF 在内存中的位置对应上 RCC = 0x4000 0000 + 0x2 0000 + 0x1000 = 0x4002 1000 刚好也与 RCC 在内存中的位置对应上 更多内存映射可以找 STM32F10XXX 的数据手册资料,如下图,可以详细的进行了解了解: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 145 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 146 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 通过以上这个存储器映像图,我们就可以通过代码与存储器地址关联起来了。 4.7.6 代码如何映射到芯片内部的寄存器 这也是从库函数中摘抄出来的一种实现方式,我们通过 struct 结构可以完成对 GPIO,RCC 等外设 模块中各个寄存器的管理,比如,一个 GPIO 模块中,有很多个寄存器,我们可以用 C 语言中的 struct 来对应这些寄存器。 在芯片中,一个寄存器连着一个寄存器,每个寄存器都是 32 位的(4 个字节);我们在 struct 结构中的成员每个也都是 32 位的,一个连着一个,刚好一一对应,大家可以看下图: 可以看到上图,每个寄存器都是 32 位的,左边是而且顺序刚好分别对应,结构体是会分配内存的, 这样这些 C 语言中的 struct 结构体中定义的成员会对应映射到对应的寄存器上,那么我们就可以通 嵌入式专业技术论坛 (www.armjishu.com)出品 第 147 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 过操纵程序中的该结构体的对应成员,就相当于操作的是对应的寄存器,这个是 C 语言和单片机软硬 件对应上的又一大关键点,请不熟悉的读者好好理解一下,如实在不理解,可以致电 STM32 神舟系列 开发板的官方工程师。 4.7.7 Main函数寄存器级分析(重点) 1.LED 灯为什么会一亮一灭呢? 我们看一下参考手册中的 GPIOx_BRR 和 GPIOx_BSRR 两个寄存器: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 148 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 分析1:从以上两个寄存器里的内容可以知道到: z ODRy = 1就会输出高电平,如果是高电平,我们查看了原理图,这个LED灯灭,可以通过操作 GPIOx_BSRR寄存器的对应位来改变 z ODRy = 0就会输出低电平,如果是低电平,我们查看了原理图,这个LED灯亮,可以通过操作 GPIOx_BRR寄存器的对应位来改变 分析2:进一步分析,我们如何通过代码来改变这个ODRy呢?大家请看下面: z 代码GPIOF->BRR = GPIO_Pin_6;可以使得GPIOx_BRR寄存器的BR6位为1,这样就是的GPIO端口F 的对应ODR6=0,即PF6管脚输出低电平,使得LED1亮。 z 代码GPIOF->BSRR = GPIO_Pin_6;可以使得GPIOx_BSRR寄存器的BS6位为1,这样就是的GPIO端口F 的对应ODR6=1,即PF6管脚输出高电平,使得LED1灭。 2.要使用 PB2 管脚需要做哪些初始化的工作呢? 分析1:使能APB2总线上的GPIO端口F的时钟,我们可以看下系统图,可以看到GPIOF是属于APB2总线 管理的,那么如何初始化这个是ST公司要求的,而不是我们STM32神舟系列开发板官方规定的,一切 都是STM32芯片厂家ST公司制定的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 149 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 分析 2:代码 RCC->APB2ENR |= RCC_APB2Periph_GPIOF;是使能 GPIOF 的时钟,我们找到寄存器 RCC_APB2ENR,仔细看看是什么操作的 点击进入文档第 61 页可以看到 6.3.7 节,可以看到 GPIOF 端口的时钟设置选项: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 150 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 我们通过代码 RCC->APB2ENR |= RCC_APB2Periph_GPIOF;来对 RCC_APB2ENR 寄存器的位 3 进行操作置位,那么 RCC_APB2Periph_GPIOF 的值请见: 代码:#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080) 从这句代码可以知道 0x00000080 的 8 化成二进制是 1000,刚好是对 RCC->APB2ENR 寄存器也就是 RCC_APB2ENR 寄存器的第 7 位置位,使得 IOPF EN 为 1,使得 IO 端口 F 时钟使能。 分析 3:配置 GPIO 端口 F 的工作模式,我们这里可以看到它配置改变了 CRL 这个寄存器。 我们找到这个 CRL 寄存器完整的名称叫 GPIOx_CRL 寄存器的内容: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 151 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 我们开始分析一下代码: z GPIOF->CRL &= 0xF0FFFFFF; GPIOF->CRL &= 0xF0FFFFFF = 1111 0000 1111 1111 1111 1111 1111 1111 可以看到将 CRL 寄存器的第 24、25、26、27 位清 0,其他位默认值不变,看上表可以知道,这 4 位刚好是管脚 PF6 的配置寄存器 z GPIOB->CRL |= 0x03000000 GPIOF->CRL |= 0x03000000 = 0000 0011 0000 0000 0000 0000 0000 0000 可以看到将 CRL 寄存器的第 24、25、26、27 位 分别 置成 0、0、1、1,其他位的 GPIO 端口值都清 0,意思就是只配置 PF6 这个管脚,其他 PF 口的管 脚配置寄存器都全部变成 0,这样 CNF6=00;MODE6=11;查表可以知道: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 152 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这样配置后 PF6 被配置成输出模式,输出速度为 50MHz,状态是通用推挽输出模式;因为我们 这个例程中需要点 LED1 灯,这是一种输出模式。 4.7.8 函数与我们这个例程之间的关系 库函数同我们这个例程的原理是一样,后续的例程,都是源自库函数的,阅读原理一样,只是我 们将一些相关功能比较密切的代码封装到一起,变成一个完整的函数。 后续该神舟文档还会升级,库函数分析版本请见下个版本的书籍。 4.8 STM32重映射功能 4.8.1 什么是STM32的重映射 就好像乾坤大挪移,移动穴位,把芯片这个管脚的功能移到另外一个管脚上。 重映射的作用简单的说就是把管脚的外设功能映射到另一个管脚,但是不是可以随便映射的,具 体对应关系参考手册上的管脚说明。比如 USART2_TX 默认在 PA2 管脚,当启用复用功能后就会将 PD5 管脚作为 USART2_TX。 4.8.2 所有的管脚都可以重映射吗 大部分都可以,但不是所有的管脚功能都能重映射,比如 ADC1_IN0 就只能在 PA0,这个具体要 看芯片的数据手册。 4.8.3 为什么要有STM32重映射这个功能 我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固定不变的,为 了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即 一个外设的引脚除了具有默认的脚位外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映 射到其它的脚 位。 比如设计的这个电路板,要 3 个串口接口,并且这 2 个串口要连在一起,那么 STM32 芯片本身 的 2 个串口接口的管脚分布到各处的,如果按照实际管脚功能来设计电路板,可能不太好走线,这样 可以通过重映射的功能,把另外好连的管脚连在一起,我们通过程序去把原来不是串口的管脚初重映 嵌入式专业技术论坛 (www.armjishu.com)出品 第 153 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 射成串口即可;这样就只需要修改软件就可以,根本不用改变硬件,这样就增加了芯片的灵活性,也 增加了硬件设计者以及产品的灵活性。 4.8.4 举例说明 在这里我们随便举一个例子,可能我们的芯片不是这个型号,但是都是同样的原理,就跟九阳神 功一样,神舟团队认为,这样举的例子才更有可重用性,你学懂了就是真的懂了,大家可以查看一下 STM32 芯片手册,我们这里举的是 STM32F103xC 中有关 USART3 引脚的摘要片段: 从这里可以看出,USART3_TX 的默认引出脚是 PB10,USART3_RX 的默认引出脚是 PB11;但 经过重映射后,可以变更 USART3_TX 的引出脚为 PD8,变更 USART3_RX 的引出脚为 PD9。 STM32 中的很多内置外设都具有重映射的功能,比如 USART、定时器、CAN、SPI、I2C 等,详 细请看 STM32 参考手册(RM0008)和 STM32 数据手册。 有些模块(内置外设)的重映射功能还可以有多种选择,下面是 RM0008 上有关 USART3 输入输出 引脚的重映射功能表: 从这个表中可以看出,USART3 的 TX 和 RX 引脚默认的引出脚位是 PB10 和 PB11,根据配置位 的设置,可以重映射到 PC10 和 PC11,还可以重映射到 PD8 和 PD9。 4.8.5 深入分析STM32重映射内部架构原理 一个模块的功能引脚不管是从默认的脚位引出还是从重映射的脚位引出,都要通过 GPIO 端口模 块实现,相应的 GPIO 端口必须配置为输入(对应模块的输入功能,如 USART 的 RX)或复用输出(对应 模块的输出功能,如 USART 的 TX),对于输出引脚,可以按照需要配置为推挽复用输出或开漏复用 输出。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 154 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这里就好比,你可以把土地的白菜移到另外一块有土的菜地,它还是可以继续茁壮的成长;但你 不能把白菜放在被子里睡觉,让它跟你一样成长,至少要有最基本的土壤;在 STM32 里,一个芯片 管脚无非就是输入或者输出,这个基本的属性一定要配对,一个串口打印输出,如果你把管脚配置成 输入,那一定是不行的,也不可能配置成功的。 上图是 STM32 的 GPIO 端口模块,使用复用功能时的配置。从图中可以看出,配置为复用输出 时,该端口对应的 GPIO 输出功能将不起作用。例如当配置 PB10 对应的引脚为复用输出功能时,操 作 PB10 对应的输出寄存器将不影响引脚上的信号。 从图中还可以看出,普通的 GPIO 端口输入功能与复用的输入功能的配置方式没有分别,这意味 着在使用引脚的复用输入功能时,可以在这个引脚的输入寄 存器上读出引脚上的信号。例如在使能 了 USART3 模块时,可以读 GPIOB_IDR 寄存器,得到 PB11 信号线上的当前状态。 有不少引脚上配备了来自多个模块的复用功能引出脚,例如本文第一张图中显示的 PB10,默认 复用功能就有 I2C2_SCL 和 USART3_TX 两个功能,TIM2 重映射后,TIM2_CH3 也使用 PB10 的复用 功能。 在使用引脚的复用功能时,需要注意在软件上只可以使能一个外设模块,否则在引出脚上可能产 生信号冲突。例如,如果使能了 USART3 模块,同时没有 对 USART3 进行重映射配置,则不可以使 能 I2C2 模块;同理如果需要使用 I2C2 模块,则不能使能 USART3 模块。但是如果配置了 USART3 的引 脚重映射,USART3 的 TX 和 RX 信号将从 PC10 和 PC11,或 PD8 和 PD9 引出,避开了 I2C2 使用的 PB10 和 PB11,这时就可以同时使用 I2C2 模块和 USART3 模块了。 USART3 模块共有 5 个信号,分别为 TX、RX、CK、CTS 和 RTS,从上面给出的第二张图中可 以看出,重映射是对所有信号同时有效。 这 5 个信号中,在使能了 USART3 模块后,只有 TX 和 RX 是始终与对应的引出脚相连,而其它 3 个信号分别有独立的控制位,控制它们是否与外部引脚 相连,如果程序中不使用某个信号的功能, 则可以关闭这个信号的功能,对应的引脚可以做为其它功能的引出脚。例如,当关闭了 USART3 的 CK、CTS 和 RTS 功能并且没有重映射 USART3 时,PB12、PB13 和 PB14 可以作为通用输入输出端口使用,也可以作为其它模块的复用功能引出脚。 下面这张图是一个内部控制连接的等效示意图,它并不表示真正的内部连接,但可以有效地帮助 嵌入式专业技术论坛 (www.armjishu.com)出品 第 155 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 理解重映射和复用引脚的概念。图中右边引出的信号,分别连接到了本文第三张图的输入输出模块。 4.8.6 STM32重映射关键指点 这里所说明的原理,如果没看明白没有关系,可以先继续往下学习,这样的概念有个映像就可以,这 个知识说明透彻之后,其他的只能在实际的代码中学习;你完全可以打开 STM32 的芯片手册,然后 请注意观察那些管脚第一个主功能,以及重映射功能是什么,然后看看代码如何去控制他们的,有疑 问再回来查看这一个章节,这才是真正的学习成功之道。 4.9 STM32的内存管理研究(KEIL编程环境下) 4.9.1 研究意义 4.9.2 举例说明并详细分析 嵌入式专业技术论坛 (www.armjishu.com)出品 第 156 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 非常简单的一个工程,没有用到任何 IO 操作,与 STM32 有关的仅仅只有芯片的选择,即其 SRAM 大小有区别。上图是工程示意图,从图中可以看出,除了自己编写的代码外,仅仅增加了 2 个文件, 即 system_stm32f10x.c 和 startup_stm32f10x_hd.s,其中为了对 startup_stm32f10x_hd.s 进行修改,将其 从库文件夹复制到了项目文件夹中。 4.9.3 举例分析 代码 1 int main() { int a,b,c,d; a=10;b=20; c=a+b; for(;;); } myex1.c(3): warning: #550-D: variable "c" was set but never used linking... Program Size: Code=796 RO-data=336 RW-data=20 ZI-data=1636 FromELF: creating hex file... "myex1.axf" - 0 Error(s), 1 Warning(s). 代码 2 int main() { const int x=16; int a,b,c,d; a=10;b=20; c=a+b; for(;;); } myex1.c(2): warning: #177-D: variable "x" was declared but never referenced myex1.c(3): warning: #550-D: variable "c" was set but never used 嵌入式专业技术论坛 (www.armjishu.com)出品 第 157 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 linking... Program Size: Code=800 RO-data=336 RW-data=20 ZI-data=1636 FromELF: creating hex file... "myex1.axf" - 0 Error(s), 2 Warning(s). 说明: (1)Code 增加了 4 字节 (2)其余没有任何变化 代码 3 int main() { const int x=16; int myArry[100]; int i; int a,b,c,d; a=10;b=20; c=a+b; for(i=0;i<100;i++) myArry[i]=i; for(;;); } myex1.c(2): warning: #177-D: variable "x" was declared but never referenced myex1.c(3): warning: #550-D: variable "myArry" was set but never used myex1.c(5): warning: #550-D: variable "c" was set but never used myex1.c(5): warning: #177-D: variable "d" was declared but never referenced linking... Program Size: Code=816 RO-data=336 RW-data=20 ZI-data=1636 FromELF: creating hex file... "myex1.axf" - 0 Error(s), 4 Warning(s). 分析:程序中增加了数组 myArry,Code 增加为 816 字节,但是 RO-data 等仍未变化 代码 4 int main() { const int x=16; int myArry[100]={1,2,3,4,5,6}; int i; int a,b,c,d; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 158 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 a=10;b=20; c=a+b; for(i=0;i<100;i++) myArry[i]=i; for(;;); } myex1.c(2): warning: #177-D: variable "x" was declared but never referenced myex1.c(3): warning: #550-D: variable "myArry" was set but never used myex1.c(5): warning: #550-D: variable "c" was set but never used myex1.c(5): warning: #177-D: variable "d" was declared but never referenced linking... Program Size: Code=1024 RO-data=360 RW-data=20 ZI-data=1636 FromELF: creating hex file... "myex1.axf" - 0 Error(s), 4 Warning(s). 分析: (1)由于 myArry 作了初始化,因此 RO-data 增加了 360-336=24 字节。原因是 32 位机中 int 型 变量是 32 位的,占 4 字节,所以初始 6 个值后,增加了 24 字节。 (2)再增加初始化变量的数量,则 RO-data 随之增加,而 Code 不再变化,也就是 Code 由代码 3 的 816 字节增加到 1024 字节,是增加了初始化处理的代码量。 根据以上分析,似乎与已知资料有冲突。 *************************************************** RO 是程序中的指令和常量 RW 是程序中的已初始化变量 ZI 是程序中的未初始化的变量 由以上 3 点说明可以理解为: RO 就是 readonly, RW 就是 read/write, ZI 就是 zero **************************************************** 如果按此说明,增加变量应该增加 RO,但从代码 1 到代码 2 的变化来看,仅是增加了 Code,却 没有增加 RO。 初始化变量时,应该增加 RW,但是从代码 2~代码 4,RW 却没有任何变化。 看来这个说法只能适用于 ARM 芯片,即运行时需要将代码调入 RAM 运行的芯片,对于 STM32 这类芯片并不完全适用。 4.9.4 观察堆栈 1) 当使用 int myArray[300]时: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 159 页,共 788 页 2) 当使得 int myArray[100]时: ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 3) 当使得 int myArray[450]时: 当然,执行是错误的,当 int myArray[409]时:正指向 0x2000000,去掉其他变量,对于这个地址 没有影响; 堆栈应该是向下生成的,而且与芯片无关,无论选择 6K RAM 还是 48K RAM 都是如此,且当数 组再大时,就会将地址置于小于 0x2000000 的地址,但编译并不报错。 4)代码 5 int myArray[400]={1,2,3,4,5,6,7,8,9,10,11,12,13,14}; int main() { const int x=16; int a,b,c,d; int i; a=10;b=20; c=a+b; for(i=0;i<100;i++) myArray[i]=i; for(i=0;i<100;i++) c+=myArray[i]; d+=x; for(;;); } 编译结果: compiling myex1.c... linking... Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636 FromELF: creating hex file... "myex1.axf" - 0 Error(s), 0 Warning(s). 分析: 本段程序将数组作为全局变量来定义,情况立即发生了变化。RW-data 变成了 1620。其中的 1600 应该是这个数组增加的 4*400=1600,而 20 则是代码 1~代码 4 中一直都有的。 经查验资料,栈的大小应该在启动代码中修改。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 160 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 更改这个:startup_stm32f10x_hd.s 可以更改栈的大小。 RO 是程序中的指令和常量(Code + RO Data);RW 是程序中的已初始化变量;ZI 是程序中的未初 始化的变量;由以上 3 点说明可以理解为: 1)RO 就是 readonly, 2)RW 就是 read/write, 3)ZI 就是 zero 简单的说就是在烧写完的时候是:FLASH 中:Code+RO Data+RW Data,运行的时候:RAM: RW Data + ZI Data,当然还要有堆栈的空间。 Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636 FLASH 占 Total ROM Size (Code + RO Data + RW Data) = 876 + 336 +1620 = 2832 = 2.8KB SRAM 占 Total RW Size (RW Data + ZI Data) = 1620 + 1636 = 3256 = 3.3KB 如果你对 ZI-Data 理解还有疑问,可以尝试一下: int myArray[400]={1,2,3,4,5,6,7,8,9,10,11,12,13,14}; 会增加 RW, 但是 int myArray[400]={0}; 就可以 增加 ZI 了。 4.10 STM32芯片加密解密 4.10.1 关于芯片加密的定义 芯片解密是指从已经被加密了的芯片里,把存储的代码拷贝出来。嵌入了程序代码的芯片有很多 种,而 MCU 只是其中一种。单片机(MCU)一般都有内部 EEPROM/FLASH 供用户存放程序和工作 数据。为了防止未经授权访问或拷贝单片机的机内程序,大部分单片机都带有加密锁定位或者加密字 节,以保护片内程序。如果在编程时加密锁定位被使能(锁定),就无法用普通编程器直接读取单片 机内的程序,这就叫单片机加密或芯片加密。单片机攻击者借助专用设备或者自制设备,利用单片机 芯片设计上的漏洞或软件缺陷,通过多种技术手段,就可以从芯片中提取关键信息,获取单片机内程 序这就叫芯片解密。 芯片解密又叫单片机解密,单片机破解,芯片破解,IC 解密,但是这严格说来这几种称呼都不 科学,但已经成了习惯叫法,我们把 CPLD 解密,DSP 解密都习惯称为芯片解密。单片机只是能装载 程序芯片的其中一个类。能烧录程序并能加密的芯片还有 DSP,CPLD,PLD,AVR,ARM 等。也有 专门设计有加密算法用于专业加密的芯片或设计验证厂家代码工作等功能芯片,该类芯片也能实现防 止电子产品复制的目的。 4.10.2 关于芯片解密方法的理论总结 1.软件攻击 嵌入式专业技术论坛 (www.armjishu.com)出品 第 161 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 该技术通常使用处理器通信接口并利用协议、加密算法或这些算法中的安全漏洞来进行攻击。软 件攻击取得成功的一个典型事例是对早期 ATMEL AT89C 系列单片机的攻击。攻击者利用了该系列单 片机擦除操作时序设计上的漏洞,使用自编程序在擦除加密锁定位后,停止下一步擦除片内程序存储 器数据的操作,从而使加过密的单片机变成没加密的单片机,然后利用编程器读出片内程序。 至于在其他加密方法的基础上,可以研究出一些设备,配合一定的软件,来做软件攻击。 近期国内出现了一种泰斗科技 51 芯片解密设备(成都一位高手搞出来的),这种解密器主要针对 SyncMos. Winbond,在生产工艺上的漏洞,利用某些编程器定位插字节,通过一定的方法查找芯片中是 否有连续空位,也就是说查找芯片中连续的 FF FF 字节,插入的字节能够执行把片内的程序送到片外 的指令,然后用解密的设备进行截获,这样芯片内部的程序就被解密完成了。 2.电子探测攻击 该技术通常以高时间分辨率来监控处理器在正常操作时所有电源和接口连接的模拟特性,并通过 监控它的电磁辐射特性来实施攻击。因为单片机是一个活动的电子器件,当它执行不同的指令时,对 应的电源功率消耗也相应变化。这样通过使用特殊的电子测量仪器和数学统计方法分析和检测这些变 化,即可获取单片机中的特定关键信息。 至于 RF 编程器可以直接读出老的型号的加密 MCU 中的程序,就是采用这个原理。 3.过错产生技术 该技术使用异常工作条件来使处理器出错,然后提供额外的访问来进行攻击。使用最广泛的过错 产生攻击手段包括电压冲击和时钟冲击。低电压和高电压攻击可用来禁止保护电路工作或强制处理器 执行错误操作。时钟瞬态跳变也许会复位保护电路而不会破坏受保护信息。电源和时钟瞬态跳变可以 在某些处理器中影响单条指令的解码和执行。 4.探针技术 该技术是直接暴露芯片内部连线,然后观察、操控、干扰单片机以达到攻击目的。 为了方便起见,人们将以上四种攻击技术分成两类,一类是侵入型攻击(物理攻击),这类攻击 需要破坏封装,然后借助半导体测试设备、显微镜和微定位器,在专门的实验室花上几小时甚至几周 时间才能完成。所有的微探针技术都属于侵入型攻击。另外三种方法属于非侵入型攻击,被攻击的单 片机不会被物理损坏。在某些场合非侵入型攻击是特别危险的,这是因为非侵入型攻击所需设备通常 可以自制和升级,因此非常廉价。 大部分非侵入型攻击需要攻击者具备良好的处理器知识和软件知识。与之相反,侵入型的探针攻 击则不需要太多的初始知识,而且通常可用一整套相似的技术对付宽范围的产品。因此,对单片机的 攻击往往从侵入型的反向工程开始,积累的经验有助于开发更加廉价和快速的非侵入型攻击技术。 4.10.3 常规芯片解密过程 侵入型攻击的第一步是揭去芯片封装(简称“开盖”有时候称“开封”,英文为“DECAP”, decapsulation)。有两种方法可以达到这一目的:第一种是完全溶解掉芯片封装,暴露金属连线。第二 种是只移掉硅核上面的塑料封装。第一种方法需要将芯片绑定到测试夹具上,借助绑定台来操作。第 二种方法除了需要具备攻击者一定的知识和必要的技能外,还需要个人的智慧和耐心,但操作起来相 对比较方便,完全家庭中操作。 芯片上面的塑料可以用小刀揭开,芯片周围的环氧树脂可以用浓硝酸腐蚀掉。热的浓硝酸会溶解 掉芯片封装而不会影响芯片及连线。该过程一般在非常干燥的条件下进行,因为水的存在可能会侵蚀 已暴露的铝线连接 (这就可能造成解密失败)。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 162 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 接着在超声池里先用丙酮清洗该芯片以除去残余硝酸,并浸泡。 最后一步是寻找保护熔丝的位置并将保护熔丝暴露在紫外光下。一般用一台放大倍数至少 100 倍 的显微镜,从编程电压输入脚的连线跟踪进去,来寻找保护熔丝。若没有显微镜,则采用将芯片的不 同部分暴露到紫外光下并观察结果的方式进行简单的搜索。操作时应用不透明的纸片覆盖芯片以保护 程序存储器不被紫外光擦除。将保护熔丝暴露在紫外光下 5~10 分钟就能破坏掉保护位的保护作用, 之后,使用简单的编程器就可直接读出程序存储器的内容。 对于使用了防护层来保护 EEPROM 单元的单片机来说,使用紫外光复位保护电路是不可行的。 对于这种类型的单片机,一般使用微探针技术来读取存储器内容。在芯片封装打开后,将芯片置于显 微镜下就能够很容易的找到从存储器连到电路其它部分的数据总线。由于某种原因,芯片锁定位在编 程模式下并不锁定对存储器的访问。利用这一缺陷将探针放在数据线的上面就能读到所有想要的数 据。在编程模式下,重启读过程并连接探针到另外的数据线上就可以读出程序和数据存储器中的所有 信息。 还有一种可能的攻击手段是借助显微镜和激光切割机等设备来寻找保护熔丝,从而寻查和这部分 电路相联系的所有信号线。由于设计有缺陷,因此,只要切断从保护熔丝到其它电路的某一根信号线 (或切割掉整个加密电路)或连接 1~3 根金线(通常称 FIB:focused ion beam),就能禁止整个保护 功能,这样,使用简单的编程器就能直接读出程序存储器的内容。 虽然大多数普通单片机都具有熔丝烧断保护单片机内代码的功能,但由于通用低档的单片机并非 定位于制作安全类产品,因此,它们往往没有提供有针对性的防范措施且安全级别较低。加上单片机 应用场合广泛,销售量大,厂商间委托加工与技术转让频繁,大量技术资料外泻,使得利用该类芯片 的设计漏洞和厂商的测试接口,并通过修改熔丝保护位等侵入型攻击或非侵入型攻击手段来读取单片 机的内部程序变得比较容易。 4.10.4 增加芯片解密难度的一些建议总结 任何一款单片机从理论上讲,攻击者均可利用足够的投资和时间使用以上方法来攻破。这是系统 设计者应该始终牢记的基本原则。因此,作为电子产品的设计工程师非常有必要了解当前单片机攻击 的最新技术,做到知己知彼,心中有数,才能有效防止自己花费大量金钱和时间辛辛苦苦设计出来的 产品被人家一夜之间仿冒的事情发生。根据解密实践提出下面建议: (1)在选定加密芯片前,要充分调研,了解芯片解密技术的新进展,包括哪些单片机是已经确认可 以破解的。尽量不选用已可破解或同系列、同型号的芯片选择采用新工艺、新结构、上市时间较短的 单片机,如可以使用 ATMEGA88PA,这种国内破解的费用一需要 6K 左右,另外相对难解密的有 ST12 系列,dsPIC30F 系列等;其他也可以和 CPLD 结合加密,这样解密费用很高,解密一般的 CPLD 也要 1 万左右。 (2)尽量不要选用 MCS51 系列单片机,因为该单片机在国内的普及程度最高,被研究得也最透。 (3)产品的原创者,一般具有产量大的特点,所以可选用比较生僻、偏冷门的单片机来加大仿冒者 采购的难度,选用一些生僻的单片机,比如 ATTINY2313,AT89C51RD2,AT89C51RC2,motorola 单片 机等比较难解密的芯片,目前国内会开发使用熟悉 motorola 单片机的人很少,所以破解的费用也相当 高,从 3000~3 万左右。 (4)在设计成本许可的条件下,应选用具有硬件自毁功能的智能卡芯片,以有效对付物理攻击;另 外程序设计的时候,加入时间到计时功能,比如使用到 1 年,自动停止所有功能的运行,这样会增加 破解者的成本。 (5)如果条件许可,可采用两片不同型号单片机互为备份,相互验证,从而增加破解成本。 (6)打磨掉芯片型号等信息或者重新印上其它的型号,以假乱真(注意,反面有 LOGO 的也要抹掉, 很多芯片,解密者可以从反面判断出型号,比如 51,WINBOND,MDT 等)。 (7)可以利用单片机未公开,未被利用的标志位或单元,作为软件标志位。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 163 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 (8)利用 MCS-51 中 A5 指令加密,其实世界上所有资料,包括英文资料都没有讲这条指令,其实这是 很好的加密指令,A5 功能是二字节空操作指令加密方法在 A5 后加一个二字节或三字节操作码,因为 所有反汇编软件都不会反汇编 A5 指令,造成正常程序反汇编乱套,执行程序无问题仿制者就不能改变 你的源程序。 (9)你应在程序区写上你的大名单位开发时间及仿制必究的说法,以备获得法律保护;另外写上你的 大名的时候,可以是随机的,也就是说,采用某种算法,外部不同条件下,你的名字不同,比如等, 这样比较难反汇编修改。 (10)采用高档的编程器,烧断内部的部分管脚,还可以采用自制的设备烧断金线,这个目前国内几 乎不能解密,即使解密,也需要上万的费用,需要多个母片。 (11)采用保密硅胶(环氧树脂灌封胶)封住整个电路板,PCB 上多一些没有用途的焊盘,在硅胶中 还可以掺杂一些没有用途的元件,同时把 MCU 周围电路的电子元件尽量抹掉型号。 (12)对 SyncMos,Winbond 单片机,将把要烧录的文件转成 HEX 文件,这样烧录到芯片内部的程序空 位自动添 00,如果你习惯 BIN 文件,也可以用编程器把空白区域中的 FF 改成 00,这样一般解密器也 就找不到芯片中的空位,也就无法执行以后的解密操作。 (13)比较有水平的加密例如:18F4620 有内部锁相环可以利用 RC 震荡产生高精度的时钟,利用上电 时擦除 18F4620 的内部数据,所以导致解密出来的文件根本不能用。 (14) NEC 系列单片机作为日系芯片的代表,单片机中设计了充足的保护措施来保证其程序代码的安 全,同时,该系列单片机没有 PROGRAM READ 功能,因此无法利用编程器将程序读出。(注:用编 程器给芯片编程时的校验功能并不是将程序读出来进行校验,而是编程器将数据送给芯片,由芯片内 核独立完成与存储区数据的比较,然后将比较结果返回给编程器)。 当然,要想从根本上防止单片机被解密,那是不可能的,加密技术不断发展,解密技术也不断发展, 至今不管哪个单片机,只要有人肯出钱去做,基本都可以做出来,只不过代价高低和周期长短的问题, 编程者还可以从法律的途径对自己的开发作出保护(比如专利)。 4.10.5 STM32加密思路-01 串口ISP设置加密 STM32 的加密,最基本的方法是置读保护,这样可以防止外部工具非法访问,在 STM32 官网发 布的 串口 ISP 软件中有置读保护和加密选项,选择一个就可以了,这样外部工具就无法对 FLASH 进 行读写操作,但我要重新烧写 FLASH 怎么办?只能清读保护,而清读保护后,芯片内部会自动擦除 FLASH 全部内容。 4.10.6 STM32加密思路-02 软件加密 在软件里做加密,比如利用 CPU 的唯一的 96 位 ID(请见神舟 III 号的例程“产品唯一身份标识 (Unique Device ID)实验(96 位唯一 ID 实验)”),或者甚至利用网卡的 MAC,如果你说人家反汇编破 解你的程序,那是可以做到的,但是成本没法估算,没人愿意出钱尝试,也就起到保护作用了,软件 加密,可以看它的闪存编程手册。 利用 STM32 的 UID 加密,具体程序可以做到比如 main 函数开始的时候,可以加一句: if(UID == 正确的 UID)运行后面代码; else 不理会/运行错误的代码; 这里还可以迷惑对手,可以运行一段的假的代码,模拟产品正常启动的样子,但就是不运行核心 部分的代码,这样可以使得解密人员误认为解密成功了,为对手造成一些经济上的成本。 采用芯片内的唯一 ID 来加密,在程序里识别芯片的 ID,如果 ID 不对,则程序不运行,当然, 这样也是有缺陷的,因为每个芯片的 ID 不一样,因此对应的程序也应该不一样,那如何处理呢?有 人建议说:采购的时候,产品同批生产的 ID 号应该是连续的,可以通过判别 ID 的范围;还有人说, 在烧录工具里做一个算法,读取芯片 ID,再修改相应的二进制文件。当然还会有很多种方法,这里 嵌入式专业技术论坛 (www.armjishu.com)出品 第 164 页,共 788 页 不展开讨论。 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4.10.7 STM32加密思路-03 外置ID芯片 可以考虑外置 ID 芯片,如果成本没有问题,可以考虑增加一颗 CPU,两颗 CPU 相互进行验证, 才执行真正的程序,增加解密的成本和难度,而且这颗芯片可以是不常用的芯片,或者是型号不同的 芯片,这里面很多的想象空间,可以利用产品的特点,来寻找合适的芯片进行处理。 4.10.8 STM32加密思路-04 程序自毁 可以考虑设置某种检测机制,发现异常时程序自毁,比如程序一启动,如果发现芯片某几个管脚 的电平出现变化,比如已经封死的 JTAG 管脚出现了其他异常的电平进入,那么就自毁程序,拷贝一 段 FF 去刷自己的 FLASH,只要覆盖一小段程序就足以让破解者无法成功破解。 这些预先可以根据自身的产品来设置一些场景,出现这些情况就做相应的急救措施。 4.10.9 STM32加密思路-05 磨IC型号 磨掉 IC 的型号,重新打一个错误的上去;还可以在周围的电阻电容上动手脚,打错的值上去, 使得破解成功后,周围的电路有个关键部分的配件的值不对,导致产品运行不正常,增加破解的难度。 4.10.10 STM32加密思路-06 高端硬件加密 目前 STM32 更多高端的芯片增加了硬件的加密,比如 STM32F4XXX 具有个 PDR 寄存器,可以 设置三级加密,如果你代码都写好了,直接设置到 LEVE2,那就 stm32 就下载不进去了,直接封锁 死,暂时没有听说解决办法,以后有没有不清楚。 还有像 STM32F4XXX 推出的 417 系列带哈希加密的,这些都是 ST 厂商提供的一些解决办法, 另外的我们与时俱进进行相应的增加吧。 4.10.11 STM32加密思路-07 AES加密 我们知道,STM32 的内部 FLASH 是用户可编程的,也就是说它支持 IAP,而 IAP 中的 APP 代 码一般是需要开放的,那么只有保证 BOOT 的代码安全,才能确保不被破解。 前面提到,当 IC 置读保护后,外部工具不能访问内部 FLASH,但 CPU 可以访问,破解者完全 可以自已编写一段代码通过 BOOT 下载到 IC 运行,然后在程序中读出你的 BOOT 代码。 所以解决办法就只能加以限制想办法使别人的代码运行不了,才能保证 BOOT 不被读出。 常用的方法是采用加密算法,如 AES;流程如下: APP 代码加密,下载时,在 BOOT 中解密,这样,只有通过正确加密的 APP 代码才能正常的运 行,因此加密的算法就成了你的密钥,而这个是你独有的。 而且这样做的好处也可以方便客服人员去客户那升级,也为了保证程序的安全;程序分为两部分, 一是 boot 引导程序,二是 app 应用程序部分,产品在出厂时,先用串口 ISP 烧写 boot,烧写的时候置 读保护,写完后,可以用 JLINK 测试了一下,确认程序读不出来,说明 FLASH 保护位有效,没有因 为后面烧写 APP 而清掉。 关键之处到了,为了安全,这里还需要把 APP 程序用 AES 之类的加密,在 BOOT 中解密写到 APP 区,这样就是说 BOOT 部分需要加入一段解密的代码,这样人家拿到你加密后的 APP 也没用。 ST 官方有一个公开源码版本的 bootloader,很稳定,再找个 AES 在 STM32 进行移植,合体变身, 这样一个强大好用的 bootloader 就诞生了;关于 AES 的密码可以由每颗 STM32 都有唯一的 ID 来作 为一个唯一输入进行产生,这样可以直接将加密后的文件交给客户自己去下载也是放心的。 这样 BOOT 代码确保不会被读出,APP 也加密了,这样就是目前最安全的模式。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 165 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 4.11 STM32低功耗经验总结 4.11.1 STM32低功耗实战项目案例故事(转载) 前两个月在公司做了一个低功耗项目,现在功耗最低 10uA 不到,平均功耗 40uA 左右,算是 达标了。因为是公司产品,就不方便贴代码、原理图了,该产品是一个小模块,可以方便的嵌入到各 种系统里面。跟 NRF2401 类似,是一个读卡器。 做这个项目中间也请了技术支持,因为外围电路芯片的功耗一直降不下来,经过与对方的反复 交流,对方提供了低功耗的测试结果、硬件方案、软件方案,经过修改测试,最终成为我们的产品, 功耗比较满意。 硬件方案选择的是 STM32,外加某公司的读卡芯片。前期完成了读卡等功能的开发,最后一 项开发内容是最艰巨也是最困难的---低功耗。在开发过程中,从硬件设计上不断裁剪元器件,软件上 不断精简代码,功耗最低也都保持在 3-4mA 左右,经过许多努力,才解决问题,解决过程如下。 电路设计上,只用到了一个 LED、串口 1、一个模拟 SPI、一个中断线、一个读卡芯片 RESET 线,硬件上就只剩下这么点东西了,这个时候我采用的是待机模式,使用的是读卡芯片的中断接 PA0 唤醒 STM32,在此之前要先使得读卡芯片进入低功耗、然后 STM32 进入低功耗,这一步完成了,貌 似没什么问题,功耗确实从几十 mA 骤降到 3mA 左右,开始还挺满意的,但是测试厂商提供的样板, 功耗却只有几十 uA,有点郁闷了。为什么会这样? 反复查看硬件、程序,都找不出原因,而且这个时候的工作效果很烂,根本就不能唤醒,所以我 就怀疑是读卡芯片一端低功耗有问题,因为我将 PA0 脚直接短接 VCC,这样就可以产生一个边沿触 发 STM32 唤醒了,但是用读卡芯片无法唤醒,所以我怀疑是读卡芯片的 RESET 脚电平不对,经检查, 确实是因为 RESET 脚加了上拉电阻,读卡芯片是高电平复位,在 STM32 进入待机后,管脚全都浮空 了,导致 RESET 被拉高,一直在复位;我去掉上拉电阻,觉得很有希望解决问题了,但是测试结果 是:有时候能唤醒,有时候不能,我仔细一想难道是因为 STM32 待机后管脚电平不确定,导致读卡 芯片 RESET 脚电平不定,而工作不正常,看样子只有换用其他方案了。后面确实验证了我的想法, 使用 STOP 模式后,唤醒问题引刃而解。 就在关键时刻,芯片原厂火种送炭,送来急需的技术支持资料,一个包含低功耗源代码,赶紧 拿过来测试,先研读下代码,使用的是 STOP 模式,而不是待机模式,使用的是任意外部中断唤醒, 这个时候就相当激动啊,赶快下载测试啊,结果功耗确实降了,但还是有 1mA,跟人家一比多了几 十倍啊。。。 我第一反应是硬件不对,经过测试修改,首先找到第一个原因,读卡芯片 RESET 管脚上拉电阻 又给焊上去了...,拆掉后功耗骤降到几百 uA,还是不行。。 测试过程中,为了去掉 LDO 的干扰,整 板采用 3.3V 供电,但是后面经过测试,LDO 的功耗其实也只有 5uA 不到,这 LDO 功耗值得赞一个; 虽然结果还是没达到预期,但是看到了希望,胜利就在眼前啊。 为此我反复看了技术支持提供的程序,发现他们的 STM32 的所有管脚的设置都有所考究:(因为 公司保密原则,代码中删除掉了关于该读卡芯片的前缀信息等) GPIO_InitTypeDef GPIO_InitStructure; /* GPIOA Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* GPIOB Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* GPIOC Periph clock enable */ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 166 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //#################################################### //USART1 Port Set //TXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //RXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //RST output pushpull mode GPIO_InitStructure.GPIO_Pin = TRST; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(PORT1, &GPIO_InitStructure); //IRQ input pull-up mode GPIO_InitStructure.GPIO_Pin = TIRQ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(PORT1, &GPIO_InitStructure); //MISO input pull-up mode GPIO_InitStructure.GPIO_Pin = MISO; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(PORT2, &GPIO_InitStructure); //NSS,SCK,MOSI output pushpull mode GPIO_InitStructure.GPIO_Pin = (NSS|SCK|MOSI); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(PORT2, &GPIO_InitStructure); //############################################################################ //TEST Port set 嵌入式专业技术论坛 (www.armjishu.com)出品 第 167 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 //TESTO input pushpull mode GPIO_InitStructure.GPIO_Pin = TESTO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(TEST_PORT, &GPIO_InitStructure); //############################################################################ //TEST Port set //TESTI output pushpull mode GPIO_InitStructure.GPIO_Pin = TESTI; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(TEST_PORT, &GPIO_InitStructure); //############################################################################ //LED Port Set //LED output pushpull mode GPIO_InitStructure.GPIO_Pin = LED; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LED_PORT, &GPIO_InitStructure); //############################################################ GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_ 15); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8| GPIO_Pin_9|GPIO_Pin_10); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStructure); 首先,想 MOSI、SCK、CS、LED、RST 这些管脚应该设置为推挽输出,TXD 设置为复用输出, 而 IRQ、RXD、MISO 设置浮空输入,什么都没接的管脚全都设置为下拉输入,而 TESTI、TESO 我 一直不解是什么东东,开始就没管,而开始的时候 MISO 我也没怎么注意,设置成上拉输入(而不是 浮空输入),反正大部分按照厂家提供的参考,我并没有照搬,测试效果一样,但功耗确是还有 80-90uA, 期间我找了好久没找到原因,给技术支持一看,原来是因为 MISO 没有设置成浮空输入,我是设置成 嵌入式专业技术论坛 (www.armjishu.com)出品 第 168 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 了上拉输入,上拉电阻一直在消耗大约 40uA 的电流。。。 好吧,这是自己不够细心导致的,以后做低功耗的项目管脚配置是个大问题,不能再这么马虎 了!!! 我将 MISO 设置成浮空输入之后,最低功耗还是有 40+,离 10uA 的最低功耗还有段距离,到 底是为什么呢? 最后我发现,该读卡芯片有个 TESTIN/TESTOUT 管脚,是用来测试用的,出厂后也就用不上了, 我也一直以为这两个脚确实没什么用,就没接;可是我发现厂家提供的样板居然接了这两个脚,但是 厂商也没说这两个脚接或不接会影响功耗啊,抱着试一试的心态,我我把 TESTIN/TESTOUT 两个管 脚接到单片机上进行相应的配置,接下来是见证奇迹的时刻了,功耗居然真的、真的降到 10uA 了。。。。。。。。。。。 此处省略 n 个字 这时候真的很激动,真的很想骂人啊,坑爹的厂家,为什么不给提示说这两个脚不接单片机会 消耗电流呢?(也许是文档里面提到了,但是几百页的文档,还是全英文的,一堆堆的文字,我再看 一遍,确实没有提到这两个管脚会有漏电流。) 项目就这样完工了,中间最重要的是技术支持的强力支持,不然项目不能完工了,这个项目低功 耗 STM32 方面难度不高,主要是读卡芯片上面的低功耗调试起来问题很多,还是人家原厂的出马才 解决了问题,因为众多原因,不能公布该芯片的资料,包括该芯片怎么进入低功耗也无法公开,所以 抱歉~~。 关于 STM32 进入低功耗,我简单的总结了一下: 1.管脚设置,这个很关键,还是跟你电路有关系,外加上拉、下拉电阻切记不能随便加 2.STM32 的 systick clock、DMA、TIM 什么的,能关就全都关掉,STM32 低功耗很简单,关键是外 围电路功耗是关键 3.选择一个低功耗的 LDO,这个项目用到的 LDO 功耗就很不错,静态功耗 10uA 都不到。 4.确定 STM32 设置没问题,进入低功耗有好几种情况可以选择(睡眠、停机、待机),我还是推荐选 择 STOP 模式,这个我觉的比较好是因为可以任意外部中断都可以唤醒,而且管脚可以保留之前的设 置,进入停机模式的代码使用库函数自带的,就一句: PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); 意思是,在进入停机模式之前,也关掉电压调节器,进一步降低功耗,使用 WFI 指令(任意中断 唤醒),但是经过测试,使用 WFE(任事件唤醒)指令效果、功耗一模一样。 最后一步是从 STOP 模式怎么恢复了,恢复其实也很简单,外部中断来了会进入中断函数,然后 STM32 就被唤醒,唤醒还要做一些工作,需要开启外部晶振(当然你也可以选择使用内部自带振荡器)、 开启你需要的外设等等。 总之,低功耗关键我觉得还是在于管脚配置,以及你对于外围电路的掌握。 4.11.2 STM32低功耗三种模式 . STM32F10xxx 有三种低功耗模式: ●睡眠模式(Cortex-M3 内核停止,外设仍在运行) ●停止模式(所有的时钟都以停止) ●待机模式(1.8V 电源关闭) 此处主要是一些经验的总结,后面带有一些基础例程,大家可以进一步深入进行熟悉,如果遇到 看不懂的地方,可以先去学习例程代码,然后再回头来查看此处文档。 4.11.3 STM32低功耗需注意的地方 1) 时钟问题: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 169 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 STM32 被唤醒以后的时钟自动切换到内部 HIS RC 振荡器,大家都是知道的,RC 振荡器的精度 是不高的。而且,休眠前对于时钟的设置都是恢复到复位状态,只是时钟这个地方复位,其他的没有。 这也会带来一个问题,可能你休眠前使用的是内部时钟,可是休眠后,时钟却变了,带来的问题就是 UART 和定时器。或许你想不使用 PLL,就是 8M,这样醒来后的时钟 HIS 也是 8M,这样虽然在时 钟上没有差别了,但是时钟却不稳定了。UART 波特率肯定不能太高,否则通信会有问题。 2)醒来时间:这个问题也是个非常大的问题, datasheet 上给出的醒来时间是 7us,这个可能真的不假,但是醒来,不能马上干你的活,为什么。 初始化 IO,你可能问,我不初始化不行吗,回答应该是否定的。因为,如果你想使用低功耗的话, 休眠前 IO 口都应该设置为模拟输入,这样才能达到 datasheet 上的 14uA,但是这样也带来一个问题, 那就是初始化 IO,醒来必须要初始化 IO。如果你还想把时钟切换到外部时钟,耗时会更加长,接近 200ms,因为 STM32 会等待外部时钟稳定后才能工作,然后还要在重新初始化所有 IO,这个非常的 耗时。可能我只需要醒来 10ms,但是这些活干完就需要 100ms。 3) RTC 唤醒: RTC 这个也是个问题,为什么?大家需要注意的是 RTC 只能使用报警才能唤醒 MCU,秒中断是 不可以唤醒的。并且报警中断必须不停的设置,设置一次只生效一次,中断完了,还需要设置下次中 断的时间。并且还有个问题,报警中断必须等待到秒中断到了之后才能设置,也就是正好秒寄存器更 新了一次的时候设置,这就带来一个问题,等待秒中断。如果睡前还想再能被报警唤醒的话必须重新 设置报警中断,而且设置报警中断的时候需要等到秒中断才能设置新的值。这个等待的时间是不定的。 可能会几百个毫秒。说以要空空的耗费几百个毫秒等到秒中断标志来设置报警中断。可能我的 MCU 只需要执行 10ms 就需要休眠了。还是要空空的耗费掉几百个毫秒 4.12 STM32的中断与事件关系的区别 嵌入式专业技术论坛 (www.armjishu.com)出品 第 170 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 这张图是一条外部中断线或外部事件线的示意图,图中信号线上划有一条斜线,旁边标志 19 字 样的注释,表示这样的线路共有 19 套。 图中的蓝色虚线箭头,标出了外部中断信号的传输路径,首先外部信号从编号 1 的芯片管脚进 入,经过编号 2 的边沿检测电路,通过编号 3 的或门进入中断“挂起请求寄存器”,最后经过编号 4 的与门输出到 NVIC 中断控制器;在这个通道上有 4 个控制选项,外部的信号首先经过边沿检测电路, 这个边沿检测电路受上升沿或下降沿选择寄存器控制,用户可以使用这两个寄存器控制需要哪一个边 沿产生中断,因为选择上升沿或下降沿是分别受 2 个平行的寄存器控制,所以用户可以同时选择上升 沿或下降沿,而如果只有一个寄存器控制,那么只能选择一个边沿了。 接下来是编号 3 的或门,这个或门的另一个输入是“软件中断/事件寄存器”,从这里可以看出, 软件可以优先于外部信号请求一个中断或事件,既当“软件中断/事 件寄存器”的对应位为“1”时, 不管外部信号如何,编号 3 的或门都会输出有效信号。 一个中断或事件请求信号经过编号 3 的或门 后,进入挂起请求寄存器,到此之前,中断和事件的信号传输通路都是一致的,也就是说,挂起请求 寄存器中记录了外部信号的电平变化。 外部请求信号最后经过编号 4 的与 NVIC 中断控制器发出一 个中断请求,如果中断屏蔽寄存器的对应位为“0”,则该请求信号不能传输到与门的另一端,实现了 中断的屏蔽。 明白了外部中断的请求机制,很容易理解事件的请求机制了。图中红色虚线箭头,标 出了外部事件信号的传输路径,外部请求信号经过编号 3 的或门后,进入编号 5 的与门,这个号 4 的 与门,用于引入事件屏蔽寄存器的控制;最后脉冲发生器把一个跳变的信号转变为一个单脉冲,输出 到芯片中的其它功能模块。 在这张图上我们也可以知道,从外部激励信号来看,中断和事件是没有分别的,只是在芯片内 部分开,一路信号会向 CPU 产生中断请求,另一路信号会向其它功能模块发送脉冲触发信号,其它 功能模块如何相应这个触发信号,则由对应的模块自己决定。在图上部的 APB 总线和外设模块接口, 是每一个功能模块都有的部分,CPU 通过这样的接口访问各个功能模块,这里就不再赘述了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 171 页,共 788 页 ARM 技术论坛 www.armjishu.com STM32 神舟 III 号用户手册 V4.0 第五章 STM32神舟III号 实战篇(寄存器版本) 5.1 通用输入/输出(GPIO) 5.1.1 脚特性 z STM32F103ZET6 总共有 113 个通用输入/输出(GPIO)口 z 每个 I/O 端口位可以自由编程 z I/O 端口寄存器可按 32 位字被访问(不允许半字或字节访问) 5.1.2 GPIO应用领域 z 通用 I/O 口 z 驱动 LED 或其他指示器 z 控制片外器件或片外器件通信 z 检测静态输入 5.1.3 管脚分配 管脚名称 PA[15:0] 类型 I/O 表 1:端口 A GPIO 管脚描述 描述 通用输入/输出 PA0 到 PA15 管脚名称 PB[15:0] 类型 I/O 表 2:端口 B GPIO 管脚描述 描述 通用输入/输出 PB0 到 PB15 管脚名称 PC[15:0] 类型 I/O 表 3:端口 C GPIO 管脚描述 描述 通用输入/输出 PC0 到 PC15 管脚名称 PD[15:0] 类型 I/O 表 4:端口 D GPIO 管脚描述 描述 通用输入/输出 PD0 到 PD15 管脚名称 类型 表 5:端口 E GPIO 管脚描述 描述 嵌入式专业技术论坛 (www.armjishu.com)出品 v 第 172 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 PE[15:0] 管脚名称 PF[15:0] 管脚名称 PG[15:0] 管脚名称 NRST I/O 通用输入/输出 PE0 到 PE15 类型 I/O 表 6:端口 F GPIO 管脚描述 描述 通用输入/输出 PF0 到 PF15 类型 I/O 表 7:端口 G GPIO 管脚描述 描述 通用输入/输出 PG0 到 PG15 类型 I/O 复位 表 8: 描述 5.1.4 GPIO管脚内部硬件电路原理剖析 I/O 接口是一颗微控制器必须具备的最基本外设功能。通常在 ARM 里,所有 I/O 都是通用的,称 为 GPIO(General Purpose Input/Output)。在 STM32 中,每个 GPIO 端口包含 16 个管脚,如 PA 端口 是 PA0~PA15。GPIO 模块支持多种可编程输入/输出管脚,GPIO 模块包含以下特性: 1) 可编程控制 GPIO 中断 ----- 包括屏蔽中断发生 ----- 边沿触发(上升沿、下降沿、双边沿触发) ----- 电平触发(高电平触发、低电平触发) 2) 输入/输出管脚最大可承受 5V 电压 3) 可通过编程控制 GPIO 管脚配置: ----- 弱上拉或弱下拉电阻 ----- 2mA、4mA、8mA 驱动,STM32 芯片管脚驱动最大是 25mA GPIO 管脚可以被配置为多种工作模式,配置不同的模式实际就是内部的驱动电路有不一样,下 面我们分析几种,大家可以从这里了解原理知识: 1. 高阻输入 高阻态是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平, 如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样。 电路分析时高阻态可做开路理解。你可以把它看作输出(输入)电阻非常大。他的极限可以认为 悬空。也就是说理论上高阻态不是悬空,它是对地或对电源电阻极大的状态。而实际应用上与引脚的 悬空几乎是一样的。 如上图所示,为 GPIO 管脚在高阻输入模式下的等效结构示意图, 表示 GPIO 管脚;这 是一个管脚的情况,其它管脚的结构也是同样的,输入模式的结构比较简单,就是一个带有施密特触 发输入(Schmitt-triggered input)的三态缓冲器(U1),并具有很高的阻抗。施密特触发输入的作用是 能将缓慢变化的或者是畸变的输入脉冲信号整形成比较理想的矩形脉冲信号。执行 GPIO 管脚读操作 时,在读脉冲(Read Pulse)的作用下会把管脚(Pin)的当前电平状态读到内部总线上(Internal Bus)。 在不执行读操作时,它可以变成高阻抗的状态,使得外部管脚与内部总线之间是隔离的。 为什么会产生这种高阻抗的管脚设计呢?因为是很多管脚都连在同一根总线上,为了不干扰其他 嵌入式专业技术论坛 (www.armjishu.com)出品 第 173 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 管脚,当某一个管脚在传送数据的适合,其他管脚配置成高阻抗,就不会干扰正在传送数据的管脚了, 这样可以很多管脚同时共用一根总线,分时复用。 为减少信息传输线的数目,大多数计算机中的信息传输线采用总线形式,即凡要传输的同类信息 都在同一组传输线,且信息是分时传送的。在计算机中一般有三组总线,即数据总线、地址总线和控 制总线。为防止信息相互干扰,要求凡挂到总线上的寄存器或存储器等,它的输入输出端不仅能呈现 0、1 两个信息状态,而且还能产生一种高阻抗状态,即好像它们的输出被开关断开,对总线状态不起 作用,此时总线可由其他器件占用。三态缓冲器即可实现上述功能,它除具有输入输出端之外,还有 一控制端,就像一个开关一样,可以控制使其变成高阻抗状态。 2. 推挽输出 推挽输出可以提高输出功率,能够更好驱动外部的设备;推挽输出的原理:在功率放大器电路中 大量采用推挽放大器电路,这种电路中用两只三极管构成一级放大器电路,两只三极管分别放大输入 信号的正半周和负半周,即用一只三极管放大信号的正半周,用另一只三极管放大信号的负半周,两 只三极管输出的半周信号在放大器负载上合并后得到一个完整周期的输出信号。 推挽放大器电路中,一只三极管工作在导通、放大状态时,另一只三极管处于截止状态,当输入 信号变化到另一个半周后,原先导通、放大的三极管进入截止,而原先截止的三极管进入导通、放大 状态,两只三极管在不断地交替导通放大和截止变化,所以称为推挽放大器。 如上图所示,为 GPIO 管脚在推挽输出模式下的等效结构示意图。U1 是输出锁存器,执行 GPIO 管脚写操作时,在写脉冲(WritePulse)的作用下,数据被锁存到 Q 和/Q。T1 和 T2 构成 CMOS 反 相器,T1 导通或 T2 导通时都表现出较低的阻抗,但 T1 和 T2 不会同时导通或同时关闭,最后形成 的是推挽输出。在推挽输出模式下,GPIO 还具有回读功能,实现回读功能的是一个简单的三态门 U2。 注意:执行回读功能时,读到的是管脚的输出锁存状态,而不是外部管脚 Pin 的状态。 推挽电路是两个参数相同的三极管或 MOSFET,以推挽方式存在于电路中,各负责正负半周的波形 放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既 可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的 电流则减小,二者的状态轮流转换。对负载而言,好像是 一个“臂”在推,一个“臂”在拉,共同 完成电流输出任务。 3. 开漏输出 开漏输出就是不输出电压,低电平时接地,高电平时不接地。如果外接上拉电阻,则在输出高电 平时电压会拉到上拉电阻的电源电压,如果开漏输出的管脚被上拉了,那么这个管脚将一直默认是输 出高电平的。 一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电 阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点 是通过改变上拉电源的电压,便可以改变传输电平,比如加上上拉电阻就可以提供 TTL/CMOS 电平 输出等。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 174 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如上图所示,为 GPIO 管脚在开漏输出模式下的等效结构示意图。开漏输出和推挽输出相比结构 基本相同,但只有下拉晶体管 T1 而没有上拉晶体管。同样,T1 实际上也是多组可编程选择的晶体管。 开漏输出的实际作用就是一个开关,输出“1”时断开、输出“0”时连接到 GND(有一定内阻)。回 读功能:读到的仍是输出锁存器的状态,而不是外部管脚 Pin 的状态。因此开漏输出模式是不能用来 输入的。 开漏输出的优点是 IC 内部仅需很小的驱动电流就可以了,因为它主要是利用外部电路的驱动能 力,这样可以减少 IC 内部的驱动,并且外部需要什么样的电压,就上拉到相应的电压,需要多大的 电流,也可以通过改变上拉电阻来调节电流,所以开漏输出是非常灵活的一种输出。 4. 钳位二极管(用来保护 GPIO 管脚) GPIO 内部具有钳位保护二极管,如下图所示。其作用是防止从外部管脚 Pin 输入的电压过高或 者过低。VDD 正常供电是 3.3V,如果从 Pin 输入的信号(假设任何输入信号都有一定的内阻)电压 超过 VDD 加上二极管 D1 的导通压降(假定超过 VDD 电压 0.6V 的时候,那么二极管 D1 导通需要 0.6V 的压降),则二极管 D1 导通,这样就会把多于的电流引到 VDD,而真正输入到内部的信号电压 不会超过 3.9V(3.3v+0.6v=3.9v)。同理,如果从 Pin 输入的信号电压比 GND 还低,则由于二极管 D2 的作用,会把实际输入内部的信号电压钳制在-0.6V 左右。 假设 VDD=3.3V,GPIO 设置在开漏模式下,外接 10kΩ上拉电阻连接到 5V 电源,在输出“1” 时,我们通过测量发现:GPIO 管脚上的电压并不会达到 5V,而是在 4V 上下,这正是内部钳位二极 管在起作用。虽然输出电压达不到满幅的 5V,但对于实际的数字逻辑通常 3.5V 以上就算是高电平了。 如果确实想进一步提高输出电压,一种简单的做法是先在 GPIO 管脚上串联一只二极管(如 1N4148),然后再接上拉电阻。参见下图,框内是芯片内部电路。向管脚写“1”时,T1 关闭,在 Pin 处得到的电压是 3.3+VD1+VD3=4.5V,电压提升效果明显;向管脚写“0”时,T1 导通,在 Pin 处得到的电压是 VD3=0.6V,仍属低电平。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 175 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以上这节就是主要介绍芯片管脚的基本驱动原理,下面开始剖析具体的 STM32 芯片管脚。 5.1.5 STM32的GPIO管脚深入分析 上节我们介绍了芯片管脚实现的硬件原理,以及一个芯片管脚被配置成不同的模式实际是不同的 驱动电路,这些驱动电路可以适用于不同的场合。STM23 的每个 GPIO 引脚都可以由软件配置成输出 (推挽或开漏),输入(带或不带上拉或下拉)或复用的外设功能端口。多数 GPIO 引脚与数字或模拟 的复用外设共用;除了具有模拟输入(ADC)功能的管脚之外,其他的 GPIO 引脚都有大电流通过能 力,这些具体如下 8 种模式: ¾ 1)输入浮空(这个输入模式,输入电平必须由外部电路确定,要根据具体电路,加外部上 拉电阻或下拉电阻,可以做按键识别) ¾ 2)输入上拉(打开 IO 内部上拉电阻) ¾ 3)输入下拉(打开 IO 内部下拉电阻) ¾ 4)模拟输入(应用 ADC 模拟输入) ¾ 5)开漏输出(输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于 做电流型的驱动,其吸收电流的能力相对强(一般 20ma 以内).能驱动大电流和大电压,LED 就 使用这种模式。) ¾ 6)推挽式输出(可以输出高,低电平,连接数字器件。推挽式输出输出电阻小,带负载能力强) ¾ 7)推挽式复用功能(复用是指该引脚打开 remap 功能) ¾ 8)开漏复用功能(复用是指该引脚打开 remap 功能) 每个 IO 口可以自由编程,单 IO 口寄存器必须要按 32 位 bit 被访问。STM32 的很多 IO 口都是 5V 兼容的,这些 IO 口在与 5V 电平的外设连接的时候很有优势,具体哪些 IO 口是 5V 兼容的,可以从 该 芯 片 的 数 据 手 册 管 脚 描 述 章 节 查 到 ( I/O Level 标 FT 的就 是 5V 电 平 兼 容 的 ) , 我 们 打 开 STM32F103ZET 的芯片手册,看到 35 页,对 FT 有详细的解释: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 176 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 STM32 的每个 IO 端口都有 7 个寄存器来控制(这里要注意的是关于芯片硬件管脚的信息可以通 过芯片手册找到资料,有关控制某个管脚寄存器的说明需要参考《STM32F10xxx 参考手册》);我们可 以从手册截图的目录看到 7 个控制 GPIO 管脚的寄存器: 他们分别是两个端口配置寄存器,一个端口有 0~15 总共 16 个管脚;两个寄存器分别描述输入和 输出的,还有一个端口设置/清除寄存器来负责管脚是输出高电平还是低电平,一个端口清除寄存器和 端口配置锁定寄存器。在需要的情况下,I/O 引脚的外设功能可以通过一个特定的操作锁定,以避免 意外的写入 I/O 寄存器,这里我们仅介绍常用的几个寄存器,来完成我们的 LED 灯点灯实验的操作; 在此,我们可以总结一下 STM32 的 IO 控制寄存器的作用: 1) STM32 的 CRL 和 CRH 寄存器主要是用来 IO 管脚的方向和速率以及何种驱动模式 2) STM32 的 ODR 寄存器是用来控制 IO 口的输出高电平还是低电平 3) STM32 的 IDR 寄存器主要是用来存储 IO 口当前的输入状态(高低电平)的。 4) STM32 的 BSRR 寄存器主要是用来直接对 IO 端某一位直接进行设置和清除操作,通过这个寄 存器可以方便的直接修改一个引脚的高低电平 5) STM32 的 BRR 寄存器用来清除某端口的某一位位 0,如果该寄存器某位为 0,那么它所对应 的那个引脚位不产生影响;如果该寄存器某位为 1,则清除对应的引脚位。 6) STM32 的 LCKR 用来锁定端口的配置,当对相应的端口位执行了 LOCK 序列后,在下次系统 复位之前将不能再更改端口位的配置。 下面开始分析常用的两个 32 位配置寄存器 GPIOx_CRL 和 GPIOx_CRH,CRL 和 CRH 控制着每个 IO 口的模式及输出速率,我们下面来介绍一下两个寄存器,接下来我们看看端口低配置寄存器 CRL 嵌入式专业技术论坛 (www.armjishu.com)出品 第 177 页,共 788 页 的描述,如下图所示: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 该寄存器的复位值为 0X4444 4444(4 化成二进制为 0100),从上图可以看到,复位值其实就是配 置端口为浮空输入模式。从上图还可以得出:STM32 的 CRL 控制着每个 IO 端口(A~G)的低 8 位的 模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。这里我们可以记住几 个常用的配置,比如 0X0 表示模拟输入模式(ADC 用)、0X3 表示推挽输出模式(做输出口用,50M 速率)、0X8 表示上/下拉输入模式(做输入口用)、0XB 表示复用输出(使用 IO 口的第二功能)。 STM32 的 IO 口位配置表如下表: 可以看到 CNFX 是上面 CRL 寄存器里的配置位,这里配置位的不同,就会产生不同的 GPIO 管 脚模式。 STM32 输出模式配置如下表: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 178 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这里 CRL 寄存器的 MODE 配置位的选项,不同的配置就会产生不同的速率。 CRH 的作用和 CRL 完全一样,只是 CRL 控制的是低 8 位输出口,而 CRH 控制的是高 8 位输出 口,大家可以自己看 STM32 手册,我们在这里 CRH 就不做详细介绍了。 给个实例,比如我们要设置 PORTB 的 12 位为上拉输入,13 位为推挽输出。代码如下: GPIOB->CRH&=0XFF00FFFF;//清掉这 2 个位原来的设置,同时也不影响其他位的设置 GPIOB->CRH|=0X00380000; //PB12 输入,PB13 输出 GPIOB->ODR = 1<<12;//PB12 上拉(1 往右移 12 个位,从 PB0 开始,相当于把二进制 1 0000 0000 0000 赋值给 GPIOB_ODR,刚好对应了 PB12) 通过这 3 句话的配置,我们就设置了 PB12 为上拉输入,PB13 为推挽输出。 IDR 是一个 GPIOx_IDR 的端口输入数据寄存器的简称(ODR 是输入数据寄存器的简称),要想知 道某个 IO 口的状态,就要读这个寄存器,再从读出的寄存器值分析出某个管脚位的状态,就可以知 道这个管脚的状态了;IDR 寄存器只用了低 16 位。该寄存器为只读寄存器,并且只能以 16 位的形式 读出。该寄存器各位的描述如下图所示: ODR 是一个端口输出数据寄存器,其作用就是控制端口的输出,对 ODR 对应寄存器位置 1 即对 应的 GPIO 管脚就会输出高电平。该寄存器也只用了低 16 位,并且该寄存器可读可写,如果读的话, 从该寄存器读出来的数据都是 0,所以读是没有意义的;只有写是有效的,该寄存器的各位描述如下 图所示: GPIOx_IDR 是端口的输入数据寄存器,GPIOx_ODR 是端口的输出寄存器,我们配置引脚的输入 输出模式是通过 GPIOx_CRL 和 GPIOx_CRH 两个寄存器来配置的,但是每个端口的 16 个引脚它们有 的可能是输出模式,有的是输入模式,甚至一会输出一会输入,而 GPIOx_IDR 和 GPIOx_ODR 两个 寄存器是以字模式(读一次就是访问 2 个字节,一个字等于 2 个字节)访问而不能以 bit 模式(bit 模 式表示一次访问一个 bit 位,一个字节等于 8 个 bit,一个字等于 16 个 bit)访问,GPIOx_IDR 只能读, 而 GPIOx_ODR 可以读写。 关于 GPIO 的输出模式下几种速度的区别:2MHz、10MHz、50MHz;这个又可以理解为输出驱 动电路的不同响应速度(芯片内部在 I/O 口的输出部分安排了多个响应速度不同的输出驱动电路,用 户可以根据自己的需要选择合适的驱动电路,通过选择速度来选择不同的输出驱动电路模块,达到最 佳的噪声控制和降低功耗的目的)。 那为什么要几种速率呢?如果选择了不合适的速率会有什么影响呢?芯片管脚的速度就好比是 嵌入式专业技术论坛 (www.armjishu.com)出品 第 179 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 信号收发的频率,速度快就表示信号收发的频率高;如果信号频率为 10MHz,而你配置了 2MHz 的带 宽,那么就会丢失很多数据,很多数据点截取不到,这个 10MHz 的方波很可能就变成了正弦波。这 个就好比是公路的设计时速,汽车速度低于设计时速时,可以平稳的运行,如果超过设计时速就会颠 簸,甚至翻车。 所以芯片管脚的输入输出速率可以理解为,输出驱动电路的带宽,即一个驱动电路可以不失真地 通过信号的最大频率;如果一个信号的频率超过了驱动电路的响应速度,就有可能信号失真。带宽速 度高的驱动器耗电大、噪声也大,带宽低的驱动器耗电小、噪声也小;比如:高频的驱动电路,噪声 也高,当不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的 EMI 性能。当然 如果要输出较高频率的信号,但却选用了较低频率的驱动模块,很可能会得到失真的输出信号。关键 是 GPIO 的引脚速度跟应用匹配,比如: 1) USART 串口,若最大波特率只需 115.2k,1M 等于 1000k,那用 2MHz 的速度就够了,既省 电也噪声小,STM32 最低的速率是 2MHz,已经可以满足要求了。 2) I2C 接口,若使用 400k 波特率,也可以选用 2M 的速度够了;当然若想把余量留大些,可以 选用 10M 的 GPIO 引脚速度。 3) SPI 接口,若使用 18M 或 9M 波特率,需要选用 50M 的 GPIO 的引脚速度,我们这里一定要 使得 GPIO 的速度大于外部应用的速度,这好像就是在高速上跑公交车,而不是在田埂上开 赛车。高速上跑公交车,公交车可以开最快的速度,而不怕翻车。 这里提到了波特率,那么什么是波特率呢?波特率是指数据信号对载波的调制速率,它用单位时 间内载波调制状态改变的次数来表示。波特率一次传输一个数据对象,而这个数据对象可能是几个比 特(bit),所以波特率跟比特率是有区别的。 比特率在数字信道中,比特率是数字信号的传输速率,它用单位时间内传输的二进制代码的有效 位(bit)数来表示,其单位为每秒比特数 bit/s(bps)、每秒千比特数(Kbps)或每秒兆比特数(Mbps)来表示(此 处 K 和 M 分别为 1000 和 1000000)。 波特率与比特率的关系为:比特率 = 波特率 X 单个调制状态对应的二进制位数。 5.1.6 在STM32中如何配置片内外设使用的IO端口 首先,一个外设在使用前,必须先配置和激活启动该外设的时钟,比如 GPIO 端口 B,那么就要 激活 GPIOB 的时钟,比如 GPIOA,那么使用 PA2 管脚前,必须要前激活 GPIOA 端口的时钟,只有 启动时钟后,这个外设才变得激活可用。 时钟被启动之后,再根据这个具体功能,对这个外设进行相应的设置和配置,这样的好处是可以 降低 STM32 芯片的内部功耗,因为需要用到的外设才被激活,激活的外设会消耗芯片的比较多的功 耗;不需要使用的外设无需初始化,这样设计可以降低芯片的功耗;好处尤其体现在类似手持设备, 功耗比较小,使得电池更加耐用。 那么如何配置管脚采用哪种模式呢?这里粗略总结对应到外设的输入输出功能基本有三种情况: 1)管脚输出:需要根据外围电路的配置选择对应的管脚为复用功能的推挽输出或复用功能的开漏 输出。 2)管脚输入:则根据外围电路的配置可以选择浮空输入、带上拉输入或带下拉输入。 3)ADC 对应的管脚:配置管脚为模拟输入。 值得注意的是,这里如果把端口配置成复用输出功能,则该引脚与它当前连的信号电路断开,和 复用功能信号电路连接,所以将管脚配置成复用输出功能后,如果只激活了该引脚的 GPIO 端口的时 钟,而忘记把复用功能的时钟激活,那么它的输出将不确定,这样会产生异常的现象。 5.1.7 例程01 单个LED点灯闪烁程序 1. 示例简介 LED 灯的正极接的是 3.3V 电源,所以我们编程让 LED 负极拉低即 GPIO 引脚端口 F 的管脚 6 拉低,即 PF6 拉低,那么 LED 灯就会变亮,相关电路图如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 180 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 注意到,这里采用GPIO管脚的低电平点灯,原因是:处理器的GPIO管脚只要输出低电平即可点灯, 处理器功耗低;如果LED的一端固定接到GND地上,那么对于处理器的GPIO管脚点灯时,就必须输出高 电平,这样增加处理器的功耗。同时,大家要注意,在设计LED灯限流时,串接的电阻放置的位置, 有人会问,也可以放在LED的右边。一般,我们不会放在右边,主要是LED灯,人手可能会去触摸到, 这样可能会将人体上的静电引导板件上,如果将电阻放在左边,静电经过电阻后,会消弱很多,以致 不会一下子因为静电就将处理器烧毁。 一般的LED灯需要15~20毫安的电流才可以点亮,我们这里是3.3V的电压,经过1K欧姆的限流电阻, 用3.3V除以1000欧姆,理论值是33毫安的电流,足以点亮LED灯了。当然如果电流如果过大,就会使 得经过的电流变下,LED灯可能点不亮或者比较暗;如果电阻过小,就会导致电流过大,可能烧掉LED 灯,所以这个限流电阻选取也是有个范围的。 2. 调试说明 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1,可以看到该 DS1 灯一亮一灭。 3. 关键代码: 相关代码如下图程序清单: /************ www.armjishu.com *******/ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 181 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 int main(void) //main 是程序入口 { /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0xF0FFFFFF; GPIOF->CRL |= 0x03000000; while (1) { GPIOF->BRR = GPIO_Pin_6; Delay(0x2FFFFF); GPIOF->BSRR = GPIO_Pin_6; Delay(0x2FFFFF); } } 看原理图可以知道,因为 LED 的正极接的是 3.3V 电源端,所以当 PF6 管脚拉低成低电平的时候, LED 灯就会亮起来。 这里要注意的是在配置 STM32 外设的时候,任何时候都要先使能该外设的时钟!!!APB2ENR 寄 存器是 APB2 总线上的外设时钟使能寄存器,其各位的描述如下: 图:寄存器 APB2ENR 各位描述 我们要使能的是 PORTF 的时钟使能位,大家可以从上表看得到在 bit7 这个位,只需要将这个位 置 1 就可以使能 PORTB 的时钟了,大家可以跟进去看看下面的这句代码,就能看到具体是设置的是 这个 RCC 寄存器了 #define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080); 这句代码 80 化成二进制是 1000 0000 刚好是 bit7 的这个位,然后对这个 APB2ENR 的 GPIOF 端 口时钟置位: RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ 这句代码相当于:RCC->APB2ENR |= 0x00000080;或上以后使得 APB2ENR 寄存器的第 bit7 这 个位(从 0 开始,32 位寄存器,bit3 实际是在第 4 位)置 1,刚好是对应的 GPIO 端口 F 的时钟位, 那么 GPIOF 的时钟就被使能了。 对 GPIOF->BRR = GPIO_Pin_6;这句代码来说,我们可以看到 GPIO_Pin_6 的定义如下: #define GPIO_Pin_6 ((uint16_t)0x0040) 对 GPIOB_BRR 这个寄存器进行赋值,我们看下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 182 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 对 GPIOF_BRR 的 BR6 位进行置 1 操作,看寄存器说明可以知道,对 BR6 置 1 后,GPIOF_ODR 寄存 器的 ODR6 位就为 0 了,使得 PF6 管脚输出低电平,灯被点亮(前面分析过,LED 灯是低电平点亮, 具体原因请见前面的原理图分析) 同样,我们分析一下代码:GPIOF->BSRR = GPIO_Pin_6;下面看下 GPIOF_BSRR 寄存器: 因为 GPIO_Pin_6 是等于 0x0040,所以 GPIOF_BSRR 寄存器的 BS6 被置 1,可以看到说明,该位置 1 后,使得 GPIOF_ODR 寄存器的 ODR6 位就为 1 了, PF6 管脚输出高电平,灯灭(前面分析过,LED 灯是低电平点亮,高电平熄灭,具体原因请见前面的原理图分析)。 其中 Delay(0x2FFFFF)是延时函数,所以在这个 while 循环里,LED 灯亮一段时间后,就熄灭一 嵌入式专业技术论坛 (www.armjishu.com)出品 第 183 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 段时间,周而复始,交替进行。整段代码就都分析完了,至于代码中许多 define 的定义,例如: /********* GPIOB 管脚的内存对应地址 *******/ #define PERIPH_BASE ((uint32_t)0x40000000) #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define GPIOF_BASE #define GPIOF (APB2PERIPH_BASE + 0x1c00) ((GPIO_TypeDef *) GPIOF_BASE)可以参看前面的基础入门篇,如 何将阅读寄存器的入门章节,这些都是于 STM32 芯片参考手册里的规定对应的。 更多关于这个寄存器的详细说明大家可以看《STM32F10xxx 参考手册》的第 7 章。 5.1.8 例程02 LED双灯闪烁实验 1. 示例简介 LED 灯的正极接的是 3.3V 电源,所以我们编程让 LED 负极拉低即 GPIO 引脚端口 F 的 Pin6 和 PIN7 拉低,即 PF6 和 PF7;那么 LED 灯就会变亮;同样将 PF6 和 PF7 管脚拉高时,LED 就 会灭掉;亮和灭各经过一段延时,就会变成闪烁的样子,这里我们编程增加了延时程序,相关电 路图如下图所示: 2. 调试说明 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1 和 DS2,可以这 2 个 LED 灯不停的 闪烁。 3. 关键代码 /************ www.armjishu.com *******/ int main(void) //main 是程序入口 { /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0x00FFFFFF; GPIOF->CRL |= 0x33000000; while (1) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 184 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 { GPIOF->BRR = GPIO_Pin_6; GPIOF->BRR = GPIO_Pin_7; Delay(0x2FFFFF); GPIOF->BSRR = GPIO_Pin_6; GPIOF->BSRR = GPIO_Pin_7; Delay(0x2FFFFF); } } 这里和上面程序不同之处是上面使用的是 PF 端口,这里使用的 PF 端口,并且同时控制 PF 端口 的 2 个管脚来控制 LED 的亮灭。 5.1.9 例程03 LED三个灯同时亮同时灭 1.示例简介 LED 灯的正极接的是 3.3V 电源,所以我们编程让 PF6、PF7、PF8 三个管脚拉低;那么 LED 灯就会变亮;同样让 PF6、PF7、PF8 三个管脚拉高时,LED 就会灭掉;亮和灭各经过一段延时, 就会变成闪烁的样子,这里我们编程增加了延时程序,相关电路图如下图所示: 2.调试说明 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1、DS2 和 DS3,可以这 3 个 LED 灯 不停的闪烁。 3.关键代码 /************ www.armjishu.com *******/ int main(void) //main 是程序入口 { /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0x00FFFFFF; GPIOF->CRL |= 0x33000000; GPIOF->CRH &= 0xFFFFFFF0; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 185 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 GPIOF->CRH |= 0x00000003; while (1) { GPIOF->BRR = GPIO_Pin_6; /*熄灭 LED 灯*/ GPIOF->BRR = GPIO_Pin_7; GPIOF->BRR = GPIO_Pin_8; Delay(0x2FFFFF); GPIOF->BSRR = GPIO_Pin_6; /*点亮 LED 灯*/ GPIOF->BSRR = GPIO_Pin_7; GPIOF->BSRR = GPIO_Pin_8; Delay(0x2FFFFF); } }这里和上面程序不同之处是这里使用 PF6、PF7、PF8 三个管脚来同时控制 LED 灯的一亮一灭。 5.1.10 例程04 LED流水灯程序 1. 示例简介 在神舟III号STM32开发板中,一共有四个LED指示灯,其中一个是电源指示灯,上电就点灯的; 另外三个LED是由三个GPIO管脚控制,当GPIO管脚输出低电平时,对应的LED灯亮;当GPIO管脚输 出高电平时,对应的LED灯灭。 下图为 LED 原理图,其中 GPIO 管脚上串的电阻,主要起限流作用。防止电流过大损坏 LED 和 GPIO 管脚: 2. 调试说明 下载代码,并且按下【复位】键,在神舟III号板上找到DS1、DS2、DS3、DS4三个灯,可以 看到这三个灯轮流闪烁,流水灯。 3. 关键代码 /************ www.armjishu.com *******/ int main(void) //main 是程序入口 { /* 使能 APB2 总线的时钟,对 GPIO 的端口 F 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 186 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0x00FFFFFF; GPIOF->CRL |= 0x33000000; GPIOF->CRH &= 0xFFFFFF00; GPIOF->CRH |= 0x00000033; while (1) { GPIOF->BRR = GPIO_Pin_6; /*熄灭 LED 灯*/ Delay(0x2FFFF); GPIOF->BRR = GPIO_Pin_7; /*熄灭 LED 灯*/ Delay(0x2FFFF); GPIOF->BRR = GPIO_Pin_8; /*熄灭 LED 灯*/ Delay(0x2FFFF); GPIOF->BRR = GPIO_Pin_9; /*熄灭 LED 灯*/ Delay(0x2FFFF); GPIOF->BSRR = GPIO_Pin_6; /*点亮 LED 灯*/ Delay(0x2FFFF); GPIOF->BSRR = GPIO_Pin_7; /*点亮 LED 灯*/ Delay(0x2FFFF); GPIOF->BSRR = GPIO_Pin_8; /*点亮 LED 灯*/ Delay(0x2FFFF); GPIOF->BSRR = GPIO_Pin_9; /*点亮 LED 灯*/ Delay(0x2FFFF); } } 程序主要设计思路就是先将所有 LED 灯逐个经过延时后熄灭,然后再逐个被点亮,如此循环, 形成 LED 流水灯。 5.2 时钟 5.2.1 什么是时钟 从 CPU 的时钟说起。 计算机是一个十分复杂的电子设备。它由各种集成电路和电子器件组成,每一块集成电路中都集 成了数以万计的晶体管和其他电子元件。这样一个十分庞大的系统,要使它能够正常地工作,就必须 有一个指挥,对各部分的工作进行协调。各个元件的动作就是在这个指挥下按不同的先后顺序完成自 己的操作的,这个先后顺序我们称为时序。时序是计算机中一个非常重要的概念,如果时序出现错误, 就会使系统发生故障,甚至造成死机。那么是谁来产生和控制这个操作时序呢?这就是“时钟”。“时 钟”可以认为是计算机的“心脏”,如同人一样,只有心脏在跳动,生命才能够继续。不要把计算机 的“时钟”等同于普通的时钟,它实际上是由晶体振荡器产生的连续脉冲波,这些脉冲波的幅度和频 率是不变的,这种时钟信号我们称为外部时钟。它们被送入 CPU 中,再形成 CPU 时钟。不同的 CPU, 其外部时钟和 CPU 时钟的关系是不同的,下表列出了几种不同 CPU 外部时钟和 CPU 时钟的关系。 CPU 时钟周期通常为节拍脉冲或T周期,它是处理操作的最基本的单位。 在微程序控制器中,时序信号比较简单,一般采用节拍电位——节拍脉冲二级体制。就是说它只 要一个节拍电位,在节拍电位又包含若干个节拍脉冲(时钟周期)。节拍电位表示一个CPU周期的 时间,而节拍脉冲把一个CPU周期划分为几个叫较小的时间间隔。根据需要这些时间间隔可以相等, 也可以不等。 指令周期是取出并执行一条指令的时间。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 187 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 指令周期常常有若干个CPU周期,CPU周期也称为机器周期,由于CPU访问一次内存所花 费的时间较长,因此通常用内存中读取一个指令字的最短时间来规定CPU周期。这就是说,这就是 说一条指令取出阶段(通常为取指)需要一个CPU周期时间。而一个CPU周期时间又包含若干个 时钟周期(通常为节拍脉冲或T周期,它是处理操作的最基本的单位)。这些时钟周期的总和则规定 了一个CPU周期的时间宽度。 5.2.2 STM32的时钟 系统时钟的选择是在启动时进行,复位时内部 8MHZ 的 RC 振荡器被选为默认的 CPU 时钟,随 后可以选择外部的、具失效监控的 4-16MHZ 时钟;当检测到外部时钟失效时,它将被隔离,系统将 自动地切换到内部的 RC 振荡器。 在 STM32 中,有五个时钟源,为 HSI、HSE、LSI、LSE、PLL,它们都是时钟所提供的来源: 1. HSI 是高速内部时钟,RC 振荡器,频率默认为 8MHz,可以从 STM32 时钟树中看到 2. HSE 是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz, 时钟树的截图如下: 3. LSI 是低速内部时钟,RC 振荡器,频率为 40kHz,可以用于驱动独立看门狗和通过程序选择驱动 RTC(RTC 用于从停机/待机模式下自动唤醒系统),时钟树的截图如下: 4. LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体,也可以被用来驱动 RTC,时钟树的截图 如下: 5. PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2、HSE 或者 HSE/2。倍频可选择为 2~16 倍, 但是其输出频率最大不得超过 72MHz,时钟树的截图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 188 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 5.2.3 STM32的时钟深入分析 众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部 晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种时钟“能量”扩散 流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低端 8 位单片机诸如 51,AVR,PIC 等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受 用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状态(假设单片机处于正常工作 的状态)。比如 51 单片机使用典型的 12MHz 晶振作为时钟源,则外设如 IO 口、定时器、串口等设备 的驱动时钟速率便已经是固定的,用户无法将此时钟速率更改,除非更换晶振。 而 STM32 微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有 固定的关系,下面来详细解析 STM32 微控制器的时钟树。下图是 STM32 微控制器的时钟树: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 189 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下表是结合图表明出来的: 标号 1 2 3 释义 内部低速振荡器(LSI,40Khz) 外部低速振荡器(LSE,32.768Khz) 外部高速振荡器(HSE,3-25MHz) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 190 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4 内部高速振荡器(HSI,8MHz) 5 PLL输入选择位 6 RTC时钟选择位 7 PLL1分频数寄存器 8 PLL1倍频寄存器 9 系统时钟选择位 10 USB分频寄存器 11 AHB分频寄存器 12 APB1分频寄存器 13 AHB总线 14 APB1外设总线 15 APB2分频寄存器 16 APB2外设总线 17 ADC预分频寄存器 18 ADC外设 19 PLL2分频数寄存器 20 PLL2倍频寄存器 21 PLL 时钟源选择寄存器 22 独立看门狗设备 23 RTC 设备 在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。假设使用外部 8MHz 晶振作为 STM32 的时钟输入源(这也是最常见的一种做法),则这个 8MHz 便是“主干”,而“分支”很显然是 最终的外部设备比如通用输入输出设备(GPIO)。这样可以轻易找出第一条时钟的“脉络”: 3——5——7——21——8——9——11——13 对此条时钟路径做如下解析:   对于 3,首先是外部的 3-25MHz(前文已假设为 8MHz)输入;   对于 5,通过 PLL 选择位预先选择后续 PLL 分支的输入时钟(假设选择外部晶振);   对于 7,设置外部晶振的分频数(假设 1 分频);   对于 21,选择 PLL 倍频的时钟源(假设选择经过分频后的外部晶振时钟);   对于 8,设置 PLL 倍频数(假设 9 倍频);   对于 9,选择系统时钟源(假设选择经过 PLL 倍频所输出的时钟);   对于 11,设置 AHB 总线分频数(假设 1 分频);   对于 13,时钟到达 AHB 总线; 在上一章节中所介绍的 GPIO 外设属于 APB2 设备,即 GPIO 的时钟来源于 APB2 总线,同样在 上图中也可以寻获 GPIO 外设的时钟轨迹: 3——5——7——21——8——9——11——15——16   对于 3,首先是外部的 3-25MHz(前文已假设为 8MHz)输入;   对于 5, 通过 PLL 选择位预先选择后续 PLL 分支的输入时钟(假设选择外部晶振);   对于 7,设置外部晶振的分频数(假设 1 分频);   对于 21,选择 PLL 倍频的时钟源(假设选择经过分频后的外部晶振时钟);   对于 8,设置 PLL 倍频数(假设 9 倍频);   对于 9,选择系统时钟源(假设选择经过 PLL 倍频所输出的时钟);   对于 11,设置 AHB 总线分频数(假设 1 分频);   对于 15,设置 APB2 总线分频数(假设 1 分频)   对于 16,时钟到达 APB2 总线; 现在来计算一下 GPIO 设备的最大驱动时钟速率(各个条件已在上述要点中假设): 1) 由 3 所知晶振输入为 8MHz,由○5——○21 知 PLL 的时钟源为经过分频后的外部晶振时钟, 并且此分频数为 1 分频,因此首先得出 PLL 的时钟源为:8MHz / 1 = 8MHz。 2) 由 8、9 知 PLL 倍频 9,且将 PLL 倍频后的时钟输出选择为系统时钟,则得出系统时钟为 8MHz 嵌入式专业技术论坛 (www.armjishu.com)出品 第 191 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 * 9 = 72MHz。 3) 时钟到达 AHB 预分频器,由 11 知时钟经过 AHB 预分频器之后的速率仍为 72MHz。 4) 时钟到达 APB2 预分频器,由 15 经过 APB2 预分频器后速率仍为 72MHz。 5) 时钟到达 APB2 总线外设 上面是原理的剖析,如果再不明白的,可以接下来看例程代码,理论联系实践是最好的老师。 5.2.4 例程01 STM32芯片32MHZ频率下跑点灯程序 1. 示例简介 让点灯程序在时钟主频 32MHz 下面运行,LED 灯的正极接的是 3.3V 电源,所以我们编程让 LED 负极拉低即 GPIO 引脚端口 F 的管脚 6 拉低,即 PF6 拉低,那么 LED 灯就会变亮,相关电路图如 下图所示: 2. 调试说明: 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1,可以看到该 DS1 灯一亮一灭。 3. 关键代码: /************ www.armjishu.com *******/ int main(void) //main 是程序入口 { /**** 程序总共 2 部分之第 1 部分 时钟频率的配置 {开始 *******/ /** 以下是关于 RCC 时钟 详细请见《STM32F10XXX 参考手册》6.3 节 RCC 寄存器描述**/ unsigned char sws = 0; RCC->CR |= 0X00010000; //使能外部高速时钟 HSEON //将 RCC_CR 寄存器的值右移 17 位,等待 HSERDY 就绪,即外部时钟就绪 while(!(RCC->CR>>17)); /* 因为手册有要求 APB1 时钟频率不超过 36MHZ,而在 STM32 中最大为 72MHZ */ /* 为了保证最大速度,我们这里设置成 2 分频 */ /* 设置寄存器 CFGR 里的 8-10 位的值为 100 */ RCC->CFGR = 0x00000400; /* 寄存器 CFGR 的 18-21 四个 bit 位配置成以下值,则 PLL 就会设置成对应的值: 0000:PLL 2 倍频输出 1000:PLL 10 倍频输出 0001:PLL 3 倍频输出 1001:PLL 11 倍频输出 0010:PLL 4 倍频输出 1010:PLL 12 倍频输出 嵌入式专业技术论坛 (www.armjishu.com)出品 第 192 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 0011:PLL 5 倍频输出 1011:PLL 13 倍频输出 0100:PLL 6 倍频输出 1100:PLL 14 倍频输出 0101:PLL 7 倍频输出 1101:PLL 15 倍频输出 0110:PLL 8 倍频输出 1110:PLL 16 倍频输出 0111:PLL 9 倍频输出 1111:PLL 16 倍频输出 我们在这里,因为 STM32 神舟 III 号上的晶振是 8MHZ 的,配置成 9 倍输出就能达到 STM32 最大 72MHZ 工作频率*/ //本例程希望设置成 32MHZ 的工作频率,我们在这里尝试一下 RCC->CFGR |= 2<<18; //2 右移动 18 位,即 0010 使得 PLL 获得 4 倍频输出,外部晶振是 8MHZ 乘以 4 就是 32MHZ RCC->CFGR |= 1<<16; //PLLSRC 设置成 1,使得 HSE 时钟作为 PLL 输入时钟 RCC->CR |= 1<<24; //将 PLL 使能 while(!(RCC->CR>>25)); //监控寄存器 CR 的 PLLRDY 位,等待 PLL 时钟就绪 RCC->CFGR |= 1<<1; //将时钟切换寄存器配置成用 PLL 输出作为系统时钟 while(sws != 0x2) //等待 CFGR 寄存器的 2,3 位为 10,系统正式切换到了 PLL 输出作为时 钟 { // 将 CFGR 寄存器右移 2 位,将 2,3 位 SWS 状态移出来,详情请见《STM32F10XXX 参考手册》54 页 sws = RCC->CFGR>>2; //这里的 0x3 为二进制的 11,这个 whlie 循环设计的一个算法,为了判断 sws 是不是为 10 sws &= 0x3; } /**程序总共 2 部分之第 1 部分 时钟频率的配置 结束} **/ /** 程序总共 2 部分之第 2 部分 点灯的配置 {开始**/ /* 使能 APB2 总线的时钟,对 GPIO 的端口 B 时钟使能 */ RCC->APB2ENR |= RCC_APB2Periph_GPIOF; /*-- GPIO Mode Configuration 速度,输入或输出 -----------------------*/ /*-- GPIO CRL Configuration 设置 IO 端口低 8 位的模式(输入还是输出)---*/ /*-- GPIO CRH Configuration 设置 IO 端口高 8 位的模式(输入还是输出)---*/ GPIOF->CRL &= 0xF0FFFFFF; GPIOF->CRL |= 0x03000000; while (1) { GPIOF->BRR = GPIO_Pin_6; Delay(0xFFFFFF); GPIOF->BSRR = GPIO_Pin_6; Delay(0xFFFFFF); } /*************** 程序总共 2 部分之第 2 部分 点灯的配置 结束} *********************************/ } 这个例程主要是体现在如何设置时钟,点灯的代码和原理图都在通用输入/输出的 GPIO 章节详细 说明了。 STM32 的时钟源有几种,有内部的 RC,也有外部的晶振,该选择哪种,代码里通过语句:RCC->CR |= 0X00010000;使能外部的晶振,那么 CR 这个寄存器全称叫做 STM23 的时钟控制寄存器,在 《STM32F10xxx 参考手册》的 60 页可以看到 RCC_CR 寄存器: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 193 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再分析一下 RCC->CR |= 0X00010000 这个语句 16 进制 0x00010000 换成二进制,是第 17 位为 1, 其他 31 个位都为 0,寄存器是从 0 开始,就是 16 位 置位 可以看到对 HSE ON 置位就是把外部的高速时钟使能,CPU 所需要的时钟是从外部获取;然后接下继 续看另外一句代码:while(!(RCC->CR>>17)),在 while 循环里,如果为 1,while 就会一直循环,如果 为 0 的话 while 就会继续执行;while 循环里还有!取反的操作,所以这句代码的意思三个是让 while 循环等到 CR 的第 17 位变成 1 才往下执行,那么看下第 17 位是什么,翻到《STM32F10xxx 参考手册》 的 60 页: 可以看到上图,第 17 位置 1 表示外部的高速时钟就绪好了,晶振起振稳定,CPU 从外部晶振稳定的 获取时钟。 接下来,就是操作一个叫做 RCC_CFGR 寄存器,这个寄存器主要负责内部时钟的倍频(倍频就 是加入输入进来是 8M 主频,经过 4 倍频后就是乘以 4 倍,等于 32M 了,所以倍频就相当于是乘)和 分频(分频就相当于是除法,比如 72M 的主频,4 分频后就是 18M 了),是一个非常重要的寄存器。 这个寄存器主要负责配置 STM32 内部总线上的一些时钟参数,比如时钟切换状态(可以知道目前 哪个时钟作为系统时钟,比如有内部的时钟,也有外部的),这个寄存器还负责 STM32 时钟内部总线 嵌入式专业技术论坛 (www.armjishu.com)出品 第 194 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 的配置,比如 AHB 时钟总线,APB1 时钟总线,APB2 时钟总线是怎么分频(有几种分频方式,例如 不分频,2 分频,4 分频,8 分频,16 分频等);还有 ADC 模数转换的分频;USB 的分频等;可以看 到这个寄存器完成了许多的功能,下面来分析我们如何操作这个寄存器的: 1)RCC->CFGR = 0x00000400; 2)RCC->CFGR |= 2<<18; 3)RCC->CFGR |= 1<<16; 4)RCC->CFGR |= 1<<1; 第 1 句代码是设置 PPRE1 寄存器为 100,从下图可以知道,设置 HCLK2 分频,这里也可以不设置, 默认 HCLK 是不分频的,我们在这里只是提醒大家,做个配置师范: 第 2 句代码是将 2 左移 18 位,即将二进制的 10 左边移动 18 位,是 PLL 4 倍频输出: 第 3 句代码是左移 16 位后置 1,表示 HSE 时钟作为 PLL 输入时钟,HSE 就是外部晶振: 第 4 句代码表示将时钟切换到外部时钟,都设置好之后,通知 STM32 的芯片可以将系统的时钟切换 给外部晶振提供时钟了: 可以从下图看到,RCC_CFGR 寄存器里的 PLLSRC 负责切换是内部 HIS 提供时钟,还是外部 HSE 晶振提供时钟,上面程序代码选择的是外部的 HSE 提供时钟;紧接着,RCC_CFGR 寄存器里的 PLLMUL,程序代码里配置的是 4 倍频,如果这里外部晶振是 8MHz 的,4 倍频后就是 32MHz 的频率 (STM32 最高可以达到 72MHz);RCC_CFGR 寄存器里的 SW 负责 HIS、PLLCLK、HSE 三个时钟来 嵌入式专业技术论坛 (www.armjishu.com)出品 第 195 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 源取其中一个,程序里选择的是 PLLCLK,这个来自 HSE 外部晶振然后 4 倍频的时钟做为整个 STM32 芯片的主时钟。 上图上面已经经过详细分析了,接下来就是一个 while(sws != 0x2)循环 while(sws != 0x2) { sws = RCC->CFGR>>2; sws &= 0x3; } 上面的代码是将 RCC_CFGR 寄存器右移 2 位后,在与上 0x3 相当于与上二进制的 11,最低两位是 1, 其他高位都是 0;这样的意思就是把 SWS 这个系统时钟切换状态的值单独截取出来,然后用 while(sws != 0x2)语句一直等待 SWS 的值为 0x2,0x2 化成二进制是 10,就是 PLL 输出作为系统时钟, 下图可以知道: 那么这里就奇怪了,为什么不是 HSE 的晶振作为系统时钟呢?而是采用 PLL,因为我们可以看到, 我们在代码里设置的就是走左边这张图的配置路线,因为把外部的晶振进行倍频了的,也有右边这种 选择,只是这个例程我们在代码里没有这么设计,以后大家可以这样设计: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 196 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最后代码配置好了,就开始点灯程序,具体细节请见代码,因为上一章节已经有详细分析。 5.2.5 例程02 STM32芯片40MHZ频率下跑点灯程序 1. 示例简介 让点灯程序在时钟主频 40MHz 下面运行,其他不变,同上个例程一样,唯一的改变就是把主频从 32MHz 改成 40MHz 了。 2. 调试说明: 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1,可以看到该 DS1 灯一亮一灭。 3. 关键代码: 查看 RCC_CFGR 寄存器的第 18~21 位的 PLLMUL,当外部晶振是 8MHz 时,将 RCC->CFGR |= 3<<18;将 16 进制的 3 化成二进制是 0011,把 PLL 设置成 5 倍频输出,8MHz 乘以 5 倍频就是 40MHz。 关键代码的改变与上面一模一样,唯一的改变就是将 RCC->CFGR |= 2<<18;变成了 RCC->CFGR |= 3<<18;这句不同 5.2.6 例程03 STM32芯片72MHZ频率下跑点灯程序 1.示例简介 让点灯程序在时钟主频 72MHz 下面运行,其他不变,同上个例程一样,唯一的改变就是把主频从 40MHz 改成 72MHz 了。 2.调试说明: 下载代码,并且按下【复位】键,在神舟 III 号板上找到 DS1,可以看到该 DS1 灯一亮一灭。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 197 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3.关键代码: 查看 RCC_CFGR 寄存器的第 18~21 位的 PLLMUL,当外部晶振是 8MHz 时,将 RCC->CFGR |= 7<<18;;将 16 进制的 7 化成二进制是 0111,把 PLL 设置成 9 倍频输出,8MHz 乘以 9 倍频就是 72MHz。 关键代码的改变与上面几乎一模一样,改变的是将 RCC->CFGR |= 3<<18;变成了 RCC->CFGR |= 7<<18。 注意:48M 和 72M 之间是 2 等待周期; 增加了 FLASH 两个时钟周期的延时,CPU 的运行频率高, 而内部 flash 的运行频率低所以 cpu 要从 flash 中取指令当然要有个等待的时间了。怎么协调:cortex 内核“意识”到它的缓冲区没有指令了,它就会去 flash 中预取,当缓冲区中有预取的指令,它自然 就不执行预取了,当然 cortex 内核肯定不是当缓冲区中没有指令了才去取指令,而是它认为被 cpu 译 码后剩余的预取指令少到一定程度后就去预取指令。关于 FLASH 更多资料请见《STM32F10xxx 闪存 编程手册》 在该手册上可以找到: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 198 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 所以在代码中,还要添加 FLASH->ACR|=0x32;FLASH 相关的寄存器的声明定义等。具体看 例程:“07.STM32 芯片 72MHZ 频率下全速跑 LED 流水灯(STM32 神舟 III 号)”。 5.3 独立按键 5.3.1 键的分类 目前,按键有多种形式。有机械接触式,电容式,轻触式等。 1. 按制作工艺分: 硬板按键:带弹簧的按键焊接在印刷电路板上 软板键盘:以导电橡胶作为接触材料放在以聚脂薄膜作为基底的印刷电路上所形成的按键。 2. 按工艺原理分: 可以将键盘分为编码键盘和非编码键盘,编码键盘的键盘电路内包含有硬件编码器,当按下某— 个键后,键盘电路能直接提供与 该键相对应的编码信息,例如 ASCII 码。 非编码键盘的键盘电路中 只有较简单的硬件,采用软件来识别按下键的位置,并提供与按下 键相对应的中间代码送主机,然 后由软件将中间代码转换成相应的字符编码,例如 ASCII 码;非编码键盘主要靠软件编程来识别的, 在单片机组成的各种系统中,用的较多的是非编码键盘。非编码键盘又分为独立键盘和行列式(又称 矩阵式)键盘。 5.3.2 按键属性 键盘实际上就是一组按键,在单片机外围电路中,通常用到的按键都是机械弹性开关,当开关闭 合时,线路导通,开关断开时,线路断开,下图是几种单片机系统常见的按键: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 199 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 弹性小按键被按下时闭合,松手后自动断开;自锁式按键按下时闭合且会自动锁住,只 有再次按下时才弹起断开。 单片机的外围输入控制用小弹性按键较好,单片机检测按键的原理是:单片机的 I/O 口既可作为 输出也可作为输入使用,当检测按键时用的是它的输入功能,我们把按键的一端接地,另一端与单片 机的某个 I/O 口相连,开始时先给该 I/O 口赋一高电平,然后让单片机不断地检测该 I/O 口是否变为 低电平,当按键闭合时,即相当于该 I/O 口通过按键与地相连,变成低电平,程序一旦检测到 I/O 口 变为低电平则说明按键被按下,然后执行相应的指令。 从上图可看出,理想波形与实际波形之间是有区别的,为什么呢?因为实际波形在按下和释放的 瞬间会有抖动现象出现,这是因为通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时, 由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。 因而在闭合及断开的瞬间均伴随有一连串的抖动,抖动时间的长短和按键的机械特性有关,一般为 5~ l0ms。为了不产生这种现象而作的措施就是按键消抖。通常我们手动按下键然后立即释放,这个动作 中稳定闭合的时间超过 20ms。因此单片机在检测键盘是否按下时都要加上去抖动操作。 消抖是为了避免在按键按下或是抬起时电平剧烈抖动带来的影响。按键的消抖,可用硬件或软件 两种方法,硬件的去抖主要是用专用的去抖动电路,也有专用的去抖动芯片;另外一种方式就是用软 件延时的方法就能很容易解决抖动问题,而没有必要再添加多余的硬件电路。所以软件消抖适合按键 比较多的情况,而硬件消抖适合按键比较少的情况。 如果按键较多,就用软件方法去抖,即检测出键闭合后执行一个延时程序,5ms~10ms 的延时, 让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测 到按键释放后,也要给 5ms~10ms 的延时,待后沿抖动消失后才能转入该键的处理程序,这样就靠软 件模拟整个按键的过程,控制只取最稳定的那个按键状态。 实现方法:一般来说,软件消抖的方法是不断检测按键值,直到按键值稳定。假设检测到按键按 下之后,为了避免检测到很多的抖动,可以先延时 5ms~10ms,再次检测,如果按键还被检测按下, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 200 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 那么就认为有一次按键输入(因为如果不避开抖动的话,会有很多次按键输入信号出现,通过去抖, 模拟人的按下的过程和时间,按下和松开按键实际也占用了 20ms 以上的时间,记录正确的按键次数。 5.3.3 STM32的位带操作 1. 什么是位带操作 还记得 51 单片机吗? 单片机 51 中也有位的操作,以一位(BIT)为数据对象的操作;例如 51 单片机可以简单的将 P1 端口的第 2 位独立操作,P1.2=0 或者 P1.2=1,就是这样把 P1 口的第三个脚 (bit2)置 0(输出低电平)或者置 1(输出高电平)。 而现在 STM32 的位段、位带别名区这些就是为了实现这样的功能,可以在 SRAM、I/O 外设空间 实现对这些区域的某一位的单独直接操作。 2. 为什么要用位带操作? 那么 51 单片机中间不是有位的操作吗,而 STM32 为什么要提出位带的操作呢?首先,这里不得 不提一个事情就是 STM32 的内部区域访问只能是 32 位的字,不能是字节或者半字,这部分 STM32 在神舟开发板手册的 GPIO 章节中提到过;而 51 单片机里一个 bit(一个字节等于 8 个 bit,一个字是 32 个 bit)。这个是 STM32 的特点决定的,所以 STM32 使用一种新型的方式来解决这个问题,设计 一个办法来解决用一次访问 32bit 的这样的操作达到 51 单片机那种只访问一个 bit 的效果。 3. 如何设计和实现位带操作的? 从编程者这个角度来说,我们操作的对象是一个一个的 bit 位,而对于 STM32 来说,它内内部只 能是 32 位 bit 每次的访问。如果要实现这个技术,必须要做一个映射,也就是从 1 个 bit 映射到 32 个 bit,就是用 STM32 内部的一次访问(32 个 bit)来代表编程者认为的 1 个 bit。 那 STM32 内部是如何解决的呢?它是在支持位带操作的地方,取个别名区空间,而这个别名区空 间可以让一次 32 位来进行访问,对这个别名进行操作就相当于对 SRAM 或者 I/O 存储空间中的位(1 个寄存器里的位就是 1 个 bit,1 个 bit 最后对应别名区空间的 32 个位,因为 STM32 芯片内部只能是 32 位去访问)进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 201 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这样呢,1MB SRAM 就可以 32M 个对应别名区空间,就是 1 位膨胀到 32 位(1bit 变为 1 个字); 我们对这个别名区空间开始的某一字操作,置 0 或置 1,就等于它映射的 SRAM 或 I/O 相应的某地址 的某一位的操作。 4. STM32 中位带操作的具体部署情况是 支持位带操作的两个内存区的范围是: 序号 支持位带操作的两个内存区的范围 1 SRAM 区中的最低 1MB: 0x2000_0000-0x200F_FFFF 2 片上外设区中的最低 1MB: 0x4000_0000-0x400F_FFFF 下面是内部空间映射图: 对应的别名区空间范围 SRAM 所对应的别名区 32MB 空间: 0x2200_0000-0x23FF_FFFF 片上外社区所对应的别名区 32MB 空间: 0x4200_0000-0x43FF_FFFF 嵌入式专业技术论坛 (www.armjishu.com)出品 第 202 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 例如:SRAM 区中的最低 1MB 空间中的 0x2000_0000 的 8 个 bit,分别对应如下: 地址 对应的 bit 位 别名空间 Bit 对应的别名空间 0x2000_00000 Bit1 0x2200_0000 跨度一个字 = 4 个字节 = 32 个 bit Bit2 0x2200_0004 跨度一个字 = 4 个字节 = 32 个 bit Bit3 0x2200_0008 跨度一个字 = 4 个字节 = 32 个 bit Bit4 0x2200_000C 跨度一个字 = 4 个字节 = 32 个 bit Bit5 0x2200_0010 跨度一个字 = 4 个字节 = 32 个 bit Bit6 0x2200_0014 跨度一个字 = 4 个字节 = 32 个 bit Bit7 0x2200_0018 跨度一个字 = 4 个字节 = 32 个 bit Bit8 0x2200_001C 跨度一个字 = 4 个字节 = 32 个 bit 可以看到上表和上图,0x2000_0000 中的一个 bit 位对应了别名区的一个 32 位的字,也就是说 STM32 芯片的内部寄存器的任意一个位,都其实对应的是别名区的 32 个位。 5. 如何用代码与位带操作挂钩 在 STM32 中,一个寄存器是 32 位的,32 个 bit 中的任意其中一个 bit 所对应的别名空间 到底该如何访问呢?首先分为两种情况,一种是在 SRAM,一种是在 FLASH 中,两个别名 空间的起地位置是不同的,SRAM 是从 0x2200_0000 开始,而 FLASH 是从 0x4200_0000 开 始。 假如在 SRAM 中的一个寄存器的地址是 A,访问寄存器 A 中的第 n 个 bit 位。那么该如 何计算呢?我们知道 SRAM 中别名区的起始地址是 0x2200_0000 对应 SRAM 中实际寄存器 地址 0x2000_0000,SRAM 中每 1 个 bit,都会对应别名区中的 32 个 bit,那么实际地址的公 式应该如下: 0x2200_0000 + (SRAM 实际寄存器地址偏移 0x2000_0000 的 bit 数)* 4 因为 0x2200_0000 这个地址每增加 1,实际上就是增加 8 个 bit(一个地址对应一个字节), 实际寄存器中的 1 个 bit 对应 32 个 bit,所以就乘以 4,地址本身增加 1 是 8bit,8bit 乘以 4 倍刚好是 32bit。 那么接下来” SRAM 实际寄存器地址偏移 0x2000_0000 的 bit 数”该如何计算呢? 对,用寄存器的地址减去这个基地址,然后在乘以 8(因为一个地址对应 8 个 bit),所以就可 以得到以下的公式: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 203 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 (A‐0x20000000)*8 以上这个公式可以知道实际寄存器离基地址有多少个 bit 的距离,访问该寄存器的第 n 个 bit 位还必须加上一个 n,就变成以下的公式: (A‐0x20000000)*8+n 好了,最后整理整个换算公式如下,FLASH 与 SRAM 的原理都是想通的: SRAM :0x22000000 +((A‐0x20000000)*8+n)*4 FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 6. 举例说明: 比如我要访问如下寄存器 GPIOB_BSRR 中的第 14bit 位 BS13,注意因为寄存器内部是从 0 开始计 数到 31 截止,所以第 14bit 相当于是第 13。 可以从下图看到,GPIO 端口 B 的起始地址是 x04001_0C00,GPIOB_BSRR 寄存器的偏移地址是 0x10,访问的第 14bit 位的 BS13。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 204 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 那么通过公式: FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 换算 0x4200_0000 + ((0x40010c00-0x40000000)*8 + 12)*4 = 实际地址 在这里我们就不具体计算了,SRAM 访问也是同理 7. 如何将理念转化成代码: 由上面几节得出,SRAM 和 FLASH 中别名区的寻址公式如下: SRAM :0x22000000 +((A‐0x20000000)*8+n)*4 FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 可以看到 0x2200_0000 和 0x4200_0000 都共同有个 x200_0000 这个数值;乘以 8 相当于再加上外 面的那个乘以 4,总共是乘以 32,而 n 是乘以 4;乘以 32 相当于是数值向左移 5 位,乘以 4 相当于向 左边移 2 位。 尝试将如下公式化成 #define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 这样就可以用 BITBAND(addr,bitnum)来表示寄存器里的任何一个 bit 位,大概原理讲到这里, 具体使用方法通过例程来体现。 5.3.4 例程01 STM32芯片按键点灯(无防抖) 1. 示例简介 通过连上 PA8 管脚的按键,学会如何从 PA8 管脚读入一个输入,如何配置 GPIO 口成输入状 态;当 PA8 获取到输入的数据,STM32 对 LED 灯的状态进行取反。按键 USER1 是一端连接了 GND, 一端连接了 PA8 管脚;当按键按下时,PA8 管脚的电平值被拉低,相关电路图如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 205 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2.调试说明: 按下 PA8 管脚所连的按键(按钮 USER1),每按一次,LED 灯会由亮变灭,或者又灭变亮,因为 没有防抖代码(下个例程会增加),会发现,有时候按下去,灯会亮灭好几次。 3.关键代码: int main(void) //main 是程序入口 { unsigned int key_up =1; RCC_init(); //初始化配置时钟频率为 72MHZ LED_init(); //LED 初始化配置 Key_init(); //初始化控制按键的 PA0 端口 while (1) { if(key_up) LEDON; else LEDOFF; // 开灯 // 关灯 If ( KEY0 == 0) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 206 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 key_up = !key_up; } } STM32 芯片的 GPIO 管脚要采集到按键按下,那么它需要被配置成输入模式,之前有讨论 GPIO 管脚的几种模式,我们接下来还是复习一下,我们看看端口低配置寄存器 CRH 的描述,如下图所示: 该寄存器的复位值为 0X4444 4444(4 化成二进制为 0100),从上图可以看到,复位值其实就是配 置端口为浮空输入模式。从上图还可以得出:STM32 的 CRH 控制着每个 IO 端口(A~G)的高 8 位的 模式。每个 IO 端口的位占用 CRH 的 4 个位,高两位为 CNF,低两位为 MODE。这里我们可以记住 几个常用的配置,比如 0X0 表示模拟输入模式(ADC 用)、0X3 表示推挽输出模式(做输出口用,50M 速率)、0X8 表示上/下拉输入模式(做输入口用)、0XB 表示复用输出(使用 IO 口的第二功能)。 STM32 的 IO 口位配置表如下表: 可以看到 CNFX 是上面 CRH 寄存器里的配置位,这里配置位的不同,就会产生不同的 GPIO 管 脚模式。 STM32 输出模式配置如下表: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 207 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这里 CRH 寄存器的 MODE 配置位的选项,不同的配置就会产生不同的速率。 CRH 的作用和 CRL 完全一样,只是 CRL 控制的是低 8 位输出口,而 CRH 控制的是高 8 位输出 口,大家可以自己看 STM32 手册,我们在这里 CRL 就不做详细介绍了。 首先看下代码:RCC_init();这里实现的是初始化配置时钟频率为 72MHZ,之前的时钟章节已经将 过了,具体细节可以看上一章的内容,有详细的介绍。 下面看下连接按键的 GPIO 管脚的具体设置,这个函数里有 3 句代码: void Key_init() { RCC->APB2ENR |= RCC_APB2Periph_GPIOA; //使能 PORTA 时钟 GPIOA->CRH &= 0XFFFFFFF0; GPIOA->CRH |= 0X00000008; //PA8 设置成输入,PA8 在按键原理图默认被上拉的 } RCC->APB2ENR |= RCC_APB2Periph_GPIOA 首先使能 PORTA 的时钟,接下来开始使用 PA0 管 脚,所以要先初始化 PA 端口的时钟,才可以使用,下面看下原理图: 可以看到 PA0 默认是被上拉到 3.3V 高电平的,GPIOA->CRH &= 0XFFFFFFF0;这句代码是将 PA0 的 GPIO_CRH 寄存器的前 4 位清 0,然后 GPIOA->CRH |= 0X00000008 这句话是将 GPIO_CRH 寄存 器的前 4 位赋值 0x8,化成二进制就是 1000,通过查表: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 208 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以知道将 GPIOA_CRL 寄存器的 PA8 管脚配置成 1000,即上拉/下拉输入模式,配置好 PA8 管 脚之后,如何才能知道按键按下呢?这时就需要时刻查看和监听 PA8 管脚是否有电平的变化,那就要 知道 PA8 的管脚的电平值,而且还要不停的去检测它是否有变化,因为我们希望当按键按下的时候, 我们能以最快的反映速度获取到这一动作。 在代码里,我们使用 if ( KEY0==0 )来判断按键是否按下了,KEY0 就是 PA8,如果按键按下,从 原理图可以知道 PA8 被拉到 GND 变成低电平,这样 PA8 就等于 0 即 KEY0 等于 0。 那么 KEY0 如何反映到 PA8 的值的呢?接下来继续分析代码: (1)#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) (2)#define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) (3)#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) (4)#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) (5)#define KEY0 PAin(8) 代码(1):上面有讲解,这个 BITBAND(addr,bitnum)最后得出的是某寄存器里的某个 bit 位所映射的 别名区的地址。 代码(2):unsigned long *表示强制把这个地址变成一个 32 位的长的地址的指针,或者说是一个指针, 指向 32 位的一个地址;然后*((volatile unsigned long *)(addr))这个表示这个地址,长达 32 位 bit 的值, 通过 MEM_ADDR(addr) 把从 addr 地址开始的连续 32 个 bit 里的值给取出来。 代码(3):BIT_ADDR(addr, bitnum)表示某寄存器的地址,对应的某 bit 位所对应的别名区的空间的值, 也就是说取出某寄存器的某 bit 位的值 代码(4):把 PA 的某个管脚,与 BIT_ADDR 进行绑定关联 代码(5):把 KEY0 设置成 PA8,使得 KEY0 能取到 GPIOA_IDR 寄存器里第 9 位也就是 PA8 的值 这样,这个例程的关键是是否取到了 PA8 的值,取到了值之后,再进行相关的操作,这个是大家 嵌入式专业技术论坛 (www.armjishu.com)出品 第 209 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以自己定义的,在这个例程中,按一下按键,我们就将 LED 灯取反,原来是亮的就变成灭的,原 来是灭的就变成亮的。 5.3.5 例程02 STM32芯片按键点灯-增加了防抖的代码 1. 示例简介: 其他都与上个例程相同,唯一不同的就是增加了防抖代码,在这里是用软件防抖 2. 调试说明: 按下 PA8 管脚所连的按键(按钮 USER1),每按一次,LED 灯会由亮变灭,或者又灭变亮,因为 增加了防抖代码,基本上可以做到按一次,就采集到一次数据,灯由亮变灭或者又灭变亮,非常的稳 定。 3. 关键代码: 原理图还是同上个例程一样: int main(void) //main是程序入口 { unsigned int key_up =1; RCC_init(); //初始化配置时钟频率为72MHZ LED_init(); //LED初始化配置 Key_init(); //初始化控制按键的PA0端口 while (1) { Delay(0xfffff); if(key_up) LEDON; else LEDOFF; // 增加了防抖功能,如果你按下按键的时候会有抖动 // 开灯 // 关灯 } } if(KEY0==0) key_up = !key_up; //取反 代码Delay(0xfffff)就是我们增加的防抖功能,如果你按下按键的时候会有抖动,我们增加一定 时间的时间再来判断按键是否按下来,这样在一定程度上可以起到消抖的作用,但是这里还有一个BUG 嵌入式专业技术论坛 (www.armjishu.com)出品 第 210 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 就是如果长时间按着按键不动,while循环里面就会运行多次灯点亮程序,如果是计数器的话,这个 就不准了,按一次键,就计算了许多次数,大家可以尝试一下如何去解决这个问题,按一次键就只亮 一次,无论一次按多长时间。 5.4 串口通信的收与发 5.4.1 什么是串口通信 串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种 通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行 传输低。 串口是计算机上一种非常通用的设备通信协议。大多数计算机(不包括笔记本电脑)包含两个基 于 RS-232 的串口。串口同时也是仪器仪表设备通用的通信协议(串口通信协议也可以用于获取远程采 集设备的数据)。 当年 51 单片机内置串口的时候,被认为是微控制器发展史上的重大事件,因为当时的串口是唯 一一个微控制器与 PC 交互的接口。MCU 微控制器经过这么多年的发展,串口仍然是其必不可少的接口 之一。 5.4.2 串口通信的属性 1. 通信存在的问题 评价一个通信是否优质,主要体现在传输的速度,数据的正确性,功耗是否低,布线成本是否低 (例如 1 根线收发都能满足就比 8 根线的并行收发要节约成本);使用是否普及(就好像大家都学英 语,世界很大部分的人都可以独立使用英语吗,会英语的人多,就非常普及,可通信面就非常广;如 果你学的鸟语,那就只能跟鸟通信,没有人能听懂)。 2. 串口到底有几个标准?(经常听说有 3 线、5 线串口) 传统的串行接口标准有 22 根线,采用标准 25 芯 D 型插头座(DB25),后来使用简化为 9 芯 D 型 插座(DB9),现在应用中 25 芯插头座已很少采用。 像现在所说的几线串口,一般都是指使用了几根线,最初的 RS-232 串口是 25 针的,所有的针脚 定义都有用到,后来变成了 9 针的,所谓全功能串口就是所有的针脚定义都使用上了,例如流量控制, 握手信号等都有用到,一般来说国外的产品做产品比较规矩,把所有的串口信号都做上去了。但是国 内的技术人员发现,其实 RS-232 串口最主要使用的就是 2,3 线,另外的接口如果不使用的话,也不 会出现很大的问题,所以,就在 9 针的基础上做精简,所以就有所谓的 2,3,4,5,6,8 线的串口 出来了。. 2 线串口只有 RXD,TXD 两根基本的收发信号线;3 线串口除了 RXD 和 TXD,还有 GND;所谓 4~9 线只是在 TXD 和 RXD 基础上增加了相应的控制信号线,依据实际需要进行设计。 一般来说,使用 5 线的 232 通信,是加了硬件流控的,即 RTS,CTS 信号,主要是为了保证高速通 信时的可靠性,如果你的通信速度不是很高,完全可以不用理会。 3. 串口的速度与距离 RS-232(串口的英文代名词)采取不平衡传输方式,即所谓单端通讯。由于其发送电平与接收电 平的差仅为 2V 至 3V 左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最长 为约 15 米,最高速率为 20kb/s。RS-232 是为点对点(即只用一对收、发设备)通讯而设计的,其驱 动器负载为 3~7kΩ。所以 RS-232 适合本地设备之间的通信。 4. 从串口通信衍生出 422 与 485 的通信方式 RS-232、RS-422 与 RS-485 都是串行数据接口标准,最初都是由电子工业协会(EIA)制订并发布 的,RS-232 在 1962 年发布,命名为 EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 211 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 RS-422 由 RS-232 发展而来,它是为弥补 RS-232 之不足而提出的。为改进 RS-232 通信距离短、 速率低的缺点,RS-422 定义了一种平衡通信接口,将传输速率提高到 10Mb/s,传输距离延长到 4000 英尺(速率低于 100kb/s 时),并允许在一条平衡总线上连接最多 10 个接收器。RS-422 是一种单机发 送、多机接收的单向、平衡传输规范,被命名为 TIA/EIA-422-A 标准。 为扩展应用范围,EIA 又于 1983 年在 RS-422 基础上制定了 RS-485 标准,增加了多点、双向通信 能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性,扩展 了总线共模范围,后命名为 TIA/EIA-485-A 标准。 由于 EIA 提出的建议标准都是以“RS”作为前缀,所以在通讯工业领域,仍然习惯将上述标准以 RS 作前缀称谓。 RS-232、RS-422 与 RS-485 标准只对接口的电气特性做出规定,而不涉及接插件、电缆或协议, 在此基础上用户可以建立自己的高层通信协议。因此在视频界的应用,许多厂家都建立了一套高层通 信协议,或公开或厂家独家使用。如录像机厂家中的 Sony 与松下对录像机的 RS-422 控制协议是有差 异的,视频服务器上的控制协议则更多了,如 Louth、Odetis 协议是公开的,而 ProLINK 则是基于 Profile 上的。 5. 串口的通信方式(串口属于串行通信) (1)并行通信和串行通信 51 单片机与外界通信的基本方式有两种:并行通信和串行通信,并行通信是指利用多条数据传 输线将一个数据的各位同时发送或接收。串行通信是指利用一条传输线将数据一位位地顺序发送或接 收。 并行通信和串行通信的示意图如下图: 在每一条传输线传输速率相同时,并行通信的传输速度比和串行通信快。然而当传输距离变长时, 并行通信的缺点就会凸显,首先是相比于串行通信而言信号易受外部干扰,信号线之间的相互干扰也 增加,其次是速率提升之后不能保证每根数据线的数据同时到达接收方而产生接收错误,而且距离越 长布线成本越高。 所以并行通信目前主要用在短距离通信,比如处理器与外部的 flash 以及外部 RAM 以及芯片内部 各个功能模块之间的通信。串行通信以其通信速率快和成本低等优点成为了远距离通信的首选。 RS232C 串口,以及差分串行总线像 RS485 串口、USB 接口、CAN 接口、IEEE-1394 接口、以太网接 口、SATA 接口和 PCIE 接口等都属于串行通信的范畴。 下图左侧为每根数据线的数据同时到达接收方,被正确采样的最理想情况;右侧的图为每根数据 线的数据不能同时到达接收方而产生接收错误情形。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 212 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 (2)异步通信与同步通信 串行通信又分为两种方式:异步通信与同步通信。 A、 异步通信及其协议 异步通信以一个字符为传输单位,通信中两个字符间的时间间隔不固定可以是任意长的,然而在 同一个字符中的两个相邻位代码间的时间间隔是固定的,接收时钟和发送时钟只要相近就可以。 通 信双方必须使用约定的相同的一些规则(也叫通信协议)。 常见的传送一个字符的信息格式规定有起 始位、数据位、奇偶校验位、停止位等,其中各位的意义如下: 或 ① 起始位 先发出一个逻辑”0”信号,表示传输字符的开始。 ② 数据位 紧接着起始位之后。数据位的个数可以是 5、6、7、8 等,构成一个字符。一般采用扩 展的 ASCII 码,范围是 0~255,使用 8 位表示。首先传送最低位。 ③ 奇偶校验位(不是必须) 奇偶校验是串口通信中一种简单的检错方式,当然没有校验位 也是可以的。数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校 验数据传送的正确性。例如,如果数据是 01100000,那么对于偶校验,校验位为 0。 ④ 停止位 它是一个字符数据的结束标志。可以是 1 位、1.5 位、2 位的高电平。由于数据是在传 输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小 嵌入式专业技术论坛 (www.armjishu.com)出品 第 213 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机 会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也 越慢。 ⑤ 空闲位 处于逻辑“1”状态,表示当前线路上没有数据传送。 B、同步通信是指数据传送是以一个帧(数据块或一组字符)为传输单位,每个帧中包含有多个字符。 在通信过程中,字符与字符之间、字符内部的位与位之间都同步,每个字符间的时间间隔是相等的, 而且每个字符中各相邻位代码间的时间间隔也是固定的。同步通信的数据格式如图所示 同步通信的特点可以概括为: ① 以数据块为单位传送信息。 ② 在一个数据块(信息帧)内,字符与字符间无间隔。 ③ 接收时钟与发送进钟严格同步 同步串行通信方式中一次连续传输一块数据,开始前使用同步信号作为同步的依据。同步字符的 插入可以是单同步字符方式或双同步字符方式,均由同步字符、数据字符和校验字符 CRC 等三部分 组成: 同步字符位于帧结构开头,用于确认数据字符的开始。 数据字符在同步字符之后,字符个数不受限制,由所需传输的数据块长度决定; 校验字符有 1~2 个,位于帧结构末尾,用于接收端对接收到的数据字符的正确性的校验。 由于连续传输一个数据块,故收发双方时钟必须相当一致,否则时钟漂移会造成接收方数据辨认 错误。这种方式下往往是发送方在发送数据的同时也通过一根专门的时钟信号线同时发送时钟信息, 接收方使用发送方的时钟来接由数据。同步串行通信方式传输效率高,但对硬件要求高,电路结构复 杂。 所有的串行接口电路都是以并行数据形式与 CPU 接口、而以串行数据形式与外部逻辑接口。所 以串口对外应该是串行发送的,速度慢,但是比并行传输要稳定很多。 6. 串口是如何解决干扰以及校验的问题 什么是数据校验?通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的 一个校验值。接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,就说明数据是 完整的。 为了理解数据校验,什么是最简单的校验呢?最简单的校验就是把原始数据和待比较数据直接进 行比较,看是否完全一样这种方法是最安全最准确的。同时这样的比对方式也是效率最低的。只适用 于简单的数据量极小的通信。 串口通信使用的是奇偶校验方法,具体实现方法是在数据存储和传输中,字节中额外增加一个比 嵌入式专业技术论坛 (www.armjishu.com)出品 第 214 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 特位,用来检验错误。校验位可以通过数据位异或计算出来;也就是说单片机串口通讯有一模式就是 一次发送 8 位的数据通讯,增加一位第 9 位用于放校验值。 奇偶校验是一种校验代码传输正确性的方法。根据被传输的一组二进制代码的数位中“1”的个数 是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。采用何种校验是事先规定好 的。通常专门设置一个奇偶校验位,用它使这组代码中“1”的个数为奇数或偶数。若用奇校验,则 当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的正确性。 奇偶校验能够检测出信息传输过程中的部分误码(1 位误码能检出,2 位及 2 位以上误码不能检出), 同时,它不能纠错。在发现错误后,只能要求重发。但由于其实现简单,仍得到了广泛使用。 5.4.3 什么是单片机的TTL电平? 单片机是一种数字集成芯片,数字电路中只有两种电平:高电平和低电平;高电平和低电平是通 过单片机的管脚进行输入和输出的,我们只要记住一句话,单片机管脚不是输入就是输出,不是高电 平就是低电平。 为了让大家在初学的时候对电平特性有一个清晰的认识,我们暂且定义单片机输出与输入为 TTL 电平,其中高电平为+5V,低电平为 OV。计算机的串口出来的为 RS-232C 电平,其中高电平为-5V— -12V, 低电平为+5V—+12V。这里要强调的是,RS-232C 电平为负逻辑电平,所以高电平为负的,低电平为正 的,大家千万不要认为上面是我写错了,因此当计算机与单片机之间要通信时,需要加电平转换芯片, 我们在神舟 51 单片机实验板上所加的电平转换芯片是 MAX3232(在串口 DB9 座附近)。初学者在学习 时先掌握上面这点就够了,若有兴趣请大家再看下面的知识点——常用逻辑电平。 知识点:常用逻辑电平 常用的逻辑电平有 TTL、CMOS、LVTTL、ECL、PECL、GTL、RS-232、RS-422、RS-485、LVDS 等。 其中 TTL 和 CMOS 的逻辑电平按典型电压可分为四类:5V 系列(5V 的 TTL 和 5V 的 CMOS)、3.3V 系列, 2.5V 系列和 1.8V 系列。 5V 的 TTL 和 5V 的 CMOS 是通用的逻辑电平。3.3V 及以下的逻辑电平被称为低电压逻辑电平,常 用的为 LVTTL 电平。低电压逻辑电平还有 2.5V 和 1.8V 两种。 那为什么 TTL 电平信号用的最多呢? 原因 1:这是因为大部分数字电路器件都用这个电平标准。就好像我们学英语,国际通用英语这 门语言,那大家都用这个语言进行交流和沟通,所以后来的人都要学习英语才能彼此相互能交流。所 以使得越来越多的电路器件使用这个电平标准。TTL 电平数据表示通常采用二进制,+5V 等同于逻辑 1, OV 等同于逻辑 O,这被称为 TTL(晶体管一晶体管逻辑电平)信号系统,这是计算机处理器控制的设 备内部各部分之问通信的标准技术。TTL 电平信号对于计算机处理器控制的设备内部的数据传输是很 理想的,首先计算机处理器控制的设备内部的数据传输对于电源的要求不高,热损耗也较低,另外 TTL 电平信号直接与集成电路连接而不需要价格昂贵的线路驱动器以及接收器电路。 原因 2:TTL 电平的特点适合设备内数据高速的传输。TTL 的通信大多数情况是采用并行数据传 输方式,但电平最高为+5V,电压相对比较低,所以传输过程中会有电压损耗和压降,导致 TTL 的传 输距离是有限的,一般只适合近距离传输;而且并行数据传输对于超过 10 英尺的距离就可能会有同 步偏差,传输距离太远,有可能造成数据不同步;所以 TTL 电平符合近距离(在芯片内部或者计算机 内部进行高速数据交互)高速的并行传输,在数字电路要求数据处理速度高的时代来说,选择 TTL 这 个标准是正确的,可靠的。 CMOS 电平最高可达 12V,CMOS 电路输出高电平在 3V~12V 之间,而输出低电平接近 0 伏。CMOS 电 路中不使用的输入端不能悬空,否则会造成逻辑混乱。另外,CMOS 集成电路因为电源电压可以在较大 范围内变化,因而对电源的要求不像 TTL 集成电路那样严格。 TTL 电路和 CMOS 电路的逻辑电平关系如下: 1) CMOS 是场效应管构成,TTL 为双极晶体管构成;因为 TTL 和 COMS 的高低电平的值不一样,所 以互相连接时需 要电平的转换。 2) TTL 电路是电流控制器件,而 coms 电路是电压控制器件。 3) TTL 电路的速度快,传输延迟时间短(5-10ns),但是功耗大;COMS 电路的速度慢,传输延迟 时间长(25-50ns),但功耗低,COMS 电路本身的功耗与输入信号的脉冲频率有关,频率越高,芯片集越 热,这是正常现象。 4) CMOS 集成电路电源电压可以在较大范围内变化,因而对电源的要求不像 TTL 集成电路那样严 嵌入式专业技术论坛 (www.armjishu.com)出品 第 215 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 格。所以,用 TTL 电平在条件允许下他们就可以兼容。要注意到他们的驱动能力是不一样的,CMOS 的 驱动能力会大一些,有时候 TTL 的低电平触发不了 CMOS 电路,有时 CMOS 的高电平会损坏 TTL 电路, 在兼容性上需注意。 5) CMOS 的高低电平之间相差比较大、抗干扰性强,TTL 则相差小,抗干扰能力差。 6) CMOS 的工作频率较 TTL 略低。 TTL 电平临界值: 1)TTL 输出电压:逻辑电平 1 = 2.4V,逻辑电平 0 = 0.4V 2)TTL 输入电压:逻辑电平 1 = 2.0V,逻辑电平 0 = 0.8V CMOS 电平临界值(设电源电压为+5V) 1) CMOS 输出电压:逻辑电平 1 = 4.99V,逻辑电平 0 = 0.01V 2) CMOS 输入电压:逻辑电平 1 = 3.5V,逻辑电平 0 = 1.5V 常用逻辑芯片的特点如下: 74LS 系列: TTL 输入:TTL 输出:TTL 74HC 系列: CMOS 输入: CMOS 输出: CMOS 74HCT 系列: CMOS 输入:TTL 输出: CMOS CD4000 系列: CMOS 输入: CMOS 输出: CMOS 通常情况下,单片机、ARM、DSP、FPGA 等各个器件之间引脚能否直接相连要参考以下方法进行 判断:一般来说,同电压的是可以相连的,不过最好还是好好查看芯片技术手册上的 VIL(逻辑电平 0 的输入电压)、VIH(逻辑电平 1 的输入电压)、VOL(逻辑电平 0 的输出电压)、VOH(逻辑电平 1 的输出电压)的值,看是否能够匹配。有些情况在一般应用中没有问题,虽然参数上有点不够匹配, 但还是在管脚的最大和最小容忍值范围之内,不过有可能在某些情况下可能就不够稳定,所以我们在 设计电路的时候要尽量保持匹配,这样是最佳的设计。 5.4.4 关于NPN和PNP的三极管基础知识? 对三极管放大作用的理解,切记一点:能量不会无缘无故的产生,所以,三极管一定不会产生能 量,但三极管厉害的地方在于:它可以通过小电流控制大电流。放大的原理就在于:通过小的交流输 入,控制大的静态直流。假设三极管是个大坝,这个大坝奇怪的地方是,有两个阀门,一个大阀门, 一个小阀门。小阀门可以用人力打开,大阀门很重,人力是打不开的,只能通过小阀门的水力打开。 所以,平常的工作流程便是,每当放水的时候,人们就打开小阀门,很小的水流涓涓流出,这涓涓细 流冲击大阀门的开关,大阀门随之打开,汹涌的江水滔滔流下。如果不停地改变小阀门开启的大小, 那么大阀门也相应地不停改变,假若能严格地按比例改变,那么,完美的控制就完成了。 在这里,基极B->发射极E就是小水流,集电极C->发射极E就是大水流。当然,如果把水流比为电 流的话,会更确切,因为三极管毕竟是一个电流控制元件。 如果某一天,天气很旱,江水没有了,也就是大的水流那边是空的。管理员这时候打开了小阀门, 尽管小阀门还是一如既往地冲击大阀门,并使之开启,但因为没有水流的存在, 所以,并没有水流出来。这就是三极管中的截止区。 饱和区是一样的,因为此时江水达到了很大很大的程度,管理员开的阀门大小已经没用了。如果 不开阀门江水就自己冲开了,这就是二极管的击穿。 在模拟电路中,一般阀门是半开的,通过控制其开启大小来决定输出水流的大小。没有信号的时 嵌入式专业技术论坛 (www.armjishu.com)出品 第 216 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 候,水流也会流,所以,不工作的时候,也会有功耗。 而在数字电路中,阀门则处于开或是关两个状态。当不工作的时候,阀门是完全关闭的,没有功 耗。 那么NPN与PNP的三极管到底有些什么区别呢? NPN和PNP主要就是电流方向和电压正负不同,说得“专业”一点,就是“极性”问题。 NPN 是用 B→E 的电流(小水流)控制 C→E 的电流(大水流),E极电位最低,且正常放大时 通常C极电位最高,即 VC>VB>VE。 PNP 是用 E→B 的电流(小水流)控制 E→C 的电流(大水流),E极电位最高,且正常放大时通 常C极电位最低,即VCCH340>PL2303,PL2303 用的最多,因为最便宜,国内很多开发板板子上,包括 USB 转串口线用的都是这种芯片,几元钱一片,电路也简单,做简单的串口应用可以,但是做嵌入式 开发如使用超级终端波特率在 115200 时就有可能出现延迟等现象。CH340 是南京沁恒的芯片,做的 还不错,对于普通应用完全能够满足。最好的是 FT232 稳定、可靠,在很多 USB 转串口的下载线、 编程器中使用的都是这一种,神舟开发板上目前使用的是 PL2303HX 芯片。 USB 转串口芯片转出来串口电平就是 TTL 电平,高电平一般是 3.3V,如果转出来的电平再经过 MAX232 或 MAX485 芯片再转一下就会输出 RS232 电平或者 485 电平。其实市面上的 USB 转串口线 一般都是这样接的。 5.4.8 例程01 最简单串口打印$字符 1. 例程简介: STM32 的 GPIOA 端口的 PA9 和 PA10 位,即串口 1;设置 PA9 为 TX 输出模式,复用功能推挽 输出模式;设置 PA10 为 RX 输入模式,模拟输入模式;对超级终端打印输出字符”$”符号。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 220 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 拿串口线将 STM32 神舟 III 号开发板上的串口 1 和电脑的串口连起来,具体硬件电路这里不细说。 2. 调试说明: 1) 打开开始菜单->程序->附件->通讯->超级终端 2) 输入“STM32 神舟系列开发板” 嵌入式专业技术论坛 (www.armjishu.com)出品 第 221 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3) 紧接着,将神舟 III 号开发板上的串口 1 和电脑的串口用串口线连起来。(我这里用的是台式机, 台式机预留的串口一般为串口 1) 4) 波特率例程代码中设置的是 115200,数据流控制是无,选择完毕,点确定按钮 嵌入式专业技术论坛 (www.armjishu.com)出品 第 222 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 5) 最后把例程程序下载到开发板里,然后按一下开发板复位或者重新上电,就会打印出“$”的字符, 一会打印一个,恭喜发财哦! 3. 关键代码: int main(void) //main 是程序入口 { RCC_init(); //时钟频率的配置 LED_init(); //LED 初始化配置 uart_init(); //串口接口初始化,这个部分是按 STM32 芯片手册的要求来做的,比较枯燥, 细节感兴趣的朋友可以去研究下 while (1) { USART1->DR = 0x24; // 打印符号$,0x24 是 ASCII 码 LEDON; //点亮 LED 灯 Delay(0xFFFFFF); // 延时 嵌入式专业技术论坛 (www.armjishu.com)出品 第 223 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 LEDOFF; // 熄灭 LED 灯 Delay(0xFFFFFF); // 延时 } } void uart_init() { float USARTDIV; /* 因为 32 位的 USART_BRR 波特率设置寄存器只有低 16 位有效,所以这里我们定义 16 位寄存 器就足够了 */ u16 USARTDIV_zhengshu; //这里相当于 u16,无符号 16 位 u16 USARTDIV_xiaoshu; //这里相当于 u16,无符号 16 位 RCC->APB2ENR|=1<<2; //使能 PORTA 口时钟 RCC->APB2ENR|=1<<14; //使能串口时钟 GPIOA->CRH&=0XFFFFF00F; GPIOA->CRH|=0X000008B0; //IO 状态设置 USARTDIV = (float)(72*1000000)/(115200*16); USARTDIV_zhengshu = USARTDIV; USARTDIV_xiaoshu = (USARTDIV - USARTDIV_zhengshu)* 16; USARTDIV_zhengshu <<=4; USARTDIV_zhengshu += USARTDIV_xiaoshu; RCC->APB2RSTR|=1<<14; //复位串口 1 RCC->APB2RSTR&=~(1<<14);//停止复位 USART1->BRR = USARTDIV_zhengshu; USART1->CR1|=0X200C; //1 位停止,无校验位. } 代码详细分析: (1)RCC_init();这个函数是负责时钟频率的配置,这里默认配置为 72MHZ,前面章节有详细分 析,这里简化,有疑问的可以翻看前面的章节细节。 (2)LED_init()这个函数是初始化 LED 的配置,这个是附带的,如果串口无法正常打印,只要程 序能运行,那 LED 灯就会进行闪烁。 (3)uart_init()这个函数负责串口的初始化,这个部分是按 STM32 芯片手册的要求来做的,比较 枯燥,细节感兴趣的朋友可以继续往下看,不感兴趣的可以跳过这一节,这个函数要把波特率初始化 为 115200,下面我们仔细分析一下代码: (3-1)初始化一下波特率的值,一个是波特率的整数部分,一个是波特率的小数部分 u16 USARTDIV_zhengshu; //这里相当于 u16,无符号 16 位,波特率的整数部分 u16 USARTDIV_xiaoshu; //这里相当于 u16,无符号 16 位,波特率的小数部分 (3-2)初始化串口的时钟,再初始化 PA9 和 PA10 两个管脚的 GPIO 端口 A 的时钟。从原理图可 以看到,USART1 的 TX 和 RX 就是 PA9 和 PA10,要使用串口不仅仅要初始化 GPIO 端口 A 的时钟, 还要初始化串口的时钟,这里是需要注意的,如果点灯程序或者只做为普通的 GPIO 管脚使用,就不 需要初始化串口的时钟。 串口时钟使能。串口作为 STM32 的一个外设,其时钟由外设始终使能寄存器控制,这里我们使 用的串口 1 是在 APB2ENR 寄存器的第 14 位。这里需要注意的一点是,除了串口 1 的时钟使能在 APB2ENR 寄存器,其他串口的时钟使能位都在 APB1ENR。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 224 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 RCC->APB2ENR|=1<<2; //使能 PORTA 口时钟 RCC->APB2ENR|=1<<14; //使能串口时钟 (3-3) 设置串口通信 RXD 和 TXD 的配置,一个管脚是接收就要设置为输入模式,一个管脚是 输出,就设置成输出模式;寄存器 CRL 是设置 GPIO 的 0~7 位,CRH 是设置 GPIO 的 8~15 位,可以 看到这里是设置 GPIOA 端口的 9 和 10 位,即 PA9 和 PA10 设置 PA9 为 TX 输出模式,复用功能推挽 输出模式设置 PA10 为 RX 输入模式,模拟输入模式 GPIOA->CRH&=0XFFFFF00F; GPIOA->CRH|=0X000008B0; //IO 状态设置 (3-4)设置波特率,在 CPU 是 72MHZ 的频率下,设置波特率为 115200;STM32 中波特率是如 何计算的,首先看下文档: (x=1、2)是给外设的时钟(PCLK1 用于串口 2、3、4、5,PCLK2 用于串口 1),USARTDIV 是一个无符号的定点数,它的值可以有串口的 USART_BRR 寄存器值得到。而我们更关心的是如何从 USARTDIV 的值得到 USART_BRR 的值,因为一般我们知道的是波特率,和 PCLKx 的时钟,要求的 就是 USART_BRR 的值。 可以看到上图波特比率寄存器 USART_BRR 是低 16 位有效,高 16 位是闲置的,最低 4 位用来存 放整数部分 DIV_Fraction,[15:4]这 12 位用来存放小数部分 DIV_Mantissa。高 16 位未使用。这里波 特率的计算通过如下公式计算: 假设我们的串口 1 要设置为 115200 的波特率,而 PCLK2 的时钟为 72M。这样,我们根据上面的 公式有: USARTDIV = / 波特率*16 = (72*1000000)/(115200*16) = 39.0625 我们查看《STM32F10XX 参考手册》中的第 525 页的一个表: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 225 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 USARTDIV 的值被设置为 39.0625,也就是 USART_BRR 寄存器 那么得到: DIV_ Mantissa = 39 = 0x27; DIV_ Fraction = 16*0.0625 = 1= 0x1; 这样,我们就得到了 USART1->BRR 的值为 0x271。只要设置串口 1 的 BRR 寄存器值为 0x271 就可以得到 115200 的波特率。 USARTDIV = (float)(72*1000000)/(115200*16);//算出 USARTDIV 的值 USARTDIV_zhengshu = USARTDIV; /* 因为波特率设置寄存器是 USARTDIV 整数在 0~3 位,小数在 4~15 位乘以 16 是因为小数点后面是 4 位,将它右移过来取成整数 */ USARTDIV_xiaoshu = (USARTDIV - USARTDIV_zhengshu)* 16; USARTDIV_zhengshu <<=4; USARTDIV_zhengshu += USARTDIV_xiaoshu; (3-5) 当 CPU 刚启动的时候一般都需要重新复位一下外设,确保该外设在正常供电稳定后,能 够稳定的工作可以看到复位一下之后就可以了,然后停止复位,让其开始正常工作。 串口复位。当外设出现异常的时候可以通过复位寄存器里面的对应位设置,实现该外设的复位, 然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复 位该外设的操作。串口 1 的复位是通过配置 APB2RSTR 寄存器的第 14 位来实现的。APB2RSTR 寄存 器的各位描述如下: 从上图可知串口 1 的复位设置位在 APB2RSTR 的第 14 位。通过向该位写 1 复位串口 1,写 0 结 束复位。其他串口的复位位在 APB1RSTR 里面。 RCC->APB2RSTR|=1<<14; //复位串口 1 RCC->APB2RSTR&=~(1<<14);//停止复位 (3-6)把 115200 的波特率设置到 USART1->BRR 寄存器中,并且设置一下串口控制的寄存器 USART_CR1。STM32 的每个串口都有 3 个控制寄存器 USART_CR1~3,串口的很多配置都是通过这 3 个寄存器来设置的。这里我们只要用到 USART_CR1 就可以实现我们的功能了,这里主要设置该串 嵌入式专业技术论坛 (www.armjishu.com)出品 第 226 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 口使能,正式启动这个串口功能该寄存器的描述在《STM32F1XX 参考手册》第 542 有更多的详细介 绍: USART1->BRR = USARTDIV_zhengshu; USART1->CR1|=0X200C; //1 位停止,无校验位. (3-7)数据发送与接收。STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一 个双寄存器,包含了发送或接收的数据。由于它是由两个寄存器组成的,一个给发送用(TDR),一个 给接收用(RDR),该寄存器兼具读和写的功能,寄存器描述如下: DR[8:0]为串口数据,可以看出,虽然是一个32位寄存器,但是只用了低9位(DR[8:0]),其他都 是保留。 代码 USART1->DR = 0x24 是被用来打印符号$,0x24 是 ASCII 码请看下图,通过把这个 0x24 输 嵌入式专业技术论坛 (www.armjishu.com)出品 第 227 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 送给 USART_DR 寄存器后,就可以打印出$字符。 (4)进入 while(1)死循环,不停的让 LED 灯亮和灭,然后每次 LED 亮灭一次,就打印一个$字 符,中间有一些延时,具体代码很简单。 5.4.9 例程02 单串口打印www.armjishu.com字符-初级 1. 例程简介: 例程同上个一样,只是打印出 www.armjishu.com这么多字符来,增加了一些ASCII码。 2. 调试说明: 其他都与上个例程一样,下载进去后,打印出来的是如下图所示 3. 关键代码: int main(void) //main 是程序入口 { RCC_init(); //时钟频率的配置 LED_init(); //LED 初始化配置 uart_init(); //串口接口初始化,这个部分是按 STM32 芯片手册的要求来做的,比较枯燥,细节 感兴趣的朋友可以去研究下 while (1) { /* 通过查 ASCII 码表打印“www.armjishu.com”的 LOGO 每打印一个字符,都需要延时一下 * 如果不加延时程序,就无法正确打印出,因为串口的缓冲数据需要一点时间才送出去,所以 需要等待一下 */ USART1->DR = 0x77; //w Delay(0xFFF); // 延时 USART1->DR = 0x77; //w Delay(0xFFF); // 延时 USART1->DR = 0x77; //w 嵌入式专业技术论坛 (www.armjishu.com)出品 第 228 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 Delay(0xFFF); // 延时 USART1->DR = 0x2e; //. Delay(0xFFF); // 延时 USART1->DR = 0x61; //a Delay(0xFFF); // 延时 USART1->DR = 0x72; //r Delay(0xFFF); // 延时 USART1->DR = 0x6d; //m Delay(0xFFF); // 延时 USART1->DR = 0x6a; //j Delay(0xFFF); // 延时 USART1->DR = 0x69; //i Delay(0xFFF); // 延时 USART1->DR = 0x73; //s Delay(0xFFF); // 延时 USART1->DR = 0x68; //h Delay(0xFFF); // 延时 USART1->DR = 0x75; //u Delay(0xFFF); // 延时 USART1->DR = 0x2e; //. Delay(0xFFF); // 延时 USART1->DR = 0x63; //c Delay(0xFFF); // 延时 USART1->DR = 0x6f; //o Delay(0xFFF); // 延时 USART1->DR = 0x6d; // m Delay(0xFFF); // 延时 USART1->DR = 0x20; // 空格 LEDON; //点亮 LED 灯 Delay(0xFFFFFF); // 延时 LEDOFF; // 熄灭 LED 灯 Delay(0xFFFFFF); // 延时 } } 代码分析: 可以看到,其实就是逐个打印出 www.armjishu.com的ASCII码而已。 5.4.10 例程03 单串口打印www.armjishu.com字符-中级 1. 例程简介: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 229 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 例程同上个一样,只是打印出 www.armjishu.com这么多字符来,增加了一些ASCII码,主要体现代 码撰写表达有区别。 2. 调试说明: 其他都与上个例程一样,下载进去后,打印出来的是如下图所示 3. 关键代码: int main(void) //main 是程序入口 { RCC_init(); //时钟频率的配置 LED_init(); //LED 初始化配置 uart_init(); while (1) { USART1_Printf(" www.armjishu.com "); LEDON; //点亮 LED 灯 Delay(0xFFFFFF); // 延时 LEDOFF; // 熄灭 LED 灯 Delay(0xFFFFFF); // 延时 } } void USART1_Printf(char *pch) { while(*pch != '\0') { USART_SendData(USART1,pch); pch++; } } void USART_SendData(USART_TypeDef* USARTx, char *Data) { USARTx->DR = *Data; Delay(0xFFF); } 代码分析: (1) 可以看到,用 USART1_Printf(" www.armjishu.com ")这个函数逐个打印出 www.armjishu.com 的字符。 (2)USART1_Printf()函数内部具体实现,就是把*pch指向这个 www.armjishu.com其中一个单 个字符,然后调用USART_SendData(USART1,pch)将这个字符往串口 1 发送输出,再用while(*pch != '\0') 判断下一个字符是不是结束符,不是的话继续打印下一个字符。 (3)最后调用 USART_SendData(USART_TypeDef* USARTx, char *Data)这个函数,将字符数据 的 USARTx->DR = *Data;给到 USART1_DR 寄存器,这里的 USART_SendData()函数中的*Data 等同于 上个函数的 USART1_Printf ()函数中的*pch,而*pch 等同于 USART1_Printf()函数中的一个字符。 关于USART1_Printf(" www.armjishu.com "),这个 www.armjishu.com在USART1_Printf()函数中创 造了一个内存空间,这个内存空间是在main函数开始调用USART1_Printf()函数时分配的,而传入 嵌入式专业技术论坛 (www.armjishu.com)出品 第 230 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 到USART1_Printf()中的pch是为 www.armjishu.com所分配的这个内存区域的一个指针的地址,然后 继 续 把 这 个 指 针 的 地 址 传 给 USART_SendData() 中 的 Data 变 量 ; 换 句 话 说 , Data 等 于 pch 等 于 www.armjishu.com字符串内存区域的首地址。 5.4.11 例程04 单串口打印www.armjishu.com字符-高级 1. 例程简介: 例程同上个一样,只是打印出 www.armjishu.com这么多字符来,主要体现代增加了一些串口传送 校验。 2. 调试说明: 其他都与上个例程一样,下载进去后,打印出来的是如下图所示 3. 关键代码: void USART1_Printf(char *pch) { while(*pch != '\0') { USART_SendData(USART1,pch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_ClearFlag(USART1, USART_FLAG_TXE); pch++; } } void USART_SendData(USART_TypeDef* USARTx, char *Data) { USARTx->DR = (*Data & (uint16_t)0x01FF); // 这里的*Data 就是一个字符 while((USARTx->SR&0x40) == 0); } 代码分析: (1) USARTx->DR = (*Data & (uint16_t)0x01FF) 这里的*Data 就是一个字符,ASCII 码是 0~127,并且 DR 是 0~8 个 bit 有效,可以看手册的 USART_DR 寄存器的描述,所以这里 实际上我们只需要取二进制的前 9 位即可。 (2) while((USARTx->SR&0x40) == 0),USART_SR 是状态寄存器 嵌入式专业技术论坛 (www.armjishu.com)出品 第 231 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 判断 TC 是不是已经发送完成,当包含有数据的一帧发送完成后,由硬件将该位置位,之前 的代码是通过一定的延时,现在是判断寄存器,判断寄存器可以使得数据在第一时间发出之后, 就能够使得开始进行下面的代码,比人工去延时的效率显著提高,所以算是比上个例程性能上的 一种优化。 (3)当发送完一个数据后,while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 查看一下寄存器说明: 判断 USART _SR 寄存器当中的 TXE 是不是为 1,如果是为 1 才能结束这个 while 循环,当等于 1 的时候,数据已经被发送出去了,进入了移位寄存器。 (4)USART_ClearFlag(USART1, USART_FLAG_TXE)这句代码是我们查看《STM32F1xx 参考手 册》获得 540 页 25.6.1 节 状态寄存器(USART_SR)章节,这里说的就是我们程序代码里的 USART_FLAG_TXE 这个标志位,等数据发送完毕后,再进行标志清空,方便进行下一次传输的 时候有效使用。 5.4.12 例程05 USART-COM1串口接收与发送实验-初级版 1.例程简介: 例程主要实现在键盘上敲一个字符,输入这个字符到串口中,然后再通过超级终端打印出来。 2.调试说明: 1)下载完程序后,打开超级终端,敲入字符 d,可以看到整个超级终端不停的输出 d 这个字符, 表示输入成功。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 232 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2)重新按下复位按键,再次输入字符 a,可以看到界面满屏幕都输出整屏 a 4. 关键代码: int main(void) { uint8_t inputstr[CMD_STRING_SIZE]; RCC_init(); uart_init(); GetInputString(inputstr); } void GetInputString (uint8_t * buffP) { uint8_t c = 0; do 嵌入式专业技术论坛 (www.armjishu.com)出品 第 233 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 { c = (uint8_t)USART1->DR; USART_SendData(USART1,c); } while (1); } void USART_SendData(USART_TypeDef* USARTx, uint8_t Data) { USARTx->DR = (Data & (uint16_t)0x01FF); } 代码分析: (1) uint8_t inputstr[CMD_STRING_SIZE] 代 码 声 明 一 个 数 组 , 可 以 看 到 程 序 中 变 量 CMD_STRING_SIZE = 128,就是表示这个数组有 128 个成员,每个成员都是 uint8_t 类 型的。 (2) 接下来就是时钟初始化函数 RCC_init()和串口初始化函数 uart_init(),之前都有详细 介绍,这里就不做具体分析了。 (3) GetInputString(inputstr) 这 句 代 码 表 示 取 inputstr[] 数 组 的 初 地 址 传 入 到 GetInputString()这个函数中,知道了 inputstr[]数组的首地址后,就可以在函数里操 作和修改这个数组的内容。这里主要是熟悉一下指针和数组的一些基础概念,前面章节 已经有详细分析。 (4) 可以看到数据寄存器 USART_DR 包含了发送或接收的数据。由于它是由两个寄存器组成 的,一个给发送用(TDR),一个给接收用(RDR),该寄存器兼具读和写的功能。 在 GetInputString()函数中,用 c = (uint8_t)USART1->DR 这句代码来读取输入到超级终端的 键盘字符,如果有输入,那么 c 就会得到输入的初值 (5) 最后 USART_SendData(USART1,c)将 c 中的字符输出到超级终端上,细节请见代码。 5.4.13 例程06 USART-COM1串口接收与发送实验-中级版 1.例程简介: 例程主要实现在键盘上敲一个字符,输入这个字符到串口中,然后再通过超级终端打印出来,例 程与上个不同的是“www.armjishu.com 键盘输入 2013 年:”的字符串,而这个字符串输入出来有一个 人机交互界面的感觉,其他都与上个例程相同 嵌入式专业技术论坛 (www.armjishu.com)出品 第 234 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2.调试说明: 1)下载完程序后,打开超级终端,按下复位按键,可以看到“www.armjishu.com 键盘输入 2013 年:”的字符串 ,然后敲入字符 d,可以看到整个超级终端不停的输出 d 这个字符,表示输入成功。 2)重新按下复位按键,可以再次看到“www.armjishu.com 键盘输入 2013 年:”的字符串,输入字 符 a,可以看到界面满屏幕都输出整屏 a 3. 关键代码: 这里代码不做具体分析,之前有详细说 5.4.14 例程05 USART-COM1串口接收与发送实验-高级版 1. 例程简介: 例程主要实现在键盘上敲一个字符,输入这个字符到串口中,而之前的例程输出都是整屏不停的 输出,这个例程加入了字符串部分代码的健壮,使得输入一个字符就是一个字符,绝对不会溢出或者 数据丢失,或者重复输入。 2. 调试说明: 下载完程序后,打开超级终端,按下复位按键,可以看到“www.armjishu.com 键盘输入 2013 年:” 的字符串 ,每敲一个字符,就会输出一个字符,不会有多余的字符出现。 3. 关键代码: uint32_t SerialKeyPressed(uint8_t *key) { if ( USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET) { *key = (uint8_t)USART1->DR; return 1; } else { return 0; } } uint8_t GetKey(void) { uint8_t key = 0; while (1) { if (SerialKeyPressed((uint8_t*)&key)) break; } return key; } void GetInputString (uint8_t * buffP) { uint32_t bytes_read = 0; uint8_t c = 0; do { 嵌入式专业技术论坛 (www.armjishu.com)出品 第 235 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 c = GetKey(); if (c == '\r') break; if (c == '\b') /* Backspace */ { if (bytes_read > 0) { USART1_Printf("\b \b"); bytes_read --; } continue; } if (bytes_read >= (CMD_STRING_SIZE)) { USART1_Printf("Command string size overflow\r\n"); bytes_read = 0; continue; } if (c >= 0x20 && c <= 0x7E) { buffP[bytes_read++] = c; SerialPutChar(c); } } while (1); USART1_Printf(("\n\r")); buffP[bytes_read] = '\0'; } 代码分析: (1) SerialKeyPressed(uint8_t *key)函数分析 1)用语句 USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET 判断 USART_DR 寄存器中是否收到数据,如果收到了数据就可以读出。 2)*key = (uint8_t)USART1->DR; 第二步就是把数据取出来放到*key 中,*key 的此时的值就 是键盘输入的字符的 ASCII 码的值。 (2) GetKey(void)函数在函数里分配了 key 的内存空间,然后调用了 SerialKeyPressed()函数; 其实这 GetKey 和 SerialKeyPressed 这两个函数在这个例程里可以合并,但是这样的写法 有个好处就是,获取键盘的输入不一定是在串口中,也有可能是 can 的数据,或者 485, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 236 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 (3) 或者是网口等其他渠道的输入,用 GetKey()这个标准函数,再在里面调用具体的子函数, 这样的好处就是增加了代码的可移植性。 GetInputString()分析获得一个输入之后,就开始一系列判断,这个输入是不是空格, 是不是换行符,如果是,就进行相对应的处理,这里值得注意的是,越详细,越复杂就 表示你的输入这部分的代码越健壮,各种异常输入情况都考虑进去了;最后经过一连串 的判断之后,合格的输入就调用 SerialPutChar()函数,把用户输入的内容输出到超级终端 上。 第六章 STM32库函数架构剖析 本章通过简单介绍 STM32 库的各个文件及其关系,让读者建立 STM32 库的概念,看完后对库有 个总体印象即可,在后期实际开发时接触了具体的库时,再回头看看这一章,相信你对 STM32 库又 会有一个更深刻的认识。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 237 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 6.1 STM32库函数到底是什么 STM32 的库函数是 ST 公司已经封装好一个软件封装库,也就是很多基础的代码,在开发产品的 时候只需要直接调用这个 ST 库函数的函数接口就可以完成一系列工作;例如,你原来要自己烧饭洗 衣服,现在 ST 库函数就好像一个保姆,你只需要使唤一声就有饭吃,有干净的衣服了。 6.2 STM32库函数的好处 在 51 单片机的程序开发中,我们直接配置 51 单片机的寄存器,控制芯片的工作方式,如中断, 定时器等。配置的时候,我们常常要查阅寄存器表,看用到哪些配置位,为了配置某功能,该置 1 还 是置 0。这些都是很琐碎的、机械的工作,因为 51 单片机的软件相对来说较简单,而且资源很有限, 所以可以直接配置寄存器的方式来开发。 STM32 库是由 ST 公司针对 STM32 提供的函数接口,即 API (Application Program Interface),开发 者可调用这些函数接口来配置 STM32 的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发 快速,易于阅读,维护成本低等优点。 当我们调用库的 API 的时候可以不用挖空心思去了解库底层的寄存器操作,就像当年我们学习 C 语言的时候,用 prinft()函数时只是学习它的使用格式,并没有去研究它的源码实现,如非必要,可以 说是老死不相往来。 实际上,库是架设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配置,向上 为用户提供配置寄存器的接口。 6.3 千人大项目如何分配工作 其实大多数项目产品研发都是用类似库函数的方式进行分解的,如果有 1000 个开发人员来负责开 发板 windows 操作系统,那么怎么做?一定是有一群人负责最底层的硬件级,寄存器的读写封装,包 括显示器的点亮,图形刷写;然后另外一群人根据底层这群人提供的接口,同步做二次开发。 所以库函数的理念完全被广泛应用于各种实际的项目和产品中,因为这样才可以使得多人协同工 作,才能做更大的项目产品。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 238 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 6.4 STM32库结构剖析 6.4.1 CMSIS标准 我们知道由 ST 公司生产的 STM32 采用的是 Cortex-M3 内核,内核是整个微控制器的 CPU。该内 核是 ARM 公司设计的一个处理器体系架构。ARM 公司并不生产芯片,而是出售其芯片技术授权。ST 公司或其它芯片生产厂商如 TI,负责设计的是在内核之外的部件,被称为核外外设或片上外设、设备 外设。如芯片内部的模数转换外设 ADC、串口 UART、定时器 TIM 等。内核与外设,如同 PC 上的 CPU 与主板、内存、显卡、硬盘的关系: 因为基于 Cortex 的某系列芯片采用的内核都是相同的,区别主要为核外的片上外设的差异,这些 差异却导致软件在同内核,不同外设的芯片上移植困难。为了解决不同的芯片厂商生产的 Cortex 微控 制器软件的兼容性问题,ARM 与芯片厂商建立了 CMSIS 标准(Cortex MicroController Software Interface Standard)。 所谓 CMSIS 标准,实际是新建了一个软件抽象层。见下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 239 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 CMSIS 标准中最主要的为 CMSIS 核心层,它包括了: z 内核函数层:其中包含用于访问内核寄存器的名称、地址定义,主要由 ARM 公司提供 z 设备外设访问层:提供了片上的核外外设的地址和中断定义,主要由芯片生产商提供 可见 CMSIS 层位于硬件层与操作系统或用户层之间,提供了与芯片生产商无关的硬件抽象层, 可以为接口外设、实时操作系统提供简单的处理器软件接口,屏蔽了硬件差异,这对软件的移植是有 极大的好处的。STM32 的库,就是按照 CMSIS 标准建立的。 6.4.2 库目录,文件简介 STM32 的 3.5 版库可以从官网获得,也可以直接从本书的附录光盘得到。本书主要采用最新版的 3.5 库文件,在高级篇的章节有部分代码是采用 3.0 的库开发的,因为 3.5 与 3.0 的库文件兼容性很好, 对于旧版的代码我们仍然使用用 3.0 版的。 解压后进入库目录:stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0 各文件夹内容说明见图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 240 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 Libraries 文件夹下是驱动库的源代码及启动文件。 Project 文件夹下是用驱动库写的例子跟一个工程模板。 还有一个已经编译好的 HTML 文件,是库帮助文档,主要讲的是如何使用驱动库来编写自己的应 用程序。说得形象一点,这个 HTML 就是告诉我们:ST 公司已经为你写好了每个外设的驱动了,想 知道如何运用这些例子就来向我求救吧。不幸的是,这个帮助文档是英文的,这对很多英文不好的朋 友来说是一个很大的障碍。但要告诉大家,英文仅仅是一种工具,绝对不能让它成为我们学习的障碍。 其实这些英文还是很简单的,我们需要的是拿下它的勇气。 网上流传有一份中文版本的库帮助文档,但那个是 2.x 版本的,但 3.x 以上版本的目录结构和库 函数接口跟 2.x 版本的区别还是比较大的,这点大家要注意下。 在使用库开发时,我们需要把 libraries 目录下的库函数文件添加到工程中,并查阅库帮助文档来 了解 ST 提供的库函数,这个文档说明了每一个库函数的使用方法。 进 入 Libraries 文 件 夹 看 到 , 关 于 内 核 与 外 设 的 库 文 件 分 别 存 放 在 CMSIS 和 STM32F10x_StdPeriph_DrIer 文件夹中。 Libraries\CMSIS\CM3 文件夹下又分为 CoreSupport 和 DeviceSupport 文件夹。 6.4.3 关于core_cm3.c文件 在 CoreSupport 中的是位于 CMSIS 标准的核内设备函数层 的 M3 核通用的源文件 core_cm3.c 和 头文件 core_cm3.h,它们的作用是为那些采用 Cortex-M3 核设计 SOC 的芯片商设计的芯片外设提供一 个进入 M3 内核的接口。这两个文件在其它公司的 M3 系列芯片也是相同的。至于这些功能是怎样用 源码实现的,我们可以不用管它,我们只需把这个文件加进我们的工程文件即可,有兴趣的朋友可以 深究。 core_cm3.c 文件还有一些与编译器相关条件编译语句,用于屏蔽不同编译器的差异,我们在开发 时不用管这部分,有兴趣可以了解一下。里面包含了一些跟编译器相关的信息,如:RealView Compiler (RVMDK),ICC Compiler (IAR),GNU Compiler。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 241 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 较重要的是在 core_cm3.c 文件中包含了 stdin.h 这个头文件,这是一个 ANSI C 文件,是独立于 处理器之外的,就像我们熟知的 C 语言头文件 stdio.h 文件一样。位于 RVMDK 这个软件的安装目录 下,主要作用是提供一些新类型定义,如: 这些新类型定义屏蔽了在不同芯片平台时,出现的诸如 int 的大小是 16 位,还是 32 位的差异。 所以在我们以后的程序中,都将使用新类型如 int8_t 、int16_t„„ 在稍旧版的程序中还可能会出现如 u8、u16、u32 这样的类型,请尽量避免这样使用,在这里提 出来是因为初学时如果碰到这样的旧类型让人一头雾水,而且在以新的库建立的工程中是无法追踪到 u8、u16、u32 这些的定义的。 core_cm3.c 跟启动文件一样都是底层文件,都是由 ARM 公司提供的,遵守 CMSIS 标准,即所有 CM3 芯片的库都带有这个文件,这样软件在不同的 CM3 芯片的移植工作就得以简化。 6.4.4 system_stm32f10x.c文件 在 DeviceSupport 文件夹下的是启动文件、外设寄存器定义&中断向量定义层 的一些文件,这是 由 ST 公司提供的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 242 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 system_stm32f10x.c,是由 ST 公司提供的,遵守 CMSIS 标准。该文件的功能是设置系统时钟和 总线时钟, M3 比 51 单片机复杂得多,并不是说我们外部给一个 8M 的晶振,M3 整个系统就以 8M 为时钟协调整个处理器的工作。我们还要通过 M3 核的核内寄存器来对 8M 的时钟进行倍频,分频, 或者使用芯片内部的时钟。所有的外设都与时钟的频率有关,所以这个文件的时钟配置是很关键的。 system_stm32f10x.c 在实现系统时钟的时候要用到 PLL(锁相环),这就需要操作寄存器,寄存器 都是以存储器映射的方式来访问的,所以该文件中包含了 stm32f10x.h 这个头文件。 6.4.5 stm32f10x.c文件 stm32f10x..h 这个文件非常重要,是一个非常底层的文件。所有处理器厂商都会将对内存的操作 封装成一个宏,即我们通常说的寄存器,并且把这些实现封装成一个系统文件,包含在相应的开发环 境中。这样,我们在开发自己的应用程序的时候只要将这个文件包含进来就可以了。 6.4.6 启动文件 Libraries\CMSIS\Core\CM3\startup\arm 文件夹下是由汇编编写的系统启动文件,不同 的文件对应不同的芯片型号,在使用时要注意。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 243 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 文件名的英文缩写的意义如下: z cl:互联型产品,stm32f105/103 系列 z vl:超值型产品,stm32f100 系列 z xl:超高密度(容量)产品,stm32f101/103 系列 z ld:低密度产品,FLASH 小于 64K z md:中等密度产品,FLASH=64 or 128 z hd:高密度产品,FLASH 大于 128 神 舟 III 号 中 用 的 芯 片 是 STM32F103ZET , 512KROM , 所 以 启 动 文 件 要 选 择 startup_stm32f10x_hd.s。 启动文件是任何处理器在上点复位之后最先运行的一段汇编程序。在我们编写的 c 语言代码运行 之前,需要由汇编为 c 语言的运行建立一个合适的环境,接下来才能运行我们的程序。所以我们也要 把启动文件添加进我们的的工程中去;所以,总的来说,启动文件的作用是: 1. 初始化堆栈指针 SP; 2. 初始化程序计数器指针 PC; 3. 设置堆、栈的大小; 4. 设置异常向量表的入口地址; 5. 配置外部 SRAM 作为数据存储器(这个由用户配置,一般的开发板可没有外部 SRAM); 6. 设置 C 库的分支入口__main(最终用来调用 main 函数); 7. 在 3.5 版的启动文件还调用了在 system_stm32f10x.c 文件中的 SystemIni() 函数配置系统时钟, 在旧版本的工程中要用户进入 main 函数自己调用 SystemIni() 函数。 6.4.7 STM32F10x_StdPeriph_DrIer文件夹 Libraries\STM32F10x_StdPeriph_DrIer 文件夹下有 inc(include 的缩写)跟 src(source 的简写)这 嵌入式专业技术论坛 (www.armjishu.com)出品 第 244 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 两个文件夹,这都属于 CMSIS 的设备外设函数 部分。src 里面是每个设备外设的驱动程序,这些外 设是芯片制造商在 Cortex-M3 核外加进去的。 进入 libraries 目录下的 STM32F10x_StdPeriph_DrIer 文件夹如下图: 在 src 和 inc 文件夹里的就是 ST 公司针对每个 STM32 外设而编写的库函数文件,每个外设对应 一个 .c 和 .h 后缀的文件。我们把这类外设文件统称为:stm32f10x_ppp.c 或 stm32f10x_ppp.h 文件, PPP 表示外设名称。 如针对模数转换(ADC)外设,在 src 文件夹下有一个 stm32f10x_adc.c 源文件,在 inc 文件夹下有一个 stm32f10x_adc.h 头文件,若我们开发的工程中用到了 STM32 内部的 ADC,则至少要把这两个文件包 含到工程里: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 245 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这两个文件夹中,还有一个很特别的 misc.c 文件,这个文件提供了外设对内核中的 NVIC(中断向 量控制器)的访问函数,在配置中断时,我们必须把这个文件添加到工程中。 6.4.8 stm32f10x_it.c、 stm32f10x_conf.h文件 在库目录的\Project\STM32F10x_StdPeriph_Template 目录下,存放了官方的一个库工程模板,我们 在 用 库 建 立 一 个 完 整 的 工 程 时 , 还 需 要 添 加 这 个 目 录 下 的 stm32f10x_it.c 、 stm32f10x_it.h 、 stm32f10x_conf.h 这三个文件。 stm32f10x_it.c,是专门用来编写中断服务函数的,在我们修改前,这个文件已经定义了一些系统 异常 的接口,其它普通中断服务函数由我们自己添加。但是我们怎么知道这些中断服务函数的接口 如何写呢?是不是可以自定义呢?答案当然不是的,这些都有可以在汇编启动文件中找到,具体的大 家自个看库的启动文件的源码去吧。 stm32f10x_conf.h,这个文件被包含进 stm32f10x.h 文件。是用来配置使用了什么外设的头文件, 用这个头文件我们可以很方便地增加或删除上面 drIer 目录下的外设驱动函数库。如下面的代码配置 表示使用了 gpio、rcc、spi、usart 的外设库函数,其它的注释掉的部分,表示没有用到。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 246 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 stm32f10x_conf.h 这个文件还可配置是否使用“断言”编译选项,在开发时使用断言可由编译器 检查库函数传入的参数是否正确,软件编写成功后,去掉“断言”编译选项可使程序全速运行。可通 过定义 USE_FULL_ASSERT 或取消定义来配置是否使用断言。 6.4.9 库各文件间的关系 前面向大家简单介绍了各个库文件的作用,库文件是直接包含进工程即可,丝毫不用修改,而有 的文件就要我们在使用的时候根据具体的需要进行配置。接下来从整体上把握一下各个文件在库工程 中的层次或关系,这些文件对应到 CMSIS 标准架构上: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 247 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上图描述了 STM32 库各文件之间的调用关系,这个图省略了 DSP 核(Cortex-M3 没有 DSP 核)和 实时系统层部分的文件关系。在实际的使用库开发工程的过程中,我们把位于 CMSIS 层的文件包含 进工程,丝毫不用修改,也不建议修改。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 248 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 对于位于用户层的几个文件,就是我们在使用库的时候,针对不同的应用对库文件进行增删(用 条件编译的方法增删)和改动的文件。 6.4.10 常用官方资料 1.《STM32 数据手册.pdf 》 这个文件相当于 STM32 的 datasheet,管脚定义,内部存储器架构分配,跟芯片硬件相关的定义 都可以从这里找得到。 2.《STM32 数据手册.pdf 》 这个文件对 STM32 的寄存器描述,它把 STM32 的时钟、存储器架构、及各种外设都描述得清清 楚楚。当我们对 STM32 的库函数的实现方式 感到困惑时,可查阅这个文件,以直接配置寄存器方式 开发的话查阅这个文档的频率会更高。 3. 《Cortex-M3 权威指南》 宋岩译。 该手册详细讲解了 Cortex 内核的架构和特性,要深入了解 Cortex-M3 内核,这是首选,经典中的 经典呀。 4.《stm32f10x_stdperiph_lib_um.chm》 这个就是前面提到的库的帮助文档,在使用库函数时,我们最好通过查阅此文件来了解库函数原 型,或库函数的调用 的方法。也可以直接阅读源码里面的函数的函数说明。 5. 其他文档 6.4.11 库函数帮助文档使用 所谓库函数,就是 STM32 的库文件中为我们编写好的函数接口,我们只要调用这些库函数,就 可以对 STM32 进行配置,达到控制目的。我们可以不知道库函数是如何实现的,但我们调用函数必 须要知道函数的功能、可传入的参数及其意义、和函数的返回值。 于是,有读者就问那么多函数我怎么记呀?神舟的回答是:会查就行了,哪个人记得了那么多。 所以我们学会查阅库帮助文档 是很有必要的。 打开库帮助文档 stm32f10x_stdperiph_lib_um.chm 见下图: 层层打开文档的目录标签 Modules\STM32F10x_StdPeriph_DrIer,可看到 嵌入式专业技术论坛 (www.armjishu.com)出品 第 249 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 STM32F10x_StdPeriph_DrIer 标签下有很多外设驱动文件的名字 MISC、ADC、BKP、CAN 等标签。 我 们 试 着 查 看 ADC 的 初 始 化 库 函 数 (ADC_Init) 看 看 , 继 续 打 开 标 签 \ADC\ADC_Exported_Functions\Functions\ADC_Init 见下图: 利用这个文档,我们即使没有去看它的具体代码,也知道要怎么利用它了。 如它的功能是:以 ADC_InitStruct 参数配置 ADC,进行初始化。原型为 void ADC_Init(ADC_TypeDef * ADCx , ADC_Init_TypeDef * ADC_InitStruct) 其中输入的参数 ADCx 和 ADC_InitSturct 均为库文档中定义的 自定义数据类型,这两个传入 参数均为结构体指针。初学时,我们并不知道如 ADC_TypeDef 这样的类型是什么意思,可以点击函 数原型中带下划线的 ADC_TypeDef 就可以查看这是什么类型了。 就这样初步了解了一下库函数,读者就可以发现 STM32 的库是写得很优美的。每个函数和数据 类型都符合见名知义 的原则,当然,这样的名称写起来特别长,而且对于我们来说要输入这么长的 英文,很容易出错,所以在开发软件的时候,在用到库函数的地方,直接把库帮助文档 中函数名称 复制粘贴到工程文件就可以了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 250 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 第七章 STM32神舟III号 实战篇 经过前两章的学习,我们对神舟III号开发板的硬件,以及其开发环境有了个比较深入的了解了, 接下来就是通过实战,来真正开始STM32的开发。通过本章的学习,你将学会STM32的大部分外设的 使用。本章将从浅入深向大家介绍如何一步步开发STM32,使你真正能独立用STM32开发自己的东西。 本章将通过一系列的实例,向大家介绍STM32的强大功能,及开发实例。 神舟III号STM32开发板实验例程基于STM32F10x_StdPeriph_Lib_V3.5.0库编写,在RVMDK 4.22 开发环境中调试运行通过。 7.1 LED流水灯实验 7.1.1 流水灯试验的意义与作用 作为开发板硬件经典入门实验,非流水灯实验莫属(流水灯也叫跑马灯)。神舟III号开发板板载 了4个LED指示灯,DS1,DS2,DS3和DS4。本实验将通过教你如何控制这四个灯实现交替闪烁的流 水灯效果。 该实验的关键在于如何控制STM32的IO口输出不同的电平。通过这一节的学习,您将初步掌握 STM32基本IO口的使用,迈出STM32学习的第一步。 7.1.2 实验原理 前面已经说过,跑马灯的关键实际上就是如何控制STM32处理器的GPIO接口作为输出接口,输出 指定的电平信号。那么,这一节,我们就主要了解STM32的GPIO的原理和控制方法。 STM32 的 IO 口可以由软件配置成 8 种模式: ¾ 模拟输入 ¾ 输入浮空 ¾ 输入下拉 ¾ 输入上拉 ¾ 开漏输出 ¾ 推挽输出 ¾ 复用功能开漏输出 ¾ 复用功能推挽输出 对应到STM32库文件中的定义如下 在我们使用一个GPIO之前,我们一般需要对GPIO管脚的时钟,和GPIO管脚模式以及速率进行设 定。 STM32的GPIO端口在作为输出时,可以软件配置端口最大支持的时钟速率,有以下几种: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 251 页,共 788 页 ¾ 输出模式,最大时钟速率10MHz ¾ 输出模式,最大时钟速率2MHz ¾ 输出模式,最大时钟速率50MHz 对应到STM32库中的定义如下: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 为了降低STM32处理器的功耗,可以依据实际的需求,选择合适的时钟速率,GPIO口支持的最大 时钟速率越低,它产生的功耗也越低。 在对STM32的GPIO管脚有了一定的了解后,我们看一个完整的GPIO端口初始化的例子。 为程序便于大家修改和移植,此处使用宏定义来定义指示灯的管脚等: 下面的LED_config函数是初始化神舟III号STM32开发板的4个LED灯对应的GPIO端口初始化的子函 数。 关于IO口更详细的介绍,请参考开发板光盘里的《【中文】STM32F系列ARM内核32位高性能微 控制器参考手册V10_1.pdf》第105页8.1节。 7.1.3 硬件设计 神舟 III 号开发板上总共有 4 个是用户 LED 指示灯,由 4 个 GPIO 管脚分别控制 LED 灯的亮灭, 当 GPIO 管脚输出低电平时,LED 指示灯亮。反之,当 GPIO 管脚输出高电平时,LED 指示灯灭。这 四个 LED 指示灯分别由 PF6、PF7、PF8 和 PF9 控制。 下图为LED原理图,其中GPIO管脚上串的电阻,主要起限流作用,防止电流过大损坏LED和GPIO 口。 GPIO管脚与对应的LED灯关系如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 252 页,共 788 页 LED灯 DS1 DS2 DS3 DS4 LED灯对应的GPIO PF6 PF7 PF8 PF9 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 5 LED 指示灯电路 7.1.4 软件设计 进入例程的文件夹,然后打开\Project \ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 253 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了时钟,这里的代 码是汇编的,大家可以了解一下就可以,这个文件里的代码是ST官方定制好了的,不需要我们修改, 我们只需要知道在这里有这个时钟调用的函数就可以。 代码分析2:那么在哪里设置的初始化成72MHZ的主频呢?在system_stm32f10x.c文件中,有个宏定义 如下,设置了SYSCLK_FREQ_72MHz之后,会在SystemInit()函数里进行调用 进入到SystemInit()函数中Æ调用SetSysClock()Æ调用SetSysClockTo72()真正去设置系统为72M 代码分析3:SetSysClockTo72 ()这里实际上与寄存器版本实现的时钟例程是一样的原理,只是这里用 的是库函数的方式来实现的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 254 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析4:调用LED_config( )函数来初始化LED指示灯 初始化板载LED指示灯 这个下面是各个具体的端口号,以及管脚,以及管脚所在的时钟总线的定义,如果需要改变成其 他管脚,只需要在这里进行修改即可,非常灵活和方便: 代 码 分 析 5 : 调 用 GPIO_ResetBits ( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin ) 和 GPIO_SetBits (GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数分别是点亮一个LED灯和熄灭一个LED灯,这里实 际上分别操作的GPIO_BRR寄存器和GPIO_BSRR寄存器: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 255 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 通过改变这些寄存器的值来设置芯片管脚的,使得芯片管脚按照寄存器手册里的规定来进行相应的工 作;可以是输出或输入,可以是高电平或是低电平(这个是另外一个寄存器来控制,大家可以对应看 手册里的寄存器说明),从而达到我们控制一个 LED 灯亮和灭。 GPIOD_BSRR 对应位设置 1,可以使得对应管脚的 ODR 位为 1;GPIO_BRR 的对应位设置 1,可 以使得对应管脚的 ODR 位为 0。 那么 ODR 位是什么呢?这个就是端口输出数据寄存器 GPIOB_ODR,实际上这个寄存器里的对 应位的变化才是真正 GPIO 管脚高低电平的变化;而寄存器 GPIOB_BSRR 和寄存器 GPIOB_BRR 则可 以间接影响到它。 当然上面程序,我们也可以改成直接操作 GPIOX_ODR 的代码,这个留个大家来做练习吧。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 256 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析6:最后在while()循环中不断的点亮和熄灭LED灯,实现流水灯的样子。 执行的流程是先关闭所有的LED灯,再点亮第一个LED灯,然后延时,再关闭所有LED灯,点亮第二 个LED灯延时,一直类推循环下去,先关闭所有再点亮一个延时。 7.1.5 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 257 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.1.6 实验现象 将固件下载在神舟 III 号 STM32 开发板后,可以看到神舟 III 号开发板的四个 LED 灯(DS1~4) 轮流闪亮,实现我们所说的流水灯效果。4 个 LED 的具体位置如下图中蓝色区域所示。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 258 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.2 蜂鸣器实验 7.2.1 蜂鸣器的简介 什么是蜂鸣器呢?蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算 机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中用作发声器 件。 1) 蜂鸣器的详细分析 蜂鸣器可以分为:电磁式和电压式。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。它是以压电 陶瓷的压电效应,来带动金属片的振动而发声; 电磁式的蜂鸣器,则是用电磁的原理,通电时将金属振动膜吸下,不通电时依振动膜的弹力弹回。 故压电式蜂鸣器是以方波来驱动,电磁式是 1/2 方波驱动,压电式蜂鸣器需要比较高的电压才能 有足够的音压,一般建议为 9V 以上。压电的有些规格,可以达到 120dB 以上,较大尺寸的也很容易达 到 100dB。 电磁式蜂鸣器:用 1.5V 就可以发出 85dB 以上的音压了,唯消耗电流会大大的高于压电式 蜂鸣器,而在相同的尺寸时,电磁式的蜂鸣器,响应频率可以做的比较低;电磁式蜂鸣器的音压一般 最多到 90dB.机械式蜂鸣器是电磁式蜂鸣器中的一个小类别。 蜂鸣器又分为有源蜂鸣器和无源蜂鸣器。这里讲的“源”,指的是:振荡源。 有源蜂鸣器,内部有振荡、驱动电路,加电源就可以响,优点是用起来省事;缺点是频率固定了, 就只一个单音。 无源的蜂鸣器与喇叭一样,需要加上交变的音频电压才能发声,也可以发出不同频率的声音。不 过,蜂鸣器的声音反正是不好听的,所以经常是加上方波,而不是加正弦。 2)蜂鸣器和喇叭的对比 蜂鸣器和喇叭主要区别如下: 1、蜂鸣器一般是高阻,直流电阻无限大,交流阻抗也很大,窄带发声器件,通常由压电陶瓷片 发声。需要较大的电压来驱动,但电流很小,几 mA 就可以了。功率也很小。 2、喇叭则是低阻,由线圈、磁铁、振膜及外壳组成。直流电阻几乎是 0,交流阻抗一般几欧到十 几欧。宽频发声器件,通常由利用线圈的电磁力推动膜片发声。 3、有源蜂鸣器只能用固定电压驱动,发生频率出厂时固定了;而喇叭通过驱动器可以发出各种 声音。可讲究音质,我们的音响、MP3、耳机、手机上都是用的喇叭,声音频率是可以改变的。一些 报警器只能发出 “滴 滴”声响的一般都是蜂鸣器,没什么音质可言。 在实际应用中我们会区分,蜂鸣器是有源还是无源,电磁式还是电压式?我们神舟 51 开发板提供了 电磁式无源蜂鸣器,下面我们会详细分析。 7.2.2 蜂鸣器的结构 一般的无源蜂鸣器的结构图,如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 259 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 1:防水贴纸 2:线轴 3:线圈 4:磁铁 5:底座 6:引脚 7:外壳 8:铁蕊 9:封胶 10:小铁 片 11:振动膜 12:电路板 蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,外接的振荡器产生的 音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期 性地振动发声。 因此要使得这种蜂鸣器发出声音,必须在外部给它接一个震荡发生器。 7.2.3 意义与作用 蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、报警 器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。用于产品的声音提醒或者 告警等。 本实验将介绍,如何通过一个GPIO管脚控制有源直流蜂鸣器。该实验与流水灯实验类似,都是学 习如何控制STM32的IO口输出。(有源蜂鸣器直接接上额定电源(新的蜂鸣器在标签上都有注明)就可 连续发声;而无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路中(交流信号)才能发声。) 7.2.4 实验原理 前面流水灯的实验已经介绍过STM32处理器GPIO接口,如何配置它的模式,时钟速率等,在这一 节就不再重复讲解GPIO接口的使用。 当蜂鸣器两端的电压大于4V,典型值为5V时,蜂鸣器就会发出固定频率的的声音。 当控制蜂鸣器的GPIO管脚的管脚输出高电平时,关闭蜂鸣器,当GPI管脚输出低电平时,蜂鸣器 发声鸣响。 7.2.5 硬件设计 在神舟III号STM32开发板中,提供了一个蜂鸣器,器鸣器连接到了处理器的PB10管脚,由处理器 的PB10管脚控制,当处理器的PB10管脚输出低电平时蜂鸣器开始鸣响,反之处理器的PB10管脚输出 高电平或OD开漏时蜂鸣器停止鸣响,。 图中PB10的电阻R14的作用为限流作用,防止电流蜂鸣器工作时电流过大,损坏处理器的管脚。 查阅STM32F103处理器可知,STM32处理器IO口能够承受的电流为25mA,如下表所示: 而蜂鸣器的的额定工作电流为30mA,因此在此处串一个电阻,保证工作电流即满足蜂鸣器的要 求,又不至于太大而损坏处理器的GPIO管脚。 其原理图如下: 图中R14实际安装22欧姆电阻使蜂鸣器的声音柔和。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 260 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 6 蜂鸣器电路 7.2.6 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了时钟,这里的代 嵌入式专业技术论坛 (www.armjishu.com)出品 第 261 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 码是汇编的,大家可以了解一下就可以,这个文件里的代码是ST官方定制好了的,不需要我们修改, 我们只需要知道在这里有这个时钟调用的函数就可以。 代码分析2:那么在哪里设置的初始化成72MHZ的主频呢?在system_stm32f10x.c文件中,有个宏定义 如下,设置了SYSCLK_FREQ_72MHz之后,会在SystemInit()函数里进行调用 进入到SystemInit()函数中Æ调用SetSysClock()Æ调用SetSysClockTo72()真正去设置系统为72M 代码分析3:SetSysClockTo72 ()这里实际上与寄存器版本实现的时钟例程是一样的原理,只是这里用 的是库函数的方式来实现的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 262 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析4:神舟III号BEEPER蜂鸣器使用的GPIO接口定义: 代码分析 5:SZ_STM32_BEEPInit()函数初始化蜂鸣器的 GPIO 管脚和配置模式 代码分析 6: 调用 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 函数指定管脚输出 高电平,使蜂鸣器停止鸣响,通过 GPIOx_BSRR 寄存器控制的。 GPIO_SetBits(GPIO_BEEPER, BEEPER_PIN); /*关闭蜂鸣器*/ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 263 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 7:调用 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数指定管脚输出 低电平,使蜂鸣器鸣响,通过 GPIOx_BRR 寄存器控制的。 GPIO_ResetBits(GPIO_BEEPER, BEEPER_PIN); /*开启蜂鸣器*/ 代码分析 8:在 while 循环中,加上延时,使得蜂鸣器发出滴滴的叫声 7.2.7 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.2.8 实验现象 将固件下载在神舟III号STM32开发板后,可以听到看到的蜂鸣器发出间断的鸣响了,蜂鸣器的位 置如下图红色框所示。 到这里,我们就完成了蜂鸣器实验的讲解,这个例程只是简单的实现蜂鸣器的鸣响和关闭控制,用蜂 鸣器来唱歌,大家相信吗?感兴趣的朋友赶紧去尝试吧! 嵌入式专业技术论坛 (www.armjishu.com)出品 第 264 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 265 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.3 按键检测实验 前面我们介绍了STM32的IO口作为输出功能使用,这一节,我们将向大家介绍如何使用STM32 的IO口作为输入功能,我们以按键的输入为例讲解,通过本节的学习,你将了解到STM32的IO口作为 输入使用的方法。本节分为如下几个小节: 1 KEY_LED按键与315M无线模块实验的意义与作用 2 实验原理 3 硬件设计 4 软件设计 5 下载与验证 6 实验现象 7.3.1 按键的介绍 首先我们先了解一下,我们常用到的键盘。键盘分为编码键盘和非编码键盘。键盘上闭合键 的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。而靠 软件编程来识别的键盘称为非编码键盘,在单片机组成的各种系统中,用的较多的是非编码键盘。 非编码键盘又分为独立键盘和行列式(又称矩阵式)键盘。独立键盘由独立按键组成,每个按键 占用一个I/O口,行列式键盘不用占那么多I/O。这里我们主要讲解的是独立按键。 键盘实际上就是一组按键,在单片机外围电路中,通常用到的按键都是机械弹性开关,当开关 闭合时,线路导通,开关断开,如下图是几种单片机系统常见的按键。 弹性小按键被按下时闭合,松手后自动断开;自锁式按键按下时闭合且会自动锁住,只有再次按 下时才弹起断开。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 266 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.3.2 单片机检测小弹性按键的原理 单片机检测按键的原理是:单片机的I/O口既可作为输出也可作为输入使用,当检测按键时用 的是它的输入功能,我们把按键的一端接地,另一端与单片机的某个I/O口相连,开始时先给该I/O 口赋一高电平,然后让单片机不断地检测该O口是否变为低电平,当按键闭合肘,即相当于该I/O 口通过按键与地相连,变成低电平,程序一旦检测到I/O口变为低电平则说明按键被按下,然后 执行相应的指令。 去抖概念:(分为软件去抖和硬件去抖) 按键是机械器件,按下或者松开时有固定的机械抖动。 什么是机械抖动?通常的按键开关为机械弹性开关,由于机械触点的弹性作用,一个按键开关在 闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串 的抖动。抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。这是一个很重要的时间参数, 在很多场合都要用到;实际上只进行一次按键操作,但有可能执行了多次按键结果,这就是抖动造成 的,所以大多数产品实际使用中都使用了按键去抖功能。 按键的连接方法和按键在被按下时其触点电压变化过程下图: 这个抖动时间虽然很短,不同按键抖动不同,但对应单片机来说,很轻松就能检测到,单片机的 运行的速度是微秒 us 级别。 用示波器跟踪一个小的按钮开关在闭合时的抖动现象,得到如下图的波形。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 267 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 观察波形可以帮助我们对抖动现象有一个直观的了解。水平轴2 m s / D i v ,抖 动 间 隙 大 约 为 1 0 m s , 在达到稳定状态前一共有6次变化,频率随时间升高。 硬件去抖最简单的就是按键两端并联电容,容量根据实验而定。当然也有专用的去抖动芯片。 软件去抖使用方便不增加硬件成本,容易调试,所以现在大都使用软件去抖。 关于软件去抖,我们在这里也详细讲解一下原理 : 1、检测到按键按下后进行 5~10ms 延时,用于跳过这个抖动区域 2、延时后再检测按键状态,如果没有按下表明是抖动或者干扰造成,如果仍旧按下,可以认为 是真正的按下。并进行对应的操作。 3、同样按键释放后也要进行去抖延时,延时后检测按键是否真正松开。 7.3.3 意义与作用 STM32的IO口在前面的流水灯实验中已经有了详细的介绍,这里我们细讲,这一节我们讲结合 STM32的库,描述如何设置STM32 的GPIO口作为输入使用。 这一节,我们将通过神舟 III 号板载有的 4 个按键(WAKEUP,TAMPER,USER1 和 USER2),来控 制板上的 4 个 LED(DS1~DS4),按下任一个按钮,对应的 LED 点亮。 7.3.4 实验原理 这 个 例 程 的 实 验 原 理 主 要 包 括 两 个 : 一 、 通 过 神 舟 III 号 开 发 板 上 的 4 个 按 钮 (WAKEUP,TAMPER,USER1和USER2),控制4个LED灯的点亮和关闭状态。 具体的对应关系如下: 现象 操作 LED1亮其它LED灭 LED2亮其它LED灭 LED3亮其它LED灭 LED4亮其它LED灭 神舟III号板载USER1按键被按下 神舟III号板载USER2按键被按下 神舟III号板载TAMPER按键被按下 神舟III号板载WAKEUP按键被按下 7.3.5 硬件设计 该实验需要使用到神舟III号开发板上的LED灯,按键,相关硬件电路如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 268 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 7 LED 指示灯电路 神舟III号STM32开发板总共有4个功能按键,分别是WAKEUP按键和TAMPER按键及两个用于自定义 功能按键,在不使用第二功能的情况下,这四个按键都可以作为通用的按键,由用户自定义其功能。 这四个按键分别与PA0、PC13、PA8和PD3四个GPIO管脚连接,当按键按下时,对应的GPIO管脚为低 电平,反之,当没有按键按下时,对应的GPIO管脚为高电平。其中PA0 (STM32的WKUP引脚)可以作 为WK_UP功能,它除了可以用作普通输入按键外,还可以用作STM32的唤醒输入。PC13可以实现备 份区寄存器的入侵功能。本实验中所有的按键均作为普通IO使用。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 269 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 8 按键输入电路 GPIO 管脚与对应的 LED 灯关系如下: LED灯 LED灯对应的GPIO DS1 PF6 DS2 PF7 DS3 PF8 DS4 PF9 GPIO 管脚与按键对应关系: 按键 按键对应的GPIO USER2 PD3 USER1 PA8 TAMPER PC13 嵌入式专业技术论坛 (www.armjishu.com)出品 第 270 页,共 788 页 WAKEUP ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 PA0 7.3.6 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 在分析例程的代码之前,我们想回顾一下关于 STM32 GPIO 的使用。 ¾ STM32 GPIO 的使用与配置 STM32 的 IO 口可以由软件配置成 8 种模式: ¾ 模拟输入 ¾ 输入浮空 ¾ 输入下拉 ¾ 输入上拉 ¾ 开漏输出 ¾ 推挽输出 ¾ 复用功能开漏输出 ¾ 复用功能推挽输出 对应到STM32库文件中的定义如下 嵌入式专业技术论坛 (www.armjishu.com)出品 第 271 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在我们使用一个GPIO之前,我们一般需要对GPIO管脚的时钟,和GPIO管脚模式以及速率进行设 定。 STM32的GPIO端口在作为输出时,可以软件配置端口最大支持的时钟速率,有以下几种: ¾ 输出模式,最大时钟速率10MHz ¾ 输出模式,最大时钟速率2MHz ¾ 输出模式,最大时钟速率50MHz 对应到STM32库中的定义如下: 速率主要针对GPIO作为输出时使用,作为输入时可以不关注。 ¾ STM32 硬件初始化 神舟III号按键使用的GPIO的接口定义 嵌入式专业技术论坛 (www.armjishu.com)出品 第 272 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 现在从 main 主函数开始分析代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 273 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了时钟,这里的代 码是汇编的,大家可以了解一下就可以,这个文件里的代码是ST官方定制好了的,不需要我们修改, 我们只需要知道在这里有这个时钟调用的函数就可以。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 274 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析2:那么在哪里设置的初始化成72MHZ的主频呢?在system_stm32f10x.c文件中,有个宏定义 如下,设置了SYSCLK_FREQ_72MHz之后,会在SystemInit()函数里进行调用 进入到SystemInit()函数中Æ调用SetSysClock()Æ调用SetSysClockTo72()真正去设置系统为72M 代码分析3:SetSysClockTo72 ()这里实际上与寄存器版本实现的时钟例程是一样的原理,只是这里用 的是库函数的方式来实现的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 275 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析4:LED_config() 初始化板载LED指示灯,实验中LED灯配合按键进行亮灭,所以在这里 初始化4个LED灯。 代码分析5:GPIO_KEY_Config()按键的GPIO初始化,按键有两种初始化方式: 1)第一种是普通的GPIO方式,也就是GPIO管脚配置成输入的状态,然后不断通过while()循环去检测 这个管脚,看看是否有按键按下,GPIO电平有变化。 2)第二种是中断的方式,配置好中断,STM32内部有中断控制器的功能,设置好中断触发机制,一 旦芯片检测到中断发生,中断控制器就会通知CPU,CPU就会调用相应的中断函数进行中断处理;如 果我们把中断配置到连接了按键的GPIO管脚上,一旦检测到按键按下,就产生中断,这样就可以不需 要CPU轮询去检测这个GPIO管脚了,有中断控制器来控制和触发,这样就节约了很多CPU资源。 由于按键相应的GPIO口变为低电平,因此,在这里我们配置按键使用的GPIO为输入上拉模式。 没有收到有效信号,保持这些GPIO口为高电平。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 276 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析6:这样重点分析一下SZ_STM32_KEYInit()函数里的中断配置过程,初始化KEY按键的 GPIO管脚,配置为带上拉的输入,按键按下时为低电平0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 277 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析7:GPIO_ReadInputDataBit()函数,传入的是GPIO的端口号和GPIO管脚,只需要访问到对 应的IDR,读取到对应管脚的IDR寄存器值就可以了 嵌入式专业技术论坛 (www.armjishu.com)出品 第 278 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析8:进入循环,SZ_STM32_KEYGetState()函数不断检测按键是否有被按下去,如有,先调 用delay(150000)函数延时一下,再进行判断,这段延时的目的是达到去按键抖动的目的: 7.3.7 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 279 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.3.8 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,重新打开电源;神舟 III 号开发板上的 4 个 LED 灯同时闪一下,然后都亮;如下图显示 在没有按键按下时,4 个 LED 灯都亮;有按键按下,相关的 LED 灯随之发生变化,具体实现现象如 下表所示: LED 灯 按键 说明 DS1 USER1 按键 按下按键 1, DS1 灯取反状态。 DS2 USER2 按键 按下按键 2, DS2 灯取反状态。 DS3 TAMPER 按键 按下按键 3, DS3 灯取反状态。 DS4 WAKEUP 按键 按下按键 4, DS4 灯取反状态。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 280 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.4 BitBand按键扫描检测实验 7.4.1 什么是位带操作 还记得 51 单片机吗? 单片机 51 中也有位的操作,以一位(BIT)为数据对象的操作;例如 51 单片机可以简单的将 P1 端口的第 2 位独立操作,P1.2=0 或者 P1.2=1,就是这样把 P1 口的第三个脚 (bit2)置 0(输出低电平)或者置 1(输出高电平)。 而现在 STM32 的位段、位带别名区这些就是为了实现这样的功能,可以在 SRAM、I/O 外设空间 实现对这些区域的某一位的单独直接操作。 7.4.2 为什么要用位带操作 那么 51 单片机中间不是有位的操作吗,而 STM32 为什么要提出位带的操作呢?首先,这里不得 不提一个事情就是 STM32 的内部区域访问只能是 32 位的字,不能是字节或者半字,也更不可能只访 问一个 bit,要访问就要一次访问 32 个 bit,这部分 STM32 在神舟开发板手册的 GPIO 章节中提到过; 而 51 单片机里一个 bit(一个字节等于 8 个 bit,一个字是 32 个 bit)。而 STM32 中一个寄存器一般 是 32 个 bit 的,每一个位都是 1 个 bit,那么如何可以访问一个寄存器中的 1 个位呢?就是 1 个 bit, 把一次访问 32bit 的 STM32 经过一系列转换达到只访问其中的一个 bit,所以 STM32 使用一种新型 的方式来解决这个问题,设计一个办法来解决用一次访问 32bit 的这样的操作达到 51 单片机那种只访 问一个 bit 的效果。 7.4.3 如何设计和实现位带操作的 从编程者这个角度来说,我们操作的对象是一个一个的 bit 位,而对于 STM32 来说,它内部只能 是 32 位 bit 每次的访问。如果要实现这个技术,必须要做一个映射,也就是从 1 个 bit 映射到 32 个 bit, 就是用 STM32 内部的一次访问(32 个 bit)来代表编程者认为的 1 个 bit。 那 STM32 内部是如何解决的呢?它是在支持位带操作的地方,取个别名区空间,而这个别名区空 间可以让一次 32 位来进行访问,对这个别名进行操作就相当于对 SRAM 或者 I/O 存储空间中的位(1 个寄存器里的位就是 1 个 bit,1 个 bit 最后对应别名区空间的 32 个位,因为 STM32 芯片内部只能是 32 位去访问)进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 281 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这样呢,1MB SRAM 就可以 32M 个对应别名区空间,就是 1 位膨胀到 32 位(1bit 变为 1 个字); 我们对这个别名区空间开始的某一字操作,置 0 或置 1,就等于它映射的 SRAM 或 I/O 相应的某地址 的某一位的操作。 7.4.4 STM32中位带操作的具体部署情况 支持位带操作的两个内存区的范围是: 序号 支持位带操作的两个内存区的范围 对应的别名区空间范围 1 SRAM 区中的最低 1MB: SRAM 所对应的别名区 32MB 空间: 0x2000_0000-0x200F_FFFF 0x2200_0000-0x23FF_FFFF 2 片上外设区中的最低 1MB: 片上外社区所对应的别名区 32MB 空间: 0x4000_0000-0x400F_FFFF 0x4200_0000-0x43FF_FFFF 下面是内部空间映射图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 282 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 例如:SRAM 区中的最低 1MB 空间中的 0x2000_0000 的 8 个 bit,分别对应如下: 地址 对应的 bit 位 别名空间 Bit 对应的别名空间 0x2000_00000 Bit1 0x2200_0000 跨度一个字 = 4 个字节 = 32 个 bit Bit2 0x2200_0004 跨度一个字 = 4 个字节 = 32 个 bit Bit3 0x2200_0008 跨度一个字 = 4 个字节 = 32 个 bit Bit4 0x2200_000C 跨度一个字 = 4 个字节 = 32 个 bit Bit5 0x2200_0010 跨度一个字 = 4 个字节 = 32 个 bit Bit6 0x2200_0014 跨度一个字 = 4 个字节 = 32 个 bit Bit7 0x2200_0018 跨度一个字 = 4 个字节 = 32 个 bit Bit8 0x2200_001C 跨度一个字 = 4 个字节 = 32 个 bit 可以看到上表和上图,0x2000_0000 中的一个 bit 位对应了别名区的一个 32 位的字,也就是说 STM32 芯片的内部寄存器的任意一个位,都其实对应的是别名区的 32 个位。 7.4.5 如何用代码来实现位带操作 在 STM32 中,一个寄存器是 32 位的,32 个 bit 中的任意其中一个 bit 所对应的别名空间 到底该如何访问呢?首先分为两种情况,一种是在 SRAM,一种是在 FLASH 中,两个别名 空间的起地位置是不同的,SRAM 是从 0x2200_0000 开始,而 FLASH 是从 0x4200_0000 开 始。 假如在 SRAM 中的一个寄存器的地址是 A,访问寄存器 A 中的第 n 个 bit 位。那么该如 何计算呢?我们知道 SRAM 中别名区的起始地址是 0x2200_0000 对应 SRAM 中实际寄存器 地址 0x2000_0000,SRAM 中每 1 个 bit,都会对应别名区中的 32 个 bit,那么实际地址的公 式应该如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 283 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 0x2200_0000 + (SRAM 实际寄存器地址偏移 0x2000_0000 的 bit 数)* 4 因为 0x2200_0000 这个地址每增加 1,实际上就是增加 8 个 bit(一个地址对应一个字节), 实际寄存器中的 1 个 bit 对应 32 个 bit,所以就乘以 4,地址本身增加 1 是 8bit,8bit 乘以 4 倍刚好是 32bit。 那么接下来” SRAM 实际寄存器地址偏移 0x2000_0000 的 bit 数”该如何计算呢? 对,用寄存器的地址减去这个基地址,然后在乘以 8(因为一个地址对应 8 个 bit),所以就可 以得到以下的公式: (A‐0x20000000)*8 以上这个公式可以知道实际寄存器离基地址有多少个 bit 的距离,访问该寄存器的第 n 个 bit 位还必须加上一个 n,就变成以下的公式: (A‐0x20000000)*8+n 好了,最后整理整个换算公式如下,FLASH 与 SRAM 的原理都是想通的: SRAM :0x22000000 +((A‐0x20000000)*8+n)*4 FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 1. 举例说明: 比如我要访问如下寄存器 GPIOB_BSRR 中的第 14bit 位 BS13,注意因为寄存器内部是从 0 开始计 数到 31 截止,所以第 14bit 相当于是第 13。 可以从下图看到,GPIO 端口 B 的起始地址是 x04001_0C00,GPIOB_BSRR 寄存器的偏移地址是 0x10,访问的第 14bit 位的 BS13。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 284 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 那么通过公式: FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 换算 0x4200_0000 + ((0x40010c00-0x40000000)*8 + 12)*4 = 实际地址 在这里我们就不具体计算了,SRAM 访问也是同理 2. 如何将理念转化成代码: 由上面几节得出,SRAM 和 FLASH 中别名区的寻址公式如下: SRAM :0x22000000 +((A‐0x20000000)*8+n)*4 FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 可以看到 0x2200_0000 和 0x4200_0000 都共同有个 x200_0000 这个数值;乘以 8 相当于再加上外 面的那个乘以 4,总共是乘以 32,而 n 是乘以 4;乘以 32 相当于是数值向左移 5 位,乘以 4 相当于向 左边移 2 位。 尝试将如下公式化成 #define BITBAND(addr,bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 这样就可以用 BITBAND(addr,bitnum)来表示寄存器里的任何一个 bit 位,大概原理讲到这里, 具体使用方法通过例程来体现。 7.4.6 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 嵌入式专业技术论坛 (www.armjishu.com)出品 第 285 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了72MHZ时钟,最 开始的例程已经对此分析过了,还有不明白的可以看下前面的例程。 代码分析2:调用SZ_STM32_LEDInit()函数初始化板载LED指示灯,前面已经有介绍 代码分析3:开始使用位带的BitBand方式,使得管脚输出高电平熄灭指示灯,这里可以看到,一个变 量就可以独立操作一个GPIO管脚,这究竟是如何做到的呢?下面继续看代码分析: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 286 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 1)首先看如下这行代码: #define LED1OBB Periph_BB((uint32_t)&LED1_GPIO_PORT->ODR, LED1_PIN_NUM) LED1OBB希望变成PF端口的第6个GPIO管脚,那就是PF.06,那么LED1_PIN_NUM=6,而 LED1_GPIO_PORT->ODR则变成了GPIOF->ODR 2)继续分析一下,把PF端口和PF端口的第6管脚这两个参数传入到Periph_BB()就可以访问到PF.06 的这个GPIO管脚了吗?还得分析一下Periph_BB()函数 代码分析4:开始详细分析和解析Periph_BB()函数,这里就比较复杂,如果感兴趣的朋友可以认真 研究和计算,如果不感兴趣,也不会影响后面的学习,等有兴趣的时候再来研究也都可以,这是STM32 神舟团队专门提供的建议: 1)Periph_BB_BASE是外设别名区基地址 #define Periph_BASE 0x40000000 // 外设基地址 Peripheral #define Periph_BB_BASE 0x42000000 // 外设别名区基地址 Peripheral bitband 从图中可以看到从0x40000000到0x40100000这1M的Bit Band区域对应了从0x42000000~0x43FFFFFF这 32MB的区域,也就是说Bit Band区域中的1个bit对应了Bit Band Alias区域32个bit的空间。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 287 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2)在 STM32 中,一个寄存器是 32 位的,32 个 bit 中的任意其中一个 bit 所对应的别名空 间到底该如何访问呢?首先分为两种情况,一种是在 SRAM,一种是在 FLASH 中,两个别 名空间的起地位置是不同的,FLASH 是从 0x4200_0000 开始。 假如在 FLASH 中的一个寄存器的地址是 A,访问寄存器 A 中的第 n 个 bit 位。那么该如 何计算呢?我们知道 FLASH 中别名区的起始地址是 0x4200_0000 对应 SRAM 中实际寄存器 地址 0x4000_0000,FLASH 中每 1 个 bit,都会对应别名区中的 32 个 bit,那么实际地址的公 式应该如下: 0x4200_0000 + (FLASH 实际寄存器地址偏移 0x4000_0000 的 bit 数)* 4 因为 0x4200_0000 这个地址每增加 1,实际上就是增加 8 个 bit(一个地址对应一个字节), 实际寄存器中的 1 个 bit 对应 32 个 bit,所以就乘以 4,地址本身增加 1 是 8bit,8bit 乘以 4 倍刚好是 32bit。 那么接下来” FLASH 实际寄存器地址偏移 0x4000_0000 的 bit 数”该如何计算呢? 对,用寄存器的地址减去这个基地址,然后在乘以 8(因为一个地址对应 8 个 bit),所以就可 以得到以下的公式: (A‐0x40000000)*8 以上这个公式可以知道实际寄存器离基地址有多少个 bit 的距离,访问该寄存器的第 n 个 bit 位还必须加上一个 n,就变成以下的公式: (A‐0x40000000)*8+n = 实际寄存器的地址距基地址的实际 bit 数 好了,最后整理整个换算公式如下,FLASH 与 SRAM 的原理都是想通的: FLASH :0x42000000 +((A‐0x40000000)*8+n)*4(实际寄存器的地址距基地址的实际 bit 数 * 4 个字节(4 个字节是 32 个 bit) 再加上 bitband 的别名区的基地址,就得出实际的别名 区 bitband 的地址了) 3)可以从下图看到,GPIO 端口 F 的起始地址是 x04001_1C00,访问的是 GPIO 管脚 6 嵌入式专业技术论坛 (www.armjishu.com)出品 第 288 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 那么通过公式: FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 换算 0x4200_0000 + ((0x40011C00-0x40000000)*8 + 12)*4 = 实际地址 4)FLASH :0x42000000 +((A‐0x40000000)*8+n)*4 这个公式化成另外一种计算方式就变成: 0x42000000 +(A‐0x40000000)*32+n*4,所以乘以32实际上是左移5位,乘以4实际上就是左 移2位,最后3个地址相加: 这3个地址,一个是最基础的地址0x42000000,一个是寄存器对应bitband区域的地址,最后一 个寄存器里面的位对应的bitband区域的地址。 代码分析5:PFSetBit(6)函数就是表示设置PF.06管脚,使得管脚管脚依次输出高电平 #define PFSetBit(n) (PFOutBit(n) = 1) #define PFOutBit(n) Periph_BB((uint32_t)&GPIOF->ODR,n) 可以看到,最终还是调用了Periph_BB()函数了,在这里只需要传入所对应寄存器的地址,以及对应的 GPIO管脚号,就可以访问到最终的bitband区域。 7.4.7 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.5如何在MDK开发 环境中使用JLINK在线调试小节进行操作。 7.4.8 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,重新打开电源;神舟 III 号开发板上的 4 嵌入式专业技术论坛 (www.armjishu.com)出品 第 289 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 个 LED 灯闪烁两次,然后从上往下熄灭 LED 灯; 在没有按键按下时,4 个 LED 灯都是熄灭;有按键按下,相关的 LED 灯随之发生变化,具体实现现 象如下表所示: LED 灯 按键 说明 DS1 USER 1 按键 按一下 USER 1 对应 DS 1 灯亮,再按一下 DS 1 灭 DS2 USER2 按键 按一下 USER2 对应 DS2 灯亮,再按一下 DS 2 灭 DS3 TAMPER 按键 按一下 TAMPER 对应 DS 3 灯亮,再按一下 DS3 灭 DS4 WAKEUP 按键 按一下 WAKEUP 对应 DS 4 灯亮,再按一下 DS 4 灭 神舟 III 号开发板按键位置,如下图 7.5 EXTI外部按键中断实验 前面我们介绍了STM32的IO口作为输出功能使用并介绍了我们以按键的输入扫描实验,这一节, 我们将向大家介绍如何使用STM32的IO口作为EXTI外部中断的输入功能,我们以按键的输入为例讲 嵌入式专业技术论坛 (www.armjishu.com)出品 第 290 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 解,通过本节的学习,你将了解到STM32的IO口作为EXTI外部中断输入使用的方法。 7.5.1 什么是中断 单片机中断系统的概念:什么是中断,我们从一个生活中的例程引入。比如说你在做A事,但是 突然间来了你想起来了更重要的B事,所以你马上去做B事了,做完之后再回来继续做A事,这个就是 中断。 7.5.2 什么是单片机的中断? 当CPU正在执行一个任务,但突然又发生了一个更高级的任务,CPU必须立即去执行的任务,所 以CPU必须中断当前的任务,并保存该任务已经执行的状态和相关信息,然后转而去执行那个更加高 级的任务,因此就引入了“中断”这个概念。 中断是指计算机在执行程序的过程中,当出现异常情况或特殊请求时,计算机停止现行程序的运 行,转向对这些异常情况或特殊请求的处理,处理结束后再返回现行程序的间断处,继续执行原程序。 中断是单片机实时地处理内部或外部事件的一种内部机制。当某种内部或外部事件发生时,单片机的 中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理,中断处理完毕后,又返回被 中断的程序处,继续执行下去。 在程序里面也是一样的。举个例子可能会容易懂点,定时中断:比如你定时1ms,主程序在运行, 每当1ms时间到后,就跑到定时中断子程序里面执行,执行完后再回到主程序(中断程序是1ms中断一 次)。那对于整个系统来说中断能实现什么好处呢?下面我们给以说明: 1)提高了CPU的效率 CPU是计算机的指挥中心,它与外围设备(如按键、显示器等)通讯的方法有查询和中断2种: 查 询的方法是无论外围IO是否需要服务,CPU每隔一段时间都要依次查询一遍,这种方法CPU需要花费 一些时间在做查询服务工作。 中断则是在外围设备需要通讯服务时主动告诉CPU,这个时候CPU才停下当前工作去处理中断程 序,不需要占用CPU主动去查询的时间,CPU可以在没有中断请求来临之前一直做自己的工作,从而 提高了CPU效率。 2)可以实现实时处理 外设任何时刻都可能发出请求中断信号,CPU接到请求后及时处理,以满足实时系统的需要。 3)可以及时处理故障 计算机系统运行过程中难免会出现故障,有许多事情是无法预料的,如电源掉电、存储器出错、 外围设备工作不正常等,这时可以通过中断系统向中断源CPU发送中断请求,由CPU及时转到相应 的出错处理程序,从而提高计算机的可靠性。 7.5.3 STM32中断的初步理解 这个例程的实验原理主要包括两个:一、通过神舟III号开发板上的4个按键(USER2、USER1、 TAMPER、WAKEUP),控制4个LED灯的点亮和关闭状态。 具体的对应关系如下: 现象 操作 LED1亮其它LED灭 LED2亮其它LED灭 LED3亮其它LED灭 LED4亮其它LED灭 神舟III号板载USER2按键被按下 神舟III号板载USER1按键被按下 神舟III号板载TAMPER按键被按下 神舟III号板载WAKEUP按键被按下 这里我们首先STM32 IO口中断的一些基础概念。STM32的每个IO都可以作为外部中断的中断输 入口,这点也是STM32的强大之处。STM32F103的中断控制器支持19个外部中断/事件请求。每个中 断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103的19个外部中断为: 线0~15:对应外部IO口的输入中断。 线16:连接到PVD输出。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 291 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 线17:连接到RTC闹钟事件。 线18:连接到USB唤醒事件。 STM32F103ZE一共有7组GPIO,每组GPIO口都有16个管脚,分别是PA[15:0]、PB[15:0]、PC[15:0]、 PD[15:0] 、PE[15:0] 、PF[15:0] 和PG[15:0]。STM32的所有GPIO管脚都可以作为中断输入源,但是 如果每个GPIO都是一个独立的中断源,则需要90个中断源,这是不科学的,所以通过复用的方式使其 对处理器来说来自GPIO的一共有16个中断Px[15:0]。具体实现是PA[0]、PB[0]、PC[0]、PD[0] 、PE[0] 、 PF[0] 和PG[0]。共享一个GPIO中断;PA[1]、PB[1]、PC[1]、PD[1] 、PE[1] 、PF[1] 和PG[1]共享一 个GPIO中断;……PA[15]、PB[15]、PC[15]、PD[15]、PE[15] 、PF[15] 和PG[15]共享一个GPIO中断, 如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 292 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 所以在硬件设计时要注意,不要将外部中断连接到PA[1]、PB[1]、PC[1]、PD[1] 和PE[1],这样 的话处理器只能选择一个作为中断源比如PA[1],那么其它的中断将无法到达处理器。 下 面 谈 谈 具 体 的 代 码 实 现 , 在 库 函 数 中 , 配 置 GPIO 与 中 断 线 的 映 射 关 系 的 函 数 GPIO_EXTILineConfig()来实现的: void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) 该函数将GPIO端口与中断线映射起来,例如: GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource3); 将中断线3与GPIOA映射起来,那么很显然是GPIOA的第3个管脚与EXTI3中断线连接了。设置好 嵌入式专业技术论坛 (www.armjishu.com)出品 第 293 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断线映射之后,那么到底来自这个IO口的中断是通过什么方式触发的呢?这里还需要对中断的一些 属性进行设置,接下来我们就要设置该中断线上中断的初始化参数了。 中断线上中断的初始化是通过函数EXTI_Init()实现的。EXTI_Init()函数的定义是: void EXTI_Init ( EXTI_InitTypeDef * EXTI_InitStruct ); 所有的参数都会被设置到EXTI_InitTypeDef这个结构体里去,下面我们用一个使用范例来说明这 个函数的使用: EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line= EXTI_Line3; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); 上面的例子设置中断线3上(EXTI_Line3;)的中断为下降沿触发(EXTI_Trigger_Falling)。STM32 的外设的初始化都是通过结构体来设置初始值的,这里就不罗嗦结构体初始化的过程了。我们来看看 结构体EXTI_InitTypeDef的成员变量, 从定义可以看出,有4个参数需要设置: typedef struct { uint32_t EXTI_Line; EXTIMode_TypeDef EXTI_Mode; EXTITrigger_TypeDef EXTI_Trigger; FunctionalState EXTI_LineCmd; }EXTI_InitTypeDef; 第一个参数是中断线的标号,取值范围为EXTI_Line0~EXTI_Line15。这个在上面已经讲过中断 线的概念。也就是说,这个函数配置的是某个中断线上的中断参数。 第二个参数是中断模式,可选值为中断EXTI_Mode_Interrupt和事件EXTI_Mode_Event。 第 三 个 参 数 是 触 发 方 式 , 可 以 是 下 降 沿 触 发 EXTI_Trigger_Falling , 上 升 沿 触 发 EXTI_Trigger_Rising,或者任意电平(上升沿和下降沿)触发EXTI_Trigger_Rising_Falling,相信学过 51的对这个不难理解。 第四个参数是使能中断 7.5.4 STM32中断的初始化过程以及手册的查询 关于中断的更加深入的理解查阅手册之后,ST 明确给出需要查看另外的几个文档 这两个手册都在光盘资料里可以找到,《STM32F10XXX 参考手册》中主要介绍的是关于中断的 屏蔽,哪根中断线进行上升沿或者下降沿触发等,如下手册目录截图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 294 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 . 这 里 没 有 涉 及 到 优 先 级 的 设 定 , 优 先 级 的 设 定 具 体 细 节 在 另 外 一 个 手 册 中 就 是 《 STM32F10xxx Cortex-M3 编程手册》,如下手册目录截图: 最后第三个手册是《CM3 技术参考手册》主要是介绍理论上的,介绍整个 NVIC 的编程器模型,有兴 趣的可以详细去研究一下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 295 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这么用户手册,那么外部中断初始化的一般要经过那些步骤呢?请见下面: 1)初始化IO口为输入。 2)开启IO口复用时钟,设置IO口与中断线的映射关系。 3)初始化线上中断,设置触发条件等(需参考《STM32F10XXX参考手册》) 4)配置中断分组(NVIC),并使能中断(需参考《STM32F10xxx Cortex-M3编程手册》) 5)编写中断服务函数。 通过以上几个步骤的设置,我们就可以正常使用外部中断了,关于IO口初始化中断之后,唯一复 杂的就只剩下中断分组的优先级了,这个优先级原本在51单片机中是比较简单的,但在M3中就被设计 得比较复杂一些,优先级无非就是这些任务按先后顺序进行切换,那么我们接来下做一些详细的分析: 7.5.5 STM32中断优先级 CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程 中断设置。但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断, 包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。而我们常用的就是这68个可屏 蔽中断,但是STM32的68个可屏蔽中断,在STM32F103系列上面,又只有60个(在107系列才有68个); 所以说这个16级的中断优先级就随客户怎么去设计,把STM32F103的这60个中断分别赋予不同的优先 级,用户可以根据各自的情况来灵活设定优先级,已使得系统能够以最高效能来进行工作,这里的 NVIC就是中断属性的设置的一个专业术语,下面看看与NVIC相关的寄存器有哪些属性: STM32的中断在这些寄存器的控制下有序的执行的。只有了解这些中断寄存器,才能了解STM32 的中断。下面简要介绍这几个寄存器: ISER[8]:ISER全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组,要使能某个 中断,必须设置相应的ISER位为1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。 ICER[8]:全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。该寄存器组与ISER 的作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和ICER一样。这里要专门设置 一个ICER来清除中断位,而不是向ISER写0来清除,是因为NVIC的这些寄存器都是写1有效的,写0 是无效的。具体为什么这么设计,请看《CM3权威指南》第125页,NVIC概览一章。 ISPR[8]:全称是:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。每个位对应的 嵌入式专业技术论坛 (www.armjishu.com)出品 第 296 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断和ISER是一样的。通过置1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写0 是无效的。 ICPR[8]:全称是:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。其作用与ISPR 相反,对应位也和ISER是一样的。通过设置1,可以将挂起的中断接挂。写0无效。 IABR[8]:全称是:Active Bit Registers,是一个中断激活标志位寄存器组。这是一个只读寄存器, 通过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。对应位所代表的中断 和ISER一样,如果为1,则表示该位所对应的中断正在被执行。 IP[240]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄存器组 相当重要!STM32的中断分组与这个寄存器组密切相关。因为STM32的中断多达60多个,所以STM32 采用中断分组的办法来确定中断的优先级。IPR寄存器组由15个32bit的寄存器组成,每个可屏蔽中断 占用8bit,这样总共可以表示15*4=60个可屏蔽中断。刚好和STM32的可屏蔽中断数相等。IP[0]的 [31~24],[23~16],[15~8],[7~0]分别对应中中断3~0,依次类推,总共对应68个外部中断。而每个可 屏蔽中断占用的8bit并没有全部使用,而是 只用了高4位。这4位,又分为抢占优先级和子优先级。抢 占优先级在前,子优先级在后。而这两个优先级各占几个位又要根据SCB->AIRCR中中断分组的设置 来决定。 寄存器ISER、ICER、ISPR、ICPR、IABR在STM32中都使用的8个(实际3个就够了,后面的留在后 面扩充?)。这些32位的寄存器中每一位对应了一个中断通道相应的标志。 比如地址在0xE000E100的ISER[0]这个32位的寄存器,第0位是中断通道0的允许位,第1位是中断 通道1的允许标志……第31位是中断通道31的允许位;接下来地址在0xE000E104的ISER[1]则是中断通 道32-63的允许位。ICER、ISPR、ICPR、IABR的结构相同,只是含义不同。注意是对这些寄存器的操 作:写1表示置位或清除,写0无任何影响。例如:对地址在0xE000E100的ISER[0]的第0位写1,表示 允许中断通道0中断;但对0xE000E100的ISER[0]的第0位写0,则没有任何作用,该位保持不变。 如果要禁止中断通道0的中断响应,那么就必须:对地址0xE000E180的ICER[0]的第0位写1,表示禁止 中断通道0的中断;对0xE000E180的ICER[0]的第0位写0,也是不起任何作用的。IP[240]用于定义240 个外部中断通道的优先级,每1个字节对应一个中断通道。4个中断通道的IP[n]字构成一个32位的寄 存器。在STM32中最多有68个外部中断通道,每个IP[n]的1个字节中只使用高4位(见前面介绍)。IP[n] 的结构如下: 7.5.6 硬件设计 神舟III号STM32开发板总共有4个功能按键,分别是WAKEUP按键和TAMPER按键及两个用于自定义 功能按键,在不使用第二功能的情况下,这四个按键都可以作为通用的按键,由用户自定义其功能。 这四个按键分别与PD3、PA8、PC13和PA0四个GPIO管脚连接,当按键按下时,对应的GPIO管脚为低 电平,反之,当没有按键按下时,对应的GPIO管脚为高电平。其中PA0 (STM32的WKUP引脚)可以作 为WK_UP功能,它除了可以用作普通输入按键外,还可以用作STM32的唤醒输入。PC13可以实现备 份区寄存器的入侵功能。本实验中所有的按键均作为普通IO使用。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 297 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 9 按键输入电路 GPIO 管脚与按键对应关系 按键 USER1 USER2 KEY3/TAMPER KEY4/WAKEUP 按键对应的GPIO PA8 PD3 PC13 PA0 本实验需要使用的 GPIO 管脚与对应的 LED 灯关系如下: LED灯 LED灯对应的GPIO DS1 PF6 DS2 PF7 嵌入式专业技术论坛 (www.armjishu.com)出品 第 298 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 DS3 PF8 DS4 PF9 7.5.7 软件设计 进入例程的文件夹,然后打开\Project \ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了时钟,这里的代 码是汇编的,大家可以了解一下就可以,这个文件里的代码是ST官方定制好了的,不需要我们修改, 我们只需要知道在这里有这个时钟调用的函数就可以。 代码分析2:初始化LED这些前面已经有详细分析,这里不细分析 代码分析4:SZ_STM32_KEYInit()初始化板载按键为中断模式 代码分析5:初始化中断线,以及中断的触发模式: 代码分析6:初始化KEY按键的中断优先级 嵌入式专业技术论坛 (www.armjishu.com)出品 第 299 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析7:BUTTON_IRQn[Button]例如在按键KEY1中对应的PD3的管脚,所以对应到的中断函数为 EXTI4_IRQn,可以在stm32f10x_it.c中找到这个对应的函数: 这里需要说明一下,STM32的IO口外部中断函数只有6个,分别为: EXPORT EXTI0_IRQHandler EXPORT EXTI1_IRQHandler EXPORT EXTI2_IRQHandler EXPORT EXTI3_IRQHandler EXPORT EXTI4_IRQHandler EXPORT EXTI9_5_IRQHandler EXPORT EXTI15_10_IRQHandler 中断线0-4每个中断线对应一个中断函数,中断线5-9共用中断函数EXTI9_5_IRQHandler,中断线10-15 共用中断函数EXTI15_10_IRQHandler。 代码分析8:关于函数EXTI_GetITStatus(EXTI_Line3)和EXTI_ClearITPendingBit(EXTI_Line3)做进一步 分析 在编写中断服务函数的时候会经常使用到两个函数,第一个函数是判断某个中断线上的中断是否 发生(标志位是否置位): ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); 这个函数一般使用在中断服务函数的开头判断中断是否发生。另一个函数是清除某个中断线上的 中断标志位: void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 这个函数一般应用在中断服务函数结束之前,清除中断标志位。 常用的中断服务函数格式为: void EXTI3_IRQHandler(void) { 嵌入式专业技术论坛 (www.armjishu.com)出品 第 300 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生 { 中断逻辑… EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE上的中断标志位 } } 在这里需要说明一下,固件库还提供了两个函数用来判断外部中断状态以及清除外部状态标志位 的 函 数 EXTI_GetFlagStatus 和 EXTI_ClearFlag ,他们 的 作 用 和前 面 两 个 函数 的 作 用 类似 。 只 是 在 EXTI_GetITStatus 函 数 中 会 先 判 断 这 种 中 断 是 否 使 能 , 使 能 了 才 去 判 断 中 断 标 志 位 , 而 EXTI_GetFlagStatus直接用来判断状态标志位。如果使用了这两个函数,可以使得程序更加的健壮。 代码分析9:NVIC_GroupConfig()配置NVIC中断优先级分组 NVIC只可以配置16种 中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4 位的数字来决定,把这个4位数字的位数,分配成抢占优先级部分和响应优先级部分。有5组分配方式。 代码分析10:NVIC_InitTypeDef结构体初始化了优先级的初始定义,首先要用NVIC_IRQChannel参数 来选择将要配置的中断向量,用NVIC_IRQChannelCmd参数来进行使能(ENABLE)或关闭(DISABLE) 该 中 断 。 在 NVIC_IRQChannelPreemptionPriority 成 员 要 配 置 中 断 向 量 的 抢 占 优 先 级 , 在 NVIC_IRQChannelSubPriority需要配置中断向量的响应优先级: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 301 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 NVIC_IRQChannel 需要配置的中断向量; NVIC_IRQChannelPreemptionPriority 配置相应中断向量抢占优先级; NVIC_IRQChannelSubPriority 配置相应中断向量的响应优先级; NVIC_IRQChannelCmd 使能或关闭相应中断向量的中断响应; 代码分析11:要配置这些优先级组,可以采用库函数NVIC_PriorityGroupConfig(),可输入的参数为 NVIC_PriorityGroup_0 ~ NVIC_PriorityGroup_4,分别为以上介绍的5种分配组。 可以看到,关于设置优先级的时候,就进入到了SCB->AIRCR这个寄存器了,这个寄存器可以在 《STM32F10xxx Cortex-M3编程手册》中找到,我们截取部分进行说明: 我 们 可 以 看 到 , SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup; 例 如 : SCB->AIRCR |= (0x05FA0000 | 0x600)这句代码设置到了AIRCR寄存器到底是什么,设置成了 0x05FA0600这个值 这里简单介绍一下STM32的中断分组:STM32将中断分为5个组,组0~4。该分组的设置是由 SCB->AIRCR寄存器的bit10~8来定义的。 AIRCR(Application Interrupt/Reset Control Register),该寄存器的[10:8]3位就是 PRIGROUP的定 义位,它的值规定了系统中有多少个抢先级中断和子优先级中断。而STM32只使用高4位bits,其可能 的值如下(来自ST的函数库头文件中的定义),那么现在就选择了下面的组1,目前优先级被设定为 嵌入式专业技术论坛 (www.armjishu.com)出品 第 302 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 组1,也就是1位抢占优先级,3位响应优先级 由于这个寄存器相当重要,为了防止误操作(写),因此当改写这个寄存器的内容时,必须要同 时向这个寄存器的高16位[31:16]写验证字(Register key) 0x05FA。 代码分析12:下面开始分析NVIC_Init() 中断优先级设置的步骤: 1. 系统运行开始的时候设置中断分组。确定组号,也就是确定抢占优先级和子优先级的分配位数。 调用函数为NVIC_PriorityGroupConfig(); 2. 设置所用到的中断的中断优先级别。对每个中断调用函数为NVIC_Init(); 函数NVIC_Init()初始化优先级等相关属性,STM32的中断如此之多,配置起来并不容易,因此, 我们需要一个强大而方便的中断控制器NVIC (Nested Vectored Interrupt Controller)。NVIC是属于Cortex 内核的器件,不可屏蔽中断 (NMI)和外部中断都由它来处理,而SYSTICK不是由NVIC来控制的。 使 用 NVIC 来 配 置 中 断 时 , 自 然 想 到 ST 库 肯 定 也 已 经 把 它 封 装 成 库 函 数 了 。 对 NVIC 初 始 化 NVIC_Init() 函数,首先要定义并填充一个NVIC_InitTypeDef 类型的结构体: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 303 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到这个函数中对3个结构体进行设置了,其中SCB->AIRCR前面已经介绍过了,这里就是把 用户设定的优先级真正的取出来: 然后存入到 代码分析13:分析一下NVIC_Type的结构体 STM32的中断在这些寄存器的控制下有序的执行的。只有了解这些中断寄存器,才能了解STM32 的中断。下面简要介绍这几个寄存器: ISER[8]:ISER全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组。要使能某个 中断,必须设置相应的ISER位为1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO 口映射等设置才算是一个完整的中断设置)。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 304 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ICER[8]:全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。该寄存器组与ISER的 作用恰好相反,是用来清除某个中断的使能的。其对应位的功能,也和ICER一样。这里要专门设置一 个ICER来清除中断位,而不是向ISER写0来清除,是因为NVIC的这些寄存器都是写1有效的,写0是无 效的。具体为什么这么设计,请看《CM3权威指南》第125页,NVIC概览一章。 ISPR[8]:全称是:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。每个位对应的中断 和ISER是一样的。通过置1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。写0是无效 的。 ICPR[8]:全称是:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。其作用与ISPR相 反,对应位也和ISER是一样的。通过设置1,可以将挂起的中断接挂。写0无效。 IABR[8]:全称是:Active Bit Registers,是一个中断激活标志位寄存器组。这是一个只读寄存器,通 过它可以知道当前在执行的中断是哪一个。在中断执行完了由硬件自动清零。对应位所代表的中断和 ISER一样,如果为1,则表示该位所对应的中断正在被执行。 IP[240]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。这个寄存器组相当 重要!STM32的中断分组与这个寄存器组密切相关。因为STM32的中断多达60多个,所以STM32采用 中断分组的办法来确定中断的优先级。IP寄存器组由240个32bit的寄存器组成,每个可屏蔽中断占用 8bit。IPR[0]的[31~24],[23~16],[15~8],[7~0]分别对应中中断3~0,依次类推。而每个可屏蔽中断占 用的8bit并没有全部使用,而是 只用了高4位。这4位,又分为抢占优先级和子优先级。抢占优先级在 前,子优先级在后。而这两个优先级各占几个位又要根据SCB->AIRCR中中断分组的设置来决定。 代码分析14:全部设置好之后,只需要进入一个while()死循环,一旦按键按下,就触发了已经配置好 的GPIO管脚的中断,从而进入到中断函数,执行中断函数里的内容 中断函数都放在stm32f10x_it.c中 嵌入式专业技术论坛 (www.armjishu.com)出品 第 305 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.5.8 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.5如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.5.9 实验现象 把程序下载到开发板后,重新上电运行。全部LED亮,然后轮流熄灭。在没有按键按下时,所有 的LED灯都灭,有按键按下,相关的LED灯会随之发生变化,具体实现现象如下表所示。 现象 操作 说明 LED1亮其它LED灭 神舟III号板KEY1按键被按下 8下时则保持最后 LED2亮其它LED灭 LED3亮其它LED灭 神舟III号板KEY2按键被按下 神舟III号板KEY3/TAMPER按键被按下 一次按键出发的 LED亮 LED4亮其它LED灭 神舟III号板KEY4/WAKEUP按键被按下 7.6 SysTick系统滴答实验 7.6.1 基本概念和原理 SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号:15)。在以前,操作系统和有 嵌入式专业技术论坛 (www.armjishu.com)出品 第 306 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 所有使用了时基的系统,都必须要一个硬件定时器来产生需要的“滴答”中断,作为整个系统的时基。 滴答中断对操作系统尤其重要。例如,操作系统可以为多个任务许以不同数目的时间片,确保没有一 个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的 各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还 让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 Cortex-M3在内核部分 包含了一个简单的定时器——SysTick timer。因为所有的CM3芯片都带有 这个定时器,软件在不同芯片生产厂商的 CM3器件间的移植工作就得以化简。该定时器的时钟源可以 是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。不过, STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同。因此,需要 阅读芯片的使用手册来确定选择什么作为时钟源。在STM32中SysTick 以 HCLK(AHB时钟)或HCLK/8 作 为运行时钟。 SysTick定时器:系统滴答定时器是一个非常基本的倒计时定时器,用于在每隔一定的时间产生一 个中断,即使是系统在睡眠模式下也能工作。它使得OS 在各CM3器件之间的移植中不必修改系统定 时器的代码,移植工作一下子容易多了。 SysTick定时器能产生中断,CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。 它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间,SysTick 的处理方式都是相同的。SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个 闹铃,用于测量时间等。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 307 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 Systick 定时器属于cortex内核部件,可以参考《Cortex-M3权威指南》或《STM32xxx-Cortex编程 手册》来了解。 7.6.2 实验原理 SysTick其实就是一个24位的倒计数定时器,当计到0时,将从STK_LOAD寄存器中自动重装载定 时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。 下面先了解跟SysTick相关的几个寄存器。 SysTick_CSR 0xE000E010 -- 控制寄存器 SysTick_LOAD 0xE000E014 -- 重载寄存器 SysTick_VAL 0xE000E018 -- 当前值寄存器 SysTick_CALRB 0xE000E01C -- 校准值寄存器 由于SysTick是CortexM3的标准组件,关于技术细节详细请参见《Cortex-M3 技术参考手册》文档 73页。 7.6.3 硬件设计 SysTick 为内部组件,这部分不需要硬件电路,这里仅在中断产生时,进行点灯操作。 7.6.4 软件设计 打开主函数: 代码分析1: 初始化LED灯以及初始化蜂鸣器,然后通过函数SZ_STM32_SysTickInit(1000)设置systick 定时器。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 308 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析2:SysTick_Config()是完成systick设置的最终函数,下面具体来分析一下寄存器: 因为STM32是SystemCoreClock时钟是72MHZ,在这里传入的值是SystemCoreClock /1000,每次振 荡时间是1/72MHZ,现在需要振荡72M/1000次总共所花的时间用以下公式来算:、 需要振荡的次数 * 每次的振荡时间 = 72M/1000 * 1/72M = 1/1000 = 0.001秒 = 1毫秒 也就是说,systick每隔1ms时钟就会产生一次systick的中断,函数内部的配置可以参看下面的寄存器 — SysTick_CSR SysTick控制与状态寄存器 复位状态为:0x00000000 SysTick_CSR寄存器的位分配如下所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 309 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以上各位的描述,如下表所示: — SysTick_LOAD 重装值寄存器 SysTick 一 个 递 减 的 计 数 器 , 当 计 数 器 递 减 到 “ 0 ” 时 , 重 装 寄 存 器 中 的 值 就 会 被 重 装 。 SysTick_LOAD重装值寄存器是一个24位宽的寄存器,如下图所示: — SysTick_VAL 当前值寄存器 使用SysTick当前值寄存器来查找寄存器中的当前值。具体寄存器的位分配如下所示: — SysTick_CALRB 校准寄存器 使用校准寄存器通过乘法或是除法运算可以将寄存器调节成任意所需的时钟速率,如下所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 310 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析3:产生中断之后进入中断函数SysTick_Handler() 调用SysTick_Handler_User()函数,每调用一次TimeIncreaseu增加1,就表示时间过了1毫 秒 代码分析4:调用SysTick_Handler_User()每隔100毫秒就进去判断一次,如果满了3秒钟 就使得蜂鸣器叫以及LED灯亮,100毫秒之后,再熄灭掉。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 311 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.6.5 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.6.6 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,重新打开电源;神舟 III 号开发板上的蜂 鸣器大约每隔 3 秒都会响一声,同时 1 个 LED1 灯会亮一下;循环周而复始。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 312 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.7 USART串口1通信实验 当我们在学习一款 CPU 的时候,最经典的实验莫过于流水灯了,会了流水灯的话就基本等于学会 会操作 I/O 口了。那么在学会操作 I/O 之后,面对那么多的片上外设我们又应该先学什么呢?有些朋 友会说用到什么就学什么,听起来这也不无道理呀。 前面我们已经通过寄存器的方式学习过串口了,下面主要是更多介绍一下 STM32 库函数的串口实 现方式,再进一步补充一点串口的更深入的知识点。 7.7.1 STM32的异步串口通讯协议 . 阅读过《STM32 中文参考手册》的读者会发现,STM32 的串口非常强大,它不仅支持最基本的 通用串口同步、异步通讯,还具有 LIN 总线功能(局域互联网)、IRDA 功能(红外通讯)、SmartCard 功 能。为实现最迫切的需求,利用串口来帮助我们调试程序,本章介绍的为串口最基本、最常用的方法, 全双工、异步通讯方式。下图为串口异步通讯协议。 重温串口的通讯协议,我们知道要配置串口通讯,至少要设置以下几个参数:字长(一次传送的数据 长度)、波特率(每秒传输的数据位数)、奇偶校验位、还有停止位。对 ST 库函数的使用已经上手的读 者应该能猜到,在初始化串口的时候,必然有一个串口初始化结构体,这个结构体的几个成员肯定就 是有来存储这些控制参数的。 7.7.2 交叉线和直连线 嵌入式专业技术论坛 (www.armjishu.com)出品 第 313 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 见上图,这是神舟 III 号 STM32 开发板的接线图,使用的为 MAX3232 芯片,把 STM32 的 PA10 引脚(复用功能为 USART1 的 Rx)接到了 DB9 接口的第 2 针脚,把 PA9 引脚(复用功能为 USART 的 Tx) 连接到了 DB9 接口的第 3 针脚。 Tx(发送端)接第 3 针脚,Rx(接收端)接第 2 针脚。这种接法是跟 PC 的串口接法一样的,如 果要实现 PC 跟神舟 STM32 开发板通讯,就要使用两头都是母的交叉线。 7.7.3 串口工作流程 1.串口传输速度控制(波特率控制) 前面的寄存器版本有提到过,这里再细讲一下,波特率,即每秒传输的二进制位数,用 b/s (bps) 表示,通过对时钟的控制可以改变波特率。在配置波特率时,我们向波特比率寄存器 USART_BRR 写 入 参 数 , 修 改 了 串 口 时 钟 的 分 频 值 USARTDIV 。 USART_BRR 寄 存 器 包 括 两 部 分 , 分 别 是 DIV_Mantissa(USARTDIV 的整数部分)和 DIVFraction(USARTDIV 的小数)部分,最终,计算公式为 USARTDIV=DIV_Mantissa+(DIVFraction/16)。 USARTDIV 是对串口外设的时钟源进行分频的,对于 USART1,由于它是挂载在 APB2 总线上的, 所以它的时钟源为 fPCLK2;而 USART2、3 挂载在 APB1 上,时钟源则为 fPCLK1,串口的时钟源经 过 USARTDIV 分频后分别输出作为发送器时钟及接收器时钟,控制发送和接收的时序。 2.收和发控制 围绕着发送器和接收器控制部分,有好多个寄存器:CR1、CR2、CR3、SR,即 USART 的三个 控制寄存器(Control Register)及一个状态寄存器(Status Register)。通过向寄存器写入各种控制参数,来 控制发送和接收,如奇偶校验位,停止位等,还包括对 USART 中断的控制;串口的状态在任何时候 都可以从状态寄存器中查询得到。具体的控制和状态检查,我们都是使用库函数来实现的,在此就不 具体分析这些寄存器位了。 3.传输过程中的数据存储 收发控制器根据我们的寄存器配置,对数据存储转移部分的移位寄存器进行控制。当我们需要发 送数据时,内核或 DMA 外设把数据从内存(变量)写入到发送数据寄存器 TDR 后,发送控制器将适时 地自动把数据从 TDR 加载到发送移位寄存器,然后通过串口线 Tx,把数据一位一位地发送出去,在 数据从 TDR 转移到移位寄存器时,会产生发送寄存器 TDR 已空事件 TXE,当数据从移位寄存器全部 发送出去时,会产生数据发送完成事件 TC,这些事件可以在状态寄存器中查询到。 而接收数据则是一个逆过程,数据从串口线 Rx 一位一位地输入到接收移位寄存器,然后自动地 转移到接收数据寄存器 RDR,最后用内核指令或 DMA 读取到内存(变量)中。 4.串口整体架构图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 314 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.7.4 例程 01 UART串口1 Printf打印输出字符 7.7.5 软件设计 进入主函数: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 315 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:SZ_STM32_COMInit(COM1, 115200);初始化串口 1,并且设置波特率为 115200,并对串 口设置了许多参数 代码分析 2:__SZ_STM32_COMInit(COM, &USART_InitStructure);开始真正的对 USART 进行初始化 的工作,这里与前面寄存器版本的初始化串口一样,唯一不同的是这里是库函数来做的。这里主要过 程分为几步,我们分开来阐述: 代码分析 3:第一步是 GPIO 初始化 1.首先先对 GPIO 初始化 GPIO 具有默认的复用功能,在使用它的复用功能的时候,我们首先要把相应的 GPIO 进行初始 化。此时我们使用的 GPIO 的复用功能为串口,但为什么是 PA9 和 PA10 用作串口的 Tx 和 Rx,而不 是其它 GPIO 引脚呢?这是从《STM32F103 数据手册》的引脚功能定义中查询到的。 选定了这两个引脚,并且 PA9 为 Tx,PA10 为 Rx,那么它们的 GPIO 模式要如何配置呢?Tx 为 发 送 端 , 输 出 引 脚 , 而 且 现 在 GPIO 是 使 用 复 用 功 能 , 所 以 要 把 它 配 置 为 复 用 推 挽 输 出 (GPIO_Mode_AF_PP) ; 而 Rx 引 脚 为 接 收 端 , 输 入 引 脚 , 所 以 配 置 为 浮 空 输 入 模 式 GPIO_Mode_IN_FLOATING。如果在使用复用功能的时候,对 GPIO 的模式不太确定的话,我们可以 从《STM32 参考手册》的 GPIO 章节中查询得到,见下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 316 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 复用功能模式设置 代码分析 4:第二步是 USART 的初始化 初始化好 GPIO 之后,就要进行 USART1 的初始化,在库函数里就是填充 USART 的初始化结构 体。这部分内容,是根据串口通讯协议来设置的。 1. .USART_BaudRate = 115200; 波特率设置,利用库函数,我们可以直接这样配置波特率,而不需要自行计算 USARTDIV 的分 频因子。在这里把串口的波特率设置为 115200,也可以设置为 9600 等常用的波特率,在《STM32 参 考手册》中列举了一些常用的波特率设置及其误差,见下图。如果配置成 9600,那么在和 PC 通讯的 时候,也应把 PC 的串口传输波特率设置为相同的 9600。通讯协议要求两个通讯器件之间的波特率、 字长、停止位奇偶校验位都相同。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 317 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2. .USART_WordLength = USART_WordLength_8b; 配置串口传输的字长。本例程把它设置为最常用的 8 位字长,也可以设置为 9 位。 3. .USART_StopBits = USART_StopBits_1; 配置停止位。把通讯协议中的停止位设置为 1 位。 4. .USART_Parity = USART_Parity_No ; 配置奇偶校验位。本例程不设置奇偶校验位。 5. .USART_HardwareFlowControl= USART_HardwareFlowControl_None; 配置硬件流控制。不采用硬件流。 硬件流,在 STM32 的很多外设都具有硬件流的功能,其功能表现为:当外设硬件处于准备好的状态 时,硬件启动自动控制,而不需要软件再进行干预。 在串口这个外设的硬件流具体表现为:使用串口的 RTS (Request to Send) 和 CTS(Clear to Send) 针脚, 当串口已经准备好接收新数据时,由硬件流自动把 RTS 针拉低(向外表示可接收数据);在发送数据前, 由硬件流自动检查 CTS 针是否为低(表示是否可以发送数据),再进行发送。本串口例程没有使用到 CTS 和 RTS,所以不采用硬件流控制。 6. USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 配置串口的模式。为了配置双线全双工通讯,需要把 Rx 和 Tx 模式都开启。 7. 填充完结构体,调用库函数 USART_Init()向寄存器写入配置参数。 8. 最后,调用 USART_Cmd() 使能 USART1 外设。在使用外设时,不仅要使能其时钟,还要调用此 函数使能外设才可以正常使用。 代码分析 5:第三步就是将 printf()进行重定向,使得串口打印的数据可以从 printf 直接输出,这样就 比较方便调试产品。 在 main 文件中,配置好串口之后,就通过下面的几行代码由串口往电脑里面的超级终端打印信息, 打印的信息为一些字符串和当前的日期。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 318 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 调用这个函数看似很简单,我们来看 printf() 这个函数。要想 printf() 函数工作的话,我们需要把 printf() 重新定向到串口中。重定向,是指用户可以自己重写 c 的库函数,当连接器检查到用户编写了 与 C 库函数相同名字的函数时,优先采用用户编写的函数,这样用户就可以实现对库的修改了。 为了实现重定向 printf()函数,我们需要重写 fputc() 这个 c 标准库函数,因为 printf()在 c 标准库函 数中实质是一个宏,最终是调用了 fputc()这个函数的。 重定向的这部分工作,由 usart.c 文件中的 fputc(int ch, FILE *f) 这个函数来完成,这个函数具体实 现如下: 重定向时,我们把 fputc()的形参 ch,作为串口将要发送的数据,也就是说,当使用 printf(),它调用 这个 fputc()函数时,然后使用 ST 库的串口发送函数 USART_SendData(),把数据转移到发送数据寄存 器 TDR,触发我们的串口向 PC 发送一个相应的数据。调用完 USART_SendData()后,要使用 while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET) 语句不停地检查串口发送是否完成 的标志位 TC,一直检测到标志为完成,才进入一下步的操作,避免出错。在这段 while 的循环检测的 延时中,串口外设已经由发送控制器根据我们的配置把数据从移位寄存器一位一位地通过串口线 Tx 发送出去了。 这个代码中调用了两个 ST 库函数。USART_SendData() 和 USART_GetFlagStatus()其说明见图下 图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 319 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 320 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 注意:这里有个 USR MicroLIB 库,如果没有效果可以对此处打钩,一般是不需要的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 321 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.7.6 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.7.7 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 1 与电脑连 接,并打开超级终端,按以下设置,如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 322 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 选择 COM1;按确定 再按确定,完成超级终端设置,重新打开电源 超级终端窗口显示信息,如下图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 323 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.7.8 例程 02 UART串口1-带SYSTICK中断Printf() 7.7.9 软件设计 此处仅仅多了一个 SYSTICK 定时器来产生中断,在串口打印的同时还可以点亮 LED 灯。 7.7.10 实验现象 实验现象同上,不同的是可以看到板子上多两个 LED 灯在不停的闪烁。 7.7.11 例程 03 UART串口1Printf输出和scanf输入 7.7.12 软件设计 关键代码分析: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 324 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:scanf()是一个 C 语言的标准库函数 scanf 函数,与 printf 函数一样,都被定义在 stdio.h 里,因此在使用 scanf 函数时要加上 #include。它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中, 其关键字最末一个字母 f 即为“格式”(format)之意。 代码分析 2: 表示敲打键盘输入的字符会被自动转化成字符串和 表示敲打键盘输入的字符会被自动转化数字。 代码分析 3:当执行到 scanf()函数的时候,程序就会被阻塞在这里,当 scanf()函数收到回车键的时 候,就会把回车键之前输入的字符,都会输入到 scanf()函数的变量中,比如这里是 ucStr 和 num 这 2 个变量参数,接下来的任务就把输入的值用作用户交互的一些事务了。 7.7.13 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 1 与电脑连接, 并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 325 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 重新打开电源;神舟 III 号 STM32 开发板上 4 个 LED 灯闪一下,LED 2 和 LED 4 灯常亮, LED 3 在 闪烁,完成一次数据输入后 LED 1 灯取反一次。 超级终端窗口显示信息,如下图 并按相关提示信息输入内容。 如输入字符串:abcd 并以空格或回车键结束; 显示结果,如图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 326 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再输入一个数字:如输入 9 ;并以空格或回车键结束; 显示结果,如下图 以上就是串口 1 的输入输出实验。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 327 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.8 USART串口2通信实验 7.8.1 意义与作用 STM32 支持 5 个串口,有的设备有需要支持多个串口进行通信,比如一个串口不停发数据,一个 串口不停接收数据;或者一个设备同时接收多路数据。 串口的使用对于我们开发调试过程中的作用是非常之大,可以用来查看,打印以及输入相关信息, 是我们在嵌入式开发中最先与中央处理器通信的接口,学习好串口的功能,对于后续神舟III号的各个 例程的调试具有至关重要作用。 STM32的通用同步异步收发器(USART)是相当丰富的,功能也很强劲。最多可提供5路串口(神 舟III号开发板使用的是STM32F103ZET6,具有5个串口)。该USART有分数波特率发生器,发送和接 收共用的可编程波特率,最高达4.5Mbits/s;可编程数据字长度(8位或9位);可配置的停止位-支持1或2 个停止位;支持单线半双工通讯;支持LIN;支持智能卡协议和IrDA SIR ENDEC规范(仅串口3支持)、 具有DMA等。通过本节的学习,你将了解到STM32串口的基本使用方法、以及使用中断模式来实现串 口收发的过程。 7.8.2 串口2与串口1的区别 这个图是从 STM32F103 数据手册中摘抄出来的,也就是说 USART1 是由 APB2 总线提供时钟,而 USART2~USART5 都是由 APB1 提供时钟,APB1 的时钟是 35MHZ,比 APB2 的时钟要慢一半,所以 USART1 实际上可以在高速一点的波特率传输的时候要比 USART2~USART5 要稳定。 7.8.3 多个串口如何同时接收源源不断发送给每个串口的数据 使用中断 嵌入式专业技术论坛 (www.armjishu.com)出品 第 328 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.8.4 两个串口同时来数据了 这个时候只能进入一个中断,会丢失数据吗 可以做到不丢失数据,原因如下: 1) 串口是低速设备,115200 的波特率对 stm32 来说也是挺慢的速度 2) 中断与数据传输覆盖的时间差 USART 串口数据传输是一种很慢的传输方式,以波特率为 38400 计算,假定数据帧格式为:8 个 数据位、1 个停止位、没有奇偶检验位,则每个字节的传输时间至少为 260us,中断处理程序只要在这 个时间之内从接受寄存器读出收到的数据,就不会造成数据丢失。 串口数据在下一个自己接收完成之前,接收 BUF 里的数据是不会被覆盖的。所以实际中断相应只 要不超过 1 个字节的传输时间就没事。适当调整下各个中断处理程序,完全来得及 如果你有 2 个串口同时传输数据,则每个串口的接收中断处理程序只要能在 130us 内完成,就不 会造成数据丢失。串口是低速设备,115200 的波特率对 stm32 来说也是挺慢的速度, 同时中断,也就 是微秒级延时,不至于丢数据。 3) STM32 的 USART 中移位寄存器和数据寄存器是分开的 下图是 STM32 USART 的框图,在图的右上方可以看到,从 USART_RX 到来的数据通过 Receive Shift Register 被转换为并行格式,只有当收到一个完整的字节后,Receive Shift Register 的内容才被送到 Receive Data Register (RDR),程序可以通过 RDR 读出收到的数据字节。 只要你的程序在下一个数据字节到来之前读出 Receive Data Register (RDR),就不会产生数据丢失。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 329 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.8.5 硬件设计 由于处理器输出的是 TTL/COMS 电平,而 PC 串口为 RS-232 电平,所以硬件需要使用一颗电平转换 芯片 MAX3232 实现双向电压转换。原理图如错误!未找到引用源。所示。由于串口外围电路很简单 也很常见,再此就不做深入讲解了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 330 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 串口数据的输入和输出是站在处理器角度看的: USART2_RX:接收数据串行输入。通过过采样技术来区别数据和噪音从而恢复数据。 USART2_TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激 活,并且不发送数据时,TX管脚处于高电平。 GND:数字地。为接收和发送信号提供参考地。 神舟III号开发板上有 2 个RS-232C串口,如 图表 11 神舟III号开发板的 2 个RS-232C串口所示。 这两个RS-232C串口为DB9 公头插针,其线序与PC电脑上的DB9 公头插针相同,都为 2 脚输入到开发 板,3 脚输出,如所 图表 10 DB9 公头线序及信号定义示。所以只要一根母到母交叉串口线就可以方 便的将这两个串口连接起来,或者将开发板上的串口与PC机连接起来。 图表 10 DB9 公头线序及信号定义 嵌入式专业技术论坛 (www.armjishu.com)出品 第 331 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 11 神舟 III 号开发板的 2 个 RS-232C 串口 DB9管脚 功能描述 1 NC 2 USART1_PA10 开发板接收 3 USART1_PA9 开发板发送 4 NC 5 GND 表格 1 串口 1(CN5)信号定义 DB9管脚 6 7 8 9 功能描述 NC NC NC NC DB9管脚 功能描述 DB9管脚 功能描述 1 NC 6 NC 2 USART2_PA3 7 NC 3 USART2_PA2 8 NC 4 NC 9 NC 5 GND 表格 2 串口 2(CN6)信号定义 注:由于串口1与USB的ID和VBUS信号复用,使用时需要改变跳线位置,所以我们推荐使用串口2, 我们的示例也大都是在串口2输出信息。 由于 STM32 的管脚数量有限,所以其串口管脚为多功能复用管脚,为了不同功能硬件不相互影 响,开发板上使用跳线来选择对应功能,在做此次试验前需要检查神舟 III 号开发板上的跳线位置是 否正确。 如果连接串口 2(推荐,默认出厂跳线既连接好了串口 2),则需要将 JP14 的 2ÅÆ3 用跳帽短接, JP12 嵌入式专业技术论坛 (www.armjishu.com)出品 第 332 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 的 2ÅÆ3 用跳帽短接,串口 2 跳线位置图所示。 跳线连接正确后使用交叉母对母串口线连接神舟III号开发板的串口2(推荐)到PC或USB转串口线, 下面可以开始软件设计了。 7.8.6 例程01 UART串口2Printf()打印 大部分原理都通串口1相同,只有少部分不一样,实验现象也是相同 7.8.7 软件设计 主要有 3 点不同之处: 1) 在__SZ_STM32_COMInit()函数中,初始化的串口接收和发送的管脚是 PD5 和 PD6 2) 串口端口由 USART1 变成了 USART2 3) 串口 USART2 的时钟总线变成了 APB1 总线 7.8.8 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按 3.5 如何在 MDK 开发环境中使用 JLINK 在线调试小节进行操作。 7.8.9 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 2 与电脑连接, 并打开超级终端,按以下设置,如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 333 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 选择 COM1;按确定 再按确定,完成超级终端设置。 重新打开电源,神舟 III 号 STM32 开发板。超级终端窗口显示信息,如下图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 334 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.8.10 例程 02 UART串口2-带SYSTICK中断Printf() 同串口 1 对应章节 7.8.11 例程 03 UART串口2Printf输出和scanf输入 同串口 1 对应章节 7.9 UART串口1和串口2同时格式化输出输入 7.9.1 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.5如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.9.2 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 2 与电脑连接, 并打开超级终端,按以下设置,如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 335 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 选择 COM1;按确定 再按确定,完成超级终端设置。 注意神舟 III 号开发板上的跳线短连接; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 336 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 串口线连接开发板串口 2,重新打开电源,超级终端窗口显示详细信息: 提示: 当前显示的窗口为串口 2/COM2/USART2。 请将注意 J14 和 J12 位置跳到 2<->3 侧。 神舟 III 号开发板 STM32 串口 2 输出实验。 请输入字符串, 以空格或者回车结尾: 根据提示输入信息: 例如输入:abc 回车键 再输入:123 回车键 超级终端显示,以下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 337 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据提示“当前为串口 2,请在串口 1 输入字符串, 以空格或者回车结尾:” 接下来,切换串口 1;把串口线与开发板串口 1 连接; 并输入:cba 回车键 超级终端显示,以下图: 以上是 UART 串口 1 和串口 2 同时格式化输出输入实验。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 338 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.10 串口高级例程之Printf中断收发实验 前面两节学习了STM32的常用接口UART串口的基本使用。之前的讲解都是串口的基本使用方法, 效率比较低。本章节我们学习在神舟系列STM32开发板上使用串口接收中断和发送中断以及FIFO缓 存来实现高效率的串口数据收发实例。 本次串口实例借鉴了著名的操作系统VxWorks操作系统的串口相关实现方法。做过驱 动的人都知道,在驱动中频繁的使用Printf函数不但会降低系统的效率,而且可能会使系 统崩溃。原因是Printf在串口打印输出是需要等待,中断中的长时间等待是致命的。所以 本章节我们一起来研究如何使Printf函数实现0等待,以及如何实现缩短串口接收中断处 理速度。 7.10.1 意义与作用 目前串口仍然是MCU微控制器必不可少的接口之一。串口的使用对于我们开发调试过程中的作用 是非常之大,可以用来查看,打印以及输入相关信息,是我们在嵌入式开发中最先与中央处理器通信 的接口,学习好串口的功能,对于后续神舟III号的各个例程的调试具有至关重要作用。 鉴于前面章节已经对串口基础知识有了讲解,相关知识请参考实验4和实验5。 本章节我们学习使用串口接收中断和发送中断以及FIFO缓存来实现高效率的串口数据收发实 例。我们一起来研究如何使Printf函数实现0等待以及如何实现缩短串口接收中断处理速度。 现讲一段经历:本人曾经在调试板件系统时,需要将某一接口(标记为接口A)的数据消息打印 出来以Debug。接口A的特点是数据收发具有突发性和不持续性,当时计算过串口在115200波特率下根 本来不及打印接口A的突发数据,而且很担心使用Printf函数对系统造成不良影响甚至BUG不能重现。 带着怀疑的态度添加了Printf函数来Debug,事实证明系统的运行几乎没有受到影响,而且串口打印的 数据几乎没有丢失!!!!!我感到很是惊讶,直到一次调试中我断开了接口A的连接后,串口依然 打印接口A的消息数据持续了十几秒,我对VxWorks操作系统的串口相关实现方法产生了浓厚的兴趣。 相比之前调试Linux驱动时由于串口输出导致其他接口中断处理不及时而丢失产生了鲜明的对比。本章 节我们以类似的方法在神舟系列STM32开发板上实现串口接收中断和发送中断以及FIFO缓存来实现 高效率的串口数据收发。 该方法在后续的USB调试和以太网口程序调试时很实用。 7.10.2 实验原理 本实验的核心是: 对于串口 Printf 输出,为了做到使 Printf 函数实现 0 等待,我们在底层使用 Buffer 缓存来自 Printf 的数据,Buffer 按照 FIFO 先入先出的结构组织。当 Printf 有数据发送时,其底层的发送函数并不是真 正的串口发送,而只是将数据写入 FIFO 并使能串口发送中断后中便退出,这个操作时 RAM 的读写 操作,执行速度很快,所以不需要等待,唯一可能影响速度的是 FIFO 的深度,如果 FIFO 较小而实际 要打印的数据量很大则 FIFO 填满以后需要等待,所以可以根据实际情况设置 FIFO 的深度。本次在神 舟系列 STM32 开发板上的实验中发送缓存 FIFO“USART_Tx_Buffer”的深度为 256 字节,用户可以 自己修改其大小。而实际的发送数据是在串口发送中断中完成的。 对于串口输入,我们在在中断中使用 Buffer 缓存串口收到的数据,默认是收到回车符时或者收到 的数据填满缓冲区时通过全局变量“USART_Rx_Done”通知前台程序。这样中断里的程序简单则处 理 速 度 快 , 中 断 可 以 快 速 返 回 。 本 次 在 神 舟 系 列 STM32 开 发 板 上 的 实 验 中 接 收 缓 存 区 USART_Rx_Buffer 的大小为 20 字节,用户可以自己修改其大小。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 339 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.10.3 硬件设计 请参阅 错误!未找到引用源。错误!未找到引用源。 章节 由于 STM32 的管脚数量有限,所以其串口管脚为多功能复用管脚,为了不同功能硬件不相互影 响,开发板上使用跳线来选择对应功能,在做此次试验前需要检查神舟 III 号开发板上的跳线位置是 否正确。 如果连接串口 2(推荐,默认出厂跳线既连接好了串口 2),则需要将 J12 和 J14 的 2ÅÆ3 用跳 帽短接; 跳线连接正确后使用交叉母对母串口线连接神舟III号开发板的串口2(推荐)到PC或USB转串口 线,下面可以开始软件设计了。 7.10.4 软件设计 这一章节我们学习使用串口接收中断和发送中断以及FIFO缓存来实现高效率的串口数据收发实 例。我们一起来研究如何使Printf函数实现0等待以及如何实现缩短串口接收中断处理速度。 本实验设计灵活,可以支持串口1或者串口2,只需修改“Printf.h”文件的以下语句: 以上定义编译结果为使用神舟系列STM32开发板上的串口2(推荐)。 以上定义编译结果为使用神舟系列STM32开发板上的串口1。 关 于 STM32 的 USART 的 库 函 数 实 现 , 主 要 是 在 STM32F10x_StdPeriph_Driver 库 的 “ stm32f10x_usart.c ” 和 “ stm32f10x_usart.h ” 两 个 文 件 里 。 以 V3.5.0 版 本 的 库 为 例 , 它 们 位 于 “STM32F10x_StdPeriph_Lib_V3.5.0 \Libraries\Stm32F10x_StdPeriph_Driver”目录的“src”和“inc” 文件夹里,前面章节已经有所讲解,本章节不再讲述。 我们自顶向下剖析分解,首先是主程序MAIN函数: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 340 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 主程序MAIN函数首先1、配置中断向量表,然后2、初始化串口,接着打印提示消息,最后进入 While循环等待串口接收数据完成或缓存区溢出,将其打印。 1、配置中断向量表 根据宏定义来使能串口1或串口2的中断: 2、初始化串口 根据宏定义初始化串口1或串口2的参数,并使能接收和发送中断: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 341 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3、串口Printf发送的实现 首先,完成串口发送单个字节的函数,在“Printf.c”文件的有如下的宏定义,这是为了兼容不同 的编译平台。 图表 12 串口 PUTCHAR_PROTOTYPE 宏定义 其实现如下: 其“USART_StoreBufferData”函数的实现如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 342 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 原理:对于串口 Printf 输出,为了做到使 Printf 函数实现 0 等待,我们在底层使用 Buffer 缓存来 自 Printf 的数据,Buffer 按照 FIFO 先入先出的结构组织。当 Printf 有数据发送时,其底层的发送函数 并不是真正的串口发送,而只是将数据写入 FIFO 并使能串口发送中断后中便退出,这个操作时 RAM 的读写操作,执行速度很快,所以不需要等待,唯一可能影响速度的是 FIFO 的深度,如果 FIFO 较小 而实际要打印的数据量很大则 FIFO 填满以后需要等待,所以可以根据实际情况设置 FIFO 的深度。本 次在神舟系列 STM32 开发板上的实验中发送缓存 FIFO“USART_Tx_Buffer”的深度为 256 字节,用 户可以自己修改其大小。而实际的发送数据是在串口发送中断中完成的。 4、串口接收的实现 串口接收相关主要是在串口接收中断中调用“USART_GetInputString”函数接收并缓存串口数据, 支持退格键: 原理:对于串口输入,我们在在中断中使用 Buffer 缓存串口收到的数据,默认是收到回车符时或 者收到的数据填满缓冲区时通过全局变量“USART_Rx_Done”通知前台程序。这样中断里的程序简 单则处理速度快,中断可以快速返回。本次在神舟系列 STM32 开发板上的实验中接收缓存区 USART_Rx_Buffer 的大小为 20 字节,用户可以自己修改其大小。 注意上述函数中变量“USART_Rx_Done”与前台 MAIN 函数中语句的对应: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 343 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 5、串口中断处理的实现 首先,根据宏定义决定是使用串口 1 中断还是或串口 2 中断 串口1中断还是或串口2中断统一如下: 前面已经讲解了在串口接收中断中调用的“USART_GetInputString”函数。 对于发送:前面“3、串口Printf发送的实现”讲解时说:而实际的发送数据是在串口发送中断中 完成的。如果发送缓冲区非空则发送数据,否则如果发送缓冲区已经为空则禁止串口发送中断(发送 中断将在缓冲区非空时由“USART_StoreBufferData”打开),“USART_SendBufferData”函数的具 体实现如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 344 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.10.5 下载与验证 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误! 未找到引用源。小节进行操作。 7.10.6 实验现象 将固件下载在神舟III号STM32开发板后,用随板配置的串口线连接神舟III号串口2与电脑的串口, 打开超级终端,并按如下参数配置串口。 本实验使用串口接收中断和发送中断以及FIFO缓存来实现高效率的串口数据收发实例。下载固 件后,可以在串口输入信息后按回车键,其实现效果如下图所示。 如果选择的是串口1,实验效果如下: 如果选择的是串口2,实验效果如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 345 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.11 RS-485总线收发实验 7.11.1 485简介 485(一般称作RS485/EIA-485)是隶属于OSI(OSI:开放系统互连基本参考模型。开放,是指非 垄断的。系统是指现实的系统中与互联有关的各部分。)模型物理层的电气特性规定为2线,半双工, 多点通信的标准。它的电气特性和RS-232大不一样。用缆线两端的电压差值来表示传递信号。RS485 仅仅规定了接受端和发送端的电气特性。它没有规定或推荐任何数据协议。 RS-232在1962年发布,命名为EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。RS-422 由RS-232发展而来,它是为弥补RS-232之不足而提出的。为改进RS-232通信距离短、速率低的缺点, RS-422定义了一种平衡通信接口,将传输速率提高到10Mb/s,传输距离延长到4000英尺(速率低于 100kb/s时),并允许在一条平衡总线上连接最多10个接收器。RS-422是一种单机发送、多机接收的单 向、平衡传输规范,被命名为TIA/EIA-422-A标准。为扩展应用范围,EIA又于1983年在RS-422基础上 制定了RS-485标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加 了发送器的驱动能力和冲突保护特性,扩展了总线共模范围,后命名为TIA/EIA-485-A标准。 RS485的特点包括: 1) 接口电平低,不易损坏芯片。RS485的电气特性:逻辑“1”以两线 间的电压差为+(2~6)V表示;逻 辑“0”以两线间的电压差为-(2~6)V表示。接口信号电平比RS232降低了,不易损坏接口电路的芯片, 且该电平与TTL电平兼容,可方便与TTL 电路连接。 2) 传输速率高。10米时,RS485的数据最高传输速率可达35Mbps,在1200m时,传输速度可达100Kbps。 3) 抗干扰能力强。RS485接口是采用平衡驱动器和差分接收器的组合,抗共模干扰能力增强,即抗 噪声干扰性好。 4) 传输距离远,支持节点多。RS485 总线最长可以传输 1200m 以上(速率≤100Kbps)一般最大支 持 32 个节点,如果使用特制的 485 芯片,可以达到 128 个或者 256 个节点,最大的可以支持到 400 个节点。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 346 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.11.2 RS485的通信概念 RS-485 是一个电气接口规范它只规定了平衡驱动器和接收器的电特性而没有规定接插件传输电 缆和通信协议。 RS-485建议性标准作为一种多点差分数据传输的电气规范,现已成为业界应用最为广泛的标准通 信接口之一,这种通信接口允许在简单的一对双绞线上进行多点双向通信,它所具有的噪声抑制能力、 数据传输速率、电缆长度及可靠性是其他标准无法比拟的,因此许多不同领域都采用RS-485作为数据 传输链路,它是一种极为经济并具有相当高的噪声抑制、传输速率、传输距离和宽共模范围的通信平 台。 RS-485是一种在工业上作为数据交换的手段而广泛使用的串行通信方式,数据信号采用差分传输 方式,也称作平衡传输,因此具有较强的抗干扰能力。它使用一对双绞线,将其中一线定义为A,另 一线定义为B。如下图所示: 通常情况下, RS-485的信号在传送出去之前会先分解成正负对称的两条线路(即我们常说的A、 B信号线),当到达接收端后,再将信号相减还原成原来的信号。发送驱动器A、B之间的正电平在+2~ +6V,是一个逻辑状态;负电平在-2~-6V,是另一个逻辑状态;另有一个信号地C,在RS-485中还有 一“使能”端。“使能”端是用于控制发送驱动器与传输线的切断与连接。当“使能”端起作用时,发送驱 动器处于高阻状态,称作“第三态”,即它是有别于逻辑“1”与“0”的第三态。 接收器也与发送端相对的电平逻辑规定,收、发端通过平衡双绞线将AA与BB对应相连,当在接 收端AB之间(DT)=(D+) - (D-)有大于+200mV的电平时,输出正逻辑电平,小于-200mV时,输出负逻 辑电平。接收器接收平衡线上的电平范围通常在200mV至6V之间。 RS-485的信号在传送出去之前会先分解成正负对称的两条线路(即我们常说的A、B信号线), 当到达接收端后,再将信号相减还原成原来的信号。如果将原来的信号标注为(DT),而被分解后的信 号分别标注为(D+)和(D-),则原始信号与分解后的信号在由传输端传送出去时的运算关系如下: (DT)=(D+) - (D-) 同样地,接收端在接收到信号后,也按上式的关系将信号还原成原来的样子。如果此线路受到干 扰时,在两条传输线上的信号会分别成为(D+)+Noise 和(D-)+Noise, 如果接收端接收此信号,它 嵌入式专业技术论坛 (www.armjishu.com)出品 第 347 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 必须按照一定的方式将其合成,合成的方程式如下: (DT)=[(D+ Noise)] - [(D-)+ Noise]=(D+) - (D-) 此方程与前一方程式的结果是一样的,干扰信号被抵消。因此在RS-485网络传输中要求两根信号 线缆必须进行对绞,进一步降低信号的共模干扰。 7.11.3 RS485的连接方式 在每一个分支中采用一条双绞线电缆作总线,将各个通讯设备手拉手串接起来,从总线到每个通 讯设备的引出线长度应尽量短,以便使引出线中的反射信号对总线信号的影响最低。如图3所示为实 际应用中常见的一些错误连接方式(a,b,c)和正确的连接方式(d,e,f)。a、b、c这三种网络连 接尽管不正确,在短距离、低速率仍可能正常工作,但随着通信距离的延长或通信速率的提高,其不 良影响会越来越严重,主要原因是信号在各支路末端反射后与原信号叠加,会造成信号质量下降。 7.11.4 RS485通信电缆中的信号反射 什么信号反射:信号沿传输线向前传播时,每时每刻都会感受到一个瞬态阻抗,这个阻抗可能是传输 线本身的,也可能是中途或末端其他元件的。对于信号来说,它不会区分到底是什么,信号所感受到 的只有阻抗。如果信号感受到的阻抗是恒定的,那么他就会正常向前传播,只要感受到的阻抗发生变 化,不论是什么引起的(可能是中途遇到的电阻,电容,电感,过孔,PCB 转角,接插件),信号都 会发生反射。 反射的影响: 如果负载阻抗小于传输线阻抗,反射电压为负,反之,如果负载阻抗大于传输线阻 抗,反射电压为正。实际问题中,PCB 上传输线不规则的几何形状,不正确的信号匹配,经过连接器 的传输及电源平面不连续等因素均会导致反射情况发生,而表现出诸如过冲/下冲以及振荡等信号失真 的现象。 注意总线特性阻抗的连续性,在阻抗不连续和阻抗不匹配就会发生信号的反射(如图1所示)下 嵌入式专业技术论坛 (www.armjishu.com)出品 第 348 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 列几种情况易产生这种不连续性:总线的不同区段采用了不同电缆,或某一段总线上有过多收发器紧 靠在一起安装,再者是过长的分支线引出到总线。总之,应该提供一条单一、连续的信号通道作为总 线。 消除这种反射的方法,就必须在电缆的末端跨接一个与电缆的特性阻抗同样大小的终端电阻,使 电缆的阻抗连续。由于信号在电缆上的传输是双向的,因此,在通讯电缆的另一端可跨接一个同样大 小的终端电阻,如图2所示。 从理论上分析,在传输电缆的末端只要跨接了与电缆特性阻抗相匹配的终端电阻,就再也不会出 现信号反射现象。但是,在实现应用中,由于传输电缆的特性阻抗与通讯波特率等应用环境有关,特 性阻抗不可能与终端电阻完全相等,因此或多或少的信号反射还会存在。 7.11.5 RS485的接地问题 接地处理不当往往会导致电子系统不能稳定工作甚至危及系统安全。RS-485传输网络的接地同样 也是很重要的,因为接地系统不合理会影响整个网络的稳定性,尤其是在工作环境比较恶劣和传输距 离较远的情况下,对于接地的要求更为严格,否则接口损坏率较高。很多情况下,连接RS-485通信链 路时只是简单地用一对双绞线将各个接口的“A”、“B”端连接起来。而忽略了信号地的连接,这种连接 方法在许多场合是能正常工作的,但却埋下了很大的隐患。 7.11.6 RS485的应用 由于RS485具有传输距离远、传输速度快、支持节点多和抗干扰能力更强等特点,所以RS485有 很广泛的应用。 SP3485芯片介绍 STM32神舟III号开发板采用SP3485作为收发器,该芯片支持3.3V供电,最大传输速度可达 10Mbps,支持多达32个节点,并且有输出短路保护。该芯片的框图如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 349 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ A、B—— 485总线接口 ¾ RO——接收输出端 ¾ DI——发送数据收入端 ¾ RE——接收使能信号(低电平有效) ¾ DE——发送使能信号(高电平有效) ¾ VCC、GND——电源与地 /RE和DE管脚控制RS-485的收发使能控制。在神舟III号中,这两个管脚与处理器的PF11管脚连接, 由PF11管脚控制神舟III号STM32开发板的RS485作为发送端还是接收端。 查看《SP3485 RS-485收发器.pdf》可知,当PF11输出高电平,此时SP3485芯片的2脚(/RE),3 脚(DE)都为高电平。SP3485工作与发送模式。逻辑关系如下表所示。 当PF11输出低高电平,此时SP3485芯片的2脚(/RE),3脚(DE)都为低电平。SP3485工作与接 收模式。逻辑关系如下表所示。 另外,上图中的R82的作用是作用RS485的终端匹配电阻,在RS-485总线网络中,终端匹配电阻 主要作用是使总线的阻抗连续,减小信号的反射,提高信号的传输质量,一般RS485网络的终端匹配 电路只需要在总线的最远端的节点并一个即可,其他接点不需要安装此匹配电阻。 在神舟III号STM32开发板中,默认终端匹配电阻都是安装的(对应原理图的R82),请依据实际情况, 选择安装或去掉此电阻。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 350 页,共 788 页 7.11.7 原理图的连接 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们通过该芯片连接STM32的串口2,实现两个开发板之间的485通信。 连接两个神舟STM32开发板的RS485接口,然后由KEY0控制发送,当按下一个开发板的KEY0的 时候,就发送5个数据给另外一个开发板,并在电脑终端上分别显示发送的值和接收到的值。 ¾ 产品连接情况 ¾ 神舟III号开发板载有RS485物理芯片,它与处理器的UART2连接,与串口2复用,可通过跳线选 择支持RS-232接口或RS-485接口,跳线定义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 351 页,共 788 页 J14和J12 1-2 2-3(默认) ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 串口2功能选择 串口2 RS-485接口 串口2 RS-232接口 神舟III号默认是安装了RS-485接口的120欧终端匹配电阻。对应上图的R82,请依据实际应用选择 是否安装此匹配电阻。 7.11.8 实验现象 8 发送数据现象 9 接收数据现象 嵌入式专业技术论坛 (www.armjishu.com)出品 第 352 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.11.9 软件设计 根据实验现象初步分析代码 在本实验中,程序运行以后,首先通过串口1打印提示信息,提示通过板上的USER1和USER2按 键设置神舟III号为发送端或者接收端,设置完成后,发送端周期性的发送数据到RS-485网络上(神舟 III号的RS485收发器与处理器的串口2连接),而接收端等待RS-485网络上的数据,并将接收到的完整 数据通过串口1打印出来。因此本实验需要用的资源有串口1,串口2,按键,LED,RS485收发器。 在本实现中,按键,LED灯以及串口,RS-485收发器方向控制等都是有处理器GPIO 连接的,因此在使用之前,我们需要对相关的GPIO初始化。 初始化部分 嵌入式专业技术论坛 (www.armjishu.com)出品 第 353 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 分别初始化 LED、RS485、系统定时器与串口,这样我们才能正常使用这些功能 串口打印数据,初始化完后,我们让串口打印我们这次的实验内容与提示信息,方便我们的操作 其中蓝色方框的为串口初始化的时候,串口打印的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 354 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 往下是我们的选择接收的时候,对数据的一个处理与给串口发送接收到的数据部分 串口打印接收到的数据“RcvCh”本次实验中,我们接收的数据为: 这个是接收数据,那么我们看下发送的数据 这里我们发送出去的数据为“TxBuffer”,而这个“TxBuffer”就是我们前面定义的一个数组 那么也就是说我们现在发送的数据就是把"www.armjishu.com STM32 神舟系列开发板 RS485 总线收 发实验\r\n"通过 485 发送出去,我们看下实验现象中发送的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 355 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如果都不是发送或者接收的话,那么我们继续等待按键的按下再执行相对应的程序操作 这个就是我们的主函数的内容,通过按键确定是接收还是发送数据,通过串口打印把数据显示出 来 深入分析例程代码 初始化RS485控制方向管脚PF11 LED初始化,配置控制LED的I/O口为推挽输出 SZ_STM32_KEYInit ()函数完成与按键连接的GPIO初始化。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 356 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在实验中,串口1用于打印程序提示信息和RS-485接收/发送的数据,因此,我们初始化串口1,作 为printf函数输出使用。关于printf的实现可参见《串口1 printf实验》详细说明。配置串口的基本参数, 具体如下所示: 除 了 串 口 1 外 , 我 们 还 能 使 用 串 口 2 作 为 printf 函 数 输 出 使 用 , 串 口 2 使 用 Printf 时 "SZ_STM32F103ZE_LIB.c"文件中fputc定义中设备改为SZ_STM32_COM2。在使用串口2之前,我们首 先需要对串口参数进行配置,主要是配置串口的波特率,数据位,奇偶校验位等信息等,具体代码如 下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 357 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在完成了初始化以后,主程序中,首先等待用于通过STM32按键设置神舟III号RS485作为接收或 发送端设置,如果作为RS485接收端,则将PF11输出低电平,控制SP3485收发器在接收模式,通过串 口1打印提示信息。如果作为RS485发送端,则将PF11输出高电平,控制SP3485收发器在发送模式, 并通过串口1打印提示信息。 这主要是通过RS485_MODE_SET()函数实现的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 358 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 设置完神舟III号的RS485工作模式后,依据实际的工作模式后,程序依据模式执行相关的代码。 按键1按下的时候,使“RS485_Mode = TX_MODE;”配置为发送模式,按键2按下的时候,使 “RS485_Mode = RX_MODE;”配置为接收模式,而当按键3按下的时候,使“RS485_Mode = IDLE;” 退出发送接收,重新设置工作模式 如果为接收模式,则接收来自485接收到的数据并保存接收到的数据。接收完完整的一串数据后, 将接收到的数据打印出来。 如果为发送模式,则把“TxBuffer”里面的数据通过485发送出去给接收端,发送完完整的一串数 据。并通过串口1打印发送的数据。延迟一段时间后,重复发送。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 359 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 发送的数据为 7.11.10 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行 操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.11.11 实验现象 在实验中,一块神舟III号STM32开发板作为RS485发送端,一块神舟III号STM32开发板作用RS485 接收端。因此,进行本实验需要准备两块神舟III号STM32开发板。 首先将固件分别下载到两块神舟III号STM32开发板,按如下连接网络。 用两个电线连接两块神舟III号的RS-485接口(J1位置),注意两块神舟III号的RS-485接口(J1位 置)的第1脚和第1脚连接,第2脚和第2脚连接。 由于485与USART2共用JPIO,所以首先请确认将J14和J12跳帽跳至1ÅÆ2(下侧),选择串口2为 RS485接口类型。 串口2可通过跳线选择接口定义如下: J14和J12 串口2功能选择 1ÅÆ2 串口2 RS-485接口 2ÅÆ3 串口2 RS-232接口 嵌入式专业技术论坛 (www.armjishu.com)出品 第 360 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 用随板配带的串口线连接神舟III号和PC机,打开超级终端 ,按如下配置超级终端参数。 上电运行神舟III号,在串口提示信息指示下,首先设置设置神舟III号—A为RS-485接收端,然收 设置神舟III号—B为RS-485发送端。具体设置方法如下: 操作 按USER1按键 按USER2按键 说明 神舟III号作为RS485发送端 神舟III号作为RS485接收端 设置成功后,神舟III号的LED指示灯也将指示具体的工作模式 现象 含义操作 DS1亮 神舟III号正常运行(上电以后,DS1点亮,在发送或接收时闪烁) DS2亮 神舟III号作为RS485发送端,周期性发送数据 DS3亮 神舟III号作为RS485发送端,接收RS485的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 361 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上电后,神舟开发板有如下打印消息: “--按USER1按键设置神舟III号为RS485发送端” “--按USER2按键设置神舟III号为RS485接收端” 首先设置设置神舟III号—A为RS-485接收端,按其“USER2”按键;然收设置神舟III号—B为RS-485 发送端,按其“USER1”按键。神舟III号—A接收端会通过串口1打印接收或发送的数据。以下是RS485 接收端的串口1打印信息。 实物连接图如下: 两块神舟 III 号开发板串口 1,用两条串口线与两台电脑一对一连好; 两块神舟 III 号开发板的 485 总线座子(开发板有显示标号)用两条杜邦线相连,485A 与 485A 连接, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 362 页,共 788 页 485B 与 485B 连接;以下图: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 两台电脑都打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 363 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 两块开发板重新打开电源,一块开发板设置为发送按下 USART1 按键,另一块开发板设置为接收按下 KEY2 按键;看超级终端显示: 发送那台的超级终端窗口显示信息: 接收那台的超级终端窗口显示信息: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 364 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以上就是RS-485的实验现象。 7.12 产品唯一身份标识(Unique Device ID)实验 7.12.1 意义与作用 产品唯一的身份标识(Unique Device ID)非常适合: ● 用来作为序列号(例如 USB 字符序列号或者其他的终端应用) ● 用来激活带安全机制的自举过程 ● 用来作为密码,在编写闪存时,将此唯一标识与软件加解密算法结合使用,提高代码在 闪存存储器内的安全性。 96 位的产品唯一身份标识所提供的参考号码对任意一个 STM32 微控制器,在任何情况下都是唯 一的。用户在何种情况下,都不能修改这个身份标识。 7.12.2 实验原理 这个 96 位的产品唯一身份标识,按照用户不同的用法,可以以字节(8 位)为单位读取,也可以以 半字(16 位)或者全字(32 位)读取。 96 位的独特 ID 位于地址 0x1FFFF7E8 ~ 0x1FFFF7F3 的系统存储区,用户可以以字节、半字、 或字的方式单独读取其间的任一地址,其中 0x1FFFFF3 中为最高字节,0x1FFFF7E8 中为最低字节。 本次试验以 ARMJISHU 的神舟系列开发板为硬件平台,通过调用系统的 Printf 函数来打印出唯一 标识 DeviceSerial。 作为扩展本次试验顺带读取位于 0x1FFF F7E0 地址的“闪存容量寄存器”获得开发板内部集成 Flash 的大小信息,通过调用系统的 Printf 函数来打印出产品内部 Flash 大小。 7.12.3 硬件设计 产品唯一身份标识(Unique Device ID)为处理器内部组件,这部分不需要硬件电路,这里仅在在串 口中输出产品唯一身份标识(Unique Device ID)即可。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 365 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.12.4 软件设计 程序中定义全局变量 IntDeviceSerial 存放读到的设备 ID,96 位的独特 ID 位于地址 0x1FFFF7E8 ~ 0x1FFFF7F3 的系统存储区,程序如下: Delay_ARMJISHU 函数流水灯使用的延时函数,用简单的 For 循环实现 下来看看main函数,其中涉及的子程序如果之前的章节已有介绍(如串口相关),则此处不再 讲述。本示例涉及的程序都添加了较为详细的注释。 在MAIN主函数中调用Get_ChipSerialNum()以后,就可以使用Printf来打印,然后作为扩展, 本次试验顺带读取位于0x1FFF F7E0地址的“闪存容量寄存器” 使用Printf来打印出来。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 366 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 367 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.12.5 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行 操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.5如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.12.6 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 2 与电脑连接(注 意开发板上 J14 和 12 位置都短接 2=3 为串口模式),并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 368 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 重新打开电源;神舟 III 号 STM32 开发板上 4 个 LED 灯闪一下,LED 2 和 LED 3 灯亮,LED 1 和 LED 4 在闪烁。 超级终端窗口显示信息,如下图,可以看到神舟 III 号开发板的串口打印出了产品唯一身份标识(Unique Device ID) 图上红框的为产品唯一身份标识。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 369 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.13 ADC模数转换实验 ADC:Analog-to-Digital Converter(模数转换器),顾名思意就是将模拟量转换成数字量的设备 或模块。 前面的例程,我们大家一起学习了STM32处理器的GPIO操作,以及串行接口的使用,在这一节, 我们将一起来简单学习STM32的ADC的使用。神舟III号将电位器上采集到的数据通过ADC转换后,通 过串口将转换的结果数据打印出来。 7.13.1 意义与作用 日常中,我们直接接触的都是一些模拟的设备,电位器、传感器、语音和视频等等,那么如何将 这些设备采集到的数据进行传输呢?模拟数据在传输过程中,数据量大,占用带宽大,受干扰严重, 直接限制影响到我们的通信传输质量。因此,在数据进行传输的第一步都需要进行模拟/数字的转换。 将模拟信号进行采样、量化、编码等一系列操作后,再传到通信信道中进行通信。 那么第一步的模拟/数字的转换便是最基础的,所以,这节先让我们简单了解模拟/数字转换的操 作,以及对数据进行处理,然后从串口打印计算结果。 7.13.2 实验原理 ADC通过读取PC3管脚输入的模拟信号输出ADC转换值,然后将ADC转换值换算成电压值并通过 串口显示。 神舟III号开发板STM32F103ZET6有2个ADC。一般STM32拥有1~3个ADC。STM32F101/102系列 有1个ADC,STM32F103系列一般有2个ADC。STM32F207/407一般有3个ADC。这个在ST官方提供的 数据手册中可以找到。例如在STM32F103的数据手册的第12页我们就可以看到芯片的ADC资源: 神舟系列开发板ADC的转换结果是12位二进制数,最小转换结果为0x0000,最大转换结果为 0xFFFF,所以我们定义一个16位的变量(ADCConvertedValue)来保存转换结果。 STM32处理器的ADC是一个12位的逐次逼近型模拟数字转换器。它有多达18个通道,可测量16 个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以 左对齐或者右对齐方式存储在16位数据寄存器中。需要强调的是ADC的输入时钟不得超过14MHz,并 有PCLK2经分频产生。神舟系列开发板的ADC是一种逐次逼近型模拟数字转换器,它的转换结果是12 位二进制数,最快转换速度1uS,这么优秀的性能不是一般的MCU所能具有的。 STM32将ADC的转换分为2个通道组:规则通道组和注入通道组。 注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续 转换。这个和中断是类似的,在实际应用中给我们提供方便。 我们通过例子说明:假如在蔬菜大棚外放了几个温度湿度传感器,大棚内也放了几个温度湿度传 嵌入式专业技术论坛 (www.armjishu.com)出品 第 370 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 感器。我们主要监控的是大棚内的温度/湿度情况,需要时刻监控。但偶尔也需要看看大棚外的温度湿 度情况;因此我们可以使用规则通道组循环扫描大棚内的传感器并显示AD转换结果,当你想看大棚 外温度湿度情况时,通过一个按钮启动注入转换组并暂时显示大棚外的信息,当你放开这个按钮后, 系统又会回到规则通道组继续检测大棚内的信息。 从系统设计上,测量并显示大棚外温度/湿度的过程中断了测量并显示大棚内温度/湿度的过程, 但程序设计上可以在初始化阶段分别设置好不同的转换组,系统运行中不必再变更循环转换的配置, 从而达到两个任务互不干扰和快速切换的结果。可以设想一下,如果没有规则组和注入组的划分,当 你按下按钮后,需要从新配置AD循环扫描的通道,然后在释放按钮后需再次配置AD循环扫描的通道。 对 于 ADC 中 涉 及 的 几 个 寄 存 器 , 如 ADC 控 制 器 ( ADC_CR ) 、 ADC 的 采 样 事 件 寄 存 器 (ADC_SMPR)、ADC规则序列寄存器(ADC_SQR)以及ADC规则数据寄存器(ADC_DR),这几 个寄存器的使用在此就不展开描述,大家有兴趣可以查阅《【中文】STM32F系列ARM内核32位高性 能微处理器参考手册V10_1》资料155页开始的关于ADC的描述。此部分涉及到的寄存器在ST标准库 的外设驱动“stm32f10x_adc.c”中有相关的定义以及初始化。ADC的工程项目中,直接调用相关函数 与定义。 为什么需要DMA? 谈到ADC时,我们就有必要提及DMA方式。因为规则通道转换的值存储在一个仅有的数据寄存 器中,所有当转换多个规则通道时,就需要使用DMA,否则将导致已经存储在ADC_DR寄存器中的数 据丢失。同时ADC采集数据时采集一次数据,结果是不准确的,所以要多采几次。那么数据量就大了。 这里就用到DMA。 只有在规则通道的转换结束时,才产生DMA请求,并将转换的数据从ADC_DR寄存器传输到用户 指定的目的地址。 DMA:Direct Memory Access(存储器直接访问)是指一种高速的数据传输操作,提供在外设和 存储器之间或是存储器和存储器之间的高速数据传输。CPU除了在数据传输开始和结束时做一点处理 外,在传输过程中CPU可以进行其他的工作。这样,在大部分时间里,CPU和输入输出都处于并行操 作状态。因此,使整个系统的效率大大提高。这样便为快速,高性能的ADC提供了通道。简单了解DMA 具有多个channel即可。详见《【中文】STM32F系列ARM内核32位高性能微处理器参考手册V10_1》 资料142页关于DMA的描述。 下面讲解ADC的设置步骤: 1) 开启PC口时钟,设置PC3为模拟输入模式。 本实验我们用到的是ADC1的通道13。神舟III号开发板的主芯片是STM32F103ZET6,通道13 对应的引脚是PC3。各个通道对应的管脚大家参考数据手册。例如: 表中的引脚名称标注中出现的ADC12_INx(x表示4~9或14~15之间的整数),表示这个引脚可以是 ADC1_INx或ADC2_INx。例如:ADC12_IN9表示这个引脚可以配置为ADC1_IN9,也可以配置为 ADC2_IN9。 2) 开启DMA时钟,对DMA进行配置。 为什么使用DMA,这里就不再重复。 3) 开启ADC1时钟,对ADC1参数进行配置。 4) 对ADC1使用的通道组进行设置,对采用顺序,转换时间进行设置。 5) 使能ADC并校准 6) 读取ADC的值 嵌入式专业技术论坛 (www.armjishu.com)出品 第 371 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.13.3 硬件设计 神舟III号开发板载有电位器与STM32处理器的PC3管脚相连,可以实现AD模数转换实现。外部模 拟信号由电位器(可调电阻)对3.3V电压分压得到,其硬件原理图如下图所示: 电位器 AD 电路 R51 为 10K 欧的电位器(类似于滑动变阻器),其管脚 2 为滑片的输出,根据分压原理,其输出 电压为: Vout = Vcc*(Rtop / Rv1) 其中 Vcc 为 3 脚的输入电压,本次是 3.3V;Rtop 为 2 脚与 3 脚的电阻值,与滑片当前的位置有 关; R51 为电位器 1 脚与 3 脚之间的电阻,本次为 10K。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 372 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.13.4 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:在系统启动文件(startup_stm32f10x_xx.s)中已经调用SystemInit()初始化了72MHZ时 钟,最开始的例程已经对此分析过了,还有不明白的可以看下前面的例程。 代码分析2:调用SZ_STM32_LEDInit()函数初始化板载LED指示灯,前面已经有介绍 代码分析3:调用SZ_STM32_COMInit( )函数初始化串口,并向超级终端打印信息。前面已经有介 绍. 代码分析4:调用SZ_STM32_ADC_Configuration()函数初始化ADC。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 373 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析5:进入while循环,通过GetADCConvertedValue ( )函数,获取ADC模数转换的结果,并将结 果转换为电压值。最后通过串口显示信息。到此我们的代码流程基本走完。 代码分析6:下面我们详细分析一下初始化ADC函数SZ_STM32_ADC_Configuration()。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 374 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 1)我们进入初始化ADC函数后,它调用的第一个函数是ADC_GPIO_Configuration()。这个函数将 GPIO管脚PC0配置成模拟输入模式(GPIO_Mode_AIN)。每个ADC通道都对应着一个GPIO引脚端口, GPIO的引脚在设置为模拟输入模式后可用于模拟电压的输入端。 2)配置完PC3引脚后,对DMA结构体的使用配置。 DMA结构体配置的内容包括。使用DMA1的第一个通道DMA1_Channel1,包括时钟设置、目标存 储地址、转换模式、数据宽度和优先级等。 数据从ADC外设的数据寄存器(DR_Address)转移到内存(ADCConvertedValue变量),内存、外设地 嵌入式专业技术论坛 (www.armjishu.com)出品 第 375 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 址 都 固 定 , 每 次 传 输 的 数 据 大 小 为 半 字 (16 位 ) , 使 用 DMA 循 环 传 输 模 式 。 DMA 传 输 的 外 设 地 址 DR_Address是一个自定义的宏: ADC_DR数据寄存器保存了ADC转换后的数值,以它作为DMA的传输源地址。它的地址是由 ADC1外设的基地址(0x4001 2400) 加上ADC数据寄存器(ADC_DR)的地址偏移 (0x4c)计算得到的。 3)电位器使用的ADC通道初始化及其重新校准。 PC3管脚是AD的第13输入通道,在代码中我们我们完全可以找到对应的配置。ADC通道和GPIO 管脚的关系可以从《【英文】STM32F103ZE数据手册V6.pdf》中找到。 代码分析7:函数SZ_STM32_ADC_Configuration()完成初始化以后,ADC将开始转换数据,同时 ADC通过DMA方式不断的更新,最新的ADC值,由于DMA通道传输无须CPU干预,由硬件自己完成, 因此。程序只需要打印读取的最新的ADC值即可,如下所示程序,重复打印ADC转换的值。 既然数据从ADC外设的数据寄存器(DR_Address)转移到内存(ADCConvertedValue变量),那么我们 使用函数GetADCConvertedValue()获取ADC模数转换的结果。我们需要转换为电压值。下面计算电压 值,计算电压值的公式: 实际电压值=ADC 转换值*Vdd/Vdd_convert_value(0xFFF) Vdd 是参考电压,3.3V。Vdd_convert_value 是 4096,因为我们这个 STM32 它的转换的精度是 12 位的, 0x1000,2 的 12 次方是 4096。有了这些数据就可以求出我们需要的电压值了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 376 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.13.5 下载与验证 如果使用JLINK下载固件,请按错误!未找到引用源。错误!未找到引用源。下载固件到神舟III 号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误!未 找到引用源。小节进行操作。 7.13.6 实验现象 将固件下载在神舟III号STM32开发板后,用随板配置的串口线连接神舟III号串口2与电脑的串口, 打开超级终端,并按如下参数配置串口。 上电运行神舟III号,串口将打印如下信息,旋转神舟III号板载的电位器,如下图所示, 串口打印的ADC转换电压值随之发生变化,如下图所示,调节电位器时转换结果随之变化,停止 调节电位器时其值稳定不变: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 377 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以上就是ADC实验现象。 7.14 ADC数据多路采集 7.14.1 意义与作用 7.14.2 实验原理 7.14.3 硬件设计 7.14.4 软件设计 7.14.5 下载与验证 7.14.6 实验现象 嵌入式专业技术论坛 (www.armjishu.com)出品 第 378 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.15 RTC实时时钟实验 本章节我们讲解 STM32 的 RTC 原理并通过每秒显示当前实时时间的例程来将掌握 RTC 实时时钟 功能及用法。 7.15.1 意义与作用 RTC(Real-time clock)是实时时钟的意思。神舟 III 号开发板的处理器 STM32F103 集成了 RTC (Real-time clock)实时时钟,在处理器复位或系统掉电但有实时时钟电池的情况下,能维持系统当前 的时间和日期的准确性。实时时钟是一个独立的定时器。RTC 实时时钟模块拥有一组连续计数的计数 器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日 期。 STM32 的 RTC 主要特性为: ● 可编程的预分频系数:分频系数最高为 220。 ● 32 位的可编程计数器,可用于较长时间段的测量。 ● 2 个分离的时钟:用于 APB1 接口的 PCLK1 和 RTC 时钟(RTC 时钟的频率必须小于 PCLK1 时 钟频率的四分之一以上)。 ● 可以选择以下三种 RTC 的时钟源: ─ HSE 时钟除以 128; ─ LSE 振荡器时钟; ─ LSI 振荡器时钟。 ● 2 个独立的复位类型: ─ APB1 接口由系统复位; ─ RTC 核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。 ● 3 个专门的可屏蔽中断: ─ 闹钟中断,用来产生一个软件可编程的闹钟中断。 ─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达 1 秒)。 ─ 溢出中断,指示内部可编程计数器溢出并回转为 0 的状态 7.15.2 实验原理 RTC由两个主要部分组成(参见下图)。第一部分(APB1接口)用来和APB1总线相连。此单元还包含 一组16位寄存器,可通过APB1总线对其进行读写操作(参见16.4节)。APB1接口由APB1总线时钟驱动, 用来与APB1总线接口。 另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。第一个 模块是RTC的预分频模块,它可编程产生最长为1秒的RTC时间基准TR_CLK。RTC的预分频模块包含 了一个20位的可编程分频器(RTC预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个 嵌入式专业技术论坛 (www.armjishu.com)出品 第 379 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编程计数器,可被初始化为当 前的系统时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如 果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。 图表 13 简化的 RTC 框图 RTC 模块和时钟配置系统(RCC_BDCR 寄存器)处于后备区域,即在系统复位或从待机模式唤醒 后,RTC 的设置和时间维持不变。 系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止 对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和 RTC 的访问: ● 设置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位,使能电源和后备接口时钟 ● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 380 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.15.3 硬件设计 神舟系列开发板的RTC的硬件设计非常简单,其主要硬件都集成在了处理器内部,外围电路主需 要一个32.768KH在的晶振和VBAT供电电池即可。 STM32F103内部已经包含了40kHz低速内部RC振荡电路LSE,但是其精准度不是很高,为此我们在 外部增加了32.768KHz的晶振电路驱动RTC实时时钟。 STM32的VBAT采用CR1220纽扣电池和VCC3.3混合供电的方式,在有外部电源(VCC3.3)的时候, BT1不给处理器的VBAT供电,而在外部电源断开的时候,则由BT1给VBAT供电。这样,VBAT总是有电的, 以保证RTC的持续运行以及后备寄存器的内容不丢失。 相关电路如下: 当安装了电池后, VBAT 管脚由+3.3V 系统电源供电。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 381 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.15.4 软件设计 我们先从main函数讲起,其中涉及的LED指示灯和串口等相关子程序如果之前的章节已有介绍, 则此处不再讲述。本示例涉及的程序都添加了较为详细的注释。 串口配置与串口输入输出章节的配置方法相同,不是本示例的重点,请参考相关章节。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 382 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上面的函数已经打印了复位的原因,此处RCC_ClearFlag()函数的目的是清除上次复位原因的记录。 函数Time_Show()是一个while死循环,每秒打印一次系统时间。全局变量TimeDisplay是否为1, 如 果 为 1 则 打 印 时 间 并 将 请 TimeDisplay 清 0 以 便 它 在 "stm32f10x_it.c" 文 件 的 "void RTC_IRQHandler(void)"函数中当发生秒中断时再次置为1,这样便实现了精准的每秒输出时间一次, 其实现如下: Time_Show() 函 数 中 又 调 用 了 两 个 子 函 数 Time_Display() 和 RTC_GetCounter() , 其 中 RTC_GetCounter()函数只是简单的读取RTC的Counter寄存器的值,其实现如下: 而Time_Display()函数是实现将RTC_GetCounter()读到RTC的Counter寄存器的值幻化为时分秒的 嵌入式专业技术论坛 (www.armjishu.com)出品 第 383 页,共 788 页 时间信息并打印,其实现如下: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ------------------------------------------------------------------------------------------------------其中的中断相关相关函数解释如下: “InterruptConfig()”函数告诉处理器中断向量表存放的起始地址,STM32支持中断向量表起始地 址动态设置,这个特性在SRAM调试和DFU固件升级时很有用,以为这些情况下中断向量表起始地址 已经不是0x0000处。此处将中断向量表起始地址设置为内部Flash的起始地址0x08000000处。 NVIC_Configuration 函 数 实 现 配 置 嵌 套 向 量 中 断 中 断 优 先 级 并 使 能 中 断 。 其 中 的 NVIC_PriorityGroupConfig 函数配置中断优先级的组织方式,STM32 的嵌套向量中断控制器可以配置 16 个可编程的优先等级,使用了 4 位表示中断优先级(2 的 4 此方就是 16),16 个可编程的优先等 级又可以分为主优先级和次优先级,例如参数 NVIC_PriorityGroup_1 表示 1bit 主优先级(pre-emption priority)3 bits 次优先级(subpriority )。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 384 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以下为中断处理函数,请看代码注释。注意其中的对全局变量TimeDisplay的置一与Time_Show() 函数中的清零操作相呼应,是实现精确1秒延时的关键。 -----------------------------------------RTC_Configuration-----------------------------------------其中的中断相关相关函数解释如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 385 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上述多个程序中都调用了以下等待的子函数调用: 为什么要不停的等待呢? RTC核完全独立于RTC APB1接口。 软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。 但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是 如此的。 这意味着,如果APB1接口曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一 次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。因此,若在读 取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄 存器同步标志)被硬件置’1’。( 注: RTC的 APB1接口不受WFI和WFE等低功耗模式的影响。) ----------------------------------------- Time_Adjust------------------------------------------ 嵌入式专业技术论坛 (www.armjishu.com)出品 第 386 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 将用户输入的时分秒信息转换为计数器的计数值并对RTC计数器赋值: Time_Regulate函数多次调用用户输入函数,请求用户输入时分秒信息并将其转化为计数数值。 用户输入函数USART_Scanf,请求用户输入小于等于输入参数的数值并将该值返回。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 387 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.15.5 下载与验证 如果使用JLINK下载固件,请按错误!未找到引用源。错误!未找到引用源。下载固件到神舟III 号开发板小节进行操作。 如果使用USB下载固件,请按错误!未找到引用源。错误!未找到引用源。小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误!未 找到引用源。小节进行操作。 7.15.6 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 2 与电脑连接, 并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 388 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 重新打开电源;神舟 III 号 STM32 开发板上 LED 2 和 LED 3 常亮,LED 1 和 LED 4 间断亮灭。 下载后串口会有打样信息输出,如果是第一次运行该程序,则串口会输出提示“RTC not yet configured....”然后会要求用户输入时分秒信息,然后就是每秒刷新一次系统时间。如下图 按照超级终端窗口显示信息提示输入时间信息, 如输入小时 11 嵌入式专业技术论坛 (www.armjishu.com)出品 第 389 页,共 788 页 如输入分钟 22 如输入秒钟 33 超级终端窗口显示,以下图: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如果上次运行时已经设置了系统时间,在复位重启或者有RTC电池时断电重启后,串口会输出提 示“No need to configure RTC....”然后每秒刷新一次系统时间。如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 390 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.16 Calendar实时时钟与农历年月日实验 上一章节我们讲解了 STM32 的 RTC 原理并介绍了通过每秒显示当前实时时间的例程。本章节我 们在上一章节的继续上继续讲解 STM32 的 RTC 的高级应用,不仅实现当前时分秒的现实,而且实现 Calendar 农历年月日与节气和公历日历年月日时分秒的计算和显示,在乐趣中让大家更深入的掌握 RTC 实时时钟功能及用法。 7.16.1 意义与作用 RTC(Real-time clock)是实时时钟的意思。神舟 III 号开发板的处理器 STM32F103 集成了 RTC (Real-time clock)实时时钟,在处理器复位或系统掉电但有实时时钟电池的情况下,能维持系统当前 的时间和日期的准确性。实时时钟是一个独立的定时器。RTC 实时时钟模块拥有一组连续计数的计数 器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日 期。本次实验不仅实现当前时分秒的现实,而且实现 Calendar 农历年月日与节气和公历日历年月日 时分秒的计算和显示,在乐趣中让大家更深入的掌握 RTC 实时时钟功能及用法。 STM32 的 RTC 主要特性为: ● 可编程的预分频系数:分频系数最高为 220。 ● 32 位的可编程计数器,可用于较长时间段的测量。 ● 2 个分离的时钟:用于 APB1 接口的 PCLK1 和 RTC 时钟(RTC 时钟的频率必须小于 PCLK1 时 钟频率的四分之一以上)。 ● 可以选择以下三种 RTC 的时钟源: ─ HSE 时钟除以 128; ─ LSE 振荡器时钟; ─ LSI 振荡器时钟。 ● 2 个独立的复位类型: ─ APB1 接口由系统复位; ─ RTC 核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。 ● 3 个专门的可屏蔽中断: ─ 闹钟中断,用来产生一个软件可编程的闹钟中断。 ─ 秒中断,用来产生一个可编程的周期性中断信号(最长可达 1 秒)。 ─ 溢出中断,指示内部可编程计数器溢出并回转为 0 的状态 7.16.2 实验原理 RTC由两个主要部分组成(参见下图)。第一部分(APB1接口)用来和APB1总线相连。此单元还包含 一组16位寄存器,可通过APB1总线对其进行读写操作(参见16.4节)。APB1接口由APB1总线时钟驱动, 用来与APB1总线接口。 另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。第一个 模块是RTC的预分频模块,它可编程产生最长为1秒的RTC时间基准TR_CLK。RTC的预分频模块包含 了一个20位的可编程分频器(RTC预分频器)。如果在RTC_CR寄存器中设置了相应的允许位,则在每个 TR_CLK周期中RTC产生一个中断(秒中断)。第二个模块是一个32位的可编程计数器,可被初始化为当 嵌入式专业技术论坛 (www.armjishu.com)出品 第 391 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 前的系统时间。系统时间按TR_CLK周期累加并与存储在RTC_ALR寄存器中的可编程时间相比较,如 果RTC_CR控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。 图表 14 简化的 RTC 框图 RTC 模块和时钟配置系统(RCC_BDCR 寄存器)处于后备区域,即在系统复位或从待机模式唤醒 后,RTC 的设置和时间维持不变。 系统复位后,对后备寄存器和 RTC 的访问被禁止,这是为了防止 对后备区域(BKP)的意外写操作。执行以下操作将使能对后备寄存器和 RTC 的访问: ● 设置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位,使能电源和后备接口时钟 ● 设置寄存器PWR_CR的DBP位,使能对后备寄存器和RTC的访问。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 392 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.16.3 硬件设计 神舟系列开发板的RTC的硬件设计非常简单,其主要硬件都集成在了处理器内部,外围电路主需 要一个32.768KH在的晶振和VBAT供电电池即可。 STM32F107内部已经包含了40kHz低速内部RC振荡电路LSE,但是其精准度不是很高,为此我们在 外部增加了32.768KHz的晶振电路驱动RTC实时时钟。 STM32的VBAT采用CR1220纽扣电池和VCC3.3混合供电的方式,在有外部电源(VCC3.3)的时候, BT1不给处理器的VBAT供电,而在外部电源断开的时候,则由BT1给VBAT供电。这样,VBAT总是有电的, 以保证RTC的持续运行以及后备寄存器的内容不丢失。 相关电路如下: 当安装了电池后, VBAT 管脚由+3.3V 系统电源供电。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 393 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.16.4 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 从main函数开始分析,其中涉及的LED指示灯和串口等相关子程序如果之前的章节已有介绍,则 此处不再讲述。同时本示例涉及的程序我们添加了详细的注释。 代码分析 1:SZ_STM32_LEDInit( )函数初始化 LED 灯,前面我们已经讲解,我们就不再重复。 代码分析 2:SZ_STM32_SysTickInit ()函数初始化系统定时器 SysTick,前面我们已经讲解,我们就不 再重复。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 394 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 3:SZ_STM32_COMInit()函数初始化串口 2,本实验通过串口 2 打印 Calendar 时钟。串 口配置不是本示例的重点。前面我们已经讲解,我们就不再重复。 代码分析 4:NVIC_GroupConfig( )为配置中断优先级分组函,RTC_NVIC_Configuration()函数是对 RTC 实时时钟的中断参数配置。 代码分析 5:以下 if...else...判断系统时间是否已经设置,并进行对应的处理。 这里面通过 BKP_ReadBackupRegister(BKP_DR1)函数读取 RTC 后备寄存器 1(BKP_DR1)的值, 判断是否事先写入的 0XA5A5,如果不是,则说明 RTC 是第一次上电,需要配置 RTC,提示用户通 过串口更改系统时间,通过函数 Time_Adjust()将实际时间转化为 RTC 计数值写入 RTC 寄存器, 然后 调用 BKP_WriteBackupRegister()函数修改后备寄存器 1(BKP_DR1)的值为 0XA5A5。 else 表示已经设置了系统时间,打印上次系统复位的原因,并使能 RTC 秒中断。 代码分析 6:上面 if...else...判断系统中,else 部分打印系统复位的原因。我们再一次进入这个判断之 前,要清除上次复位原因的记录。否则再一次进入判断,进入 else 产生的复位的原因不一样的话,它 串口打印的复位原因是不变的。 代码分析 7:while 循环显示当前系统时钟。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 395 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在本次循环中,调用 Time_Display()函数显示当前的时钟,每秒打印一次系统时间。全局变量 TimeDisplay 是 否 为 1 , 如 果 为 1 则 打 印 时 间 并 将 请 TimeDisplay 清 0 以 便 它 在 " SZ_STM32F107VC_LIB.c"文件的"void RTC_IRQHandler(void)"函数中当发生秒中断时再次置为 1,这 样便实现了精准的每秒输出时间一次。我们可以发现 Time_Display()函数调用了 RTC_GetCounter() 函数读取 RTC 的 Counter 寄存器的值,其实现如下: 注意:此实验的 Time_Display()函数与上一个实验有所不同。此处的 Time_Display()函数使用静态 局部变量 FirstDisplay 保证在第一次调用该函数时计算并打印当前时间对应的农历年月日与农历节气, 并且将 RTC_GetCounter()读到 RTC 的 Counter 寄存器的值转换为年月日时分秒的时间信息并打印,其 实现如下: 此处的Time_Display()函数调用了计算农历日期与节气的三个函数,这三个函数位于calendar.c中, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 396 页,共 788 页 在calendar.h 中的声明如下图所示: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 本例程与上一章节的例程在程序文件上多了以下四个文件: 其中“date.c”实现了时间信息与计数值之间的相互转换功能。 其 中 “ calendar.c ” 实 现 了 超 强 的 日 历 功 能 , 支 持 农 历 , 24 节 气 几 乎 所 有 日 历 的 功 能 , 日历时间以1970年为元年,用32bit的时间寄存器可以运行到2100年左右。 到此,我们主函数部分框架流程基本完成,下面我们对一些比较重要的函数进行分析。 代码分析8:我们来看一下有关中断函数。NVIC_GroupConfig()和,RTC_NVIC_Configuration()。 NVIC_Configuration 函 数 实 现 配 置 嵌 套 向 量 中 断 中 断 优 先 级 并 使 能 中 断 。 其 中 的 NVIC_PriorityGroupConfig 函数配置中断优先级的组织方式,STM32 的嵌套向量中断控制器可以配置 16 个可编程的优先等级,使用了 4 位表示中断优先级(2 的 4 此方就是 16),16 个可编程的优先等 级又可以分为主优先级和次优先级,例如参数 NVIC_PriorityGroup_1 表示 1bit 主优先级(pre-emption priority)3 bits 次优先级(subpriority )。 RTC_NVIC_Configuration()函数使能RTC中断。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 397 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以下为中断处理函数,请看代码注释。注意其中的对全局变量TimeDisplay的置一与Time_Show() 函数中的清零操作相呼应,是实现精确1秒延时的关键。 RTC配置中有关中断相关函数解释如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 398 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上述多个程序中都调用了以下等待的子函数调用: 为什么要不停的等待呢? RTC核完全独立于RTC APB1接口。 软件通过APB1接口访问RTC的预分频值、计数器值和闹钟值。 但是,相关的可读寄存器只在与RTC APB1时钟进行重新同步的RTC时钟的上升沿被更新。RTC标志也是 如此的。 这意味着,如果APB1接口曾经被关闭,而读操作又是在刚刚重新开启APB1之后,则在第一 次的内部寄存器更新之前,从APB1上读出的RTC寄存器数值可能被破坏了(通常读到0)。因此,若在读 取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄 存器同步标志)被硬件置’1’。 ( 注: RTC的 APB1接口不受WFI和WFE等低功耗模式的影响。) 代码分析9:实验操作中,我们可以输入时间信息。最后我们看一下,时间调整有关的函数。 Time_Adjust函数实现时间调整相关功能,首先调用Time_Regulate(&systmtime)函数请求用户输入年月 日时分秒等信息,然后使用mktimev函数将用户输入的年月日时分秒等信息转换为计数器的计数值并 对RTC计数器赋值保存。 Time_Regulate函数多次调用用户输入函数,要求用户输入年月日时分秒等信息: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 399 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.16.5 下载与验证 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误!未 找到引用源。小节进行操作。 7.16.6 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源,用串口线神舟 III 号串口 2 与电脑连接, 并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 400 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 重新打开电源;神舟 II 号 STM32 开发板上 LED 2 和 LED 3 常亮,LED 1 和 LED 4 间断亮灭。 超级终端窗口显示信息,如果是第一次运行该程序,则串口会输出提示“RTC not yet configured....” 然后会要求用户输入公历的年月日和时分秒信息如下图所示,如下图 提示输入相关的时间信息, 请输入年份:15 请输入月份:10 请输入日期:01 嵌入式专业技术论坛 (www.armjishu.com)出品 第 401 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 请输入时钟:12 请输入分钟:00 请输入秒钟:30 完成以上相关信息输入后,超级终端窗口显示,以下图: 7.17 EEPROM读写测试实验 7.17.1 意义与作用 EEPROM是一种电可擦可编程只读存储器,掉电后数据不丢失。是单片机应用系统中经常会用到 的存储器。EEPROM掉电后数据不会丢失,而且可以用电信号直接清除存储数据和再编程,正是由于 它的这一特性,EEPROM在嵌入式设备中应用广泛,用于产品出厂数据的保存,产品运行过程中一些 数据量不大的重要数据保存等。 在本章节,我们以最常见的 I2C 接口的 24CXX 芯片为例进行学习研究。它采用 PHILIPS 公司开 发的两线式串行总线(I2C 总线)。通过本章节实验,我们将对 I2C 总线有一个深入的了解,进而掌握 如何读写访问 24CXX 这一系列的 I2C 接口 EEPROM。 7.17.2 I2C的介绍 I2C 总线的定义 I2C(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制 器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据,读写访问简 单。在 CPU 与被控 IC 之间、IC 与 IC 之间进行双向传送,高速 I2C 总线一般可达 400kbps 以上。 I2C 总线特点 嵌入式专业技术论坛 (www.armjishu.com)出品 第 402 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 I2C 总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此 I2C 总线占用的空 间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达 25 英尺, 并且能够以 10Kbps 的最大传输速率支持 40 个组件。I2C 总线的另一个优点是,它支持多主控 (multimastering), 其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的 传输和时钟频率。当然,在任何时间点上只能有一个主控。 I2C 总线工作状态 I2C 总线在传送数据过程中共有三种特殊类型信号,它们分别是:开始信号、结束信号和应答信 号。 开始信号:SCL为高电平期间,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为高电平期间,SDA由低电平向高电平跳变,结束传送数据。 应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收 到数据。CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU 接收到应答信号后, 根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 403 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 I2C 总线三种特殊类型信号时序图为: 7.17.3 实验原理 神舟III号开发板板载的EEPROM芯片型号为24C02,该芯片的总容量是256个字节。 本节实验的基本原理:神舟III号通过STM32F103ZET6处理器本身自带的硬件I2C接口与24C02相连, 我们首先往EEPROM中写入一连串的有规律的数据,然后顺序读出,通过串口打印读出的数据,判断 读出的数据是否正确,从而得知EERPOM是否可以正常访问。 7.17.4 硬件设计 本实验需要用到的硬件资源: ¾ 串口 2:串口的输入输出实验在前面已经进行了详细的讲解,在这里就不在重复。具体串口输入 输出实验。 ¾ I2C EEPROM 24C02 STM32F103ZET6处理器具有两个I2C接口,I2C接口与管脚对应关系如下表所示。 I2C接口 管脚名 对应GPIO 功能描述 I2C1 I2C1_SCL PB6 I2C1接口的时钟 I2C1_SDA PB7 I2C1接口的数据 I2C2 I2C2_SCL PB10 I2C2接口的时钟 I2C2_SDA PB11 I2C2接口的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 404 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 神舟III号自带了24C02的EEPROM芯片,该芯片的容量为2Kbit,也就是256个字节,对于我们普通 应用来说是足够了的。你也可以选择换大的芯片,因为在原理上是兼容24C02~24C512全系列的EEPROM 芯片的。神舟III号通过处理器自带硬件I2C1接口与EEPROM 24C02连接,电路图如下: EEPROM 原理图 AT24C02是美国ATMEL公司的低功耗CMOS串行EEPROM,它是内含256×8位存储空间,具有工 作电压宽(2.5~5.5V)、擦写次数多(大于10000次)、写入速度快(小于10ms)等特点。 AT24C02的1、2、3脚是三条地址线,用于确定芯片的硬件地址。如上图中,A0~A2全部接地, 对应I2C的硬件地址为0xA0。 第4脚为电源输入端,第8脚为GND管脚。 第5脚SDA为串行数据输入/输出,数据通过这条双向I2C总线串行传送,在神舟III号中,与处理器 的PB7管脚连接。 第6脚SCL为串行时钟输入线,在神舟III号中,与处理器的PB6管脚连接。 SDA和SCL都需要和正电源间各接一个5.1K的电阻上拉。 第7脚为AT24C02的写保护端,如果需要禁止对AT24C02进行读写,需要上拉到电源。在神舟III 号中,为了方便随时对AT24C02进行访问操作,将WP管脚接地,禁止AT24C02的写保护功能。 24C02的特性如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 405 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.17.5 软件设计 神舟 III 号 EEPROM 读写试验位于神舟 III 号光盘\源码\ EEPROM 读写测试实验\Project 目录 把代码下载到神舟 III 号板子上后,用随板配置的串口线连接神舟 III 号串口 2 与电脑的串口,打 开超级终端,并按如下参数配置串口。 超级终端串口参数配置 上电运行神舟 III 号,串口将打印信息,如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 406 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 407 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 实验现象:往 24C02 写入数据,然后读出 24C02 里面的数据,写入写出 2 个数据进行比较,相同的话 测试通过,反之失败。 初步根据实验现象查看代码(大体的思路) 以下为工程文件中主要代码的解释与说明。 1)、地址数据的定义 嵌入式专业技术论坛 (www.armjishu.com)出品 第 408 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2)、初始化 3)、写入与读出数据的对比与结果 比较 1: 比较 2: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 409 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最后是 LED 状态 以上为主函数的整体框架 进一步分析程序代码 1)、初始化部分 LED 初始化 神舟III号I2C1接口初始化。 我们首先将I2C1接口初始化为复用功能开漏输出,从原理图上可以看到,我们的24C02的SCL与 SDA接的是PB6和PB7管脚,所以我们要对它们进行一个配置。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 410 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 然后,对 I2C1 接口进行初始化,具体为设置 I2C 接口的模式(由于 I2C 接口可工作在 I2C 模式 或者 SMBA 模式,因此在初始化时,需要设置其具体工作模式),I2C 主机地址,以及 I2C 速率等等。 在完成了I2C接口初始化以后,我们就可以正常的使用I2C1接口了,下面是神舟III号EEPROM读 嵌入式专业技术论坛 (www.armjishu.com)出品 第 411 页,共 788 页 写访问程序。 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这段代码主要是将0x00~0xFF顺序写入到EEPROM中,然后再依次从EEPROM中读出这些数据, 并通过串口打印。 24C02中带有片内地址寄存器。每写入或读出一个数据字节后,该地址寄存器自动加1,以实现对 下一个存储单元的读写。所有字节均以单一操作方式读取。为降低总的写入时间,一次操作可写入多 达8个字节的数据。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 412 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中I2C_WriteS_24C函数,是24CXX EEPROM的页写入函数,在神舟III号,我们使用的24C02的 页大小为8,也就是说,可以单次连续8个字节写入。具体的函数实现如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 413 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中I2C_ReadS_24C函数,是24CXX EEPROM的页读出函数,在神舟III号,我们使用的24C02的 页大小为8,也就是说,可以单次连续8个字节读出。具体的函数实现如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 414 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 415 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下面我们根据程序代码来了解下 IIC 主要的特殊类型信号 ¾ 首先我们看下起始信号 函数中,只要 NewState 与 DISABLE 不相等的话,在这里我们用到了一个 I2C 中的 CR1 寄存器,只 要不相等,就为这个寄存器赋一个值,相等的话也赋一个值,下面我们看下 NewState 与 DISABLE 是怎么样的,而 CR1 的寄存器赋值后呢?下面我们进入 NewState 与 DISABLE 看下 只要不等于的话,我们给 CR1 赋值 CR1_START_Set,否则赋值 CR1_START_Reset 下面我们分别看下这 2 个值是什么 分别是 0x0100 和 0xFEFF,那么我们看下把它们赋值给 CR1 寄存器后会怎么样,打开我们的 嵌入式专业技术论坛 (www.armjishu.com)出品 第 416 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 STM32F103ZE 的参考手册,找到 CR1 的寄存器 赋的值中,0x0100 那么也就是第 8 位为 1,其他为 0,我们找到第八位 根据第八位的描述,该位为 1 时,即可产生一个起始条件。把 0xFEFF 赋值给 CR1 时,因为是相与的, 那么也就是第 8 位为 0,我们可以看到,当第八位为 0 时,是没有起始条件产生的。这个便是我们的 产生起始信号的例程代码。 ¾ 我们再看下停止信号 函数中,只要 NewState 与 DISABLE 不相等的话,为 CR1 寄存器赋一个 CR1_STOP_Set 的值,相等 的话赋一个 CR1_STOP_Reset 的值,我们看下这两个值是多少的 嵌入式专业技术论坛 (www.armjishu.com)出品 第 417 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 分别是 0x0200 和 0xFDFF,那么我们看下把它们赋值给 CR1 寄存器后会怎么样,赋的值中,0x0200 那么也就是第 9 位为 1,其他为 0,我们找到第九位 当第九位为 1 时,主模式下是产生一个停止条件,从模式下,是释放 SCL 和 SDA 线。相等时,与上 0xFDFF,那么第九位为 0,也就是无停止条件产生。 其他的信号查看方法和起始信号与停止信号一样。 以下是 MAIN 函数中,完成数据写入读出比对情况: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 418 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 所以,我们的神舟 III 号执行我们的这个 MAIN 函数后就可以得到我们上面所达到的实验现象了。 7.18 TIMER定时器中断实验 7.18.1 意义与作用 对于TIMER定时器大家应该不会陌生,51单片机内部就有定时器,作为高性能的STM32开发板 自然少不了对其介绍。定时器属于STM32处理器的内部资源。神舟系列的本例程通过TIMER定时器, 产生的中断定时在串口输出打印信息。我们按照以下的几个部分对STM32处理器的TIMER进行学习。 7.18.2 实验原理 神舟III开发板使用的处理器是ARM CORTEX-M3系列的STM32F103ZET,其内部含有多达10 个定时器,包括: −多达4个16位定时器,每个定时器有多达4个用于输入捕获/输出比较/PWM或脉冲计数的通道和增 量编码器输入 −1个16位带死区控制和紧急刹车,用于电机控制的PWM高级控制定时器 −2个看门狗定时器(独立的和窗口型的) −系统时间定时器:24位自减型计数器 −2个16位基本定时器用于驱动DAC 按功能分为: −2个高级控制定时器(两个高级控制定时器TIM1和TIM8,可以被看成是分配到6个通道的三相PWM 发生器,它具有带死区插入的互补PWM输) −4个普通定时器(达4个可同步运行的标准定时器TIM2、TIM3、TIM4和TIM5) −2个基本定时器(这2个定时器主要是用于产生DAC触发信号,也可当成通用的16位时基计数器) −2个看门狗定时器 −1个系统嘀嗒定时器SysTick。 下表比较了高级控制定时器、普通定时器和基本定时器的功能: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 419 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 前面我们已经介绍了系统嘀嗒定时器SysTick的使用,本次示例以通用定时器TIM5为例来完成一 个一秒中断一次的基本功能。通用定时器介绍如下: 通用定时器(TIMx) STM32F103xC系列产品中,内置了多达4个可同步运行的标准定时器 (TIM2、TIM3、TIM4和TIM5)。每个定时器都有一个16位的自动加载递加/递减计数器、一个16位 的预分频器和4个独立的通道,每个通道都可用于输入捕获、输出比较、PWM和单脉冲模式输出,在 最大的封装配置中可提供最多16个输入捕获、输出比较或PWM通道。 它们还能通过定时器链接功能 与高级控制定时器共同工作,提供同步或事件链接功能。在调试模式下,计数器可以被冻结。任一标 准定时器都能用于产生PWM输出。每个定时器都有独立的DMA请求机制。 这些定时器还能够处理增 量编码器的信号,也能处理1至3个霍尔传感器的数字输出。 STM32定时器定时时间的计算 首先我们来看一下如何计算定时器的时间来完成一个一秒中断一次的基本功能。 假如系统时钟是 72Mhz,如上图所示 TIM2-7 是由 PCLK1 得到,一般的配置包括我们本次的 示例中 PCLK2 = HCLK(72MHz)。也就是说本次示例中 TIM5 模块入口时钟是 72Mhz。 TIM5 模块入口时钟经过一个预分频器后的时钟才是 TIM5 计数器的时钟(用 CK_CNT 表示)。 预分频器的系数为:TIMx_PSC ,当 TIMx_PSC=0 时表示不分频,则 TIM5 计数器的时钟用 CK_CNT=模块入口时钟 72Mhz;当 TIMx_PSC=1 时表示不分频,则 TIM5 计数器的时钟用 CK_CNT=模块入口时钟 36Mhz;以此类推。 公式为:CK_CNT= fCK_PSC/(PSC[15:0]+1),其中 PSC 最大为 65535。 其次是 TIM5 计数器的计数值的设置,TIM5 计数器以 CK_CNT 为时钟来计数,向下计数到 0 或向上计数到设定值(TIMx_ARR)则产生中断。我们以向上计数为例,从 0 开始计数到设定值 TIMx_ARR 时产生中断。要产生一秒一次中断则要使计数器的值乘以预分频值=系统时钟 72MHz, 其中计数器的值和预分频值都必须小于 65535。我们使预分频值为 7200,计数器值为 10000,则 7200 * 10000 = 7200000 即 72M。其中拆分法有很多,比如 35000 * 2000 = 7200000,只 要注意计数器的值和预分频值都必须小于 65535 即可。 当然既然是一秒一次的重复中断,当然中断要是自动装载的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 420 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.18.3 硬件设计 TIMER 定时器为 STM32 处理器内部组件,这部分不需要硬件电路,这里仅在中断产生时,进行 串口打印操作。 说明:本实例需要用到使用GPIO管脚控制LED的相关知识和串口相关知识,关于LED的其它函数 请查看“LED跑马灯实验”, 关于串口的函数请查看“串口输入输出实验”,此处不再介绍。本历 程中主要是针对STM32定时器示例中新增添的代码进行说明。 7.18.4 软件设计 进入例程的文件夹,然后打开\Project \ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析 1:SZ_STM32_LEDInit(LED1)函数初始化 LED 灯,前面我们已经讲解,我们就不再重复。 代码分析 2:SZ_STM32_COMInit()函数初始化串口 2,前面我们已经讲解,我们就不再重复。 代码分析 3:SZ_STM32_SysTickInit ()函数初始化系统定时器 SysTick,前面我们已经讲解,我们就不 再重复。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 421 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 4:TIM5_Init()函数对 TIM5 进行初始化。 本函数配置定时器参数。前面实验原理章节的“STM32定时器定时时间的计算”部分已经介绍 了定时时间的计算方法,从 TIM5_Init函数中我们可以看出TIM5的参数配置流: 1)TIM5时钟使能。调用RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE) 函数现实。 2)初始化定时器参数,设置自动重装值,分频系数,计数方式等。调用TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure) 函 数 实 现 。 函 数 中 用 到 结 构 体 , 结 构 体 类 型 是 TIM_TimeBaseInitTypeDef。 typedef struct { uint16_t TIM_Prescaler; uint16_t TIM_CounterMode; uint16_t TIM_Period; uint16_t TIM_ClockDivision; uint8_t TIM_RepetitionCounter; } TIM_TimeBaseInitTypeDef 大家翻开其它的工程,我们初始化配置其它的接口的话,也常常用到类似的函数。这样的结构体 包含了这个接口的信息。比如我们配置GPIO管脚的时候,要确定是那个管脚,管脚的速率,输入输出 模 式 等 。 这 里 TIM_Prescaler 用 来 配 置 分 频 系 数 。 TIM_CounterMode 用 来 设 置 计 数 方 式 。 TIM_Period用来配置自动重载计数周期。TIM_RepetitionCounter用来设置时钟分频因子。 3)经过TIM_TimeBaseInit()函数初始化TIM5之后,我们清除TIM5溢出中断标志,打开TIM5 的溢出中断,使能TIM5,当然还要配置TIM5中断参数。这里的每一个功能都调用了对应的函数实现。 到此我们的初始化函数基本完成。 代 码 分 析 5 : TIM5 中 断 触 发 的 时 候 , 进 入 中 断 服 务 函 数 。 我 们 看 一 下 中 断 服 务 函 数 TIM5_IRQHandler()。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 422 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断服务函数中,我们调用SZ_STM32_LEDToggle(LED1)函数控制LED1灯闪烁,并且通过串口 打印提示信息,信息中的数值加1。armjishu.com提心您: 不建议在中断中使用Printf, 此示例只是演示。 为什么使用静态变量counter?目的是每次进入定时器中断函数数静态变量counter保持上次退出 时的值,这样才能达到计数的目的。否则,如果去掉static关键字则每次进入中断函数时counter为0, 串口打印的数值也为0,就达不到每次打印的数值加1的目的。 由上述分析可知每产生一次定时器中断,进入定时器中断服务程序,中断服务程序中,都调用 SZ_STM32_LEDToggle(LED1)函数,而我们配置的是每秒中断一次,那么SZ_STM32_LEDToggle(LED1) 函数每秒中会被调用1次。同时使用静态变量counter将中断服务函数执行的次数记录下来。 至此神舟系列TIMER定时器中断相关软件程序介绍完毕! 7.18.5 下载与验证 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误! 未找到引用源。小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 423 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.18.6 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源, 用串口线神舟 III 号串口 2 与电脑连接,并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 再按确定,完成超级终端设置。 重新打开电源;神舟III号STM32开发板上LED 1灯间断亮灭,LED2至LED4都常亮。 并且串口打印的数值每秒加1: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 424 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 armjishu.com提心您: 不建议在中断中使用Printf, 此示例只是演示。 7.19 IWDG独立看门狗 STM32 内部自带了 2 个看门狗:独立看门狗(IWDG)和窗口看门狗(WWDG)。这一章,介绍 如何使用 STM32 的独立看门狗(以下简称 IWDG)。 7.19.1 什么是看门狗 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造 成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成 整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑, 便产生了一种专门用于监测单片机程序运行状态的模块或者芯片,俗称“看门狗”(watchdog) 。 其实就是相当一个装满时间数值的倒计时器一样,启动之后就开始倒计时,倒计时为零传送一个复位 信号到 CUP,又重新开始倒计时。 7.19.2 为什么是独立看门狗呢 就是在芯片内部独立的一部分,独立的看门狗是基于一个 12 位的递减计数器和一个 8 位的预分 频器,它由一个内部独立的 40kHz 的 RC 振荡器提供时钟;因为这个 RC 振荡器独立于主时钟,所以 它可运行于停机和待机模式。它可以被当成看门狗用于在发生问题时复位整个系统,或作为一个自由 定时器为应用程序提供超时管理。通过选项字节可以配置成是软件或硬件启动看门狗。在调试模式下, 计数器可以被冻结。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 425 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.19.3 怎么使用独立看门狗IWDG 前面已经介绍了,独立看门狗相当于一个独立的倒计时器,那要用之前就要给这个倒计时设置一 个启动开关才能用,而启动开关这里就是用 Key Register 键值寄存器;有了开关那可以用,但倒计数 的值不可能是无穷大,所以在这里也要设置一个 Reload Register 重装载寄存器用来控制我们想要时 间;控制启动开关、时间长短都有了,还有一个倒计时节奏速度,也就是频率,这里就用到了 Prescaler Register 预分频寄存器;好,有了这三个寄存器,我们就可以进行对它控制操作。对这几个寄存器进 行进一步的了解: Key Register 键值寄存器的作用是: (1)控制独立看门狗的启用功能; (2)改变另外两个寄存器(Prescaler Register 预分频寄存器)和(Reload Register 重装载寄存器) 作用状态功能; (3)改变看门狗计数器为 0 时,复位的产生或重新再计数。 Prescaler Register 预分频寄存器的作用是:用来设置看门狗时钟的分频系数。 Reload Register 重装载寄存器的作用是:用来重新加载为倒计数计数器的初值。 Status Register 状态寄存器的作用是:设置(Prescaler Register 预分频寄存器)和(Reload Register 重装载寄存器)两个寄存器读操作的有效性。 其实使用独立看门狗就是在控制和设置几个寄存器。接下来一步一步详细操作怎么使用独立看门 狗 IWDG。 键值寄存器 IWDG_KR(Key Register): 首先是键值寄存器 IWDG_KR,该寄存器功能上面所说,接下是各位的描述,如图: 位 31:16 保留,始终读为 0。 位 15:0 KEY[15:0]:键值(只写寄存器,读出值为 0x0000) 软件必须以一定的间隔写入 0xAAAA,否则,当计数器为 0 时,看门狗会产生 复位。 写入 0x5555 表示允许访问 IWDG_PR 和 IWDG_RLR 寄存器。 写入 0xCCCC,启动看门狗工作(若选择硬件看门狗则不受此命令字限制)。 在键值寄存器(IWDG_KR)中写入 0xCCCC,开始启用独立看门狗;此时计数器开始从其复位 值 0xFFF 递减计数。当计数器计数到末尾 0x000 时,会产生一个复位信号(IWDG_RESET)。 无论 何时,只要键寄存器 IWDG_KR 中被写入 0xAAAA, IWDG_RLR 中的值就会被重新加载到计数器 中从而避免产生看门狗复位,这里相当于喂狗,每一定时间内喂一次,防止看门狗自动复位。 IWDG_PR 和 IWDG_RLR 寄存器具有写保护功能。要修改这两个寄存器的值,必须先向 IWDG_KR 寄存器中写入 0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保 嵌入式专业技术论坛 (www.armjishu.com)出品 第 426 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 护。重装载操作(即写入 0xAAAA)也会启动写保护功能。 预分频寄存器 IWDG_PR(Prescaler Register): 接下来,介绍预分频寄存器(IWDG_PR),该寄存器用来设置看门狗时钟的分频系数,最低为 4,最 高位 256,该寄存器是一个 32 位的寄存器,但是我们只用了最低 3 位,其它都是保留位。预分频 寄存器各位定义如图: 位 31:3 保留,始终读为 0。 位 2:0 PR[2:0]:预分频因子。 这些位具有写保护设置,上面已有介绍。通过设置这些位来选择计数器的预 分频因子。要改变预分频因子,IWDG_SR 寄存器的 PVN 位必须位 0。 000:预分频因子= 4 001:预分频因子= 8 010:预分频因子= 16 011:预分频因子= 32 100:预分频因子= 64 101:预分频因子= 128 110:预分频因子= 256 111:预分频因子= 256 注意:对此寄存器进行读操作,将从 VDD 电压域返回预分频值。如果写操作 正在进行,则读对的值可能是无效的因此,只有当 IWDG_SR 寄存器的 PVU 位为 0 时,读出的值才有效。 重装载寄存器 IWDG_RLR(Reload Register): 介绍一下重装载寄存器 IWDG_RLR。该寄存器用来保存重装载到计数器中的值。该寄存器也是一个 32 位寄存器,但是只有低 12 位是有效的,该寄存器的各位描述如图: 位 31:12 保留,始终读为 0。 位 11:0 RL[11:0]:看门狗计数器重装载值,这些位具有写保护功能。前面已有介绍。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 427 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 用于定义看门狗计数器的重装载值,每当向 IWDG_KG 寄存器写入 0xAAAA 时,重装载值会被传送到计数器中。随后计数器从这个值开始递减计数。 看门狗超时周期可通过此重装载值和时钟预分频值来计算。 只有当 IWDG_SR 寄存器中的 RVU 位为 0 时,才能对此寄存器进行修改。 注意:对此寄存器进行读操作,将从 VDD 电压域返回预分频。如果写入操 作正在进行,则读回的值可能是无效的。因此,只有当 IWDG_SR 寄存器的 RVU 位为 0 时,读出的值才有效。 状态寄存器 IWDG_SR(Status Register): 位 31:2 保留。 位1 RVU:看门狗计数器重装载值更新此位由硬件置‘1’用来指示重装载值的更 新正在进行中。当在 VDD 域中的重装载更新结束后,此为由硬件清‘0’(最 多需 5 个 40KHz 的 RC 周期)。重装载值只有在 RVU 位被清‘0’后才可更新。 位0 PVU:看门狗预分频值更新此位由硬件置‘1’用来预分频值的更新正在进行中。 当在 VDD 域中的预分频值更新结束后,此位由硬件清‘0’(最多需 5 个 40KHz 的 RC 周期)。预分频值只有在 PVU 位被清‘0’后才可更新。 注:如果在应用程序中使用了多个重装载值或预分频值,则必须在 RVU 位被清除后才能重新改变预 装载值,在 PVU 位被清除后才能重新改变预分频值。然而,在预分频和/或重装值更新后,不必等待 RVU 或 PVU 复位,可继续执行下面的代码。(即是在低功耗模式下,此写操作仍会被继续执行完成。) 以上就是对独立看门狗有关几个寄存器的功能操作等介绍。 7.19.4 启动STM32的独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效。 这里需要注意独立看门狗的时钟是一个内部 RC 时钟,所以并不是准确的 40Khz,而是在 30~60Khz 之间的一个可变化的时钟,只是我们在估算的时候,以 40Khz 的频率计算,看门狗对时间的要求不 是很精确,所以,时钟有些偏差,都是可以接受的。 接下来就可以启动 STM32 的独立看门狗,启动过程可以按以下步骤实现: (1)向 IWDG_KR 写入 0x5555。 通过这步,取消 IWDG_PR 和 IWDG_RLR 的写保护,使后面可以操作这两个寄存器。 设置 IWDG_PR 和 IWDG_RLR 的值。 这两步设置看门狗的分频系数,和重装载的值。 怎么计算看门狗溢出时间呢? 由此,就可以知道看门狗的喂狗时间(也就是看门狗溢出时间),该时间的计算方式为: Tout=((4×2^prer) ×RLR) /40KHz 嵌入式专业技术论坛 (www.armjishu.com)出品 第 428 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中 Tout 为看门狗溢出时间(单位为 ms);prer 为看门狗时钟预分频值(IWDG_PR 值), 范围为 0~7(十进制,转二进制 000~111 以上面预分频对应);RLR 为看门狗的重装载值(IWDG_RLR 的值低 12 位)。 看门狗复位时间=(预分频×重装载值) /40KHz 根据公式推算就可以知道重装载值、预分频系数与溢出时间的关系,做出一个简单参考表格: 重装载值(RLR 寄存器低 12 位) 预分频 内部 RC 看门狗复位时间(ms) 625 1(最小值) 64 40 KHz 1000 ms 64 40 KHz 1.6 ms(在预分频 64 最小时间) 4096(最大值) 64 40 KHz 6553.6 m(s 在预分频 64 最大时间) 2500 1(最小值) 16 40 KHz 1000 ms 16 40 KHz 0.4 ms(在预分频 16 最小时间) 4096(最大值) 16 40 KHz 1638.4 m(s 在预分频 16 最大时间) 假设:预分频系数设定 prer 值为 4,重装载值 RLR 值为 625,那么就可以得到 Tout=64×625/40=1000ms,这样,看门狗的溢出时间就是 1s,只要你在一秒钟之内,有一次写入 0XAAAA 到 IWDG_KR,就不会导致看门狗复位(当然写入多次也是可以的)。这里需要提醒大家的 是,看门狗的时钟不是准确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门 狗复位。 (2)向 IWDG_KR 写入 0XAAAA。 通过这句,将使 STM32 重新加载 IWDG_RLR 的值到看门狗计数器里面。即实现独立看门狗的 喂狗操作。 (3)向 IWDG_KR 写入 0XCCCC。 通过这句,来启动 STM32 的看门狗。注意 IWDG 在一旦启用,就不能再被关闭!想要关闭, 只能重启,并且重启之后不能打开 IWDG,否则问题依旧,所以在这里提醒大家,如果不用 IWDG 的 话,就不要去打开它,免得麻烦。 7.19.5 软件设计 7.19.6 下载与验证 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错误! 未找到引用源。小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 429 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.19.7 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,关闭电源, 用串口线神舟 III 号串口 2 与电脑连接,并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 再按确定,完成超级终端设置。 重新打开电源;神舟 III 号 STM32 开发板上 LED 1 和 LED3 灯亮慢慢的暗又慢慢的亮,又轮到 LED2 和 LED4 灯亮慢慢的暗又慢慢的亮,一直循环。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 430 页,共 788 页 超级终端窗口显示信息,如下图 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.20 窗口看门狗 7.20.1 什么是窗口看门狗 窗口看门狗(WWDG)通常被用来监测,由外部干扰或不可预见的逻辑条件造成的应用程序背离正 常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位变成 0 前被刷新,看门狗电路在达到 预置的时间周期时,会产生一个 MCU 复位。在递减计数器达到窗口寄存器数值之前,如果 7 位的递 减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个 MCU 复位。这表明递减计数器需要在一 个有限的时间窗口中被刷新。也就是在独立看门狗的递减时间上设置一个有效的“窗口”只有在这“窗 口”内才能进行有效的“喂狗操作”。在“窗口”之外的喂狗操作和“窗口”的上线到下限中未进行 喂狗操作都将默认未错误操作,将会产生一个 MCU 复位。我们将之称为窗口看门狗。 7.20.2 窗口看门狗的特性 ● 可编程的自由运行递减计数器 ● 条件复位 ─当递减计数器的值小于 0x40,(若看门狗被启动)则产生复位。 ─当递减计数器在窗口外被重新装载,(若看门狗被启动)则产生复位。见 0。 ● 如果启动了看门狗并且允许中断,当递减计数器等于 0x40 时产生早期唤醒中断(EWI),它可以 被用于重装载计数器以避免 WWDG 复位,在了解了窗口看门狗的的特性后我们在来看窗口看门狗的 时序图。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 431 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 窗口看门狗时序图 时序图中,T[6:0]就是 WWDG_CR 的低七位,W[6:0]即是 WWDG->CFR (控制寄存器)的低 七位。T[6:0]就是窗口看门狗的计数器,而 W[6:0]则是窗口看门狗的上窗口(上窗口的值不是固定的 用户可以根据自己的需要进行设置,因为 WWDG->CFR 这个寄存器只有低 7 位提供给用户来设置窗 口的上限所以我们最大只能设置到 7F,最小不能小于下窗口值),下窗口值是固定的(0X40)。当窗 口看门狗的计数器在上窗口值之外被刷新,或者低于下窗口值都会产生复位。 7.20.3 窗口看门狗的计算公式: 窗口看门狗的超时公式如下: 其中: Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1; Twwdg:WWDG 超时时间(单位为 ms) Fpclk1:APB1 的时钟频率(单位为 Khz) WDGTB:WWDG 的预分频系数 T[5:0]:窗口看门狗的计数器低 6 位 根据上面的公式,那么可以得到最早喂狗时间-最晚喂狗时间表如表所示: WDGTB 最小超时值 最大超时值 0 113us 7.28ms 1 227us 14.56ms 2 455us 29.12ms 3 910us 嵌入式专业技术论坛 (www.armjishu.com)出品 58.25ms 第 432 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最小超时值为窗口看门狗计数周期时间=1s/FPCK1X(4096×2^WDGTB)列假设 Fpclk1=36Mhz,预分 频系数为 1,看门狗的计数周期时间 us=1000000(1S=1000ms=1000000us)/36000000(1MZH=1000KZH=1000000ZH)X(4096×1) ≈ 113us 最大超时值为窗口的最大值=1S/FPCK1×(4096×2*WDGTB)×(7F-3F) 注意:7F 为窗口上限最大值 40 为窗口下限 STM 系统默认值是固定的 3F 将报错 7.20.4 窗口看门狗要用到哪些寄存器 在了解了窗口看门狗的一些基本特性后我们来介绍下窗口看门狗 3 个寄存器,首先介绍控制寄存器 (WWDG_CR),该寄存器的各位描述如下图所示: 位 31:8 保留 位7 WDGA:激活位 此位油软件值 1,但仅能由硬件在硬件复位后清零,当 WDGA=1 时,看门狗可以 产生复位 0:禁止看门狗 1:启用看门狗 位 6:0 T[6:0]: 7 位计数器(MSB 至 LSB) (7-bit counter) 这些位用来存储看门狗的计数器值。每(4096x2WDGTB)个 PCLK1 周期减 1。当计 数器值从 40h 变为 3Fh 时(T6 变成 0),产生看门狗复位 可以看出,这里我们的 WWDG_CR 只有低八位有效,T[6:0]用来存储看门狗的计数器值,随 时更新的,每个看窗口看门狗计数周期(4096×2^ WDGTB)减 1。当该计数器的值从 0X40 变为 0X3F 的时候,将产生看门狗复位。 WDGA 位则是看门狗的激活位,该位由软件置 1,以启动看门狗,并且一定要注意的是该位一 旦设置,就只能在硬件复位后才能清零了。 窗口看门狗的第二个寄存器是配置寄存器(WWDG_CFR),该寄存器的各位及其描述如下图所 示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 433 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 该位中的 EWI 是提前唤醒中断,也就是在快要产生复位的前一段时间(T[6:0]=0X40)来提醒 我们,需要进行喂狗了,否则将复位!因此,我们一般用该位来设置中断,当窗口看门狗的计数器值 减到 0X40 的时候,如果该位设置,并开启了中断,则会产生中断,我们可以在中断里面向 WWDG_CR 重新写入计数器的值,来达到喂狗的目的。注意这里在进入中断后,必须在不大于 1 个窗口看门狗 计数周期的时间(在 PCLK1 频率为 36M 且 WDGTB 为 0 的条件下,该时间为 113us)内重新写 WWDG_CR,否则,看门狗将产生复位! 最后我们要介绍的是状态寄存器(WWDG_SR),该寄存器用来记录当前是否有提前唤醒的标志。 该寄存器仅有位 0 有效,其他都是保留位。当计数器值达到 40h 时,此位由硬件置 1。它必须通过 软件写 0 来清除。对此位写 1 无效。即使中断未被使能,在计数器的值达到 0X40 的时候,此位也 会被置 1。 下面我们来看下窗口看门狗的架构图: 如果看门狗被启动(WWDG_CR 寄存器中的 WDGA 位被置’1’), 并且当 7 位(T[6:0])递减 嵌入式专业技术论坛 (www.armjishu.com)出品 第 434 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 计数器从 0x40 翻转到 0x3F(T6 位清零)时,则产生一个复位。如果软件在计数器值大于窗口寄存器中 的数值时重新装载计数器,将产生一个复位。这里我要讲的是窗口看门狗它不像独立看门狗内部有一 个独立的时钟它是用来自与 RCC 的外部时钟驱动的,也就是说当外部时钟受到影响窗口看门狗也会 受到相应的影响,这样做有什么好处那?它的好处在于它不光更严格的监视了系统喂狗操作,而且它 关联到外部时钟当外部时钟不走了,这狗也将失去作用。 7.20.5 窗口看门狗与独立看门狗的区别 独立看门狗 Iwdg——有独立时钟(内部低速时钟 LSI---40KHz),所以不受系统硬件影响的系统 故障探测器。主要用于监视硬件错误。 窗口看门狗 wwdg——时钟与系统相同。如果系统时钟不走了,这个狗也就失去作用了,主要用 于监视软件错误 对于一般的看门狗,程序可以在它产生复位前的任意时刻刷新看门狗,但这有一个隐患,有可能 程序跑乱了又跑回到正常的地方,或跑乱的程序正好执行了刷新看门狗操作,这样的情况下一般的看 门狗就检测不出来了;如果使用窗口看门狗,程序员可以根据程序正常执行的时间设置刷新看门狗的 一个时间窗口,保证不会提前刷新看门狗也不会滞后刷新看门狗,这样可以检测出程序没有按照正常 的路径运行非正常地跳过了某些程序段的情况。 7.20.6 怎么使用窗口看门狗 介绍完窗口看门狗的原理、窗口看门狗将要用到的特殊功能寄存器以及窗口看门狗与独立看门 狗的区别后我们在来介绍要如何使用窗口看门狗,这里我们介绍的是用中断来喂狗,具体步骤如下; 1) 使能 WWDG 时钟 前面我们介绍独立看门狗和窗口看门都的区别时特别说明了独立看门狗使用的是内部低速时 钟,不存在使能的问题。而 WWDG 是使用的 PCLK1 的时钟,在使用前需要先使能时钟的。 2) 设置 WWDG_CFR 和 WWDG_CR 两个寄存器 在使能好时钟过后,我们设置 WWDG 的 CFR 和 CR 两个寄存器,对 WWDG 进行配置。 包括使能窗口看门狗、开启中断、设置计数器的初始值、设置窗口值并设置分频数 WDGTB 等。 这里要注意的是用户根据自己的需要设定时间,先要通过上面的看门狗超时公式和外部晶振算出我 们需要设定的时间那个分频段,在根据预分频时基算出 WWDG_CR 的计数器值。 如:假设我们使用的是 36M 的外部晶振,我们将要设定的时间是 3.41ms,我们不难算出应该 设定的 WDGTB[0:0]然后我们可以 3.41ms=1s/36M×(4096×1)×计算器值。可以算出大概为 30,也 就表示在 WWDG_CR 的计数器次数在加上 3F 得出 WWDG_CR 的计数值为 5D 3) 开启 WWDG 中断并分组 在 设 置 完 了 WWDG 后 , 需 要 配 置 该 中 断 的 分 组 及 使 能 。 这 点 通 过 我 们 之 前 所 编 写 的 MY_NVIC_Init 函数实现就可以了。 4)编写中断服务函数 在最后,还是要编写窗口看门狗的中断服务函数,通过该函数来喂狗,喂狗要快,否则当 窗口看门狗计数器值减到 0X3F 的时候,就会引起软复位了。在中断服务函数里面也要将状态寄存 器的 EWIF 位清空。 7.20.7 硬件设计 本实验中,我们只需要用到 2 个 LED 灯,分别是 LED1 和 LED2,通过 STM32 的窗口看门狗 的功能在看门狗中断的时候对我们的 LED 进行一个取反闪烁的效果,通过串口把数据打印出去。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 435 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.20.8 软件设计 我们先来看下主函数,开始的时候,我们因为需要使用 LED 观察看门狗的状态,所以先是对 LED 进行了一个初始化,并让 LED 都熄灭,防止影响到下面。 初始化串口,并让串口输出打印我们这次的实验目的 先是点亮我们的 LED1,延时一段时间 对窗口看门狗进行一个配置,如寄存器、中断的配置函数 熄灭 LED1,在这里等待窗口看门狗的中断 深入分析程序代码 嵌入式专业技术论坛 (www.armjishu.com)出品 第 436 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ 使能时钟,窗口看门狗使用的是 PCLK1 的时钟,需要先使能时钟。方法是: ¾ 设置窗口值和分频数 设置窗口值的函数是: 这个函数就一个入口参数为窗口值 设置分频数的函数是: 这个函数同样只有一个入口参数就是分频值。 ¾ 开启窗口看门狗中断 开启 WWDG 中断的函数为: ¾ 窗口看门狗配置分组 配置 NVIC 中断优先级分组 中断 NVIC 配置,中断函数 WWDG_IRQn。 我们看下看门狗的寄存器配置是怎么样的,首先是使能看门狗,并设置一个计数值。在这个函数 嵌入式专业技术论坛 (www.armjishu.com)出品 第 437 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 里面,是用一个 0x80 与上 0x7f,得到一个新的数值给到寄存器 WWDG_CR,使得第七位为 1,使能看 门狗。 我们再来看下这个函数,它的主要作用是让窗口看门狗配置为中断模式,计数值递减到 0x40 的 时候产生中断,只能是复位清除。 我们下面看下中断函数是怎么样的,当看门狗计数值到 0x40 产生中断时会怎么样操作的,首先 进入中断之后先是重新给寄存器重新载入计数值,然后清除中断标志位,清除完中断标志位后对 LED2 进行一个状态转换的功能,让串口输出打印一串字符。也就是说我们的窗口看门狗每一次执行中断就 会点亮或者熄灭一次 LED,并打印一次数据 这样就能看到我们前面做实验现象中,LED2 进行一个闪烁的效果了 7.20.9 实验现象 板子串口 2 连接串口线到电脑打印串口数据,为板子供电,观察 LED1 与 LED2 的状态 嵌入式专业技术论坛 (www.armjishu.com)出品 第 438 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 板子上电时,先会对 LED1 点亮,延时一段时间后熄灭,等待看门狗中断,运行中断函数,改变 LED2 的状态,产生一次中断改变一次,达到闪烁的效果。看门狗在计数器递减到 0x40 的时候产生中 断,避免递减到 0x3f 的时候产生的复位信号。 下面为串口打印现象 先是打印串口初始化的信息,然后打印我们窗口看门狗中断函数里面的数据。 7.21 输入捕获实验 7.21.1 意义与作用 通过该实验,我们能够通过定时器捕获我们引脚上的高低电平脉冲宽度或者测量频率,对定时器 有了一个更全面的认识与运用。在这里介绍了通用定时器作为输入捕获的使用,我们将用 TIM5 的通 道 1(PA0)来做输入捕获,捕获 PA0 上低电平的脉宽(用 KEY4 按键输入低电平),通过串口打印低 电平脉宽时间。 7.21.2 输入捕获介绍 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器,除了 TIM6 和 TIM7,其 他定时器都有输入捕获功能。STM32 的输入捕获,简单的说就是通过检测 TIMx_CHx 上的边沿信号, 在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的 通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断 /DMA 等。 7.21.3 实验原理 输入捕获就是用定时器 TIMx(除了 TIM6 和 TIM7)来捕获高低电平的脉宽,这里我们就也捕获 通用定时器 TIM5 的高电平脉宽来讲解,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的 嵌入式专业技术论坛 (www.armjishu.com)出品 第 439 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 时候 TIM5_CNT 的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时 的 TIM5_CNT 值。这样,前后两次 TIM5_CNT 之差,就是高电平的脉宽,同时 TIM5 的计数频率 我们是知道的,从而可以计算出高电平脉宽的准确时间。 7.21.4 与输入捕获相关的寄存器 了解了输入捕获的基本原理后,我们来简要的分析下输入捕获将要用到的寄存器,在上面原理讲 解的时候我们知道输入捕获就是用定时器来测量边沿的宽度或者频率,那么就会用到定时器,因此会 用到 TIMx_ARR、TIMx_PSC 这两个寄存器在此我就不做过多的说明相信看来我们前面知识的朋友都 会明白。在通用定时器每个定时器都会有 4 个通道来进行输入捕获因此就会涉及到通道的选择所以会 用到 TIMx_CCMR1 和 TIMx_CCMR2 这两个寄存器,应为本次实验只用到定时器 5 的通道 1 所以我 们就只用到 TIMx_CCMR1 这个寄存器。我们需要用到中断来处理捕获数据,所以必须开启通道 1 的 捕获比较中断,即 CC1IE 设置为 1 我们要将捕获计数器的值到捕获寄存器中就要用到 TIMx_CCER 寄存器,最后再来看看捕获/比较寄存器 1:TIMx_CCR1,该寄存器用来存储捕获发生时,TIMx_CNT 的值,我们从 TIMx_CCR1 就可以读出通道 1 捕获发生时刻的 TIMx_CNT 值,通过两次捕获(一 次下降沿捕获,一次上升沿捕获)的差值,就可以计算出低电平脉冲的宽度。 下面我们在来看看各个寄存器各位的功能说明; 首先 TIMx_ARR 和 TIMx_PSC,这两个寄存器用来设自动重装载值和 TIMx 的时钟分频,用法 同前面介绍的,我们这里不再介绍。 再来看看捕获/比较模式寄存器 1:TIMx_CCMR1,这个寄存器在因此必须注意,同一个位在输 出模式和输入模式下的功能是不同的。有必要重新介绍,该寄存器的各位描述如图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 440 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 当在输入捕获模式下使用的时候,对应图的第二行描述,从图中可以看出,TIMx_CCMR1 明显 是针对 2 个通道的配置,低八位[7:0]用于捕获/比较通道 1 的控制,而高八位[15:8]则用于捕获/ 比较通道 2 的控制,因为 TIMx 还有 CCMR2 这个寄存器,所以可以知道 CCMR2 是用来控制通道 3 和通道 4。 在次我们用到的是定时器 5 的通道 1 我们重点介绍 TIMx_CMMR1 的[7:0]位(其实高 8 位配置 类似),TIMx_CMMR1 和 TIMx_CMMR2 也是大同小异的有兴趣的朋友可以去 STM32 手册上做深入 了解。其中 CC1S[1:0],这两个位用于 CCR1 的通道配置,这里我们设置 IC1S[1:0]=01,也就是配置 IC1 映射在 TI1 上关于 IC1,即 CC1 对应 TIMx_CH1。输入捕获 1 预分频器 IC1PSC[1:0],这个 比较好理解。设置我们是 几 次边沿就触发 1 次捕获,我们这里是 1 次边沿就触发 1 次捕获所以选 择 00 就是了。输入捕获 1 滤波器 IC1F[3:0],这个用来设置输入采样频率和数字滤波器长度。其中, fck_int 是定时器的输入频率(TIMxCLK),一般为 72Mhz,而 Fdtc 则是根据 TIMx_CR1 的 CKD[1:0] 的设置来确定的,如果 CKD[1:0]设置为 00,那么 Fck_int=Fdtc。N 值就是滤波长度,举个简单的例 子:假设 IC1F[3:0]=0011,并设置 IC1 映射到通道 1 上,且为上升沿触发,那么在捕获到上升沿的 时候,再以 fck_int 的频率,连续采样到 8 次通道 1 的电平,如果都是高电平,则说明却是一个有效 嵌入式专业技术论坛 (www.armjishu.com)出品 第 441 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 的触发,就会触发输入捕获中断(如果开启了的话)。这样可以滤除那些高电平脉宽低于 8 个采样周 期的脉冲信号,从而达到滤波的效果。这里,我们不做滤波处理,所以设置 IC1F[3:0]=0000,只要采 集到上升沿,就触发捕获。 再来看看捕获/比较使能寄存器:TIMx_CCER,本章我们要用到这个寄存器的最低 2 位,CC1E 和 CC1P 位。这两个位的描述如图所示: 所以,要输入捕获使能位开启,必须设置 CC1E=1,而 CC1P 输入捕获 1 极性设置位用户可以根 据自己的需要来配置(0:捕获到上升沿触发 1:捕获到下降沿触发)。 接下来我们再看看 DMA/中断使能寄存器:TIMx_DIER,我们需要用到中断来处理捕获数据,所 以必须开启通道 1 的捕获比较中断,即 CC1IE 设置为 1。 当我们开启 CC1IE DMA/中断使能寄存器后将 CC1 配置为输出模式,当捕获事件发生时该位由硬 件置 1,它由软件清零或通过读 TIM_CCR1 清零。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 442 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 控制寄存器:TIMx_CR1,我们只用到了它的最低位,也就是用它来使能定时器的,这里前面两 章都有介绍,请大家参考前面的章节 最后再来看看捕获/比较寄存器 1:TIMx_CCR1,该寄存器用来存储捕获发生时,TIMx_CNT 的 值,我们从 TIMx_CCR1 就可以读出通道 1 捕获发生时刻的 TIMx_CNT 值,通过两次捕获(一次 下降沿捕获,一次上升沿捕获)的差值,就可以计算出低电平脉冲的宽度。 至此,我们把本章要用的几个相关寄存器都介绍完了,本章要实现通过输入捕获,来获取 TIM5_CH1(PA0)上面的高电平脉冲宽度,并从串口打印捕获结果。 7.21.5 输入捕获配置的步骤 下面我们介绍输入捕获的配置步骤: 1)开启 TIM5 时钟,配置 PA0 为上拉输入。 首先我们要用到那个定时器就必须要先使能它的时钟。这里要使用 TIM5,我们必须先开启 TIM5 的时钟(通过 APB1ENR 设置)。这里我们还要配置 PA0 为上拉输入,因为我们要捕获 TIM5_CH1 上 面的低电平脉宽,而 TIM5_CH1 是连接在 PA0 上面的。 2)设置 TIM5 的 ARR 和 PSC。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 443 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在开启了 TIM5 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来设置输入捕获的自动 重装载值和计数频率(也就是初始化定时器,这样我们才知道定时器的计数频率和定时器的溢出值)。 3)设置 TIM5 的 CCMR1 TIM5_CCMR1 寄存器控制着输入捕获 1 和 2 的模式,包括映射关系,滤波和分频等。这里我 们需要设置通道 1 为输入模式,且 IC1 映射到 TI1(通道 1)上面,并且不使用滤波(提高响应速度) 器。 4)设置 TIM5 的 CCER,开启输入捕获,并设置为上升沿捕获。 TIM5_CCER 寄存器是定时器的开关,并且可以设置输入捕获的边沿。只有 TIM5_CCER 寄存器 使能了输入捕获,我们的外部信号,才能被 TIM5 捕获到,否则一切白搭。同时要设置好捕获边沿, 才能得到正确的结果。 5)设置 TIM5 的 DIER,使能捕获和更新中断,并编写中断服务函数 因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降沿,必 须在捕获上升沿之后,设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢 出必须做处理,否则结果就不准了。这两件事,我们都在中断里面做,所以必须开启捕获中断和更新 中断。设置了中断必须编写中断函数,否则可能导致死机。我们需要在中断函数里面完成数据处理和 捕获设置等关键操作,从而实现高电平脉宽统计。 6)设置 TIM5 的 CR1,使能定时器 最后,必须打开定时器的计数器开关,通过设置 TIM5_CR1 的最低位为 1,启动 TIM5 的计数 器,开始输入捕获。通过以上 6 步设置,定时器 5 的通道 1 就可以开始输入捕获了,同时因为还 用到了串口输出结果,所以还需要配置一下串口。 7.21.6 硬件设计 本次实验中,我们只需要使用到 KEY4 的按键资源,该按键接到处理器的 PA0 端口上,是一个上 拉输入的按键,当按键按下去的时候,使得 PA0 得到一个低电平的电压,实现捕获低电平持续时间的 测试实验,通过我们的串口线,把得到的数据传输到我们的串口工具上显示出来。 7.21.7 软件设计 开始的时候,先是定义了输入捕获的状态与捕获值,为下面的函数所使用 主函数的时候,先是对 LED 进行了一个初始化 嵌入式专业技术论坛 (www.armjishu.com)出品 第 444 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 初始化函数,分别对串口与定时器做了一个初始化,串口初始化完了后输出打印我们我们这次实 验内容“ARMJISHU.COM-->输入捕获实验”其中红色方框上的数据是在串口初始化的时候串口输出 的数据,而我们的蓝色方框的数据则是我们这句代码发出的数据。 通过设置TIM5_Cap_Init(),将TIM5_CH1的捕获计数器设计为1us计数一次,并设置重装载值为最 大,所以我们的捕获时间精度为1us。 主函数通过 TIM5CH1_CAPTURE_STA 的第 7 位,来判断有没有成功捕获到一次低电平,如果成 功捕获,则将高电平时间通过串口输出到电脑。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 445 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 详细分析代码 TIM5_Init 函数中,开启 TIM5 时钟和 GPIOA 时钟,配置 PA0 为上拉输入,要使用 TIM5,我们 必须先开启 TIM5 的时钟。这里我们还要配置 PA0 为上拉输入,因为我们要捕获 TIM5_CH1 上面的低 电平脉宽,而 TIM5_CH1 是连接在 PA0 上面的。 使用定时器的时候需要对定时器进行一个配置使用,配置完后还要对我们的输入捕获进行一个参 数的设置 嵌入式专业技术论坛 (www.armjishu.com)出品 第 446 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 配置 TIM5 中断向量参数函数 当定时器 TIM5 产生中断的时候,进行的处理函数,该函数中,因为我们要捕获的是低电平信号 的脉宽,所以,第一次捕获是下降沿,第二次捕获时上升沿,必须在捕获下降沿之后,设置捕获边沿 为上升沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了。 这两件事,我们都在中断里面做,所以必须开启捕获中断和更新中断。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 447 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.21.8 实验现象 程序下载到我们的神舟 III 号开发板上后,连接我们的串口线到串口 2 上,波特率设置为 115200, 具体串口设置可查看我们前面的串口介绍,复位后即可打印出我们串口初始化时的数据,然后通过 KEY4 按键得到低电平的脉宽时间,通过实验现象可看到捕获到的数据有 2 个是低于 10us 的,这种就 是按键按下时发生的抖动。这就是为什么我们按键输入的时候,一般都需要做防抖处理,防止类似的 情况干扰正常输入。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 448 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.22 315M无线模块扫描实验 前面“按键检测”章节我们介绍了STM32的IO口作为输入功能的使用方法,本章节我们以315M 无线模块扫描为例继续讲解IO相关知识,通过本节的学习,你将了解到STM32的IO口作为输入实现无 线控制的功能。本节分为如下几个小节: 4.14.1 315M无线模块实验的意义与作用 4.14.2 实验原理 4.14.3 硬件设计 4.14.4 软件设计 4.14.5 下载与验证 4.14.6 实验现象 7.22.1 意义与作用 STM32的IO口在前面的流水灯实验、蜂鸣器实验和按键检测实验中已经有了详细的介绍,这一节 我们讲结合STM32的库,描述如何设置STM32的GPIO口与315M无线模块的连接与使用。 这一节,我们将通过神舟 III 号板载的 315M 无线模块上 4 个按键,来控制板上的蜂鸣器和 4 个 LED(LED1~4),按下任一个按钮,对应的 LED1~4 点亮,同时蜂鸣器会鸣响,还会在串口输出按键 或无线控制的提示信息。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 449 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.22.2 实验原理 这个例程的实验原理主要是通过神舟III号上的315无线模块,接收315M无线遥控上的4个按钮(遥 控上的A、B、C、D键),控制蜂鸣器和4个LED灯的点亮和关闭状态。 具体的对应关系如下: 现象 操作 备注 LED1亮其它LED灭 LED2亮其它LED灭 LED3亮其它LED灭 LED4亮其它LED灭 蜂鸣器鸣响 神舟III号板载KEY1按键被按下 同时串口会 或者315M无线遥控的按键A被按下 有打印提示 神舟III号板载KEY2按键被按下 或者315M无线遥控的按键C被按下 神舟III号板载KEY3/TAMPER按键被按下, 或者315M无线遥控的按键B被按下 神舟III号板载KEY4/WAKEUP按键被按下, 或者315M无线遥控的按键D被按下 315M无线遥控的按键任意键被按下 7.22.3 硬件设计 神舟III号开发板板载了315M无线模块,可以接受遥控器的信号,当遥控的一个按键按下时,对 应的无线模块的D0~3管脚变为有效。需要指出的是,无线模块当输出为高电平有效,经过三极管放大 取反以后并为低电平有效,再将这些送给神舟开发板的STM32。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 450 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图表 15 315M 无线接口原理图 当无线模块的VT脚有效(低电平)时,表示无线模块接收到遥控的按键信号;当VT管脚无效(高 电平)时,表示无线模块没有接收到遥控的按键信号,与无线模块连接的几个管脚的电平变化是按键 引起的。 315M无线收发模块如下所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 451 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 而神舟III号通过三极管将315M无线模块与板上的按键进行了资源复用。神舟III号STM32开发板 总共有4个功能按键,分别是WAKEUP按键和TAMPER按键及两个用于自定义功能按键,在不使用第二功 能的情况下,这四个按键都可以作为通用的按键,由用户自定义其功能。这四个按键分别与PC4、PB10、 PC13和PA0四个GPIO管脚连接,当按键按下时,对应的GPIO管脚为低电平,反之,当没有按键按下 时,对应的GPIO管脚为高电平。其中PA0 (STM32的WKUP引脚)可以作为WK_UP功能,它除了可以 用作普通输入按键外,还可以用作STM32的唤醒输入。PC13可以实现备份区寄存器的入侵功能。本实 验中所有的按键均作为普通IO使用。 图表 16 按键输入电路 该实验需要使用到神舟III号开发板上的LED灯,按键,相关硬件电路如下: 图表 17 LED 指示灯电路 GPIO 管脚与无线模块对应关系 无线模块 按键对应的GPIO D3 PD3 D2 PA8 D1 PC13 嵌入式专业技术论坛 (www.armjishu.com)出品 第 452 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 D0 PA0 VT PB10(蜂鸣器) GPIO 管脚与按键对应关系 按键 KEY1 KEY2 KEY3/TAMPER KEY4/WAKEUP 按键对应的GPIO PA8 PC3 PC13 PA0 GPIO 管脚与对应的 LED 灯关系如下: LED灯 LED灯对应的GPIO LED1 PD6 LED2 PD7 LED3 PD8 LED4 PD9 7.22.4 软件设计 在分析例程的代码之前,我们想回顾一下关于 STM32 GPIO 的使用。 STM32 GPIO 的使用与配置 STM32 的 IO 口可以由软件配置成 8 种模式: ¾ 模拟输入 ¾ 输入浮空 ¾ 输入下拉 ¾ 输入上拉 ¾ 开漏输出 ¾ 推挽输出 ¾ 复用功能开漏输出 ¾ 复用功能推挽输出 对应到STM32库文件中的定义如下 在我们使用一个GPIO之前,我们一般需要对GPIO管脚的时钟,和GPIO管脚模式以及速率进行设 定。 STM32的GPIO端口在作为输出时,可以软件配置端口最大支持的时钟速率,有以下几种: ¾ 输出模式,最大时钟速率10MHz ¾ 输出模式,最大时钟速率2MHz 嵌入式专业技术论坛 (www.armjishu.com)出品 第 453 页,共 788 页 ¾ 输出模式,最大时钟速率50MHz 对应到STM32库中的定义如下: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 速率主要针对GPIO作为输出时使用,作为输入时可以不关注。 神舟III号的“315M无线模块扫描”位于神舟III号光盘\编译好的固件\ 315M无线模块扫描目录中。 为程序便于大家修改和移植,此处使用宏定义来定义指示灯的管脚等: 下面的LED_config函数是初始化神舟III号STM32开发板的4个LED灯对应的GPIO端口初始化的子函 数。 关于LED的其它函数请查看“LED跑马灯实验”章节,关于串口相关知识请“串口Printf输出实现” 章节,此处主要介绍无线控制和按键相关程序。 为程序便于大家修改和移植,此处使用宏定义来定义按键和315无线模块对应的管脚: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 454 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 神舟III号按键使用的GPIO的接口接口初始化,由于按键或无线模块上的按键按下时会使相应的 GPIO口变为低电平,因此,在这里我们配置按键使用的GPIO为输入上拉模式。没有收到有效信号, 保持这些GPIO口为高电平。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 455 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 无线遥控按键和开发板上轻触开关检测函数,当有无线遥控按键或开发板上轻触开关按下时,函 数返回对应的键值。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 456 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 说明:在本例程中,由于蜂鸣器和315M无线接收模块的VT使用了相同的GPIO管脚,只要无线 遥控上的任意按键按下,无线接收模块的VT信号就为低电平,经过三极管放大取反后的低电平被 Check_315M_Wireless程序检测到,同时驱动蜂鸣器鸣响。 介绍完基本的函数,我们再来分析一下main主程序: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 457 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 以上主程序首先显示初始化串口,打印提示信息。然后是初始化LED和无线按键的GPIO,如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 458 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最后主程序进入while死循环,不停的检测来自无线模块的控制信号和按键的状态信息。程序按以 下顺序执行 说明:在本例程中,由于按键和315M无线模块使用了相同的GPIO管脚,我们主要是利用前面提 到的方法二,即蜂鸣器是否发声来判断具体是按键(开发板上的轻触开关)被按下还是无线模块接收 到遥控信号。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 459 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.22.5 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操 作。 如果使用USB下载固件,请按3.5如何通过USB接口下载固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.22.6 实验现象 下载固件后上电运行。遥控有按键按下时蜂鸣器会鸣响,对应的LED灯会随之发生点亮,同时串口 会有提示信息;在开发板上的轻触开关被按下时蜂鸣器不会鸣响,对应的LED灯会随之发生点亮,同 时串口会有提示信息。 用串口线神舟 III 号串口 2 与电脑连接,并打开超级终端,按以下设置,如下图: 选择 COM1;按确定 嵌入式专业技术论坛 (www.armjishu.com)出品 第 460 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 再按确定,完成超级终端设置。 外设器件:315M 无线模块,315M 无线遥控器;将 315M 无线模块插在神舟 III 号开发板上, 重新打开电源;可以看到神舟 III 号开发板上的 4 个 LED 灯(LED1——LED4)都亮, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 461 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 315M 遥控器按键和神舟 III 号板按键操作说明,以下表: LED 灯现象 按键操作 LED1 亮,其它 LED 灭 神舟 III 号板 KEY1 按下或 315M 无线遥控的按键 A 按下 LED2 亮,其它 LED 灭 神舟 III 号板 KEY2 按下或 315M 无线遥控的按键 C 按下 LED3 亮,其它 LED 灭 神舟 III 号板 KEY3 按下或 315M 无线遥控的按键 D 按下 LED4 亮,其它 LED 灭 神舟 III 号板 KEY4 按下或 315M 无线遥控的按键 B 按下 蜂鸣器响 315M 无线遥控按任意按键按下 如用 315M 无线遥控器按下:A、B、C、D 按键;超级终端窗口显示信息,以下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 462 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.24 CAN总线实验 这一节我们将向大家介绍STM32的CAN总线的基本使用。在本小节,我们初始化CAN总线,分别 测试轮询模式和中断模式下的CAN总线环回,并通过神舟III号的LED等指示CAN环回的数据传送结 果。 7.24.1 什么是CAN总线 CAN,全称“Controller Area Network”,即控制器局域网,是国际上应用最广泛的工业级现场 总线之一。它是一种具有国际标准而且性能价格比又较高的现场总线,当今自动控制领域的发展中能 发挥重要的作用。最初 CAN 被设计作为汽车环境中的微控制器通讯,在车载各电子控制装置 ECU 之 间交换信息,形成汽车电子控制网络。比如:发动机管理系统、变速箱控制器、仪表装备、电子主干 系统中,均嵌入 CAN 控制装置。 CAN 控制器局部网是 BOSCH 公司为现代汽车应用领先推出的一种多主机局部网,由于其卓越性 能现已广泛应用于工业自动化、多种控制设备、交通工具、医疗仪器以及建筑、环境控制等众多部门。 在北美和西欧,CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并 且拥有以 CAN 为底层协议专为大型货车和重工机械车辆设计的 J1939 协议。近年来,其所具有的高 可靠性和良好的错误检测能力受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐 射强和振动大的工业环境。控制器局部网将在我国迅速普及推广。 由于 CAN 为愈来愈多不同领域采用和推广,导致要求各种应用领域通信报文的标准化。为此, 嵌入式专业技术论坛 (www.armjishu.com)出品 第 463 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 1991 年 9 月 PHILIPS SEMICONDUCTORS 制订并发布了 CAN 技术规范(VERSION 2.0)。该技术 规范包括 A 和 B 两部分。2.0A 给出了曾在 CAN 技术规范版本 1.2 中定义的 CAN 报文格式,而 2.0B 给出了标准的和扩展的两种报文格式。此后,1993 年 11 月 ISO 正式颁布了道路交通运载工具--数字 信息交换--高速通信控制器局部网(CAN)国际标准(ISO11898),为控制器局部网标准化、规范化推 广铺平了道路。 7.24.2 CAN总线的特点 CAN 总线是一种串行数据通信协议,它是一种多主总线,通信介质可以是双绞线、同轴电缆或光 导纤维。通信速率可达 1MBPS。CAN 总线通信接口中集成了 CAN 协议的物理层和数据链路层功能, 可完成对通信数据的成帧处理,包括位填充、数据块编码、循环冗余检验、优先级判别等项工作。 CAN 协议的一个最大特点是废除了传统的站地址编码,而代之以对通信数据块进行编码。采用这 种方法的优点可使网络内的节点个数在理论上不受限制,数据块的标识码可由 11 位或 29 位二进制数 组成,因此可以定义 211 或 229 个不同的数据块,这种按数据块编码的方式,还可使不同的节点同时 接收到相同的数据,这一点在分布式控制系统中非常有用。数据段长度最多为 8 个字节,可满足通常 工业领域中控制命令、工作状态及测试数据的一般要求。同时,8 个字节不会占用总线时间过长,从 而保证了通信的实时性。CAN 协议采用 CRC 检验并可提供相应的错误处理功能,保证了数据通信的 可靠性。CAN 卓越的特性、极高的可靠性和独特的设计,特别适合工业过程监控设备的互连,因此, 越来越受到工业界的重视,并已公认为最有前途的现场总线之一。 另外,CAN 总线采用了多主竞争式总线结构,具有多主站运行和分散仲裁的串行总线以及广播通 信的特点。CAN 总线上任意节点可在任意时刻主动地向网络上其它节点发送信息而不分主次,因此可 在各节点之间实现自由通信。CAN 总线协议已被国际标准化组织认证,技术比较成熟,控制的芯片已 经商品化,性价比高,特别适用于分布式测控系统之间的数通讯。CAN 总线插卡可以任意插在 PC AT XT 兼容机上,方便地构成分布式监控系统。 7.24.3 CAN总线技术介绍 1 位仲裁 要对数据进行实时处理,就必须将数据快速传送,这就要求数据的物理传输通路有较高的速度。在 几个站同时需要发送数据时,要求快速地进行总线分配。实时处理通过网络交换的紧急数据有较大的不 同。一个快速变化的物理量,如汽车引擎负载,将比类似汽车引擎温度这样相对变化较慢的物理量更频 繁地传送数据并要求更短的延时。 CAN 总线以报文为单位进行数据传送,报文的优先级结合在 11 位标识符中,具有最低二进制数的 标识符有最高的优先级。这种优先级一旦在系统设计时被确立后就不能再被更改。总线读取中的冲突 可通过位仲裁解决。当几个站同时发送报文时,站 1 的报文标识符为 011111;站 2 的报文标识符为 0100110;站 3 的报文标识符为 0100111。所有标识符都有相同的两位 01,直到第 3 位进行比较时,站 1 的 报文被丢掉,因为它的第 3 位为高,而其它两个站的报文第 3 位为低。站 2 和站 3 报文的 4、5、6 位相 同,直到第 7 位时,站 3 的报文才被丢失。注意,总线中的信号持续跟踪最后获得总线读取权的站的报文。 在此例中,站 2 的报文被跟踪。这种非破坏性位仲裁方法的优点在于,在网络最终确定哪一个站的报文 被传送以前,报文的起始部分已经在网络上传送了。所有未获得总线读取权的站都成为具有最高优先权 报文的接收站,并且不会在总线再次空闲前发送报文。 CAN 具有较高的效率是因为总线仅仅被那些请求总线悬而未决的站利用,这些请求是根据报文在 整个系统中的重要性按顺序处理的。这种方法在网络负载较重时有很多优点,因为总线读取的优先级已 被按顺序放在每个报文中了,这可以保证在实时系统中较低的个体隐伏时间。 对于主站的可靠性,由于 CAN 协议执行非集中化总线控制,所有主要通信,包括总线读取 (许可)控 制,在系统中分几次完成。这是实现有较高可靠性的通信系统的唯一方法。 2 CAN 与其它通信方案的比较 在实践中,有两种重要的总线分配方法:按时间表分配和按需要分配。在第一种方法中 ,不管每个节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 464 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 点是否申请总线,都对每个节点按最大期间分配。由此,总线可被分配给每个站并且是唯一的站,而不论 其是立即进行总线存取或在一特定时间进行总线存取。这将保证在总线存取时有明确的总线分配。在 第二种方法中,总线按传送数据的基本要求分配给一个站 ,总线系统按站希望的传送分配(如:Ethernet CSMA/CD)。因此,当多个站同时请求总线存取时,总线将终止所有站的请求,这时将不会有任何一个站 获得总线分配。为了分配总线,多于一个总线存取是必要的。 CAN 实现总线分配的方法,可保证当不同的站申请总线存取时,明确地进行总线分配。这种位仲裁 的方法可以解决当两个站同时发送数据时产生的碰撞问题。不同于 Ethernet 网络的消息仲裁,CAN 的 非破坏性解决总线存取冲突的方法,确保在不传送有用消息时总线不被占用。甚至当总线在重负载情况 下,以消息内容为优先的总线存取也被证明是一种有效的系统。虽然总线的传输能力不足,所有未解决 的传输请求都按重要性顺序来处理。在 CSMA/CD 这样的网络中,如 Ethernet,系统往往由于过载而崩溃, 而这种情况在 CAN 中不会发生。 3 CAN 的报文格式 在总线中传送的报文,每帧由 7 部分组成。CAN 协议支持两种报文格式,其唯一的不同是标识符(ID) 长度不同,标准格式为 11 位,扩展格式为 29 位。 在标准格式中,报文的起始位称为帧起始(SOF),然后是由 11 位标识符和远程发送请求位 (RTR)组 成的仲裁场。RTR 位标明是数据帧还是请求帧,在请求帧中没有数据字节。 控制场包括标识符扩展位(IDE),指出是标准格式还是扩展格式。它还包括一个保留位 (ro),为将来 扩展使用。它的最后四个字节用来指明数据场中数据的长度(DLC)。数据场范围为 0~8 个字节,其后 有一个检测数据错误的循环冗余检查(CRC)。 应答场(ACK)包括应答位和应答分隔符。发送站发送的这两位均为隐性电平(逻辑 1),这时正确接 收报文的接收站发送主控电平(逻辑 0)覆盖它。用这种方法,发送站可以保证网络中至少有一个站能正 确接收到报文。 报文的尾部由帧结束标出。在相邻的两条报文间有一很短的间隔位,如果这时没有站进行总线存取, 总线将处于空闲状态。 4 数据错误检测 不同于其它总线,CAN 协议不能使用应答信息。事实上,它可以将发生的任何错误用信号发出。CAN 协议可使用五种检查错误的方法,其中前三种为基于报文内容检查。 4.1 循环冗余检查(CRC) 在一帧报文中加入冗余检查位可保证报文正确。接收站通过 CRC 可判断报文是否有错。 4.2 帧检查 这种方法通过位场检查帧的格式和大小来确定报文的正确性,用于检查格式上的错误。 4.3.应答错误 如前所述,被接收到的帧由接收站通过明确的应答来确认。如果发送站未收到应答,那么表明接收 站发现帧中有错误,也就是说,ACK 场已损坏或网络中的报文无站接收。CAN 协议也可通过位检查的方 法探测错误。 4.4 总线检测 有时,CAN 中的一个节点可监测自己发出的信号。因此,发送报文的站可以观测总线电平并探测发 送位和接收位的差异。 4.5 位填充 一帧报文中的每一位都由不归零码表示,可保证位编码的最大效率。然而,如果在一帧报文中有太 多相同电平的位,就有可能失去同步。为保证同步,同步沿用位填充产生。在五个生。在五个连续相等 位后,发送站自动插入一个与之互补的补码位;接收时,这个填充位被自动丢掉。例如,五个连续的低电平 嵌入式专业技术论坛 (www.armjishu.com)出品 第 465 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 位后,CAN 自动插入一个高电平位。CAN 通过这种编码规则检查错误,如果在一帧报文中有 6 个相同 位,CAN 就知道发生了错误。 如果至少有一个站通过以上方法探测到一个或多个错误,它将发送出错标志终止当前的发送。这可 以阻止其它站接收错误的报文,并保证网络上报文的一致性。当大量发送数据被终止后,发送站会自动 地重新发送数据。作为规则,在探测到错误后 23 个位周期内重新开始发送。在特殊场合,系统的恢复时 间为 31 个位周期。 但这种方法存在一个问题,即一个发生错误的站将导致所有数据被终止,其中也包括正确的数据。 因此,如果不采取自监测措施,总线系统应采用模块化设计。为此,CAN 协议提供一种将偶然错误从永久 错误和局部站失败中区别出来的办法。这种方法可以通过对出错站统计评估来确定一个站本身的错误 并进入一种不会对其它站产生不良影响的运行方法来实现,即站可以通过关闭自己来阻止正常数据因 被错误地当成不正确的数据而被终止。 4.6 CAN 可靠性 为防止汽车在使用寿命期内由于数据交换错误而对司机造成危险,汽车的安全系统要求数据传输 具有较高的安全性。如果数据传输的可靠性足够高,或者残留下来的数据错误足够低的话,这一目标不 难实现。从总线系统数据的角度看,可靠性可以理解为,对传输过程产生的数据错误的识别能力。 残余数据错误的概率可以通过对数据传输可靠性的统计测量获得。它描述了传送数据被破坏和这 种破坏不能被探测出来的概率。残余数据错误概率必须非常小,使其在系统整个寿命周期内,按平均统 计时几乎检测不到。计算残余错误概率要求能够对数据错误进行分类 ,并且数据传输路径可由一模型 描述。如果要确定 CAN 的残余错误概率,我们可将残留错误的概率作为具有 80~90 位的报文传送时位 错误概率的函数,并假定这个系统中有 5~10 个站,并且错误率为 1/1000,那么最大位错误概率为 10—13 数量级。例如,CAN 网络的数据传输率最大为 1Mbps,如果数据传输能力仅使用 50%,那么对于一个工作 寿命 4000 小时、平均报文长度为 80 位的系统,所传送的数据总量为 9×1010。在系统运行寿命期内, 不可检测的传输错误的统计平均小于 10—2 量级。换句话说,一个系统按每年 365 天,每天工作 8 小时, 每秒错误率为 0. 7 计算,那么按统计平均,每 1000 年才会发生一个不可检测的错误。 4.应用举例 某医院现有 5 台 16T/H 德国菲斯曼燃气锅炉,向洗衣房、制剂室、供应室、生活用水、暖气等设 施提供 5kg/cm2 的蒸汽,全年耗用天然气 1200 万 m3,耗用 20 万吨自来水。医院采用接力式方式供热, 对热网进行地域性管理,分四大供热区。其中冬季暖气的用气量很大,据此设计了基于 CAN 现场总 线的分布式锅炉蒸汽热网智能监控系统。现场应用表明:该楼宇自动化系统具有抗干扰能力强,现场 组态容易,网络化程度高,人机界面友好等特点。 7.24.4 CAN总线关键特性参数 CAN 总线有如下基本特点: ◎ 废除传统的站地址编码,代之以对通信数据块进行编码,可以多主方式工作; ◎ 采用非破坏性仲裁技术,当两个节点同时向网络上传送数据时,优先级低的节点主动停止数 据发送,而优先级高的节点可不受影响继续传输数据,有效避免了总线冲突; ◎ 采用短帧结构,每一帧的有效字节数为 8 个,数据传输时间短,受干扰的概率低,重新发送 的时间短; ◎ 每帧数据都有 CRC 校验及其他检错措施,保证了数据传输的高可靠性,适于在高干扰环境下 使用; ◎ 节点在错误严重的情况下,具有自动关闭总线的功能,切断它与总线的联系,以使总线上其 他操作不受影响; ◎ 可以点对点,一对多及广播集中方式传送和接受数据。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 466 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 CAN 总线的优点 ● 具有实时性强、传输距离较远、抗电磁干扰能力强、成本低等优点; ● 采用双线串行通信方式,检错能力强,可在高噪声干扰环境中工作; ● 具有优先权和仲裁功能,多个控制模块通过 CAN 控制器挂到 CAN-bus 上,形成多主机局部 网络; ● 可根据报文的 ID 决定接收或屏蔽该报文; ● 可靠的错误处理和检错机制; ● 发送的信息遭到破坏后,可自动重发; ● 节点在错误严重的情况下具有自动退出总线的功能; ● 报文不包含源地址或目标地址,仅用标志符来指示功能信息、优先级信息。 STM32 处理器的 CAN 总线,支持 CAN 协议 2.0A 和 2.0B。具有以下特点: — 支持CAN协议2.0A和2.0B主动模式 — 波特率最高可达1兆位/秒 — 支持时间触发通信功能 发送 — 3个发送邮箱 — 发送报文的优先级特性可软件配置 — 记录发送SOF时刻的时间戳 接收 — 3级深度的2个接收FIFO — 14个位宽可变的过滤器组-由整个CAN共享标识符列表 — FIFO溢出处理方式可配置 — 记录接收SOF时刻的时间戳 — 可支持时间触发通信模式 ‹ 禁止自动重传模式 ‹ 16位自由运行定时器 ‹ 定时器分辨率可配置 ‹ 可在最后2个数据字节发送时间戳 管理 — 中断可屏蔽 — 邮箱占用单独1块地址空间,便于提高软件效率 7.24.5 CAN总线的三种工作模式 STM32 的 CAN 一共有 3 个主要的工作模式,分别是初始化、正常和睡眠模式。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 467 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 z 初始化模式 软件通过对CAN_MCR寄存器的INRQ位置1,来请求bxCAN进入初始化模式,然后等待硬件对 CAN_MSR寄存器的INAK位置1来进行确认软件通过对CAN_MCR寄存器的INRQ位清0,来请求 bxCAN退出初始化模式,当硬件对CAN_MSR寄存器的INAK位清0就确认了初始化模式的退出。 当bxCAN处于初始化模式时,报文的接收和发送都被禁止,并且CANTX引脚输出隐性位(高电 平)。 z 正常模式 在初始化完成后,软件应该让硬件进入正常模式,以便正常接收和发送报文。软件可以通过对 CAN_MCR寄存器的INRQ位清0,来请求从初始化模式进入正常模式,然后要等待硬件对CAN_MSR 寄存器的INAK位置1的确认。在跟CAN总线取得同步,即在CANRX引脚上监测到11个连续的隐性位 (等效于总线空闲)后,bxCAN才能正常接收和发送报文。 z 睡眠模式(低功耗) 软件通过对CAN_MCR寄存器的SLEEP位置1,来请求进入这一模式。在该模式下,bxCAN的时钟 停止了,但软件仍然可以访问邮箱寄存器。当bxCAN处于睡眠模式,软件想通过对CAN_MCR寄存器 的INRQ位置1,来进入初始化式,那么软件必须同时对SLEEP位清0才行。 有2种方式可以唤醒(退出睡眠模式)bxCAN:通过软件对SLEEP位清0,或硬件检测CAN总线的 活动。 7.24.6 实验原理 — CAN 发送报文介绍 应用程序选择1个空发送邮箱;设置标识符,数据长度和待发送数据;然后对CAN_TIxR寄存器的 TXRQ位置1,来请求发送。TXRQ位置1后,邮箱就不再是空邮箱;而一旦邮箱不再为空,软件对邮 箱寄存器就不再有写的权限。TXRQ位置1后,邮箱马上进入挂号状态,并等待成为最高优先级的邮箱, 参见发送优先级。一旦邮箱成为最高优先级的邮箱,其状态就变为预定发送状态。一旦CAN总线进入 空闲状态,预定发送邮箱中的报文就马上被发送(进入发送状态)。一旦邮箱中的报文被成功发送后, 它马上变为空邮箱;硬件相应地对CAN_TSR寄存器的RQCP和TXOK位置1,来表明一次成功发送。 如果发送失败,由于仲裁引起的就对CAN_TSR寄存器的ALST位置1,由于发送错误引起的,就 对TERR位置1。 原来发送的优先级可以由标识符和发送请求次序决定: — 由标识符决定 当有超过1个发送邮箱在挂号时,发送顺序由邮箱中报文的标识符决定。根据CAN协议,标识符 数值最低的报文具有最高的优先级。如果标识符的值相等,那么邮箱号小的报文先被发送。 — 由发送请求次序决定 通过对CAN_MCR寄存器的TXFP位置1,可以把发送邮箱配置为发送FIFO。在该模式下,发送的 优先级由发送请求次序决定。该模式对分段发送很有用。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 468 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — CAN 接收报文介绍 接收到的报文,被存储在3级邮箱深度的FIFO中。FIFO完全由硬件来管理,从而节省了CPU 的处理负荷,简化了软件并保证了数据的一致性。应用程序只能通过读取FIFO输出邮箱,来读取FIFO 中最先收到的报文。 根据CAN协议,当报文被正确接收(直到EOF域的最后1位都没有错误),且通过了标识符过滤, 那么该报文被认为是有效报文。 — 接收相关的中断条件 z 一旦往FIFO存入1个报文,硬件就会更新FMP[1:0]位,并且如果CAN_IER寄存器的FMPIE位 为1,那么就会产生一个中断请求。 z 当FIFO变满时(即第3个报文被存入),CAN_RFxR寄存器的FULL位就被置1,并且如果 CAN_IER寄存器的FFIE位为1,那么就会产生一个满中断请求。 z 在溢出的情况下,FOVR位被置1,并且如果CAN_IER寄存器的FOVIE位为1,那么就会产生 一个溢出中断请求 — 标识符过滤 在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广 播的形式把报文发送给所有的接收者。(注:不是一对一通信,而是多机通信)节点在接收报文时- 根据标识符的值-决定软件是否需要该报文;如果需要,就拷贝到SRAM里;如果不需要,报文就被 丢弃且无需软件的干预。 为满足这一需求,bxCAN为应用程序提供了14个位宽可变的、可配置的过滤器组(13~0), 以便只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用 一定的CPU开销。每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成。 过滤器的模式的设置 z 通过设置CAN_FM0R的FBMx位,可以配置过滤器组为标识符列表模式或屏蔽位模式。 z 为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。 z 为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。 z 应用程序不用的过滤器组,应该保持在禁用状态。 过滤器优先级规则 z 位宽为32位的过滤器,优先级高于位宽为16位的过滤器 z 对于位宽相同的过滤器,标识符列表模式的优先级高于屏蔽位模式 z 位宽和模式都相同的过滤器,优先级由过滤器号决定,过滤器号小的优先级高 嵌入式专业技术论坛 (www.armjishu.com)出品 第 469 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 上面的例子说明了bxCAN的过滤器规则:在接收一个报文时,其标识符首先与配置在标识符 列表模式下的过滤器相比较;如果匹配上,报文就被存放到相关联的FIFO中,并且所匹配的 过滤器的序号被存入过滤器匹配序号中。如同例子中所显示,报文标识符跟#4标识符匹配, 因此报文内容和FMI4被存入FIFO。 如果没有匹配,报文标识符接着与配置在屏蔽位模式下的过滤器进行比较。 如果报文标识符没有跟过滤器中的任何标识符相匹配,那么硬件就丢弃该报文,且不会对软件有 任何打扰。 — 接收邮箱(FIFO) 在接收到一个报文后,软件就可以访问接收FIFO的输出邮箱来读取它。一旦软件处理了报文(如 把它读出来),软件就应该对CAN_RFxR寄存器的RFOM位进行置1,来释放该报文,以便为后面收到 的报文留出存储空间。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 470 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断 bxCAN占用4个专用的中断向量。通过设置CAN中断允许寄存器(CAN_IER),每个中断源都 可以单独允许和禁用。 发送中断可由下列事件产生: ─ 发送邮箱0变为空,CAN_TSR寄存器的RQCP0位被置1。 ─ 发送邮箱1变为空,CAN_TSR寄存器的RQCP1位被置1。 ─ 发送邮箱2变为空,CAN_TSR寄存器的RQCP2位被置1。 FIFO0中断可由下列事件产生: ─ FIFO0接收到一个新报文,CAN_RF0R寄存器的FMP0位不再是‘00’。 ─ FIFO0变为满的情况,CAN_RF0R寄存器的FULL0位被置1。 ─ FIFO0发生溢出的情况,CAN_RF0R寄存器的FOVR0位被置1。 FIFO1中断可由下列事件产生: ─ FIFO1接收到一个新报文,CAN_RF1R寄存器的FMP1位不再是‘00’。 ─ FIFO1变为满的情况,CAN_RF1R寄存器的FULL1位被置1。 ─ FIFO1发生溢出的情况,CAN_RF1R寄存器的FOVR1位被置1。 错误和状态变化中断可由下列事件产生: ─ 出错情况,关于出错情况的详细信息请参考CAN错误状态寄存器(CAN_ESR)。 ─ 唤醒情况,在CAN接收引脚上监视到帧起始位(SOF)。 ─ CAN进入睡眠模式。 波特率设定 CAN总线通信的难点在于 波特率的设定 ,当然如果是近距离通信,只有 几十米 那就可以忽略了, 如果几公里 波特率 位序 时序 都需要好好计算 不然通信是不成功的。 CAN控制器器只需要进行少量的设置就可以进行通信,就可以像RS232/485那样使用。其中较难设 置的部分就是通信波特率的计算。CAN总线能够在一定的范围内容忍总线上CAN节点的通信波特率的 偏差,这种机能使得CAN总线有很强的容错性,同时也降低了对每个节点的振荡器精度。 实际上,CAN总线的波特率是一个范围。假设定义的波特率是250KB/S,但是实际上根据对寄存 器的设置,实际的波特率可能为200~300KB/S(具体值取决于寄存器的设置),简单介绍一个波特率的 计算,在CAN的底层协议里将CAN数据的每一位时间(TBit)分为许多的时间段(Tscl),这些时间段包 括: A. 位同步时间(Tsync) B. 时间段1(Tseg1) C. 时间段2(Tseg2) 其中位同步时间占用1个Tscl;时间段2占用(Tseg1+1)个Tscl;时间段2占用(Tseg2+1)个Tscl,所以 CAN控制器的位时间(TBit)就是:TBit=Tseg1+Tseg2+Tsync=(TSEG1+TSEG2+3)*Tscl,那么CAN的波 特率(CANbps)就是1/TBit。 但是这样计算出的值是一个理论值。在实际的网络通信中由于存在传输的延时、不同节点的晶体 的误差等因素,使得网络CAN的波特率的计算变得复杂起来。CAN在技术上便引入了重同步的概念, 以更好的解决这些问题。这样重同步带来的结果就是要么时间段1(Tseg1)增加TSJW(同步跳转宽度 SJW+1),要么时间段减少TSJW,因此CAN的波特率实际上有一个范围: 1/(Tbit+Tsjw) ≤CANbps≤1/(Tbit-Tsjw) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 471 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 CAN有波特率的值由以下几个元素决定: A. 最小时间段Tscl; B. 时间段1 TSEG1; C. 时间段2 TSEG2; D. 同步跳转宽度 SJW 那么Tscl又是怎么计算的呢?这是总总线时序寄存器中的预分频寄存器BRP派上了用场,Tscl= (BRP+1)/FVBP。FVBP为微处理器的外设时钟。 而TSEG1与TSEG2又是怎么划分的呢?TSEG1与TSEG2的长度决定了CAN数据的采样点,这种方 式允许宽范围的数据传输延迟和晶体的误差。其中TSEG1用来调整数据传输延迟时间造成的误差,而 TSEG2则用来调 整不同点节点晶体频率的误差。但是他们由于过于灵活,而使初次接触CAN的人有点无所适从。 TSEG1与TSEG2的是分大体遵循以下规则: Tseg2≥Tscl2,Tseg2≥2TSJW,Tseg1≥Tseg2 总的来说,对于CAN的波特率计算问题,把握一个大的方向就行了,其计算公式可了规结为: BitRate = Fpclk/( (BRP+1) * ((Tseg1+1)+(Tseg2+1)+1) 7.24.7 硬件设计 在神舟 III 号 STM32 开发板中,我们使用了处理器 STM32F103ZET6 的 CAN 外扩 TI 的 VP230 CAN 总线收发芯片来实现 CAN 总线接口。 相关硬件电路如下: 其中 VP230 是 TI 公司推出的 3.3V CAN 总线收发器。它具有如下特性: — 工作电压为 3.3V — 满足 HBM 模式 16KV 的 ESD 防护 — 允许总线上最到 120 个节点 — 符合 ISO 11898 标准要求 — 具有过热关断保护功能 嵌入式专业技术论坛 (www.armjishu.com)出品 第 472 页,共 788 页 VP230 的逻辑框图如下: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 管脚功能如下: 7.24.4 软件设计 时钟使能配置 在本实验中,我们分别通过轮询和中断两种方式,测试CAN总线的环回,并通过LED灯只是CAN 总线环回结果。因此,我们使用到的硬件资源有LED灯,CAN1总线接口,在使用这些资源之前,我 们需要先使能这么资源模块的时钟,具体代码如下: — CAN 总线中断配置 在本实验中,我们通过分别利用轮询和中断方式进行CAN的环回(loopback)实验,因此,我们 需要设置CAN1接口的接收终端及其优先级,在本例程中,设置中断组1个,CAN1的子优先级级为0, 相关代码如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 473 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — LED 灯配置 在神舟III号STM32开发板中,4个LED灯由GPIOF6~9这四个GPIO管脚控制,当GPIO输出低电平 时,LED灯亮,反之,LED灯熄灭,为了使用LED灯,我们需要将神舟III号LED占用的GPIO初始化为 推挽输出模式,相关代码如下: 神舟III号LED灯使用的GPIO接口定义 神舟III号LED灯使用的GPIO接口初始化 嵌入式专业技术论坛 (www.armjishu.com)出品 第 474 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 轮询方式CAN总线环回测试 在本实验中,CAN环回实验,分成中断和轮询两种模式进行测试,其中轮询方式的CAN接口初始 化和测试主要是由TestStatus CAN_Polling(void)函数实现的。 在这个函数中,我们首先对CAN1接口进行配置,包括bus-off管理,wake-up模式设置等等, 其 中CAN_Init函数根据CAN_InitStruct中指定的参数初始化CAN寄存器,相关代码如下: CAN_InitStruct结构体的成员说明见下表 CAN_TTCM CAN_ABOM CAN_AWUM CAN_NART CAN_RFLM CAN_TXFP CAN_MODE CAN_SJW CAN_BS1 CAN_BS2 CAN_Prescaler CAN_TTCM用来使能或去使能时间触发通讯模式 CAN_ABOM用来使能或者去使能自动离线管理 CAN_AWUM用来使能或者去使能自动唤醒模式 CAN_NART用来使能或者去使能非自动重传模式 CAN_RFLM用来使能或者去使能FIFO锁定模式 CAN_TXFP用来使能或者去使能发送FIFO优先级 设置CAN工作模式,可设置为正常工作模式(CAN_Mode_Normal) 静默模式(CAN_Mode_Silent),环回模式( CAN_Mode_LoopBack) 和静默环回模式(CAN_Mode_Silent_LoopBack) 定义重新同步跳跃宽度,即每位中可以延长或缩短多少个时间单位 的 上 限 , 可 设 置 为 1 ~ 4 个 时 间 单 位 ( CAN_SJW_1tq ~ CAN_SJW_4tq) 设 定 时 间 段 1 的 时 间 单 位 数 目 , 可 设 置 为 1 ~ 16 个 时 间 单 位 (CAN_BS1_1tq~ CAN_BS1_16tq)。 设 定 时 间 段 2 的 时 间 单 位 数 目 , 可 设 置 为 1 ~ 16 个 时 间 单 位 (CAN_BS1_1tq~ CAN_BS1_16tq)。 设定一个时间单位的长度,它的范围是1~1024 嵌入式专业技术论坛 (www.armjishu.com)出品 第 475 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在 完 成 CAN 的 基 本 参 数 配 置 以 后 , 我 们 还 需 要 对 滤 波 器 的 参 数 进 行 配 置 , 这 个 主 要 是 通 过 CAN_FilterInit函数实现的,相关代码如下: CAN_FilterNumber CAN_FilterMode CAN_FilterScale CAN_FilterIDHigh CAN_FilterIDLow CAN_FilterMaskIDHigh CAN_FilterMaskIDLow CAN_FilterFIFOAssignment CAN_FilterActivation 指定待初始化的过滤器,它的范围是1到13 指定过滤器将被初始化的模式,可设置为标识符屏蔽位模式 ( CAN_FilterMode_IdMask ) 或 者 标 识 符 列 表 模 式 (CAN_FilterMode_IdList) 过滤器位宽,可设置为2个16位过滤器(CAN_FilterScale_Two16bit) 或者1个32位过滤器(CAN_FilterScale_One32bit)。 用来设定过滤器标识符(32位位宽时为其高段位,16位宽时为第一 个)。它的范围是0x0000到0xFFFF。 用来设定过滤器标识符(32位位宽时为其低段位,16位宽时为第二 个)。它的范围是0x0000到0xFFFF。 用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其高 段位,16位宽时为第一个)。它的范围是0x0000到0xFFFF。 用来设定过滤器屏蔽标识符或者过滤器标识符(32位位宽时为其低 段位,16位宽时为第二个)。它的范围是0x0000到0xFFFF。 设置指向过滤器的FIFO(0或者1) 使能或者去使能过滤器 前面,我们完成了CAN总线接口的参数配置和滤波器配置,正常情况下,我们就可以使用CAN总线接 口了,在接下来,我们来看一下另两个非常重要的函数CAN_Transmit()和CAN_Receive(),如何发 送和接收一个正确格式的CAN帧。 在我们的例程中,CAN_Transmit()相关的代码为 它的相关参数说明如下: StdId 用来设定标准标识符。可设置为0到0x7FF ExtId 用来设定扩展标识符,可设置为0到0x3FFFF IDE 用来设定消息标识符的类型,可设置为使用标准标识符(CAN_ID_STD) 或者使用标准标识符+扩展标识符(CAN_ID_EXT) RTR 设定待传输消息的帧类型,可设置为数据帧(CAN_RTR_DATA)或者远 程帧(CAN_RTR_REMOTE) DLC 用来设定带传输消息的帧长度。取值范围0到0x8 Data[8] 待传输的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 476 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在调用Transmit发送一帧数据后,程序通过CAN_TransmitStatus()函数,检查CAN数据帧是否正 常传输,待进入传输状态以后,由于是采用LoopBack方式,数据应该马上环回回接收侧,因此程序接 下来又调用CAN_MessagePending()检查CAN接口的挂号信息数据,大于等于1表示接收到的新的数 据,调用CAN_Receive函数进行处理。相关代码为 它的相关参数说明如下: StdId 用来设定标准标识符。可设置为0到0x7FF ExtId 用来设定扩展标识符,可设置为0到0x3FFFF IDE 用来设定消息标识符的类型,可设置为使用标准标识符(CAN_ID_STD) 或者使用标准标识符+扩展标识符(CAN_ID_EXT) RTR 设定待传输消息的帧类型,可设置为数据帧(CAN_RTR_DATA)或者远 程帧(CAN_RTR_REMOTE) DLC 用来设定带传输消息的帧长度。取值范围0到0x8 Data[8] 待传输的数据 FMI 设定消息将要通过的过滤器索引 至此,就实现了一个CAN总线的LoopBack模式的数据收发,在例程中,还对接收的数据的正确性进行 了一系列的判断,最终确认接收到的数据是否出现错误。并返回对应的状态。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 477 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断方式CAN总线环回测试 前面,我们分析了CAN总线环回实验的轮询模式的具体实现过程,接下来,我们一起分析一下, 中断模式下的CAN总线的环回具体实现过程。这个主要是在CAN_Interrupt(void)函数实现的。 首先,和轮询模式一样,我们也需要通过利用CAN_Init函数和CAN_FilterInit函数初始化CAN接口 和滤波器参数。 主要的不同是,在晚上上述初始化以后,我们需要使用CAN FIFO的中断,并完成对应的中断服 务程序。 在主程序中,开启了FIFO的中断响应使能以后,程序调用了CAN_Transmit函数发送CAN数据帧,由 于CAN工作与环回模式,发送的数据帧环回回CAN接口,在中断服务程序中,对接收的帧进行处理。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 478 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 注意函数CAN_Interrupt(void)的最后要关中断呢? 因为一旦往FIFO存入1个报文,硬件就会更新FMP[1:0]位,并且如果CAN_IER寄存器的FMPIE位 为1,那么就会产生一个中断请求。所以中断函数执行完后就要清除FMPIE标志位。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 479 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 中断服务程序位于stm32f10x_it.c文件中,具体的函数实现为 当FIFO产生中断时,处理器将自动进入中断服务程序。并对数据正确性进行判断,并返回对应的状态。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 480 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.24.5 下载与测试 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 7.24.6 实验现象 首先将固件分别下载到神舟III号STM32开发板,上电运行开发板,正常情况下,LED指示灯指示 程序运行结果。 现象 含义操作 DS1亮 DS2亮 DS3亮 DS4亮 轮询模式CAN总线接收成功 中断模式CAN总线接收成功 轮询模式CAN总线接收失败 中断模式CAN总线接收失败 7.25 SPI FLASH读写实验 本节将利用SPI来实现对神舟III号板载的FLASH(W25X16)的读写,并将结果通过串口显示在 PC机上。后续升级,便将显示结果从LCD屏上显示出来。 7.25.1 SPI FLASH(W25X16)读写程序实验的意义与作用 SPI总线是Motorola公司推出的三线同步接口,主要应用在FLASH,EEPROM以及一些数字通信中。 神舟III号硬件上使用到SPI接口的有:触摸屏,音频DA芯片PCM1770,W25X16,ENC28J60以太网芯 片以及2.4G无线模块。 SPI总线接口作为一种非常基本的外设接口,但是其应用却是很广泛。通过本例程SPI对W25X16 的读写实验,让大家简单了解SPI的通信原理。 7.25.2 SPI的介绍 什么是 SPI SPI(Serial Peripheral Interface——串行外设接口)总线是 Motorola 公司推出的一种同步串行外设接 口,它用于 MCU 与各种外围设备以串行方式进行通信。 SPI 的通信方式 SPI 用于 MCU 与各种外围设备以串行方式进行通信(8 位数据同时同步地被发送和接收),系统 可配置为主或从操作模式。是一种高速的,全双工,同步的通信总线 SPI 的连接方式 SPI 是一个环形总线结构,在芯片的管脚上只占用四根线,节约了芯片的管脚,由串行时钟线 (SCK)、主机输入/从机输出数据线 MISO、主机输出/从机输入数据线 MOSI 和低电平有效的从机选 择线 CS(NSS)。构成,其时序其实很简单,主要是在 SCK 的控制下,两个双向移位寄存器进行数据 交换。在 SPI 接口中,数据的传输只需要 1 个时钟信号和 2 条数据线。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 481 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 MISO: 主设备数据输入,从设备数据输出。 MOSI: 主设备数据输出,从设备数据输入。 SCK: 时钟信号,由主设备产生。 CS(NSS): 从设备选择。这是一个可选的引脚,用来选择主/从设备。它的功能是用来作为“片 选引脚”,让主设备可以单独地与特定从设备通讯,避免数据线上的冲突。从设备的NSS引脚可以 由主设备的一个标准I/O引脚来驱动。一旦被使能(SSOE位),NSS引脚也可以作为输出引脚,并在 SPI处于主模式时拉低;此时,所有的SPI设备,如果它们的NSS引脚连接到主设备的NSS引脚,则 会检测到低电平,如果它们被设置为NSS硬件模式,就会自动进入从设备状态。当配置为主设备、 NSS配置为输入引脚(MSTR=1,SSOE=0)时,如果NSS被拉低,则这个SPI设备进入主模式失败状 态:即MSTR位被自动清除,此设备进入从模式。 SPI 的内部结构 SPI 内部结构简明图 从图中可以看出,主机和从机都有一个串行移位寄存器,主机通过向它的 SPI 串行寄存器写入一 个字节来发起一次传输。寄存器通过 MOSI 信号线将字节传送给从机,从机也将自己的移位寄存器中 的内容通过 MISO 信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读 操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一 个字节,就必须发送一个空字节来引发从机的传输。 SPI 总线的特点 SPI 主要特点有: 可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断 嵌入式专业技术论坛 (www.armjishu.com)出品 第 482 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 标志;写冲突保护;总线竞争保护等。 由于 SPI 系统总线只需 3~4 位数据线和控制线即可扩展具有 SPI 的各种 I/O 器件,而并行总线扩 展方法需 8 根数据线、8~16 位地址线、2~3 位控制线,因而 SPI 总线的使用可以简化电路设计,省 掉了很多常规电路中的接口器件,提高了设计的可靠性。 SPI 总线的特性 STM32集成的SPI接口特征如下: ● 3线全双工同步传输 ● 带或不带第三根双向数据线的双线单工同步传输 ● 8或16位传输帧格式选择 ● 主或从操作 ● 支持多主模式 ● 8个主模式波特率预分频系数(最大为fPCLK/2) ● 从模式频率 (最大为fPCLK/2) ● 主模式和从模式的快速通信 ● 主模式和从模式下均可以由软件或硬件进行NSS管理:主/从操作模式的动态改变 ● 可编程的时钟极性和相位 ● 可编程的数据顺序,MSB在前或LSB在前 ● 可触发中断的专用发送和接收标志 ● SPI总线忙状态标志 ● 支持可靠通信的硬件CRC ─ 在发送模式下,CRC值可以被作为最后一个字节发送 ─ 在全双工模式中对接收到的最后一个字节自动进行CRC校验 ● 可触发中断的主模式故障、过载以及CRC错误标志 ● 支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求 时钟信号的相位和极性 SPI_CR寄存器的CPOL和CPHA位,能够组合成四种可能的时序关系。CPOL(时钟极性)位控制在 没有数据传输时时钟的空闲状态电平,此位对主模式和从模式下的设备都有效。如果CPOL被清’0’, SCK引脚在空闲状态保持低电平;如果CPOL被置’1’,SCK引脚在空闲状态保持高电平。 如果CPHA(时钟相位)位被置’1’,SCK时钟的第二个边沿(CPOL位为0时就是下降沿,CPOL位为’1’ 时就是上升沿)进行数据位的采样,数据在第二个时钟边沿被锁存。如果CPHA位被清’0’,SCK时钟的 第一边沿(CPOL位为’0’时就是上升沿,CPOL位为’1’时就是下降沿)进行数据位采样,数据在第一个时 钟边沿被锁存。 SPI总线工作方式 根据CPOL时钟极性和CPHA时钟相位的组合,选择数据捕捉的时钟边沿,SPI接口有四种不同的 数据传输时序。下图显示了SPI传输的4种CPHA和CPOL位组合。此图可以解释为主设备和从设备的 SCK脚、MISO脚、MOSI脚直接连接的主或从时序图。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 483 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 CPOL时钟极性和CPHA时钟相位的组合选择数据捕捉的时钟边沿。上图显示了SPI传输的4种 CPHA和CPOL位组合。此图可以解释为主设备和从设备的SCK脚、MISO脚、MOSI脚直接连接的主或 从时序图。 注意: 1. 在改变CPOL/CPHA位之前,必须清除SPE位将SPI禁止。 2. 主和从必须配置成相同的时序模式。 3. SCK的空闲状态必须和SPI_CR1寄存器指定的极性一致(CPOL为’1’时,空闲时应上拉SCK为高 电平;CPOL为’0’时,空闲时应下拉SCK为低电平)。 4. 数据帧格式(8位或16位)由SPI_CR1寄存器的DFF位选择,并且决定发送/接收的数据长度。 数据帧格式 根据SPI_CR1寄存器中LSBFIRST位,输出数据位时可以MSB在先也可以LSB在先。根据SPI_CR1 寄存器的DFF位,每个数据帧可以是8位或是16位。所选择的数据帧格式对发送和/或接收都有效。 关于STM32的SPI详细资料请详见《【中文】STM32F系列ARM内核32位高性能微控制器参考手册 V10_1.pdf》一文的第457页。 本例程中,我们采用STM32的SPI1作为主模式来读取外部SPI FLASH芯片(W25X16),实现读 嵌入式专业技术论坛 (www.armjishu.com)出品 第 484 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 写功能。下面简单说明SPI1部分的配置情况: 在主配置时,在SCK脚输出串行时钟。 配置步骤: a) 配置 SPI 串行时钟波特率; b) 定义数据传输和串行时钟间的相位关系。 c) 设置 8 位或 16 位数据帧格式; d) 如果需要 NSS 引脚工作在输入模式,硬件模式下,在整个数据帧传输期间应把 NSS 脚连接到 高电平,在软件模式下,需设置 SPI_CR1 寄存器的 SSM 位和 SSI 位。如果 NSS 引脚工作在 输出模式,则只需要设置 SSOE 位; e) 必须设置 MSTR 位和 SPE 位(只当 NSS 脚被连接到高电平,这些位才能保持置位)。 在这个配置中,MOSI引脚是数据输出,而MISO引脚是数据输入。 SPI芯片W25X16的介绍 W25X16是华邦公司推出的容量为16Mb,也就是2M字节的芯片,容量大小跟AT45DB161是一样 的。 W25X16芯片将2M的容量分为32个块(Block),每个块大小为64K字节,每个块又分为16个扇区 (Sector),每个扇区4K个字节。W25X16的最少擦除单位为一个扇区,也就是每次必须擦除4K个字 节。这样我们需要给W25X16开辟一个至少4K的缓存区。 W25X16的擦写周期为10000次,具有20年的数据保存期限,支持电压为2.7~3.6V,W25X16支持 标准的SPI,还支持双输出的SPI,最大SPI时钟可以到75Mhz(双输出时相当于150Mhz),详细的W25X16 的介绍,请参考“…\\神舟III号光盘\外围器件数据手册”文件下的《W25X16 SPI Flash数据手册.pdf》 7.25.3 硬件设计 神舟III号开发板载有SPI FLASH芯片W25X16,该芯片的容量为2M字节(16MBit),与AT45DB161 属于同一级别,W25X16的管脚定义如下: 其管脚含义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 485 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据以上定义,神舟III号开发板与W25X16理解的原理图如下: SPI FLASH电路原理图 7.25.4 软件设计 本例程在库文件的基础上,我们根据实际使用,还需要增加两个文件,一个是SPI外设驱动文件, 另外一个则是W25X16芯片的驱动代码。 1、我们先看SPI外设驱动文件,包括spi.c文件和spi.h头文件。对于spi.h文件,主要是头文件的声 明,以及SPI1初始化和读写一个字节的函数。而spi.c则是相关函数的具体实现,其中SPIx_init初始化 SPI1接口为主模式读取FLASH芯片。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 486 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 SPI接口读写FLASH的一个字节的函数,如下所示: 2、我们接着介绍W25X16芯片的驱动文件,包括flash.c和flash.h两个文件。其中flash.h文件的内容, 主要包括FLASH的CS,W25X16相关的一些指令设置以及flash.c文件中包括的一些函数声明,而flash.c 文件的主要内容便是关于SPI对FLASH的读操作,写操作函数,其中包括SPI读取flash ID的函数。 其中主要的几个函数是描述如下: — 获取 SPI FLASH ID 嵌入式专业技术论坛 (www.armjishu.com)出品 第 487 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — SPI FLASH 读函数 在指定地址开始读取指定长度的数据。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 488 页,共 788 页 — SPI FLASH 写函数 往指定地址写入指定长度的的数据。 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3、下面将对主函数进行简单分析。本例程还是将从串口打印信息,点灯操作,按键配置,按键扫 描,这些在之前例程中已经讲解了,在此不累赘。那么主程序中,上电初始化操作后,包括前面提到 的一些配置后,将开始读取Flash的ID,作为Flash是否存在,或是其他异常问题的判断。如果读取到ID, 说明Flash在位,否则,不在位。当Flash准备好后,我们将通过按钮1,将由SPI1接口,把提前设置好 的字符组“const u8 TEXT_Buffer[]={"神舟III号 SPI 读写访问程序"}”中的数据写到Flash W25X16中; 然后,我们通过按钮2的检测,将写到W25X16的字符组读取出来,并在串口显示出来。下面简单了解 一下代码,详细的代码设计,请详阅main()函数。 上电后,读取Flash的ID号,作为在位判断,如果不在位,则循环打印“check failed”等。否则准 备好,并提示写flash或是读flash操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 489 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 循环检测按键是否按下,根据不同的按键值,进行不同的操作。同时启动LED1灯的闪烁,表示系 统正在运行中。 7.25.5 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 490 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.25.6 实验现象 下载固件后,连接串口到PC机,按照要求设置波特率为115200,上电运行神舟III号,串口将输出 提示信息,按下USER2键,往SPI FLASH写入一串数据,按下USER1按键,将从SPI FLASH读出之前 写入的一串数据,在正常情况下,数据为“神舟III号 SPI 读写访问程序”,具体串口提示信息如下, 请按提示信息按下USER1或USER2键进行SPI FLASH读写操作。 7.26 SRAM 访问实验 7.26.1 SRAM访问实验的意义与作用 SRAM 是英文 Static RAM 的缩写,它是一种具有静止存取功能的内存,不需要刷新电路即能保存 它内部存储的数据。SRAM 的速度非常快,在快速读取和刷新时能够保持数据完整性。它的用途广泛, 用于 CPU 内部的一级缓存以及内置的二级缓存,以及一些嵌入式设备,如网络服务器以及路由器等。 而 STM32 处理器具有 FSMC(Flexible Static Memory Controller)总线,通过合适的参数配置,可 支持不同的外部存储器类型。包括 SRAM,NorFlash,Nand Flash 等。 在本实验,将介绍如何通过 STM32 处理器的 FSMC 总线访问 SRAM。 STM32F103ZET6 自带了 64K 字节的 SRAM,对一般应用来说,已经足够了,不过在一些对内存 要求高的场合,STM32 自带的这些内存就不够用了。比如跑算法或者跑 GUI 等,就可能不太够用, 所以战舰 STM32 开发板板载了一颗 1M 字节容量的 SRAM 芯片:IS62WV25616,满足大内存使用的 需求。 本章,我们将使用 STM32 来驱动 IS62WV25616,实现对 IS62WV25616 的访问控制,并测试其容 量。 7.26.2 IS62WV25616简介 S62WV25616 是 ISSI(Integrated Silicon Solution, Inc)公司生产的一颗 16 位宽 256K(256*16, 即 512K 字节)容量的 CMOS 静态内存芯片。该芯片具有如下几个特点: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 491 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 „ 高速。具有 45ns/55ns 访问速度 „ 低功耗 „ TTL 电平兼容 „ 全静态操作。不需要刷新和时钟电路 „ 三态输出 „ 字节控制功能。支持高/低字节控制 IS62WV25616 的功能框图如图所示: 图中 A0~A17 为地址线,总共 18 根地址线(即 2^18=256K,1K=1024);IO0~15 为数据线,总共 16 根数据线。CS2 和 CS1 都是片选信号,不过 CS2 是高电平有效 CS1 是低电平有效;OE 是输出使能 信号(读信号);WE 为写使能信号;UB 和 LB 分别是高字节控制和低字节控制信号; 在 STM32 神舟 III 号中,使用的 SRAM 的 IS61LV25616 这一有 ISSI 公司推出的 SRAM 芯片。 IS61LV25616 容量为 4M 比特(如果需要配置更大容量的 SRAM,可以直接替换为 IS61LV51216, IS61LV51216 与 IS61LV25616 完全 pin-to-pin 兼容,而容量确是原来的一倍,达到 8M 比特)。 IS61LV25616 的管脚定义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 492 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在神舟III号中,通过FSMC总线与IC61LV25616LL SRAM连接,具体电路如下: 在上图中,我们可以看到以下信息 从原理图可以看出,IS62WV25616同STM32的连接关系: A[0:18]接FMSC_A[0:18] D[0:15]接FSMC_D[0:15] UB接FSMC_NBL1 LB接FSMC_NBL0 OE接FSMC_NOE WE接FSMC_NWE 嵌入式专业技术论坛 (www.armjishu.com)出品 第 493 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 CE接FSMC_NE3 本章,我们使用FSMC的BANK1 区域3来控制IS62WV25616,关于FSMC的详细介绍,在之前的LCD章节 已经有过详细介绍,我们采用的是读写不同的时序来操作TFTLCD模块(因为TFTLCD模块读的速度比写 的速度慢很多),但是在本章,因为IS62WV25616的读写时间基本一致,所以,我们设置读写相同的时 序来访问FSMC。关于FSMC的详细介绍,请大家看《STM32参考手册》。 IS62WV25616就介绍到这,最后,我们来看看实现IS62WV25616的访问,需要对FSMC进行哪些配置。 FSMC的详细配置介绍在之前的LCD实验章节已经有详细讲解,这里就做一个概括性的讲解。步骤如下: 1)使能FSMC时钟,并配置FSMC相关的IO及其时钟使能。 要使用FSMC,当然首先得开启其时钟。然后需要把FSMC_D0~15,FSMCA0~18等相关IO口,全部配置 为复用输出,并使能各IO组的时钟。 使能FSMC时钟的方法: RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE); 对于其他IO口设置的方法前面讲解很详细,这里不做过多的讲解。 2)设置FSMC BANK1区域3。 此部分包括设置区域3的存储器的工作模式、位宽和读写时序等。本章我们使用模式A、16位宽, 读写共用一个时序寄存器。使用的函数是: void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct) 3)使能BANK1区域3。 使能BANK的方法跟前面LCD实验也是一样的,这里也不做详细讲解,函数是: void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); 通过以上几个步骤,我们就完成了FSMC的配置,可以访问IS62WV25616了,这里还需要注意,在上图中, SRAM的CE管脚与FSMC_NE3连接。 查看STM参考手册可知,SRAM连接到STM32F103ZET6处理器的BANK 1 SRAM3。 因为我们使用的是BANK1的区域3,所以HADDR[27:26]=10,故外部内存的首地址为0X68000000。 z SRAM 数据宽度 从上图中可以看出,与 SRAM 连接的数据线为 FSMC_D0~D15,一共 16 位。也就是说神舟 III 号上 使用的 SRAM 为 16 位数据宽度的 SRAM。 7.26.3 STM32处理器FSMC总线简介 FSMC(Flexible Static Memory Controller,可变静态存储控制器)是 STM32 系列中内部集成 256 KB 以上 Flash,后缀为 xC、xD 和 xE 的高存储密度微控制器特有的存储控制机制。之所以称为“可变”, 是由于通过对特殊功能寄存器的设置,FSMC 能够根据不同的外部存储器类型,发出相应的数据/地 址/控制信号类型以匹配信号的速度,从而使得 STM32 系列微控制器不仅能够应用各种不同类型、 不同速度的外部静态存储器,而且能够在不增加外部器件的情况下同时扩展多种不同类型的静态存储 嵌入式专业技术论坛 (www.armjishu.com)出品 第 494 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 器,满足系统设计对存储容量、产品体积以及成本的综合要求。 4.12.1.1 FSMC优点 ①.支持多种静态存储器类型。 STM32 通过 FSMC 可以与 SRAM、ROM、PSRAM、Nor Flash 和 NandFlash 存储器的引脚直接相连。 ②.支持丰富的存储操作方法。 FSMC 不仅支持多种数据宽度的异步读/写操作,而且支持对 Nor/PSRAM/Nand 存储器的同步突发访问方式。 ③.支持同时扩展多种存储器。 FSMC 的映射地址空间中,不同的 BANK 是独立的,可用于扩 展不同类型的存储器。当系统中扩展和使用多个外部存储器时,FSMC 会通过总线悬空延迟时间参数 的设置,防止各存储器对总线的访问冲突。 ④.支持更为广泛的存储器型号。通过对 FSMC 的时间参数设置,扩大了系统中可用存储器的速 度范围,为用户提供了灵活的存储芯片选择空间。 ⑤.支持代码从 FSMC 扩展的外部存储器中直接运行。不需要首先调入内部 SRAM。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 495 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.12.1.2.FSMC内部结构 STM32 微控制器之所以能够支持Nor Flash/SRAM和Nand Flash这两类访问方式完全不同的存储器 扩展,是因为FSMC内部实际包括Nor Flash和Nand/PC Card两个控制器,分别支持两种截然不同的存 储器访问方式。在STM32 内部,FSMC的一端通过内部高速总线AHB连接到内核Cortex-M3,另一端 则是面向扩展存储器的外部总线。内核对外部存储器的访问信号发送到AHB总线后,经过FSMC转换 为符合外部存储器通信规约的信号,送到外部存储器的相应引脚,实现内核与外部存储器之间的数据 交互。FSMC起到桥梁作用,既能够进行信号类型的转换,又能够进行信号宽度和时序的调整,屏蔽 掉不同存储类型的差异,使之对内核而言没有区别。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 496 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.12.1.3. FSMC映射地址空间 FSMC 管理 1 GB 的映射地址空间。该空间划分为 4 个大小为 256 MB 的 BANK,每个 BANK 又 划分为 4 个 64 MB 的子 BANK,如下表所列。FSMC 的 2 个控制器管理的映射地址空间不同。Nor Flash 控制器管理第 1 个 BANK,Nand/PC Card 控制器管理第 2~4 个 BANK。由于两个控制器管理的存储 器类型不同,扩展时应根据选用的存储设备类型确定其映射位置。其中,BANK1 的 4 个子 BANK 拥 有独立的片选线和控制寄存器,可分别扩展一个独立的存储设备,而 BANK2~BANK4 只有一组控制 寄存器。 FSMC对每个存储块分配一个唯一的片选信号NE[4:1]。 7.26.4 实验原理 在本实验中,将SRAM挂到STM32F103ZET6的FSMC总线的Bank 3上(具体分析见4.12.4 硬件设计 此节)。 在本实验中,首先按照SRAM芯片要求,初始化好FSMC总线后,往SRAM芯片内固定地址写入一 串确定的值,然后程序读回之前写入的数据,判断写入与读出的值是否一致,通过神舟III号的LED灯 指示程序执行结果。各种灯的指示具体含义如下: LED指示灯 DS1闪烁 DS2亮 DS3亮 含义 程序正在执行过程中 写入神舟III号SRAM的数据与读出的数据一致,也就是说访问SRAM成功 写入神舟III号SRAM的数据与读出的数据不一致,也就是说访问SRAM失败 嵌入式专业技术论坛 (www.armjishu.com)出品 第 497 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.26.5 硬件设计 SRAM访问实验要用到的硬件资源有: ¾ 串口 1:串口 1 在本实验中用于打印 SRAM 访问提示信号和显示 SRAM 访问程序运行结果。 串口的输入输出实验在前面已经 进行了详细的讲解,在这里就不在重复。 具体见 4.5 串口 1 的发送与接收实验。 ¾ LED 指示灯:LED 指示灯主要用于指示 SRAM 访问程序运行状态和 SRAM 访问结果。 ¾ IC61LV25616LL SRAM 嵌入式专业技术论坛 (www.armjishu.com)出品 第 498 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.26.6 软件设计 神 舟 III 号 EEPROM 读 写 试 验 位 于 神 舟 III 号 光 盘 \ 源 码 \ STM32F10x_StdPeriph_Lib_V3.3.0.rar\ \Project\12.SRAM访问实验(神舟II号)目录。 进入12.SRAM访问实验(神舟II号)\ MDK-ARM 目录后,双击Project.uvproj可以打开工程,以下 为工程文件中主要代码的解释与说明。 4.12.5.1. FSMC的初始化 在使用SRAM之前,我们需要对SRAM使用的FSMC BANK进行参数配置,使之与SRAM芯片的要 求相符合。 在前面的硬件设计原理部分,我们可以得到一下参数。 参数 说明 存储器类型 SRAM 储存器数据宽度 16 位 使用的数据线一共 16 位,FSMC_D[0:15] 占用的 FSMC BANK BANK1 的子板块 3 硬件上与 STM32F103 的 FSMC_NE3 相连 在STM32技术参考手册中,针对FSMC引脚的GPIO模式配置,已经进行了说明。具体FSMC总线 的配置如下: 说明 ,上表是整个FSMC接口的引脚的初始化配置说明,实际初始化时可只初始化具体存储器使 用的FSMC引脚。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 499 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如下为神舟III号访问SRAM时,FSMC引脚的初始化,只初始化了与SRAM连接的相关引脚。 在完成FSMC引脚的初始化以后,我们还需要配置FSMC可编程的存储器的参数。包括访问时序, 是否支持非对齐访问和等待周期管理(只针对突发模式访问PSRAM和NOR闪存)。 针对NOR 控制器,我们需要初始化下表中的参数。 对应神舟III号SRAM访问程序中,对应的存储器的参数配置程序如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 500 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 由于STM32处理器的FSMC总线支持多种存储器类型,因此,我们还需要对FSMC总线的工作模式 和参数进行设置。为了支持神舟III号的SRAM,对FSMC总线的配置程序如下: 至此,我们完成了FSMC总线的初始化。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 501 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.12.5.2. SRAM访问程序 在完成FSMC的初始化以后,我们就可以对SRAM进行读写操作了。在本实验中,首先按照SRAM 芯片要求,初始化好FSMC总线,往SRAM芯片内固定地址写入一串确定的值,程序再从这一地址, 读回之前写入的数据。判断写入与读出的值是否一致,通过串口和神舟III号的LED灯指示程序执行结 果。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 502 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.26.7 下载与测试 在 神舟III号光盘\编译好的固件\12.SRAM访问程序实验目录下的SRAM访问.hex文件即为前面我 们分析的SRAM访问试验编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板 中,观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 7.26.8 实验现象 将程序下载到神舟III号后,重现上电运行,正常情况下,串口打印如下信息。 同时神舟 III 号的 LED 指示灯也会指示运行结果,具体 LED 指示灯的状态及其含义如下: LED指示灯 含义 DS1闪烁 程序正在执行过程中 DS2亮 写入神舟III号SRAM的数据与读出的数据一致,也就是说访问SRAM成功 DS3亮 写入神舟III号SRAM的数据与读出的数据不一致,也就是说访问SRAM失败 嵌入式专业技术论坛 (www.armjishu.com)出品 第 503 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.27 Nor Flash访问程序实验 在提到Nor Flash时候,我们就不得不提到Nand Flash。Nor和Nand Flash是现在市场上两种主要的 非易失闪存技术。其中,Intel于1988年首先开发出Nor flash技术,彻底改变了原先由EPROM和EEPROM 一统天下的局面。紧接着,1989年,东芝公司发表了Nand flash结构,强调降低每比特的成本,更高的 性能,并且象磁盘一样可以通过接口轻松升级。 经过了十多年之后,仍然有相当多的硬件工程师分不清Nor和Nand闪存。在这里,我们首先对Nor Flash和Nand Flash从应用领域和特性等方面来认识Nor Flash与Nand Flash。 7.27.1 Nor Flash与Nand Flash的区别 4.13.1.1 性能比较 Flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写 入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。 Nand 器件执行擦除操作是十分简单的,而Nor则要求在进行擦除前先要将目标块内所有的位都写为0。 由于擦除Nor器件时是以64~128KB 的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦 除Nand器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms。执行擦除时块尺寸的不同进 一步拉大了 Nor 和 NAND之间的性能差距。 Nor Flash与Nand Flash的主要性能区别在于: ● Nor的读速度比Nand稍快一些。 ● Nand的写入速度比Nor快很多。 ● Nand的4ms擦除速度远比Nor的5s快。 ● 大多数写入操作需要先进行擦除操作。 ● Nand的擦除单元更小,相应的擦除电路更少。 4.13.1.2 接口差别 Nor flash带有SRAM接口,有足够的地址引脚来寻址,可以轻松地挂接在CPU的地址、数据总线 上,对CPU的接口要求低。可以很容易地存取其内部的每一个字节。 Nand Flash器件使用复杂的I/O口来串行地存取数据,各个产品或厂商的方法可能各不相同。8个引 脚用来传送控制、地址和数据信息。由于时序较为复杂,所以一般CPU最好集成Nand控制器。另外由 于NandFlash没有挂接在地址总线上,所以如果想用NandFlash作为系统的启动盘,就需要CPU具备特 殊的功能,如s3c2410在被选择为NandFlash启动方式时会在上电时自动读取NandFlash的4k数据到地址0 的SRAM中。如果CPU不具备这种特殊功能,用户不能直接运行NandFlash上的代码,那可以采取其他 方式,比如好多使用NandFlash的开发板除了使用NandFlash以外,还用上了一块小的NorFlash来运行启 动代码。 Nand 读和写操作采用 256 字节的板,这一点有点像硬盘管理此类操作,很自然地,基于 Nand 的 存储器就可以取代硬盘或其他块设备。 4.13.1.3 容量和成本 Nand flash 的单元尺寸几乎是 Nor 器件的一半,由于生产过程更为简单,Nand 结构可以在给定 的模具尺寸内提供更高的容量,也就相应地降低了价格。 Nor flash占据了容量为1~16MB闪存市场的大部分,而Nand flash只是用在8~128MB的产品当中, 这也说明Nor主要应用在代码存储介质中,Nand适合于数据存储,Nand 在CompactFlash、Secure Digital、 PC Cards和MMC 存储卡市场上所占份额最大。 相比起NandFlash来说,NorFlash的容量要小,一般在1~16MByte左右,一些新工艺采用了芯片叠 加技术可以把NorFlash的容量做得大一些。在价格方面,NorFlash相比NandFlash来说较高。 NandFlash生产过程更为简单,Nand结构可以在给定的模具尺寸内提供更高的容量,这样也就相应 地降低了价格。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 504 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.13.1.4 可靠性和耐用性 采用flash介质时一个需要重点考虑的问题是可靠性。对于需要扩展MTBF的系统来说,Flash 是 非常合适的存储方案。可以从寿命(耐用性)、位交换和坏块处理三个方面来比较Nor和Nand的可靠性。 ¾ 寿命(耐用性) 在Nand 闪存中每个块的最大擦写次数是一百万次,而Nor的擦写次数是十万次。Nand存储器除 了具有10比1的块擦除周期优势,典型的Nand块尺寸要比Nor器件小8倍,每个Nand存储器块在给定的 时间内的删除次数要少一些。 ¾ 位交换 所有flash 器件都受位交换现象的困扰。在某些情况下(很少见,Nand发生的次数要比Nor多),一 个比特位会发生反转或被报告反转了。一位的变化可能不很明显,但是如果发生在一个关键文件上, 这个小小的故障可能导致系统停机。如果只是报告有问题,多读几次就可能解决了。当然,如果这个 位真的改变了,就必须采用错误探测/错误更正(EDC/ECC)算法。位反转的问题更多见于Nand闪存, Nand的供应商建议使用Nand闪存的时候,同时使用EDC/ECC算法。这个问题对于用 Nand 存储多媒 体信息时倒不是致命的。当然,如果用本地存储设备来存储操作系统、配置文件或其他敏感信息时, 必须使用EDC/ECC系统以确保可靠性。 ¾ 坏块处理 Nand器件中的坏块是随机分布的。以前也曾有过消除坏块的努力,但发现成品率太低,代价太 高,根本不划算。 Nand 器件需要对介质进行初始化扫描以发现坏块,并将坏块标记为不可用。在已 制成的器件中,如果通过可靠的方法不能进行这项处理,将导致高故障率。 ¾ 易于使用 可以非常直接地使用基于Nor的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。 由于需要I/O接口,Nand要复杂得多。各种Nand器件的存取方法因厂家而异。 在使用Nand器件时,必 须先写入驱动程序,才能继续执行其他操作。向Nand 器件写入信息需要相当的技巧,因为设计师绝 不能向坏块写入,这就意味着在Nand器件上自始至终都必须进行虚拟映射。 ¾ 软件支持 当讨论软件支持的时候,应该区别基本的读/写/擦操作和高一级的用于磁盘仿真和闪存管理算法 的软件,包括性能优化。在Nor器件上运行代码不需要任何的软件支持,在Nand器件上进行同样操作 时,通常需要驱动程序,也就是内存技术驱动程序(MTD),Nand和Nor器件在进行写入和擦除操作时 都需要MTD。 使用 Nor 器件时所需要的 MTD 要相对少一些,许多厂商都提供用于 Nor 器件的更 高级软件,这其中包括 M-System的TrueFFS驱动,该驱动被Wind River System、Microsoft、QNX Software System、Symbian和Intel等厂商所采用。 驱动还用于对DiskOnChip产品进行仿真和Nand闪存的管理,包括纠错、坏块处理和损耗平衡。 Nand Flash内部结构是用与非门组成存储单元的。有非易失性,读写速度快,而且比较容易做到 大容量。目前单片Nand Flash存储容量可以达到8Gbit(1GByte)。Nor Flash有易失性,掉电不保存数据。 随机存储速度比Nand Flash 快得多。所以一般用Nor Flash 用做内存片,或者叫做数据缓冲。而Nand Flash则一般用来做存储数据用。比方说,U盘.MP3等。 4.13.1.5应用领域 Flash在嵌入式行业应用广泛,但是由于Nor Flash与Nand Flash他们的容量,性能和价格等方面的 差异,在不同的市场, Nor 的传输效率很高,在小容量时具有很高的成本效益,更加安全,不容易 出现数据故障,因此,主要应用以代码存储为主,多与运算相关,而Nand Flash由于容量可以很大, 而成本又低,它的市场份额处于不断的增长中。 在手机市场,Nor Flash主要用于存储代码和数据;而Nand Flash随着技术的发展,高速手机平台 也开始使用Nand Flash+ SDRAM架构。 在便携式消费类电子产品市场,处于成本考虑,基本上没有厂家使用Nor Flash存储器。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 505 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在PC市场,Nor Flash主要用于PC的BIOS部分,并且多为4Mb-16Mb小容量的。 7.27.2 FSMC扩展Nor Flash配置 SRAM/ROM、Nor Flash 和 PSRAM 类型的外部存储器都是由 FSMC 的 Nor Flash 控制器管理的, 扩展方法基本相同,其中 Nor Flash 最为复杂。通过 FSMC 扩展外部存储器时,除了传统存储器扩展 所需要的硬件电路外,还需要进行 FSMC 初始化配置。FSMC 提供大量、细致的可编程参数,以便能 够灵活地进行各种不同类型、不同速度的存储器扩展。外部存储器能否正常工作的关键在于: 用户根据选用的存储器型号,对配置寄存器进行合理的初始化配置。 (1)确定映射地址空间 根据选用的存储器类型确定扩展使用的映射地址空间。Nor Flash 只能选用 BANK1 中的 4 个子 BANK。选定映射子 BANK 后,即可确定以下 2 方面内容: ①硬件电路中用于选中该存储器的片选线 FSMC_NEi(i 为子 BANK 号,i=1,…,4); ②FSMC 配置中用于配置该外部存储器的特殊功能寄存器号。 (2)配置存储器基本特征 根据选用的存储器芯片确定需要配置的存储器特征,FSMC 根据不同存储器特征可灵活地进行工 作方式和信号的调整。主要包括以下方面: ①存储器类型(MTYPE)是 SRAM/ROM、PSRAM,还是 Nor FlaSh; ②存储芯片的地址和数据引脚是否复用(MUXEN),FSMC 可以直接与 AD0~AD15 复用的存储器 相连,不需要增加外部器件; ③存储芯片的数据线宽度(MWID),FSMC 支持 8 位/16 位两种外部数据总线宽度; ④对于 Nor Flash(PSRAM),是否采用同步突发访问方式(B URSTEN); ⑤对于 Nor Flash(PSRAM),NWAIT 信号的特性说明(WAITEN、WAITCFG、WAITPOL); ⑥对于该存储芯片的读/写操作,是否采用相同的时序参数来确定时序关系(EXTMOD)。 (3)配置存储器时序参数 FSMC 通过使用可编程的存储器时序参数寄存器,拓宽了可选用的外部存储器的速度范围。FSMC 的 NorFlash 控制器支持同步和异步突发两种访问方式。选用同步突发访问方式时,FSMC 将 HCLK(系 统时钟)分频后,发送给外部存储器作为同步时钟信号 FSMC_CLK。此时需要的设置的时间参数有 2 个: ①HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频; ②同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。 对于异步突发访问方式,FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据建立时 间(DATAST)和地址保持时间(ADDHLD)。FSMC 综合了 SRAM/ROM、PSRAM 和 Nor Flash 产品的 信号特点,定义了 4 种不同的异步时序模型。选用不同的时序模型时,需要设置不同的时序参数。在 实际扩展时,根据选用存储器的特征确定时序模型,从而确定各时间参数与存储器读/写周期参数指 标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出 FSMC 所需要 嵌入式专业技术论坛 (www.armjishu.com)出品 第 506 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 的各时间参数,从而对时间参数寄存器进行合理的配置。 7.27.3 Nor Flash访问实验的意义与作用 在前面,我们比较了Nor Flash和Nand Flash的区别,Nand Flash虽然在容量和成本方面比较有优势, 但是在易用性和数据安全方面,Nor Flash还是有不可替代的优势,因此Nor Flash一般用于程序存储。 Nor flash带有SRAM接口,有足够的地址引脚来寻址,可以轻松地挂接在CPU的地址、数据总线 上,对CPU的接口要求低。在本章节,我们将一起分析,如何通过STM32的FSMC接口访问Nor Flash。 7.27.4 实验原理 在本实验中,将Nor Flash挂到STM32F103ZET6的FSMC总线的板块1的子板块2上(与前一节描述 的,将SRAM挂在板块1的子板块3上类似)。。 在本实验中,首先按照Nor Flash芯片要求,初始化好FSMC总线后,往Nor Flash芯片内固定地址 写入一串确定的值,然后程序读回之前写入的数据,判断写入与读出的值是否一致,通过神舟III号的 LED灯指示程序执行结果。各种灯的指示具体含义如下: LED指示灯 含义 DS1闪烁 程序正在执行过程中 DS2亮 写入神舟III号SRAM的数据与读出的数据一致,也就是说访问SRAM成功 DS3亮 写入神舟III号SRAM的数据与读出的数据不一致,也就是说访问SRAM失败 嵌入式专业技术论坛 (www.armjishu.com)出品 第 507 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.27.5 硬件设计 NOR FLASH访问实验要用到的硬件资源有: ¾ 串口 1:串口 1 在本实验中用于打印 Nor Flash 访问提示信号和显示 Nor Flash 访问运行结果。 串口的输入输出实验在前面已经 进行了详细的讲解,在这里就不在重复。 具体见 4.5 串口 1 的发送与接收实验。 ¾ LED 指示灯:LED 指示灯主要用于指示 Nor Flash 访问程序运行状态和 Nor Flash 访问结果。 ¾ 39VF1601 NOR FLASH 4.12.4.1.硬件原理 在神舟III号中,通过FSMC总线与39VF1601 NOR Flash连接,具体电路如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 508 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在上图中,我们可以看到以下信息 z NOR FLASH 数据宽度 从上图中可以看出,与 NOR FLASH 连接的数据线为 FSMC_D0~D15,一共 16 位。也就是说神舟 III 号 上使用的 Nor Flash 为 16 位数据宽度的 Nor Flash。 z Nor Flash 的地址范围 在上图中,Nor Flash 的 CE 管脚与 FSMC_NE2 连接。将 Nor Flash 扩展到 Nor Flash 控制器管理的 BANK1 的第 2 个子 BANK。 查看STM参考手册可知,SRAM连接到STM32F103ZET6处理器的BANK 1 子板块2。 4.12.4.2.Nor Flash芯片说明 在神舟 III 号中,使用的 Nor Flash 是 SST 公司推出的 SST39VF160。它的容量为 16M 比特(如果 需要配置更大容量的 Nor Flash,可以直接替换为 SST39VF3201, SST39VF6401 等大容量的 Nor Flash, 他们与 SST39VF160 完全 pin-to-pin 兼容,而容量却更大,达到 64M 比特)。 SST39VF160 的管脚定义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 509 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.27.6 软件设计 神 舟 III 号 Nor Flash 读 写 试 验 位 于 神 舟 III 号 光 盘 \ 源 码 \ STM32F10x_StdPeriph_Lib_V3.3.0.rar\ \Project\13.Nor Flash访问实验(神舟II号)目录。 进入13.Nor Flash访问实验(神舟II号)\ MDK-ARM 目录后,双击Project.uvproj可以打开工程,以 下为工程文件中主要代码的解释与说明。 4.12.5.1. 应用STM32固件对FSMC进行初始化配置 ST 公司为用户开发提供了完整、高效的工具和固件库,其中使用 C 语言编写的固件库提供了覆 盖所有标准外设的函数,使用户无需使用汇编操作外设特性,从而提高了程序的可读性和易维护性。 在使用Nor Flash之前,我们需要对使用的FSMC BANK进行参数配置,使之与Nor Flash芯片的要 求相符合。 在前面的硬件设计原理部分,我们可以得到一下参数。 参数 说明 存储器类型 Nor 储存器数据宽度 16 位 使用的数据线一共 16 位,FSMC_D[0:15] 占用的 FSMC BANK BANK1 的子板块 2 硬件上与 STM32F103 的 FSMC_NE2 相连 在STM32技术参考手册中,针对FSMC引脚的GPIO模式配置,已经进行了说明。具体FSMC总线 的配置如下: 说明 ,上表是整个FSMC接口的引脚的初始化配置说明,实际初始化时可只初始化具体存储器使 用的FSMC引脚。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 510 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如下为神舟 III 号访问 Nor Flash,FSMC 引脚的初始化,只初始化了与 Nor Flash 连接的相关引脚。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 511 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 STM32 固件库中提供的FSMC的Nor Flash控制器操作固件,主要包括 2 个数据结构和 3 个函数。 数据结构FSMC_NorSRAMTimingInitTypeDef对应时间参数寄存器FSMC_BTR和FSMC_BWTR的结构 定义。 在完成FSMC引脚的初始化以后,我们还需要配置FSMC可编程的存储器的参数。包括访问时序, 是否支持非对齐访问和等待周期管理(只针对突发模式访问PSRAM和NOR闪存)。 针对NOR 控制器,我们需要初始化下表中的参数。 对应神舟III号Nor Flash访问程序中,对应的存储器的参数配置程序如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 512 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 FSMC_NorSRAMinitTypeDef对应特征配置寄存器FSMC_BCR的结构定义,并包含2个指向对应 BANK的FSMC_BTR和FSMC_BWTR寄存器的FSMC_NorSRAMTimingInitTypeDef结构指针。 由于STM32处理器的FSMC总线支持多种存储器类型,因此,我们还需要对FSMC总线的工作模式 和参数进行设置。为了支持神舟III号的Nor Flash,SRAM,针对上述SST39VF160芯片扩展要求,利用 固件库对FSMC总线的配置程序如下: 至此,我们完成了FSMC总线的初始化。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 513 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.12.5.2. Nor Flash访问程序 在完成FSMC的初始化以后,我们就可以对Nor Flash进行读写操作了。在本实验中,首先按照Nor Flash芯片要求,初始化好FSMC总线,往Nor Flash芯片内固定地址写入一串确定的值,程序再从这一 地址,读回之前写入的数据。判断写入与读出的值是否一致,通过串口和神舟III号的LED灯指示程序 执行结果。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 514 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.27.7 下载与测试 在 神舟III号光盘\编译好的固件\13.Nor Flash访问试验目录下的Nor Flash读写.hex文件即为前面 我们分析的Nor Flash访问试验编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发 板中,观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 7.27.8 实验现象 将程序下载到神舟III号后,重现上电运行,正常情况下,串口打印如下信息。 同时神舟 III 号的 LED 指示灯也会指示运行结果,具体 LED 指示灯的状态及其含义如下: LED指示灯 含义 DS1闪烁 程序正在执行过程中 DS2亮 写入神舟III号SRAM的数据与读出的数据一致,也就是说访问Nor Flash成功 DS3亮 写入神舟III号SRAM的数据与读出的数据不一致,也就是说访问Nor Flash失败 嵌入式专业技术论坛 (www.armjishu.com)出品 第 515 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.28 Nand Flash访问实验 7.28.1 Nand Flash访问实验的意义与作用 在Nor Flash访问实验一节,我们已经比较Nor Flash和Nand Flash的区别。Nand Flash由于在容量和 成本方面上有明显的优势,虽然它的数据安全和可靠性方面不及Nor Flash, 但是这些很大程度上,可以 在软件和驱动层来避免由于Nand Flash本身的问题导致数据的丢失。 Nand Flash主要用于数据数据存储。 Nand Flash和SRAM,Nor Flash不一样,它的数据线和地址线是复用的。操作Nand Flash,需要特 别的访问控制协议,在本章节,我们将一起分析,如何通过STM32的FSMC接口访问Nand Flash, 以及 了解Nand Flash的访问操作。 7.28.2 实验原理 4.14.2.1.FSMC扩展Nand Flash配置 SRAM/ROM、Nor Flash和PSRAM类型的外部存储器都是由FSMC的Nor Flash控制器管理的,通 过STM32处理器的FSMC访问Nand Flash之前,需要根据NAND闪存的特性初始化FSMC的NAND闪存 控制器功能、时序、数据总线宽度等参数,才能访问控制NAND闪存存储器: ● 开启或关闭存储器就绪/繁忙(Ready/Busy)信号作为FSMC的输入等待。 ● 开启或关闭存储器就绪/繁忙(Ready/Busy)信号作为FSMC的中断输入源: 中断可以以下述3种方式产生: ─ 在就绪/繁忙信号的上升沿产生中断:存储器刚刚完成一个操作,新的状态已经就绪。 ─ 在就绪/繁忙信号的下降沿产生中断:存储器开始一个新的操作。 ─ 在就绪/繁忙信号为高电平时产生中断:存储器已经就绪。 ● 选择NAND存储器的数据总线宽度:8或16位。 ● 开启或关闭ECC计算逻辑。 ● 指定ECC计算的页面大小:可以是256、256、1024、2048、4096或8192字节/页。 用户可以配置FSMC的时序分别满足NAND闪存的不同段的操作:公共段和属性段。可配置的时 序是: ● 建立时间:这是发送命令字之前地址的建立时间(以HCLK为单位),即从地址有效至开始读写 操作之间的时间。(译注:这里讲的读写操作是指对NAND内控制单元的读写,不一定是对NAND 中存储单元的操作) ● 等待时间:这是发送命令字所需要的时间(以HCLK为单位),即从NOE和NWE信号下降至上升 之间的时间。 ● 保持时间:这是发送命令字后地址保持的时间(以HCLK为单位),即从NOE和NWE信号下降至 上升至整个操作周期结束的时间。 ● 数据总线高阻时间:这个参数只在写操作时有效,它是在开始写操作后数据总线保持高阻状态 的时间(以HCLK为单位),即从地址有效至FSMC驱动数据总线的时间。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 516 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下图显示了一个典型的NAND存储器访问的不同时序。 4.14.2.2.NAND FLASH操作 操作NAND闪存存储器,需要使用特别的访问协议,所有的读写操作,需要有下述步骤: 1. 向NAND闪存存储器发送一个命令 2. 发送读或写的地址 3. 读出或写入数据 为了使用户可以方便地操作NAND闪存,FSMC的NAND存储块被划分为3个段:数据段、地址段和命 令段。 实际上,这3个段的划分反映了真实的NAND闪存存储器的结构。写入命令段的任何地址,结果 都是向NAND闪存写入命令。写入地址段的任何地址,结果都是向NAND闪存写入读写操作的地址; 根据所用NAND闪存的构造,通常需要4~5个写入地址段才能写入一个读写操作的地址。写入或读出数 据段的任何地址,结果都是写入或读出NAND的内部单元,该单元的地址是之前在地址段写入的那个 地址。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 517 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.28.3 硬件设计 在 神 舟 III 号 中 , 通 过 FSMC 总 线 与 HY27UF081G2A NAND Flash 连 接 , 具 体 电 路 如 下 : HY27UF081G2A芯片与FSMC管脚的对应关系 NAND FLASH信号 FSMC信号 管脚/端口分配 AL ALE/A17 PD11 CL CLE/A16 PD12 I/O0~7 D0~7 端口D/端口E /E NCE2 PD7 /R NOR PD4 /W NWE PD5 R/B NWAIT/INT2 PD6/PG6 信号说明 地址锁存信号 命令锁存使能 数据总线D0~7 片选使能 输出使能 写使能 就绪/繁忙信号 神舟III号中NAND的就绪/繁忙信号可选择连接至FSMC_NWAIT信号,或者FSMC_INT2信号。 如 果 NAND 的 就 绪 / 繁 忙 信 号 连 接 至 FSMC_NWAIT 管 脚 , 就 初 始 化 时 需 要 使 用 等 待 功 能 管 理 NAND闪存的操作。 如果NAND的就绪/繁忙信号连接到INT2,作为一个中断源使用,这样CPU可以在NAND闪存操作 的等待周期内执行其他的任务。把这个信号作为中断源使用时有3种用法,可以选择就绪/繁忙信号的 上升沿、下降沿或高电平触发中断。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 518 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.14.3.1.NAND Flash芯片说明 在神舟III号中,使用的NAND Flash是Hynix公司推出的HY27UF081G2A NAND Flash。它的容量 为1G比特。HY27UF081G2A的特性如下: ● NAND接口:8位总线宽度,复用的地址/数据线。 ● 页大小:(2K + 64)字节 ● 页读/编程时序: ─ 随机访问:25μs (最大) ─ 顺序访问:30ns (最小) ─ 页编程时间:200μs(典型值) HY27UF081G2A 的管脚定义如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 519 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.28.4 软件设计 神舟III号Nand Flash读写试验位于神舟III号光盘\源码\ STM32F10x_StdPeriph_Lib_V3.3.0.rar\ \Project\14.Nand Flash访问实验(神舟III号)目录。 进入13.Nand Flash访问实验(神舟III号)\ MDK-ARM 目录后,双击Project.uvproj可以打开工程, 以下为工程文件中主要代码的解释与说明。 4.14.4.1. 应用STM32固件对FSMC进行初始化配置 ST 公司为用户开发提供了完整、高效的工具和固件库,其中使用 C 语言编写的固件库提供了覆 盖所有标准外设的函数,使用户无需使用汇编操作外设特性,从而提高了程序的可读性和易维护性。 在使用Nand Flash之前,我们需要对Nand Flash使用的FSMC BANK进行参数配置,使之与Nand Flash芯片的要求相符合。 在前面的硬件设计原理部分,我们可以得到以下参数。 参数 说明 存储器类型 Nand Flash 占用的 FSMC BANK BANK2 硬件上与 STM32F103 的 FSMC_NE2 相连 储存器数据宽度 8位 一共 8 位数据线,D0~7 ECC 页大小 2048 字节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 520 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — FSMC管脚初始化 Nand Flash里面占用的GPIO管脚如下表所示: NAND FLASH信号 FSMC信号 管脚/端口分配 信号说明 AL ALE/A17 PD11 地址锁存信号 CL CLE/A16 PD12 命令锁存使能 I/O0~7 D0~7 端口D/端口E 数据总线D0~7 /E NCE2 PD7 片选使能 /R NOR PD4 输出使能 /W NWE PD5 写使能 R/B NWAIT/INT2 PD6/PG6 就绪/繁忙信号 在STM32技术参考手册中,针对FSMC引脚的GPIO模式配置,已经进行了说明。具体FSMC总线 的配置如下: 说明 ,上表是整个FSMC接口的引脚的初始化配置说明,实际初始化时可只初始化具体存储器使 用的FSMC引脚。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 521 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 如下为神舟 III 号访问 Nand Flash,FSMC 引脚的初始化,只初始化了与 Nand Flash 连接的相关引脚。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 522 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — 配置FSMC存储器时间参数 在完成FSMC引脚的初始化以后,我们还需要配置FSMC可编程的存储器的参数。STM32 固件库 中 提 供 的 FSMC 的 Nand Flash 的 初 始 化 主 要 包 括 2 个 数 据 结 构 。 数 据 结 构 FSMC_NAND_PCCARDTimingInitTypeDef对应时间参数寄存器定义。 针对NAND控制器,我们需要初始化下表中的参数。 这些参数需要根据NAND存储器的特性和STM32F10xxx的HCLK时钟计算。 根据Nand Flash存储器数据手册中访问时序参数,可以得到下述公式: 读或写访问时间是NAND存储器的片选信号,从下降沿至上升沿之间的时间,这是FSMC时序参 数的函数: 读/写访问时间 = ((SET + 1) + (WAIT + 1) + (HOLD + 1)) × HCLK 等待时间是读/写使能信号,从下降沿至上升沿之间的时间: 读/写使能信号低至高时间 = (WAIT + 1) × HCLK 对于读操作,数据总线高阻时间(HiZ)是由片选建立时间和数据建立时间衡量: 片选建立时间 – 数据建立时间 = HiZ × HCLK 保持时间参数可以在第一个公式中获得。实际上,NAND存储器的数据手册给出了写操作中片选低至 写使能高的时序,保持时间可以由此计算得出: 片选低至写使能高时间 = ((SET + 1) + (WAIT + 1)) × HCLK 为了保证正确地配置FSMC的时序,下述因素应加以考虑: z 最大读/写访问时间 z FSMC内部各部分的延迟 z 存储器内部各部分的延迟 因此,我们得到下述公式: (WAIT + 1) × HCLK = max (tWP, tRP) ((SET + 1) + (WAIT + 1)) × HCLK = max (tCS, tALS, tCLS) HOLD = max (tCH, tALH, tCLH)/HCLK 还需要满足下述公式的验证: ((SET + 1) + (WAIT + 1) + (HOLD + 1)) × HCLK = max (tRC, tWC) HiZ = (max (tCS, tALS, tCLS) – tDS)/HCLK) – 1 考虑FSMC和存储器内部各部分的延迟,这些公式变为如下形式: z WAIT需要满足: (WAIT+1+ SET + 1) = ((tCEA + tsu(Data_NE) + tv(A_NE))/HCLK) WAIT = ((tCEA + tsu(Data_NE) + tv(A_NE))/HCLK) – SET – 2 z SET需要满足 (SET + 1) = max ((tCS, tALS, tCLS) – max (tWP, tRP))/HCLK – 1 SET = (max (tCS, tALS, tCLS) – max (tWP, tRP))/HCLK – 1 嵌入式专业技术论坛 (www.armjishu.com)出品 第 523 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下表列出了NAND存储器各项参数的意义和时序。 使用上述公式、存储器时和STM32F10xxx参数,我们得到: z 地址建立时间:0x1 z 地址保持时间:0x3 z 数据建立时间:0x2 z 数据总线高阻时间:0x1 对应神舟III号Nor Flash访问程序中,对应的存储器的参数配置程序如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 524 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — 配置FSMC存储器时间参数 FSMC_NorSRAMinitTypeDef对应特征配置寄存器FSMC_BCR的结构定义,并包含2个指向对应 BANK的FSMC_BTR和FSMC_BWTR寄存器的FSMC_NorSRAMTimingInitTypeDef结构指针。对应神舟 III号中的初始化代码如下: 至此,我们完成了FSMC总线的初始化。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 525 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.14.4.2. Nand Flash访问程序 在完成FSMC的初始化以后,我们就可以对Nand Flash进行读写操作了。在本实验中,首先按照Nand Flash芯片要求,初始化好FSMC总线,读取Nand Flash ID并打印,如果Nand Flash的ID读取成功,则往 Nand Flash芯片内固定地址写入一串确定的值,程序再从这一地址,读回之前写入的数据。判断写入 与读出的值是否一致,通过串口和神舟III号的LED灯指示程序执行结果。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 526 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.28.5 下载与测试 在 神舟III号光盘\编译好的固件\14.Nand Flash访问试验目录下的Nand Flash读写.hex文件即为前 面我们分析的Nand Flash访问试验编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号 开发板中,观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 7.28.6 实验现象 将程序下载到神舟III号后,重现上电运行,正常情况下,串口打印如下信息。 同时神舟 III 号的 LED 指示灯也会指示运行结果,具体 LED 指示灯的状态及其含义如下: LED指示灯 含义 DS1闪烁 程序正在执行过程中 DS2亮 写入神舟III号SRAM的数据与读出的数据一致,也就是说访问SRAM成功 DS3亮 写入神舟III号SRAM的数据与读出的数据不一致,也就是说访问SRAM失败 DS4亮 没有读到Nand Flash的ID,或者ID不正确 嵌入式专业技术论坛 (www.armjishu.com)出品 第 527 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.29 2.4G无线模块实验 7.29.1 2.4G无线模块通讯实验的意义与作用 现实生活中,无线通信到处存在,手机、电视、无线遥控以及卫星等等。很多爱好者非常期望了 解无线通信时如何实现的?从信号的编码,信道传输,信号编码以及传输过程中,根据距离控制发送 功率等等?以下我们将简单了解这一系列的实现过程。 7.29.2 试验原理 首先我们简单了解nRF24L01无线模块的特点以及工作原理。 nRF24L01无线模块,主要芯片是nRF24L01,其特点如下: — 采用 GFSK 方式调制,数据传输率为 1Mb/s 或者 2Mb/s; — 具有自动应答和自动再发射功能; — 125 个频道,可以满足多点通信; — 具有 CRC 校验; — 低电压供电:1.9V~3.6V; nRF24L01内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块。其功耗低,在以-6dBm 功率发射时,工作电流只有9mA;而接收时,工作电流只有12.3mA。接下来,我们一起了解nRF24L01 的收发原理。 发送数据时,首先将nRF24L01配置为发送模式;接着把发送地址和发送数据按照时序要求经过SPI 总线写入nRF24L01缓存区,发送数据必须在SPI片选CSN为低时,连续写入。而发送地址在发射时写 入一次即可,然后使能管脚置高并保持10uS以上,同时延迟130uS后发送数据;如果开启自动应答功 能时,nRF24L01在发送数据后就进入接收模式,接收应答信号。若收到应答,则表示此次通信成功; 若没有收到应答,就自动重新发射该数据(自动重启功能需开启)。当发送成功后,IRQ中断标志变 低,通过SPI通知处理器。在一次发送成功后,如果发送堆栈中有数据而且使能为高时,则进入下一 次发射;否则进入空闲模式。 在接收数据时,先将nRF24L01设置为接收模式,接着延迟130uS进入接收状态等待数据的到来。 当接收检测到有效的地址和CRC时,就将数据包存储在接收堆栈中,同时中断标志位IRQ置低,通知 处理器取数据。如果开启自动应答,接收方同时接入发射状态,回传应答信号。直到接收结束,便将 使能关闭,进入空闲模式。 关于nRF24L01的配置以及模式选择等详细资料介绍,请参考nRF24L01的详细资料。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 528 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.29.3 硬件设计 2.4G无线模块的通信,处理器通过SPI总线控制nRF24L01模块。在上电后先检测nRF24L01模式 是否在位。如果在位,便提示选择nRF24L01模块的工作模式:发送或接收。硬件设计如下: GPIO 管脚与 2.4G 无线模块 nRF24L01 管脚对应关系 nRF24L01 GPIO管脚 PCB管脚 SPI信号 管脚 说明 SCK PB14 5 SPI2_SCK SPI2接口信号 MISO PB13 7 SPI2_MISO MOSI PB15 6 SPI2_MOSI CE PC5 3 —— 由 于 SPI2 上 除 了 与 2.4G 无 线 模 块 nRF24L01X 相连以外,还与音频 DA 芯 片 PCM1770 以及 TFT 的触摸芯片相连, 而 SPI2 本身只有一根 CS 信号,因此在 这 里 使 用 PC5 作 为 2.4G 无 线 模 块 nRF24L01 的 SPI2 接口的 CS 信号。 CSN PF10 4 —— 2.4G无线模块nRF24L01的模块选择信号 IRQ PG15 8 2.4G 无线模块 nRF24L01 的中断输出信 号 注意:由于硬件资源的限制,PG15 除了 与 2.4G 无线模块 nRF24L01 模块的中断 输出连接外,还与 LCD 模块上的 SD 卡 片选信号相连,因此在使用神舟 III 号时, 2.4G 无线模块 nRF24L01 与屏上的 SD 卡不能同时使用。 GND —— 1 —— 地信号 VCC —— 2 —— 电源输入 嵌入式专业技术论坛 (www.armjishu.com)出品 第 529 页,共 788 页 而2.4G无线模块管脚定义如下。 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 请用随神舟III号STM32开发板配送的杜邦线连接2.4G模块与板上的2.4G无线模块的座,具体连接对应 关系如下。 nRF24L01无线模块 神舟III号2.4G模块扩展座 信号名 1 1 GND 2 2 VCC 3 3 PC5 4 4 PF10 5 7 PB13 6 6 PB15 7 5 PB14 8 8 PG15 嵌入式专业技术论坛 (www.armjishu.com)出品 第 530 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.29.4 软件设计 本例程的试验思想是借用两块带有2.4G无线模块nRF24L01的神舟III号开发板,上电初始化检测 nRF24L01模块是否在位,如果没有在位,则提示检查nRF24L01无线模块的连接情况;如果在位,则 提示选择nRF24L01工作模式:发送或者接收,在开发板上USER1按键和USER2按键分别对应着接收 模式和发送模式。通过选择USER1或USER2按键,进行无线的通信过程。而对于按键的初始化及按键 检测,在前面的章节已经详细讲解,在此不累赘。 神舟III号Nand Flash读写试验位于神舟III号光盘\源码\ STM32F10x_StdPeriph_Lib_V3.3.0.rar\ \Project\16.2.4G无线模块实验(神舟III号)目录。 进入16.2.4G无线模块实验(神舟III号)\ MDK-ARM 目录后,双击Project.uvproj可以打开工程, 以下为工程文件中主要代码的解释与说明。 — LED 与按键等初始化 主要是2.4G无线模块实验需要用到的串口,LED灯和按键的初始化。配置LED灯使用的GPIO管脚 为推挽输出模式,按键使用的GPIO管脚 配置为上拉输入模式,另外配置了串口1作为我们的输入输出 设备,波特率为115200,相关的函数如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 531 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — NRF24L01 无线模块访问接口初始化 在实验例程中,NRF24L01_Init()函数来完成无线模块使用的接口的初始化,主要是分配给 NRF24L01的CE信号以及SPI CS信号的舒适化。以及SPI2接口的初始化。 其中SPI2_Init函数是SPI2接口的初始化函数,配置SPI2的时钟频率以及工作模式,具体函数如下, 它与前面所讲的SPI FLASH(W25X16)访问的SPI接口初始化基本相同。主要区别是在SPI的工作模 式和工作频率区别,如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 532 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在完成上述程序后,我们就可以通过SPI2接口正常访问无线模块了,在实际使用无线模块收发数 据之前我们能还需要设计模块的工作模式。正常情况下,一个带有2.4G无线模块的神舟III号设置为发 送模式后,另一个带有2.4G无线模块的神舟III号开发板设置为接收模式,即可接收到前一个模块发送 的数据。因此,设置2.4G无线模块的发送接收模式,主要是通过以下两个函数RX_Mode和Tx_Mode 来设置无线模块的工作模式。相关代码如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 533 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最后,我们就可以通过NRF24L01_RxPacket和NRF24L01_TxPacket两个函数启动对应的接收和发 送流程。 7.29.5 下载与测试 在 神舟III号光盘\编译好的固件\16. 2.4G无线模块试验目录下的2.4G无线模块实验.hex文件即为 本节我们分析的实验所编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板中, 观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 534 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.29.6 实验现象 将一块带有2.4G无线模块的神舟III号开发板烧录好固件后,上电运行,按USER1按键设置为接收 模式,同时,将另一块烧录好固件的带有2.4G无线模块的神舟III号开发板,上电运行,按USER2键设 置为发送模式。 正常情况下,处于发送模式的神舟III号串口1将打印如下信息。 处于接收模式的神舟III号串口1将打印如下信息。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 535 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.30 收音机实验 这一节我们将向大家介绍如何通过STM32处理器访问TEA5767收音模块,控制收音模块,使之自 动搜台,并选择某一频段,将收到的音乐通过耳机播放出来。本节分为如下几个部分: 4.17.1 收音机实验的意思与作用内部温度传感器简介 4.17.2 硬件设计 4.17.3 软件设计 4.17.4 下载与测试 4.17.5 实验现象 7.30.1 收音机实验的意义与作用 PHILIPS的TEA5767高灵敏度收音模块芯片,这块芯片属于低电压和低功耗的全集成单芯片FM收 音产品,可完全免费调到欧洲、美国和日本的调频波段,FM频率可以支持76MHz~108MHz,收音效 果非常出色,可存储50个电台频道.数码录音和高清晰度CD直录功能(LINE-IN),可以直接通过转录 线把传统音响上的音乐以MP3格式录制到内置的闪存里,并可以将收音内容直接录制下来,同时它支 持80MHZ以下的校园网FM广播,还有实用的高清晰度CD直录功能(LINE-IN)现场录音功能等等! TEA5767内置了主频高达75MHZ的数字信号处理器,实现384KBPS/48KHZ的MD级高品质MP3音 乐文件回放,加上拥有一般MP3播放器难以企及的高保真回放线路(信噪比高达95DB,THD总谐波失 真率〈0。05%〉同时它非常省电。 通过本实验,我们将熟悉FM收音的基本实现过程,以及TEA5767模块的使用。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 536 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.30.2 实验原理 在神舟III号STM32开发板中,我们使用目前主流的模块来实现收音机功能,模块的主芯片为 TEA5767HL,这是一款有Philip针对手持应用场合推出的低功耗FM立体收音芯片。 芯片具有如下特性: — 高灵敏、低噪声高频放大器, — 收音频率:87.6MHz~108MHz,(支持频率范围在76MHz~87.5MHz 之间的校园收音频道), — LC 调谐振荡器使成本更低,RF AGC 电路 — 内置调频中频选择 ,I2C 总线控制 — 内置FM 立体声解调器 ,PLL 合成调谐解码器 — 两个可编程端口 ,软静音,SNC(立体声噪声消除) — 自适应立体声解码,自动搜索功能 — 等待模式,需要一个7.6MHz晶体 — 40 脚LQFP 封装 芯片的管脚示意图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 537 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 芯 片 本 身 通 过 三 线 接 口 进 行 访 问 , 分 别 是 WRITE/READ , CLOCK 和 DATA 三 个 管 脚 , WRITE/READ管脚上的一个上升沿表示使能数据写入如TEA5767,对应的时序示意图如下: 在进行写操作时,都是5个字节连续写入的,因此,我们在访问TEA5767模块时,应确保是5个字 节连续写入的,各个字节的含义如下: 第一个字节 第一个字节可以实现静音控制,控制搜台模式以及PLL的[13:8]这几位。 第二个字节 第二个字节,设置PLL的[7:0]位。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 538 页,共 788 页 第三个字节 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 第四个字节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 539 页,共 788 页 第五个字节 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 相反的,WRITE/READ管脚上的一个下降沿表示从TEA5767读出数据,对应的时序示意图如下: 在进行读操作时,都是5个字节连续读的,5个字节的含义如下: 第一个字节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 540 页,共 788 页 第二个字节 第三个字节 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 第四个字节 第五个字节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 541 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 神舟III号采用的是现成的TEA5767收音机模块,在访问时,我们只需要标准的I2C接口即可对他 进行访问。 7.30.3 硬件设计 在神舟III号开发板中,STM32处理器通过PB6,PB7访问TEA5767模块,PB6,PB7为STM32本身的 I2C总线GPIO管脚,我们可以通过I2C接口访问TEA5767模块,在本例程中,是通过PB6,PB7软件模式 I2C接口对模块进行的访问。 在上图中,收音机模块的ANT管脚通过电容与音频座相连,这样当耳机插入到音频座以后,就可 以作为收音的天线使用。 TEA5767模块外形图如下。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 542 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.30.4 软件设计 在本实验中,我们需要通过串口1控制收音模块的配置,包括串口1的输入输出,在本实验中,我 们采用的是串口中断模式,因此,在NVIC_Configuration()函数中完成。 — GPIO 初始化 在本实验中,使用到的硬件资源有I2C1接口有LED灯以及串口以及I2C1接口用于收音机模块的初 始化,在使用之前,我们需要对相关的GPIO初始化,对应的函数主要是GPIO_Configuration(),具体 代码如下: 在上面的代码中,将I2C1接口使用的GPIO管脚PB6,PB7初始化开漏输出模式;将LED灯使用的 GPIO 管 脚 PF6~9 初 始 化 为 推 挽 输 出 模 式 ; 将 串 口 USART1_TX 初 始 化 为 复 用 推 挽 输 出 模 式 , USART1_RX初始化为复用开漏输入模式。关于GPIO使用的更多详细介绍请参见《4.1 流水灯实验》 一节介绍。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 543 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 串口1初始化 在本实验中,串口1用于收音机实验的提示信息输出以及输入设置,在设置串口波特率以及串口 参数后,我们选择串口1使用中断模式接收键盘数据,相关代码如下。 当我们按电脑键盘上按键时,程序将检测到串口接收到数据,进入对应的串口接收中断服务程序 USART1_IRQHandler(void),判断用户输入的按键值,并设置对应的标志rec_f,以便退出中断服务 程序后,主程序依据标志执行对于那个的操作。中断服务程序具体代码如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 544 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 前面介绍了串口,LED灯等通用外围资源的设置,在接下来我们将进行TEA5767的访问,首先看 一下TEA5767的模式设置。 — TEA5767 模式设置 其中Tx_Buffer的值为TEA5767的模式设置,主要是设置TEA5767静音,处于搜台模式,具体 TxBuffer的参数含义请查看TEA5767数据手册,或者查看43.17.2实验原理的相关描述。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 545 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — TEA5767 搜台 PLL 设置 TEA5767的搜台PLL设置主要是在SetPLL函数实现的,程序语句FM_FREQ设置的频率计算PLL 值,并依据串口接收中断服务程序中的设置的rec_f状态标志变量的值 ,控制收音模块启动搜台或者 只是设置搜台的频率而不改变TEA5767的工作模式,具体代码如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 546 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — 主程序 在主程序中,只要检测到电脑上键盘有输入按键,就将依据中断服务程序中设置的状态,执行相 应的程序。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 547 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.30.5 下载与测试 在 神舟III号光盘\编译好的固件\17. 收音机试验目录下的收音机实验.hex文件即为本节我们分析 的实验所编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板中,观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 548 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.30.6 实验现象 将程序下载到神舟III号后,按如下连接好硬件: 1. 将耳机插入到神舟III号的J27(收音机音频接口)中; 2. 用随板配置的串口线连接神舟III号串口1与电脑串口,打开超级终端,按如下参数配置串口。 上电运行,串口1将打印如下信息: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 549 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 按照串口提示的信息,即可执行对应的操作,如按键盘上的S,可以开始搜台,1P,可以选择第 一个频道(注意:播放选定频道之前需要先搜台)。以下为一些操作效果图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 550 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.31 网口程序实验 7.31.1 ENC28J60网口程序实验的意义与作用 以太网是应用最为广泛的局域网,包括标准的以太网(10Mbit/s)、快速以太网(100Mbit/s)、千兆 (1000Mbit/s)以太网和 10G(10Gbit/s)以太网,采用的是 CSMA/CD 访问控制法,它们都符合 IEEE802.3 规范。 在本实验中使用的 ENC28J60 是一款 SPI 接口的以太网控制芯片来实现 10M 以太网,对那些没有 集成以太网控制器的处理器或者微控制器来说,只需要一个 SPI 接口或者用 GPIO 模拟一个 SPI 接口, 就可以通过外扩 ENC28J60 实现标准的 10M 以太网。通过本实验,我们将了解以太网的一些基本知识, 掌握如何使用 ENC28J60 设计以 10M 以太网接口,使我们以后设计的产品功能更丰富,使用更方便。 7.31.2 实验原理 以太网最早由 Xerox(施乐)公司创建,在 1980 年,DEC、lntel 和 Xerox 三家公司联合开发成为 一个标准。以太网是应用最为广泛的局域网,包括标准的以太网(10Mbit/s)、快速以太网(100Mbit/s)和 10G(10Gbit/s)以太网,采用的是 CSMA/CD 访问控制法,它们都符合 IEEE802.3。 IEEE802.3 规定了包括物理层的连线、电信号和介质访问层协议的内容。以太网是当前应用最普 遍的局域网技术。它很大程度上取代了其他局域网标准,如令牌环、FDDI 和 ARCNET。历经 100M 以太网在上世纪末的飞速发展后,目前千兆以太网甚至 10G 以太网正在国际组织和领导企业的推动下 不断拓展应用范围。 常见的 802.3 应用为: — 10M: 10base-T (铜线 UTP 模式) — 100M: 100base-TX (铜线 UTP 模式) — 100base-FX(光纤线) — 1000M: 1000base-T(铜线 UTP 模式) 在神舟 III 号中,使用 SPI 接口的 ENC28J60 以太网控制器实现 10M 以太网功能,ENC28J60 是 MicrochipTechnology(美国微芯科技公司)近期推出的 28 引脚独立以太网控制器。符合 IEEE802.3 协议,而且只有 28 引脚,既能提供相应的功能,又可以大大简化相关设计,减小空间。 ENC28J60 与 STM32F103ZET6 处理器通过 SPI1 连接访问,支持 10Mbps。STM32F103ZET6 通过 SPI1 接口发送命令,访问 ENC28J60 的寄存器或读写接收/发送缓冲区,完成相关操作。复位也可通过 SPI1 接口由软件实现,软件复位不影响 RESET 引脚的状态。 ENC28J60 是极具特色的独立以太网控制器:SPI 接口使得小型单片机也能具有网络连接功能;集 成 MAC 和 PHY 无需其他外设;具有可编程过滤功能,可自动评价、接收或拒收多种信息包,减轻了 主控单片机的处理负荷;内部继承可编程的 8KB 双端口 SRAM 缓冲器,操作灵活方便。不足之处为 仅支持 10BASET。 在本实验中,我们实现了 HTTP 网页访问,支持平行交叉网线自适应,一根网线就可以很方便的 与路由器或 PC 连接,连接后可以通过网络访问和控制板上的资源,从而实现以太网远程控制功能。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 551 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.31.4 硬件设计 在神舟 III 号开发板上,使用了 ENC28J60 SPI 以太网变压器以及 HR911105A 集成变压器的 RJ45 接头来实现 10M 以太网口。 ENC28J60 是一款在嵌入式系统中应用的极为普遍的 SPI 接口以太网控制器。它具有如下特性: — IEEE802.3 兼容的以太网控制器 — 接收器和冲突抑制电路 — 支持一个带自动极性检测和校正的 10BASE-T 端口 — 支持全双工和半双工模式 — 可编程在发生冲突事自动重发 — 可编程填充和 CRC 生成 — 可编程自动拒绝错误数据包 — 最高速度可达 10Mb/s 的 SPI 接口。 神舟 III 号开发板上,处理器通过 SPI1 接口访问 ENC28J60 以太网控制器,GPIO 和接口对应关系如 下表所示: ENC28J60管脚 GPIO管脚 SPI信号 说明 /CS PA4 SPI1_NSS SPI1接口信号 SCK PA5 SPI1_SCK SO PA6 SPI1_MISO SI PA7 SPI1_MOSI /INT PC2 —— ENC28J60的中断输入 嵌入式专业技术论坛 (www.armjishu.com)出品 第 552 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ENC28J60 的硬件设计需要注意复位电路时钟振荡器,振荡器启动定时器,时钟输出引脚,变压器、 终端和其他外部器件,输入/输出电平等几个方面。 时钟振荡器 ENC28J60 需要一个 25MHz 的晶振,接在 OSC1 和 OSC2 脚上;也可由外部时钟信号来驱动。此 时 3.3V 的外部时钟接在 OSC1 脚上,OSC2 断开或者通过一个电阻接地来降低系统噪声。 振荡器启动定时器 ENC28J60 内部有一个振荡器启动时钟 OST(OscillatorStart upTimer),上电 7500 个时钟周期(300 μs),OST 期满后内部的 PHY 方能正常工作。这时不能发送或者接收报文。上位机可通过检测 ENC28J60 内部 ESTAT 寄存器中的 CLKRDY 位的状态来决定是否可设置发送或接收报文。 需要注意的是,当 ENC28J60 上电复位或者从 PowerDown 模式下唤醒时,必须检测 ESTAT 寄存器 中的 CLKRDY 是否置位。只有 CLKRDY 置位后才能发送、接收报文,访问相关寄存器。 时钟输出引脚 CLKOUT 引脚可为系统中的其他设备提供时钟源。上电后 CLKOUT 引脚保持低电平,复位结束后 OST 计数。OST 期满后,CLKOUT 输出频率为 6.25MHz 的时钟。 时钟输出功能通过 ECOCON 寄存器禁止、调整和使能。时钟输出可设置为 1、2、3、4、8 分频, 上电后默认为 4 分频。ECOCON 寄存器配置改变以后,CLKOUT 引脚有 80~320ns 的延迟(保持低电 平),然后按照设定输出固定频率的时钟信号。 软件或者 RESET 引脚上的复位信号不会影响 ECOCON 寄存器的状态。PowerDown 模式也不会影 响时钟的输出。当禁止时钟输出时,CLKOUT 引脚保持低电平。 变压器、终端和其他外部器件 为了实现以太网接口 ENC28J60,需要几个标准的外部器件:脉冲变压器、偏置电阻、储能电容 和去耦电容。 差分输入引脚(TPIN+/TPIN-),需要一个 1∶1 变比的脉冲变压器来实现 10BASET。差分输出引脚 (TPOUT+/TPOUT-),需要一个变比为 1∶1、带中心抽头的脉冲变压器。变压器需要有 2kV 或更高的 隔离能力,防静电。对变压器的详细要求请参考芯片手册第 16 章“电气特性”。每个部分都需要通过 2 个 50Ω、精度为 1%的电阻和 1 个 0.01 μF 的电容串联后接地。 笔者采用的是中山汉仁公司的集成以太网隔离变压器 RJ45 插座 HR911105A。 所有的供电引脚(VDD、VDDOSC、VDDPLL、VDDRX、VDDTX)必须接在外部的同一个 3.3V 电源上;同理,所有的地(VSS、VSSOSC、VSSPLL、VSSTX)必须接在同一个外部地上。每个供电引 脚和地之间应当接 1 个 0.1μF 的陶瓷电容去耦(电容要尽可能接近供电引脚)。 驱动双绞线接口需要较大的电流,所以电源线应尽可能宽,与引脚的连接尽可能短,以降低电源 线内阻的消耗。 输入输出电平 ENC28J60 是一个 3.3V 的 CMOS 器件,但它设计得非常容易统一到 5V 系统中去:SPI、CS、SCK、 SI 输入和 RESET 引脚一样,都可承受 5 V 电压。当 SPI 和中断输入与 3.3 V 驱动的 CMOS 输出不兼 容时,可能需要一个单向的电平转换器。74HCT08 (四与门), 74ACT125(四三态缓冲器)和许多具有 TTL 电平输入的 5 V CMOS 缓冲器芯片都可以提供所需的电平转换。 — LED 配置 LEDA 和 LEDB 引脚在复位时支持极性自动检测。既可直接驱动 LED,又可灌电流驱动。复位时 ENC28J60 检测 LED 的连接,并按照 PHLCON 寄存器的默认设置来驱动。运行过程中的 LED 极性转 换直到下一次系统复位后才能被检测到。LEDB 的连接比较特殊,在复位过程中检测它的连接,决定 如何初始化 PHCON1 寄存器的 PDPXMD 位。如果 LEDB 直接驱动 LED,则 PHCON1.PDPXMD 位被 清零,PHY 工作在半双工模式;如果 LEDB 吸收反向电流点亮 LED,则 PHCON1.PDPXMD 被置位, PHY 工作在全双工模式;如果 LEDB 没有连接,则 PHCON1.PDPXMD 复位后的值不确定。这时主控 制器必须适当设置该位,以使 PHY 工作在所需的状态(半双工或全双工)。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 553 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.31.4 软件设计 在本实验中,我们主要是学习 ENC28J60 的使用以及简单的 TCP,UDP 包的处理,使用到资源主 要有 ENC28J60,LED 灯和串口 1,在程序运行以前,我们首先需要对这些接口进行初始化。 — GPIO 接口初始化 在本节我们使用的 GPIO 接口资源主要由 LED 灯,串口以及 ENC28J60 芯片所占用的 SPI1 接口。 因此,我们在正式运行程序之前,需要对这些 GPIO 接口进行初始化,包括设置他的输入输出属性等, 相关代码如下。 串口 1 初始化 在本例程中,串口 1 用于输入输出提示信号,波特率设置为 115200,无硬件流控模式,详细代码 如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 554 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 第 555 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — SPI 接口初始化 在神舟 III 号开发板上,STM32F103ZET6 处理器通过 SPI1 接口与 ENC28J60 相连,同时 SPI1 还 和 板 载 的 SPI FLASH 连 接 , 在 前 面 的 GPIO 接 口 初 始 化 部 分 , 我 们 已 经 初 始 化 分 配 给 SPI FLASH(W25X16)的 CS 信号为高,使之在访问 ENC28J60 网口时,不会和 W25X16 产生冲突。这 SPI1_Init()函数中,主要是对 SPI1 使用的 GPIO 口进行初始化,以及 SPI1 接口的模式,速度等参数配 置,具体的程序如下: — ENC28J60 初始化 前面我们描述了 GPIO 接口,串口和 SPI1 接口的初始化。通过 SPI1 可以正常访问 ENC28J60。 Enc28j60Init 函数实现对 ENC28J60 芯片的初始化。包括 ENC28J60 的工作模式,MAC 地址设置等, 主要是通过芯片的寄存器操作,通过 enc28j60write 函数来实现,在这里就不展开分析,有兴趣的朋友 可以查看 enc28j60Init 函数与 enc28j60write 函数的具体实现。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 556 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 — WebServer 实现 在完成了上述程序以后,神舟 III 号处理器网口实验相关的硬件接口已经初始化完成,为了支持 网页访问,我们需要对一些 TCP,UTP 包进行解析,这主要是 simple_server()函数实现的。相关代码 如下: Simple_server()函数支持 ARP 和 ICMP 包的响应,这样我们在执行 ping 神舟 III 号 IP 地址时, 神舟 III 号就能做出正确的响应。相关代码如下: TCP 包处理程序,如果收到 TCP 包,且端口号为 80,则按如下程序处理。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 557 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 UDP 包处理程序,当接收到 UDP 包,且端口号为 1200,则按如下进行处理。 7.31.5 下载与测试 在 神舟III号光盘\编译好的固件\18.网口程序实验目录下的ENC28J60网口程序实验.hex文件即为 本节我们分析的实验所编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板中, 观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 558 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.31.6 实验现象 将程序下载到神舟III号后,使用网线将神舟III号连到和同一个局域网中,并确认电脑的IP与神舟 III号IP在同一个网段(注意:神舟III号确认的IP是192.168.1.15,上电时,神舟III号将通过串口1打印 其IP和MAC地址信息,以串口打印的信息为准)。上电运行神舟III号。 假设设置电脑的IP为192.168.1.15,打开电脑的命令行,执行“ping 192.168.1.15”,其中192.168.1.15 是神舟III号的IP,正常情况下,可以ping通,打印信息如下: 在IE浏览器中,输入http://192.168.1.15/SZIII ,神舟III号支持HTTP访问,可以看到如下界面。 点击上图中的开启DS1_LED可以控制神舟III号的LED灯DS1的亮灭。另外,在神舟III号的串口1会打 印相关的提示信息,包括本机IP,MAC,以及提示接收和发送的包。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 559 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.32 TFT彩色液晶屏只显示红色 本实验向大家介绍如何使用 STM32 驱动 LCD 屏,及使用触摸屏控制器检测触点坐标 7.32.1 术语解释 1) 引言 将普通图像的信息数字化后,即得到数字图像,最后转换为合适计算机处理的数字。LCD 控制器 则被用于将数字图象传输到 LCD 显示屏进行显示。所以,如果需要理解 LCD 控制器的工作原理,有 必要了解一些图象基础知识 2) 帧 显示屏所显示的一幅完整画面就是一个帧。 3) 象素 “象素”是由图像和元素这两个单词的字母所组成的,是构成数字图象的最小单位。我们若把数 字图象放大数倍,就会发现数字图象其实是由许多色彩相近的小方点所组成,这些小方点就是“象素”。 4) 分辨率 分辨率有很多种,例如打印分辨率、影像分辨率等。此处仅仅就 LCD 显示器的分辨率进行阐释。 分辨率是指显示器所能显示点数的多少,可以把整个显示器想象成是一个棋盘,而分辨率就是棋盘经 线和纬线交叉点的数目。由于屏幕上的点、线和面都是由点组成的,所以显示器可以显示的点数越多, 显示画面就越精细。 对于 LCD 显示器来说,象素的数目和分辨率在数值上相等,都等于屏幕上横向点个数和纵向点个 数的乘积。 比如 STM32 神舟系列开发板所配的 2.8 寸或者 3.2 寸液晶屏的分辨率是 240*320 的,有这么多个 点。 7.32.2 液晶彩屏原理简介 LCD,即液晶显示器,因为其功耗低、体积小,承载的信息量大,因而被广泛用于信息输出、与 用户进行交互,目前仍是各种电子显示设备的主流。 因为STM32内部没有集成专用的液晶屏和触摸屏的控制接口,所以在显示面板中应自带含有这些 驱动芯片的驱动电路(液晶屏和触摸屏的驱动电路是独立的),STM32芯片通过驱动芯片来控制液晶屏 嵌入式专业技术论坛 (www.armjishu.com)出品 第 560 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 和触摸屏。以神舟III号开发板3.2寸液晶屏(240*320)为例,它使用ILI9320或者SSD1289芯片控制液 晶屏,通过XPT2046芯片控制触摸屏。 液晶屏的控制芯片内部结构相对比较复杂,液晶屏的彩屏驱动电路最主要的是位于中间 GRAM(Graphics RAM),可以理解为显存。GRAM就好比是一个彩屏数据缓冲buffer,我们可以把大批的 显示内容以显示矩阵的形式写到buffer里,让彩屏LCD来读取buffer里的数据再由彩屏驱动芯片显示 到显示屏上,随着GRAM逐渐丰富和完善,除了显示矩阵以外还放很多的命令,GRAM中每个存储单元都 对应着液晶面板的一个像素点。它右侧的各种模块共同作用把GRAM存储单元的数据转化成液晶面板的 控制信号,使像素点呈现特定的颜色,而像素点组合起来则成为一幅完整的图像。到现在,这些驱动 /控制电路以及buffer都合起来放在一片芯片中,统一被称为driver IC,这个driver IC就是上一段 我们所说的ILI9320或者SSD1289的driver IC芯片。 7.32.3 液晶彩屏图像像素分析 TFT就是“Thin Film Transistor”的简称,一般代指薄膜液晶显示器,而实际上指的是薄膜晶体管 (矩阵)——可以“主动的”对屏幕上的各个独立的像素进行控制。对于图象产生的基本原理为:显 示屏由许多可以发出任意颜色的光线的像素组成,主要控制各个像素显示相应的颜色就可以达到目 的。在TFT LCD中一般会采用背光技术,为了能精确的控制每一个像素的颜色和亮度就需要在每一个 想色之后安装一个类似百叶窗的开关,当“百叶窗”打开时光线就可以透射过来,而“百叶窗”关上 之后,光线就无法透射。 图像数据的像素点由红(R)、绿(G)、蓝(B)三原色组成,三原色根据其深浅程度被分为0~255 个级别,它们按不同比例的混合可以得出各种色彩。如R:255,G255,B255混合后为白色。 根据描述像素点数据的长度,主要分为8、16、24及32位。如以8位来描述的像素点可表示28=256 色,16位描述的为216=65536色,称为真彩色,也称为64K色。实际上受人眼对颜色的识别能 力的限制, 16位色与12位色已经难以分辨了。 神舟王III号开发板上配带的TFT LCD屏,LCD屏为320x240分辨率,ILI9320液晶控制器液晶控制 器自带显存,其总大小为自带显存,其总大小为172800(240*320*18/8)字节。 STM32神舟王III号开发板支持2.8/3.2寸的ILI9320或SSD1289的TFT LCD,在本例程中,我们以 ILI9320控制器进行简单的介绍。 ILI9320采用的是16位控制模式,以16位描述的像素点。按照标准格式,16位的像素点的 三原色描述的位数为R:G:B =5:6:5,描述绿色的位数较多是因为人眼对绿色更为敏感 ILI9320最高能够控制18位的LCD,但为了数据传输简便,我们采用它的16位控制模式, 以16位描述的像素点。按照标准格式,16位的像素点的三原色描述的位数为R:G:B =5:6: 5,描述绿色的位数较多是因为人眼对绿色更为敏感。ILI9320控制模块的16位数据与显存间的对 应关系如下所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 561 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们且看第一种配置TRI为0,DFM任意时的图形,低5位为蓝色B,中间6位为绿色G,最高5位为 红色R;图中的是默认16条数据线时,像素点三原色的分配状况,DB1~DB5为5根线为蓝色,DB6~DB8 以及DB10~DB12六根线为绿色,DB13~DB17这五根线为红色。这样分配有D0和D9位是无效的,使得 刚好使用完整的16位。 RGB比例为5:6:5是一个十分通用的颜色标准,5+6+5=16位,表示5根线表示红色,6根线表示 蓝色,5根线表示蓝色;如黑色的编码为0x0000,白色的编码为0xffff,红色为0xf800。比如红色0xf800, 化成RGB5:6:5的二进制就是11111 000000 00000,刚好可以看到R是红色的5位数据值是11111,G 是绿色的值是000000,B是蓝色00000,因为红色寄存器内容都是1,而其他两种颜色都为0,所以最终 会显示出红色。 7.32.4 控制器命令分析 我们这里用IL9320的命令做分析,其他像SSD1289,IL9341,IL9325等都是同样的道理;下面我 们了解几个重要的指令描述,如下图红框中内容。 1)00h指令,当为读操作时,读取控制器的型号;当为写操作时,打开/关闭OSC振荡器,当写操 嵌入式专业技术论坛 (www.armjishu.com)出品 第 562 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 作设置OSC比特位为1时,开启内部振荡器;为0时,停止振荡器。然后至少等待10ms时钟稳定后, 再继续其它功能的设置。我们在代码设计中就是通过指令00h读取LCD控制器的型号,从而针对具体 型号的控制器进行初始化操作,以便于兼容各种不同系列的LCD控制器。 2)03h指令,入口模式命令。 我们重点关注的是I/D0、I/D1、AM这3个位,因为这3个位控制了屏幕的显示方向。AM控制GRAM 的更新方向:当AM=“0”,表示地址更新方向为垂直方向;当AM=“1”,表示地址更新方向为水 平方向;I/D[1:0]:当更新一个显示数据时,控制地址计数器自动增1和减1。详细内容如下所示: 图:GRAM显示方向设置图 通过这几个位的设置,我们就可以控制屏幕的显示方向了,这种方法虽然简单,但是不是很通用, 比如不同的液晶,可能这里差别就比较大,不能完全通用,比如9341和9320就完全不通用,具体要 参考液晶屏手册。 3)07h,显示控制命令。该命令CL位用来控制是8位彩色,还是26万色。为0时26万色,为1时八 位色。D1、D0、BASEE这三个位用来控制显示开关与否的。当全部设置为1的时候开启显示,全0是关 闭。我们一般通过该命令的设置来开启或关闭显示器,以降低功耗。 D[1:0]:设置为“11”时,打开显示;设置为“00”时,关闭显示;而配合BASEE比特位,可以 用来设置开启或是关闭显示器时,系统是挂起还是运行状态,以此设置在挂起状态,达到降低功耗 的目的。 而CL比特位,当CL为1时,选择8位彩色;当CL为“0”时,选择为262144彩色: 4)20h和21h指令 分别为设置GRAM的行地址(X坐标)和列地址(Y坐标)。我们通过此两个指令的设置,指定 需要写入的点,然后再设置颜色,便实现在指定点写入一个颜色的;20h用于设置列地址(X坐标, 0~239),21h用于设置行地址(Y坐标,0~319)。当我们要在某个指定点写入一个颜色的时候,先 嵌入式专业技术论坛 (www.armjishu.com)出品 第 563 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 通过这两个命令设置到改点,然后写入颜色值就可以了。 5)22h指令 写数据到GRAM命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。该命令是我 们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要先写入 命令编号,然后写入操作数。 6)R50~R53,行列GRAM地址位置设置。这几个命令用于设定你显示区域的大小,我们整个屏的 大小为240*320,但是有时候我们只需要在其中的一部分区域写入数据,如果用先写坐标,后写数据 这样的方式来实现,则速度大打折扣。此时我们就可以通过这几个命令,在其中开辟一个区域,然后 不停的丢数据,这样就不需要频繁的写地址了,大大提高了刷新的速度。 HSA[7:0]/HEA[7:0]:指定区域的垂直方向上的起点和终点。通过设置HAS和HEA比特,以限制 GRAM区域的垂直方向上的大小。 VSA[8:0]/VEA[8:0]:指定区域的水平方向上的起点和终点。通过设置VSA和VEA比特,以显示 GRAM区域的水平方向上的大小。 其中: 可以看到 IL9320 中设置这个显示区域的代码如下,这里是设置 240-*320 大小: 命令部分到此,我们先简单了解到这里。有兴趣的朋友可以参阅《ILI9320控制器资料》一文, 我们接下来看看要如何才能驱动STM32神舟系列的TFTLCD模块, TFTLCD显示需要的相关设置步骤如 下: 1)初始化设置STM32与彩屏模块相连接的IO管脚 这一步,先将我们与TFTLCD模块相连的IO口进行初始化,以便驱动LCD。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 564 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 2)初始化彩屏模块。 通过向彩屏模块写入一系列的设置,来启动TFTLCD的显示。为后续显示字符和数字做准备。比如: 【复位TFT】Æ 【驱动IC初始化代码】Æ【复位所有的寄存器】Æ【开启显示】Æ【显存清0】Æ【开 始显示】Æ【显示各种图画】 3)开始使用彩屏,通过彩屏模块的一些控制信号线来控制彩屏。 这里就是通过我们设计的程序,将要显示的字符送到彩屏模块就可以了,这些函数将在软件设计 的时候介绍。通过以上三步,我们就可以使用STM32神舟系列彩屏模块来显示字符和数字了, 并且可 以显示各种颜色的背景。 7.32.5 FSMC介绍 STM32系列中内部集成256 KB以上FlaSh,后缀为xC、xD和xE的高存储密度微控制器特有的存储控 制机制,一般芯片引脚数在100脚以上的STM32F103芯片都带有FSMC接口,FSMC能够根据不同的外部存 储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度,从而使得STM32系列微控制器不 仅能够应用各种不同类型、不同速度的外部静态存储器,而且能够在不增加外部器件的情况下同时扩 展多种不同类型的静态存储器,满足系统设计对存储容量、产品体积以及成本的综合要求。 图:FSMC框图 嵌入式专业技术论坛 (www.armjishu.com)出品 第 565 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 从上图我们可以看出,STM32的FSMC将外部设备分为3类:NOR/PSRAM设备、NAND设备、PC 卡设备。他们共用地址数据总线等信号,他们具有不同的CS以区分不同的设备。 FSMC主要的优势有以下几点: 1)支持多种静态存储器类型。STM32通过FSMC可以与SRAM、ROM、PSRAM、NOR Flash和NANDFlash 存储器的引脚直接相连。 2 ) 支 持 丰 富 的 存 储 操 作 方 法 。 FSMC 不 仅 支 持 多 种 数 据 宽 度 的 异 步 读 / 写 操 作 , 而 且 支 持 对 NOR/PSRAM/NAND存储器的同步突发访问方式。 3)支持同时扩展多种存储器。FSMC的映射地址空间中,不同的BANK是独立的,可用于扩展不同 类型的存储器。当系统中扩展和使用多个外部存储器时,FSMC会通过总线悬空延迟时间参数的设置, 防止各存储器对总线的访问冲突。 4)支持更为广泛的存储器型号。通过对FSMC的时间参数设置,扩大了系统中可用存储器的速度 范围,为用户提供了灵活的存储芯片选择空间。 5)支持代码从FSMC扩展的外部存储器中直接运行,而不需要首先调入内部SRAM。 这里我们介绍下为什么可以把TFTLCD当成SRAM设备用:首先我们了解下外部SRAM的连接,外部 SRAM的控制一般有:地址线(如A0~A18)、数据线(如D0~D15)、写信号(WR)、读信号(OE)、片 选信号(CS),如果SRAM支持字节控制,那么还有UB/LB信号。而TFTLCD的信号包括:RS、D0~D15、 WR、RD、CS、RST和BL等,其中真正在操作LCD的时候需要用到的就只有:RS、D0~D15、WR、RD和CS; 这里比较关键点就是TFT LCD并不需要用到FSMC的地址线(如A0~A18),它只需要用到16根数据线以 及一些其他的控制信号线就可以了,并且操作时序和SRAM的控制完全类似,下面是对比表: 资源 SRAM 神舟TFT LCD 写信号(WE) 有 有 读信号(OE) 有 有 片选信号(CS) 有 有 数据线(D0~D15) 有 有 地址线(如A0~A18) 有 无 RS(TFT中决定是数据还是命令) 无 有 RST 无 有 BL 无 有 TFT LCD通过RS信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号,比如 我们把RS接在A0上面,那么当FSMC控制器写的地址刚好让A0这根信号线为0(A1~A18因为并没有连接 到TFT上,所以可以忽略不计)的时候,会使得连在A0上的TFT信号RS也为0,对TFT LCD来说,就是写 命令;同样,当FSMC写地址的地址让A0这个地址变成1的时候,A0上的TFT信号RS也会变成1,对TFTLCD 来说,就是写数据了。这样,就把数据和命令区分开了,当然RS也可以接在其他地址线上,STM32神 舟开发板是把RS连接在FSMC_A0上面的。 STM32的FSMC支持8/16/32位数据宽度,我们这里用到的LCD是16位宽度的,所以在配置FMSC控制 器属性的时候,选择16位宽就OK了。我们再来看看FSMC的外部设备地址映像,STM32的FSMC将外部存 储器划分为固定大小为256M字节的四个存储块,如下图: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 566 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图:FSMC存储块地址映像 从上图可以看出,FSMC总共管理1GB空间,拥有4个存储块(Bank),本章,我们用到的是块1, 所以在本章我们仅讨论块1的相关配置,其他块的配置,请参考《STM32参考手册》第19章(324页) 的相关介绍。 STM32的FSMC存储块1(Bank1)被分为4个区,每个区管理64M字节空间,每个区都有独立的寄存 器对所连接的存储器进行配置。Bank1的256M字节空间由28根地址线(2的28次方是256M,其中26根地 址线来自外部存储器地址FSMC_A[25:0]),另外2根地址线对4个区进行寻址(AHB总线是26和27): Bank1所选区 片选信号 地址范围 AHB总线 [27:26] [25:0] 第1区 FSMC_NE1 0X6000,0000~0X63FF,FFFF 00 第2区 FSMC_NE2 0X6400,0000~0X67FF,FFFF 01 FSMC_A[25:0] 第3区 FSMC_NE3 0X6800,0000~0X6BFF,FFFF 10 第4区 FSMC_NE4 0X6C00,0000~0X6FFF,FFFF 11 当我们选择使用Bank1的第2个区,即使用FSMC_NE2来外接外部设备的时候,即对应了 FSMC[27:26]=01,我们要做的就是配置对应第2区的寄存器组,来适应外部设备即可;同样,如 果当我们选择使用Bank1的第4个区,即使用FSMC_NE4来外接外部设备的时候,即对应了 FSMC[27:26]=11,我们要做的就是配置对应第4区的寄存器组,STM32的FSMC总线各Bank配置寄 嵌入式专业技术论坛 (www.armjishu.com)出品 第 567 页,共 788 页 存器如表: ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到,我们需要操作的TFT彩屏与操作SRAM是相同的控制器,都是负责存储块的Bank1的内 部控制器NOR FLASH控制器,对于NOR FLASH控制器,主要是通过FSMC_BCRx(x=1、2、3、4)、FSMC_BTRx (x=1、2、3、4)和FSMC_BWTRx(x=1、2、3、4)寄存器设置(其中x=1~4,对应Bank中的4个区), 下面介绍一下这几个配置寄存器各负责的功能: FSMC_BCRx ( x=1,2,3,4 ) : SRAM/NOR 闪 存 片 选 控制 寄 存 器 (FSMC_BCR1, FSMC_BCR2, FSMC_BCR3, FSMC_BCR4)每个Bank对应1个寄存器,这个寄存器包含了每个存储器块的控制信息,可以用于SRAM、 ROM、异步或成组传输的NOR闪存存储器(TFT LCD也可以),主要包括设置数据总线宽度,比如8位、 16位;存储类型的设置,比如SRAM或者PSRAM或者NOR闪存;地址/数据是否复用;存储块使能设置。 FSMC_BTRx(x=1,2,3,4):闪存片写时序寄存器(FSMC_BTR1,FSMC_BTR2,FSMC_BTR3,FSMC_BTR4); 可以通过这个寄存器设置模式,总线恢复时间,时钟分频,数据保持时间等时序相关的设置。 FSMC_BWTRx(x=1,2,3,4):闪存写时序寄存器(FSMC_BWTR1,FSMC_BWTR2,FSMC_BWTR3,FSMC_BWTR4); 采用哪种访问模式,数据保持时间,地址保持时间,底子好建立时间(单位是HCLK时钟周期) 通过这3个寄存器,可以设置FSMC访问外部存储器的时序参数,可以使得支持更多的外部存储器, 拓宽了可选用的外部存储器的速度范围。例如:FSMC的NOR FLASH控制器支持同步和异步突发两种访 问方式。选用同步突发访问方式时,FSMC将HCLK(系统时钟)分频后,发送给外部存储器作为同步时钟 信号FSMC_CLK。此时需要的设置的时间参数有2个(这些都不用太关注,有需要时再去研究,我们已 经实现了具体的代码,可以直接从代码中去看一下如何进行设置的): 1,HCLK与FSMC_CLK的分频系数(CLKDIV),可以为2~16分频; 2,同步突发访问中获得第1个数据所需要的等待延迟(DATLAT)。 对于异步突发访问方式,FSMC主要设置3个时间参数(这些都不用太关注,有需要时再去研 究,我们已经实现了具体的代码,可以直接从代码中去看一下如何进行设置的):地址建 立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。FSMC综合了SRAM/ROM、PSRAM和 NOR Flash产品的信号特点,定义了4种不同的异步时序模型。选用不同的时序模型时,需要设置不同 的时序参数,如下表所列: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 568 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这里只是简单的介绍一些关于FSMC的参数设置,FSMC最终被设置成能够按照FSMC所控制的目 标器件的时序,规范来与之沟通,至于详细的设置,在这个例程中不需要花费太多精力关注细节,大 体知道是这么一回事就可以了,如果有必要用到的时候,就具体去进行研究就可以了。 7.32.6 FSMC函数初始化 1.FSMC初始化函数: 根 据 前 面 的 讲 解 , 初 始 化 FSMC 主 要 是 初 始 化 三 个 寄 存 器 FSMC_BCRx , FSMC_BTRx , FSMC_BWTRx,那么在固件库中是怎么初始化这三个参数的呢? 固件库提供了3个FSMC初始化函数分别为 FSMC_NORSRAMInit();(可以用来初始化NOR和SRAM存储器) FSMC_NANDInit(); (可以用来初始化NAND存储器) FSMC_PCCARDInit();(可以用来初始化PC CARD等存储器) 这三个函数分别用来初始化4种类型存储器。这里根据名字就很好判断对应关系,下面我们看看 函数定义: void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef * FSMC_NORSRAMInitStruct); 这个函数只有一个入口参数,也就是FSMC_NORSRAMInitTypeDef类型指针变量,这个结构体的 成员变量非常多,因为FSMC相关的配置项非常多。 typedef struct { uint32_t FSMC_Bank; uint32_t FSMC_DataAddressMux; uint32_t FSMC_MemoryType; uint32_t FSMC_MemoryDataWidth; uint32_t FSMC_BurstAccessMode; uint32_t FSMC_AsynchronousWait; uint32_t FSMC_WaitSignalPolarity; uint32_t FSMC_WrapMode; uint32_t FSMC_WaitSignalActive; uint32_t FSMC_WriteOperation; uint32_t FSMC_WaitSignal; 嵌入式专业技术论坛 (www.armjishu.com)出品 第 569 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 uint32_t FSMC_ExtendedMode; uint32_t FSMC_WriteBurst; FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct; }FSMC_NORSRAMInitTypeDef; 从这个结构体我们可以看出,前面有13个基本类型(unit32_t)的成员变量,这13个参数是用来配 置片选控制寄存器FSMC_BCRx。最后面还有两个FSMC_NORSRAMTimingInitTypeDef指针类型的成 员变量。FSMC有读时序和写时序之分,这里就是用来设置读时序和写时序的参数了,也就是说,这 两个参数是用来配置寄存器FSMC_BTRx(闪存片读时序寄存器)和FSMC_BWTRx(闪存片写时序寄 存器),后面我们会讲解到。下面我们主要来看看模式A下的相关配置参数: 参数-存储块标号:参数FSMC_Bank用来设置使用到的存储块标号和区号,前面讲过,我们是使 用的存储块1区号4,所以选择值为FSMC_Bank1_NORSRAM4。 参 数 FSMC_MemoryType 用 来 设 置 存 储 器 类 型 , 我 们 这 里 是 SRAM , 所 以 选 择 值 为 FSMC_MemoryType_SRAM。 参数-数据位宽度:参数FSMC_MemoryDataWidth用来设置数据宽度,可选8位还是16位,这里我 们是16位数据宽度,所以选择值为FSMC_MemoryDataWidth_16b。 参数-写使能:参数FSMC_WriteOperation用来设置写使能,毫无疑问,我们前面讲解过我们要向 TFT写数据,所以要写使能,这里我们选择FSMC_WriteOperation_Enable。 参数FSMC_ExtendedMode是设置扩展模式使能位,也就是是否允许读写不同的时序,这里我们采取的 读写不同时序,所以设置值为FSMC_ExtendedMode_Enable。 下面再介绍一下其他几个相关参数的意义吧:参数FSMC_DataAddressMux用来设置地址/数据复 用使能,若设置为使能,那么地址的低16位和数据将共用数据总线,仅对NOR和PSRAM有效,所以 我们设置为默认值不复用,值FSMC_DataAddressMux_Disable。 参 数 FSMC_BurstAccessMode , FSMC_AsynchronousWait , FSMC_WaitSignalPolarity , FSMC_WaitSignalActive,FSMC_WrapMode,FSMC_WaitSignal FSMC_WriteBurst和FSMC_WaitSignal 这些参数在成组模式同步模式才需要设置,大家可以参考中文参考手册了解相关参数的意思。 接 下 来 我 们 看 看 设 置 读 写 时 序 参 数 的 两 个 变 量 FSMC_ReadWriteTimingStruct 和 FSMC_WriteTimingStruct,他们都是FSMC_NORSRAMTimingInitTypeDef结构体指针类型,这两个参 数 在 初 始 化 的 时 候 分 别 用 来 初 始 化 片 选 控 制 寄 存 器 FSMC_BTRx 和 写 操 作 时 序 控 制 寄 存 器 FSMC_BWTRx。 下面我们看看FSMC_NORSRAMTimingInitTypeDef类型的定义: typedef struct { uint32_t FSMC_AddressSetupTime; uint32_t FSMC_AddressHoldTime; uint32_t FSMC_DataSetupTime; uint32_t FSMC_BusTurnAroundDuration; uint32_t FSMC_CLKDivision; uint32_t FSMC_DataLatency; uint32_t FSMC_AccessMode; }FSMC_NORSRAMTimingInitTypeDef; 这个结构体有7个参数用来设置FSMC读写时序。其实这些参数的意思我们前面在讲解FSMC的时 嵌入式专业技术论坛 (www.armjishu.com)出品 第 570 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 序的时候有提到,主要是设计地址建立保持时间,数据建立时间等等配置,对于我们的实验中,读写 时序不一样,读写速度要求不一样,所以对于参数FSMC_DataSetupTime设置了不同的值,大家可以 对照理解一下。记住,这些参数的意义在前面讲解FSMC_BTRx和FSMC_BWTRx寄存器的时候都有提 到,大家可以翻过去看看。 2.FSMC使能函数 FSMC对不同的存储器类型同样提供了不同的使能函数: void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState); void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState); void FSMC_PCCARDCmd(FunctionalState NewState); 这个就比较好理解,我们这里不讲解,我们是 SRAM,所以使用的第一个函数;这些如果有必要再 去详细了解,因为这个都是 ST 官方设计 STM32 芯片的时候就已经预先规定好的了,我们只需要按照 他们的规则和要求去设置和使用它就足够了,因为其他芯片厂商不一定会使用 FSMC 这个协议的。 7.32.7 硬件设计 本实验的硬件设计包括两个方面: 一、TFT LCD屏的原理设计,主要体现TFT LCD屏上的信号连接情况; 二、神舟III号开发板上的TFT座的信号连接情况。 首先是TFT的硬件设计: 下面这些信号是真正与LCD液晶屏相连接的: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 571 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到FSMC的数据线FSMC_D0~FSMC_D15都被使用了,而FSMC的地址线只使用了FSMC_A0这根管 脚跟RS(TFT LCD选择数据线是发的是命令还是发的是数据这根关键的信号线)连接。 7.32.8 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 572 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:首先掉用 ili9320_Initializtion()函数对 TFT LCD 彩色液晶屏进行初始化,然后在 while() 循环中调用 ili9320_Clear(Red)函数来循环显示红色。 代码分析 2:LCD_WriteReg()这个是写 LCD 的寄存器函数,可以看到这个函数实现代码如下: void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue) { LCD->LCD_REG = LCD_Reg; LCD->LCD_RAM = LCD_RegValue; } 可以看到 LCD 这个结构体的定义如下: #define LCD_BASE ((u32)(0x60000000 | 0x0C000000)) 这里的 LCD_BASE,是根据外部电路的连接来确定的,这里使用的 Bank1 的第 4 个区,就是从 地址 0x6C00,0000 开始,看下表: 在使用 FSMC 驱动液晶屏的时,通过前面的硬件原理图可以看到,TFT LCD 的 RS 是接在 FSMC_A0 上面,CS 接在 FSMC_NE4 上,并且是 16 位数据总线。 #define LCD ((LCD_TypeDef *) LCD_BASE)关于 LCD_TypeDef 结构体地址,被强制指定到地址 LCD_BASE(地址为:0x6C00,0000)那么可以得到 LCD->LCD_REG 的地址就是 0x6C00,0000,对应 的 FSMC_A0 的状态为 0(即 RS=0,RS 是前面提到过的 TFT 液晶屏命令和数据的控制信号线,写 0 表示命令),那么 LCD->LCD_RAM 的地址就是 0x6C00,0001(结构体地址自增,因为都是 vu16 型号 的),那么此时对应的 FSMC_A0 的状态为 1(即 RS=1,RS 是前面提到过的 TFT 液晶屏命令和数据 的控制信号线,写 1 表示数据)。 typedef struct { vu16 LCD_REG; vu16 LCD_RAM; } LCD_TypeDef; 所以,有了这个定义,LCD->LCD_REG 就是写命令,而 LCD->LCD_RAM 就是默认对某个寄存 器写数据;所以如果是写 LCD,可以先确定写哪个寄存器,然后再往这个寄存器写什么数据内容: LCD->LCD_REG = 要写的命令,写哪个寄存器 LCD->LCD_RAM = 对哪个寄存器要写什么样的数据 嵌入式专业技术论坛 (www.armjishu.com)出品 第 573 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 反过来,读 LCD 的内部的数据就是相反: LCD->LCD_REG = 要读的哪个寄存器 读出来的数据是什么 = LCD->LCD_RAM 代码分析 3:LCD_X_Init()函数完成 LCD 与 CPU 之间管脚的初始化,包括初始化 FSMC 总线 void LCD_X_Init(void) { LCD_CtrlLinesConfig(); //配置 LCD 控制管脚 LCD_FSMCConfig(); //配置 FSMC 总线接口 } 1) LCD_CtrlLinesConfig()配置 LCD 控制管脚 配置 LCD 控制管脚,连接 TFT 彩色液晶屏的这些管脚都要被初始化一下时钟和 GPIO 管脚功能, 具体哪些管脚可以看下 TFT 液晶屏的原理图。 2) LCD_FSMCConfig()配置 FSMC 总线接口 配置 FSMC 总线接口,以及 FSMC 总线控制器的初始化 这里设置了比如:数据/地址复用=禁用;数据宽度 = 16 位;写操作 = 使能;扩展模式 = 使能; 异步等待 = 禁用等,主要是配置了 FSMC 控制器,具体细节如果有兴趣的话可以看下 STM32 的使用 手册的 FSMC 章节进行研究,这里代码中都已经设置配好了。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 574 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 4:读取液晶屏的 ID 型号,0x0000h 指令,当为读操作时,读取控制器的型号; 1) LCD->LCD_REG = 0x0000 表示这是 0x0000 指令,是读取液晶屏的 ID 型号,实际上是将 LCD 的 LCD_TypeDef 这个 STRUCT 结构体的地址设定到 0x0000 然后接下来用 LCD->LCD_RAM 来读取 数据。 2) data = LCD->LCD_RAM 是用来读取数据,这个 0x0000 指令地址的数据就是液晶屏的 ID 号,比 如 IL9320 的液晶屏读出来的 ID 号是 0x9320,比如 SSD1289 型号的液晶屏读出来的 ID 号就是 0x8989 代码分析 5:开始判断液晶屏是哪个型号,比如是 9320 还是 SSD1289 型号,判断出型号之后,就会 进入该型号具体的配置显示过程 嵌入式专业技术论坛 (www.armjishu.com)出品 第 575 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 比如设置晶振打开,液晶屏的显示大小(比如是 230*320),显示的扫描方式是从左边往右边扫描 还是从下往上扫描等参数,具体可以详细看一下液晶屏的寄存器说明表。 代码分析 6:ili9320_Clear(Red)将 TFT LCD 彩色液晶屏显示红色,将屏幕填充成指定的颜色,如清屏, 则填充 0xffff;如显示红色,则填充 0xF800。 i. ili9320_SetCursor(0,0)先设置坐标,然后往坐标写颜色 ii. LCD_WriteRAM_Prepare()准备填充 GRAM,填充 GRAM 就是写数据到液晶屏里 iii. 写颜色,一个点一个点的写,这里的液晶屏是 320*240 点阵的,所以 320*240=76800 for(index=0;index<76800;index++) { LCD->LCD_RAM=Color; } 代码分析 7:ili9320_SetCursor(0,0) 通过 ili9320_SetCursor()函数可以实现光标的位置,可以看到 SSD1289 芯片手册中,关于寄存器 4E 和 4F 寄存器分别是设置光标的 X 位置和 Y 位置: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 576 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 表示刷屏就是从这个点开始刷。 代码分析 8:LCD_WriteRAM_Prepare()函数 R34,写数据到 GRAM 命令,当写入了这个命令之后,地址计数器才会自动的增加和减少。该命 令是我们要介绍的这一组命令里面唯一的单个操作的命令,只需要写入该值就可以了,其他的都是要 先写入命令编号,然后写入操作数。 代码分析 8:开始一个点一个点的写入颜色到 GRAM 里,因为之前的 R34 已经定位好了 LCD 的 STRUCT 结构体的位置,那么可以计算一下 GRAM 的大小,总共是 320*240 = 76800 个点,每个点的 颜色是 5:6:5 的模式是 16 位来表示,就是 2 个字节,所以 GRAM 的大小是 76800*2 字节 = 150KB 大 小,也就是说,液晶屏的 GRAM 大小最少是这么大才能存到一屏数据。 for(index=0;index<76800;index++) { LCD->LCD_RAM=Color; } 7.32.9 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.32.10 实验现象 将固件下载到神州 III 号开发板后,复位,神州 III 号开发板正常情况下将显示红色 嵌入式专业技术论坛 (www.armjishu.com)出品 第 577 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.33 TFT彩色液晶屏显示蓝色 7.33.1 硬件设计 硬件设计同上 7.33.2 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析 1:ili9320_Clear(Blue);可以看到还有很多其他的颜色,其中 blue 是蓝色 嵌入式专业技术论坛 (www.armjishu.com)出品 第 578 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中#define Blue 0x001F 我们把 0x001F 化成二进制就是 0000 0000 0001 1111,对于 5:6:5 的显示 模式来说,可以看下图,DB1~DB5 这个 5 位是都是 1,它是设定蓝色颜色的;而 DB6~DB12 都是 0 表示不显示绿色;DB12~DB17 也是为 0,它是设定红色颜色,表示不显示红色,这样一来就只会显示 出蓝色的颜色。 7.33.3 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.33.4 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示蓝色 嵌入式专业技术论坛 (www.armjishu.com)出品 第 579 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.34 TFT彩色液晶屏如何显示一个点 7.34.1 扫描的简要分析 本实验在 LCD 屏上指定的位置显示一个点。 7.34.2 硬件设计 硬件设计同上 7.34.3 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 580 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:ili9320_Initializtion( ),彩屏初始化函数。前面我们已经讲了,我们就不再重复,这里它 的主要是将彩屏初始化,并将彩屏刷成绿色。 代码分析 2:ili9320_SetPoint(120, 160, Black),画点函数。 画点的时候,先确定位置,然后再画点。值得注意的是,这个点有点小,仔细看才能看出来。 代码分析 3:函数 ili9320_SetCursor( )设置光标的位置,即指定画点的位置。 不同的液晶控制器,设置光标位置使用的寄存器是不同的。比如说,控制器 8989 设置光标的时 嵌入式专业技术论坛 (www.armjishu.com)出品 第 581 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 候用到的是寄存器 0x004e 和 0x004f。而控制器 9320,用到的是 0x0020 和 0x0021。这个在控制器的 芯片手册中有具体的说明。 设置光标函数,有两个参数,这个两个参数是有范围限定的。比如我们这里的液晶屏是 240x320。 那么函数的第一个参数的范围是:0<=Xpos<=240。第二个参数的范围是:0<=Ypos<=320。 代码分析 4:LCD_WriteRAM_Prepare()函数,准备向 RAM 中写数据。 这里向控制器送入 LCD_REG_34 命令。而 LCD_REG_34 等于 0x22。 0x22 命令是写数据到 GRAM 命令,写入这个命令后,地址计数器才会自动的增加和减少。这里 我们我们写入这个命令,为下面填充数据做准备。 代码分析 5:调用 LCD_WriteRAM()函数,向 LCD RAM 写数据。 通过函数 LCD->LCD_RAM = RGB_Code 向 GRAM 写数据。即向对应的彩屏的 FSMC 端口发送 数据,我们这里发送的是画点的数据。 为什么是彩屏的 FSMC 呢?这个可以从地址上看得出来。LCD 是类型为 LCD_TypeDef,指向 LCD_BASE 的指针。LCD_BASE 的地址定义如下: 画点函数,就是通过彩屏的 FSMC 端口向 GRAM 存储单元传输数据。而 GRAM 中每个存储单元 都对应着液晶控制器面板的一个像素点。LCD 控制器(9320、8989 等等)通过其它的组件的共同作 嵌入式专业技术论坛 (www.armjishu.com)出品 第 582 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 用把我们写入 GRAM 存储单元中的数据转化为液晶面板控制信号,使对应的像素点呈现特定的颜色。 传输完数据之后,拉高片选信号线(CS),表示一次传输数据完成。到此画点函数,我们分析完 成。 7.34.4 下载与测试 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使用 JLINK在线调试小节进行操作。 7.34.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示绿色,在屏的中间显 示一个黑点。注意,我们只是显示一个点,看的时候要仔细,可以把保护膜撕下来观察黑点。 7.35 TFT彩色液晶屏显示一个数字1 7.35.1 扫描的简要分析 本实验我们在 LCD 屏上指定的位置显示一个数字 1。我们这个 1 是通过字模显示的。 7.35.2 什么是字模 液晶屏其实就是一个由许多像素点组成的点阵,若要在上面显示一个字符,则需要很多像素 点共同构成,比如 8*16 的 ASCII 码字符,或者 16*16 的点阵显示的汉字。 如果每个 8*16 或者 16*16 的点阵区域来显示一个字符,把黑色的像素点以 1 来表示,空白以 0 表示,每个像素点的状态以一个二进制位来记录,用 8*16/8=16 个字节或者 16*16/8=32 个字节 就可以把这个字记录下来。这个 16 字节或者 32 字节就被称之为该字符的字模。当然还有其他常 用的字模是 24*24,32*32 的。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 583 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以把这个‘字模’两个字转化成以下的 32 个字节的字模: 比如看下,开头的 0x02 和 0x00,就是显示’字’的最上面那一点,显示第一行;比如下面这一行黑体, 可以数一下,从上面往下数是第 10 行,那么可以看到第 10 行是 0x7F 和 0xFE,确实是一个正确的字 模显示;在这样的字模中,以两个字节表示一行像素点,16 行构成一个字模: 7.35.3 ASCII码的字符解释 下图是 ASCII 码字符表 嵌入式专业技术论坛 (www.armjishu.com)出品 第 584 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 现在将这些 ASCII 字符表转化成 8x16 的数组,也就是说一个字符的高度是 8,宽度是 16,16 也 就是两个字节,那么一个字符就是 8 行,每行都是 16 个 bit,等于是 8*16/8 = 16 个字节大小。可以看 到下面的 ASCII 字符,红框框住的是 16 个字节,显示一个字符。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 585 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到整个数组 ascii_8x16[1536]总共有 1536 个成员,每个成员就是一个单独的字节,而 16 个 字节就是一个字符,那么这个数组总共能描述多少个字符呢?总共是 1536/16 = 96 个字符,从下面的 这张表来看,这个 96 个字符就是描述的是从 ASCII 值 32 到 127 这 96 个字符。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 586 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 比如我们希望显示 www.armjishu.com 到液晶屏上,那么这个LOGO所有的字符都能在ASCII码表中通 过查表获得,接下来的软件分析会进一步分析如何用具体的软件代码来显示字符到LCD液晶屏上。 7.35.4 硬件设计 硬件设计同上 7.35.5 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 587 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:ili9320_Initializtion( ),彩屏初始化函数。前面我们已经讲了,我们就不再重复,这里它 的主要是将彩屏初始化,并将彩屏刷成绿色。 代码分析 2:LCD_DrawChar(10, 100, &ASCII_Table[0]),显示数字 1 函数。 函数 LCD_DrawChar(),一共 3 个参数,第一、第二个参数设定字符显示的坐标。第三个参数 设定要显示的字符。 代码分析 3:显示字符函数中。本实验使用的字符大小是 24x48。即显示一个字模需要 24x48=1152 个 bit,1152/8=144 个字节。 代码分析 3:设定字符显示的位置调用函数 LCD_SetCursor(),这个函数我们前面已经说明,这里就 不再重复。下面的 for 循环用到我们前面 24、48,即 Width 和 Height 数据。For 循环通过这两个数据 限定显示字符的大小。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 588 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们显示一个字符使用到 24x48=1152 个 bit,我们编写代码的时候,设定高度(Height)是 48, 宽度(width)是 24。每画完一次宽度(width),高度(Height)加 1。依次次循环,最终将整个字符 显示出来。 :代码分析 4:在 for(i = Width; i > 0;)循环里面,对数据进行相应的判断及显示。 我们这里 i = Width,前面我们定义了 Width 等于 24,所以调用 if 语句进行判断赋值的时候 K=8。 cpFontArray[index]是我们传进来的第三个参数。这个参数是一个指针,指向我们要显示的数据的首地 址。最终通过判断决定对应的点是显示黑色(BackColor)还是白色(TextColor)。 代码分析 5:我们知道显示一个点,是设定显示点的坐标,然后写数据。我们数字 1 也是一样的道理, 不同的是我们写入了很多点的数据。我们看一下显示的结果。 下面我们对数字 1 的数据进行分析,在此我们数字 1 设定的字模是 24x48。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 589 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 , 上面我们说了,字模的宽度是 24,高度是 48。我们先显示完一个宽度,高度加 1,再显示一个宽 度,高度再加 1,如此循环,最终显示一个字符。数字 1 的字模数据中,为了方便大家观察,我们将 数据分成 3 个字节一行。刚好是 3x8=24(bit),和宽度吻合。其实这样划分之后,大家数一下数字 1 数 据的高度,刚好是 48 行的。 我们显示一个数字 1,从形状上,我们可以看到它的头是斜的,尾部是一横,中间部分是 1 竖。 那么我们的数据中间部分应该是一样的。我们对一下数据发现中间的数据都是 0x00,0x38,0x00。我们 将它化为二进制等于 0000 0000 0011 1000 0000 0000,就是说一个宽度中,中间有 3 个点是黑色的, 两边都是白色的。连续这样的数据就组成了 1 竖(数字 1 的中间部分)。 数字 1 的头部是上窄下宽,那么头部的数据从上往下,应该是上面的数据是 1 的位数比下面的少。 大家观察一下,它头部的数据。从上往下,数据中 1 的位数增大。 大家看一下数字 1 尾部的数据: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 590 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 0x07,0xFF,0xC0,化为二进制为 0000 0111 1111 1111 1100 0000,这样的一个宽度数据组成一横(数 字 1 的底部)。 代码分析 6:我们看一下实验的效果 通过显示的结果我们可以推断出,液晶屏刷的方向。我们可以看到显示的 1 是竖着的,我们可以 判断出它的刷屏是在水平方向上的。如果刷屏方向是在竖直方向上的,那么数字 1 的显示应该是卧倒 的。 那么竖屏是从左到右刷,还是从右到左刷呢?刷屏的起始点在哪里呢?我们看一下数字 1 的头部, 它的突出部分是在左边。那么它刷屏的方向,是从左到右刷屏。从右向左的刷的话,突出部分是指向 右边的。刷屏的起始点是在左上角的第一个点。如果是在右下脚的话,显示的数字 1 就倒立过来了。 那么通过数字 1 的显示,可以看出屏在显示数字 1 的时候显示的方向是:从左到右刷屏,而且是 从左上角开始刷屏。 7.35.6 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.35.7 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示数字 1。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 591 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.36 TFT彩色液晶屏显示变异的数字1 7.36.1 简要分析 本实验我们对数字 1 的字模数据,进行改造显示特殊的数字 1,改变显示 1 的数组的值,看看这个 数字 1 会不会变形。 7.36.2 软件分析 代码分析 1:显示数字 1 的实验的时候,我们已经对相关的函数进行了解释。我们这里主要针对两个 实验的数字 1 的数据进行对比分析。 (显示数字 1 的数据) (显示变异数字 1 的数据) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 592 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们观察它两的数据发现,变异的数字 1 的数据和普通数字 1 的数据不同的地方是在数据的中间 部分。普通的数字 1 的数据的中间部分是一长串的宽度数据,0x00,0x38,0x00。变异数字 1 的数据中 间部分是一段宽度数据 0x00,0x38,0x00,加上一段宽度数据 0x00,0xFF,0x00,再加上一段宽度数据 0x00,0x38,0x00 构成。 0x00,0x38,0x00 化为二进制的数据是 0000 0000 0011 1000 0000 0000。0x00,0xFF,0x00 化为二进制 的数据是 0000 0000 1111 1111 0000 0000。很明显,0x38 只有 3 个 1,而 0xFF 是 8 个 1。那么最终在 液晶屏上显示的时候,特殊的数字 1 中间部分不是规则的一竖,应该是两头小一点,中间胖一点的一 竖。 7.36.3 软件分析 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示特殊数字 1。 7.37 TFT彩色液晶屏显示数字9 7.37.1 简要分析 上个例程显示了一个数字 1 之后,这个例程我们打算显示一个数字 9,再加深一下这个字模转成 数字的过程。 7.37.2 软件分析 进入例程的文件夹,然后打开\MDK-ARM\ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 593 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:显示数字 1 的实验的时候,我们已经对相关的函数进行了解释。我们这里主要针对数字 9 的数据进行对比分析。 (显示数字 1 的数据) (显示数字 9 的数据) 我们观察它两的数据发现,变异的数字 1 的数据和数字 9 的数据有很多的不同点。首先,数字 1 的中间部分是规律性的 0x00,0x38,0x00。而数字 9 并没有这样子的规律。 我们看一下,数字 9 的数据。开头的都是 0x00,那些都是空白的,我们不管它。第一个非 0 的数 据宽度是 0x01,0xF8,0x00。化为二进制是 0000 0001 1111 1000 0000 0000,大家发现这个二进制中间部 分有连续的 6 个 1,那么我们的这个 9 的头部是封顶的。 往下的一长串数据中,中间部分都都有 0。比如 0x70,0x00,0x60。我们这个数字 9,中间是空的。 空完之后,下面封一次底,完成数字 9 的上面的圆圈部分。 7.37.3 下载测试 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节 嵌入式专业技术论坛 (www.armjishu.com)出品 第 594 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 进行操作。 7.37.4 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示数字 9。 7.38 TFT彩色液晶屏显示一个英文 7.38.1 简要分析 本实验我们显示一个大写的英文字母 A。 7.38.2 硬件设计 硬件设计同上 7.38.3 软件分析 进入例程的文件夹,然后打开\MDK-ARM\ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 595 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:显示英文字母的实验原理,和显示数字的实验原理是一样的。我们主要对比一下显示数 字 9 和显示英文 A 的数据。 , 这个和显示数字,基本是一样的,最大的区别是显示的内容不一样。这个可以从显示数据中看出 来。我们显示引文的时候,字模的大写也是 24x48。 分析一下字母 A 的数据。我们发现字母 A 的数据,只有一行是连续不断的十几个位都是 1。从 A 的 形状上不难猜出它描述的是 A 中间的的横杠。 7.38.4 下载与测试 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节 进行操作。 7.38.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示英文字母 A。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 596 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.39 TFT彩色液晶屏显示26个英文字母 7.39.1 简要分析 本实验显示 26 个英文字母 7.39.2 硬件设计 硬件设计同上 7.39.3 软件分析 进入例程的文件夹,然后打开\MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 597 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:ili9320_Initializtion( ),彩屏初始化函数。前面我们已经讲了,我们就不再重复,这里它 的主要是将彩屏初始化,并将彩屏刷成绿色。 代码分析 2:显示 26 个英文字母。 本实验和显示单个数字、单个英文基本一致。不同的是,通过 for 循环增加了显示的英文的数量。 一个英文字母的宽度是 24 位,13 个占的位数是 24x13=312(bit)。我们屏幕宽度 320,所以我们分两 行显示,每行显示 13 个字母。具体的字符数据如下: 7.39.4 下载与测试 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 598 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.39.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将显示 26 个英文字母。 7.40 TFT彩色液晶屏显示图片 7.40.1 图片格式介绍 图片格式有非常多的种类,比如 JPEG、BMP 和 GIF 等多种不同的类型,我们实验中主要是使用 LCD 屏来显示 BMP 图片。 BMP 文件格式,又称为位图(Bitmap)或是 DIB(Device-Independent Device,设备无关位图),是 Windows 系统中广泛使用的图像文件格式。BMP 文件保存了一幅图像中所有的像素。 BMP 格式可以保存单色位图、16 色或 256 色索引模式像素图、24 位真彩色图象,每种模式中单 一像素点的大小分别为 1/8 字节,1/2 字节,1 字节和 32 字节。目前最常见的是 256 位色 BMP 和 24 位色 BMP。 BMP 文件格式还定义了像素保存的几种方法,包括不压缩、RLE 压缩等。常见的 BMP 文件大多是不 压缩的。Windows 所使用的 BMP 文件,在开始处有一个文件头,大小为 54 字节。保存了包括文件格 式标识、颜色数、图像大小、压缩方式等信息,因为我们仅讨论 24 位色不压缩的 BMP,所以文件头 中的信息基本不需要注意,只有―大小‖这一项对我们比较有用。图像的宽度和高度都是一个 32 位 整数,在文件中的地址分别为 0x0012 和 0x0016。54 个字节以后,如果是 16 色或 256 色 BMP,则还 有一个颜色表,但在 24 位色 BMP 文件则没有,我们这里不考虑。接下来就是实际的像素数据了。因 此总的来说 BMP 图片的优点是简单。 7.40.2 深入了解BMP图片 BMP 文件的格式大体上分为 4 部分。 第一部分为位图文件头。 第二部分为位图信息头。 第三部分为调色板。 第四部分就是实际的图像数据了。 BMP 的内容,网上的资料很多,都说烂了。从操作上讲,如果想在液晶屏上显示图片的话,还是 比较简单的。大体上说,使用我们提供的图像转换软件,将要显示的图像转换成数据,替代我们提供 的代码中的图像数据就可以了。 针对于本实验,我们直接看一下转换出来的 BMP 图像数据。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 599 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 转换的出的数据,并非都是都是用于绘制的图像实际数据。在图像数据之前还有一串数据。比如: 。 这里的 0x40,0x01,表示图像的宽度。0xF0,0x00 表示图像的高度。0x0140 化为 10 进制等于 320; 0x00F0 化为 10 进制是 240。其它位代表的意义,我们在代码中进行说明,在这里不一一列举。 7.40.3 使用工具将图片转换成二进制码 在本实例中,在main函数中有以下函数调用: LCD_Image2LcdDrawBmp565Pic()函数可以在指定的位置显示图片。当然显示的大小是有限制 的。比如我们本实验显示的图片是240x320,屏幕也是240x320。那么我们显示图片的时候,指定的 显示坐标应该是(0,0),刚好整屏显示。 本实验使用的图片转换工具是:Img2Lcd.exe。 该软件的使用方法如下: 1) 双击“Image2Lcd 2.9.exe”,打开软件。 2) 单击“打开”选项,选择要转换的图片。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 600 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3) 对转换的图片进行设置。具体的设置入下图: 我们这里是C语言,输出的数据类型选择“C语言数组(*.C)”。这里大家要留意的是“输 出图像”。我们屏幕最大的宽度和高度是320和240。假如输出的图像刚好是(320,240),在代码 中设置图像显示位置的时候应该是在开始的位置,即坐标(0,0)。如果选择其他位置,图片的 显示错乱。 扫描模式,我们选择水平扫描。 “输出灰度”这里,我们选择的是“16位真彩色”。本实验中针对的是16位彩色,颜色数据 的排序是红、绿、蓝。颜色的位数分别是红色5位,绿色6位,蓝色5位。 勾选“包含图像头数据”。我们转换出来的数据,并非都是都是用于绘制的图像实际数据, 它还包含了图像头数据。 将数组拷贝出来,替换 QQ_LCON_80X80.C 文件中的“gImage_QQ_ICON_80X80_16[153608]”数组 内容和 QQ_LCON_80X80.h 文件中对应的数组定义,重新编译后即可显示用户自己的图片。 7.40.4 硬件设计 硬件设计同上 嵌入式专业技术论坛 (www.armjishu.com)出品 第 601 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.40.5 软件分析 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 进入到 main()函数中: 代码分析 1:液晶屏的初始化等细节前面的例程都有详细介绍,这个例程中主要是 LCD_Image2LcdDrawBmp565Pic ( )函数显示了图片。 代码分析 2:LCD_Image2LcdDrawBmp565Pic(0, 0, gImage_C) 嵌入式专业技术论坛 (www.armjishu.com)出品 第 602 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 本函数有 3 个参数,第一、第二个参数设置图片显示的位置。第三个参数是指针,指向我们转换 出来的数组数据的首地址。 代码分析 3:画图函数中首先定义了 HEADCOLOR 类型的“* BmpHeadr”。我们看一下 HEADCOLOR 是什么。 大家可以发现,HEADCOLOR 里面分别包含了多个数据。有 4 个 unsigned char 类型,两个 unsigned short 类型。我们算一下它们总共占用了多少字节。unsigned char 占用一个字节,unsigned short 占用两 个字节。那么它们一共就是占用了 8 个字节。 这 8 个字节就是,我们转换的图片的头数据。它们的意义分别为:scan,扫描模式。gray, 灰度 值。w,h 分别是图像的宽度和高度。is565,16 位彩色。Rgb,描述 R G B 颜色分量的排列顺序。 代码分析 4:定义完“* BmpHeadr”后,将指针 BmpHeadr 指向我们转换出来的图片数组数据,读取 图片的宽度(Width)和高度(Height)。并跳过图像的头数据,将指针 BmpData 指向显示图片的实际 数据。 代码分析 5:通过对图像头数据的判断,调用 LCD_DrawBmp565Pic()函数显示图片。 代码分析 6:图片显示函数 LCD_DrawBmp565Pic()。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 603 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 LCD_DrawBmp565Pic(uint16_t StartX, uint16_t StartY, uint16_t Width, uint16_t Height, const uint16_t *BmpAddress)函数一共包含 5 个参数。第一、第二个参数是显示图像的起始点,本实验我们 给的点是(0,0)。第三、第四个参数分别表示图像的宽度和高度。第 5 个参数就是指向跳过图像头数 据后的第一个数据,即我们用于绘制图画的第一个数据。 代码分析 7:绘制图片,也是一个点一个点的画。只是速度太快我们人眼无法看出。 显示图片的时候,首先设定显示的范围,这里用到了 3 个寄存器 0x0044、0x0045、0x0046。我们 算一下给 0x0044 和 0x0046 的数据,0xEF00 和 0x013F。我们将十六进制 0xEF 化为十进制得 239。0x13F 化为十进制是 319。相信大家对这两个数据非常的熟悉。对 0x0044、0x0045、0x0046 的介绍大家参考 控制芯片的手册。 显示的时候,设置显示时的位置。写入命令 0x22,准备写入 GRAM。然后通话 LCD_WriteRAM ()函数写数据。本实验中,可以通过两个 for 循环,先显示完一个宽度(Width),高度(Height)加 1,依此类推,绘制完整幅图片。 7.40.6 下载与测试. 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小节 进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 604 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.40.7 实验现象 将固件下载到神舟 III 号开发板后,复位,神舟 III 号开发板正常情况下将显示一张图片。 7.41 TFT彩色液晶屏显示图片并刷屏【未更新】 7.41.1 硬件设计 硬件设计同上。 7.41.2 软件设计 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 第 605 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 本实验和显示图片实验原理是一样的,不同的是添加的刷屏的功能。在 while(1)循环中,先将 屏刷成绿色,然后 LCD_Image2LcdDrawBmp565Pic()函数将 QQ 图片显示屏的中央。再进入一个 while()循环,整并显示 QQ 图标。 7.41.3 下载与测试 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按 如何通过 MDK 编译和在线调试 小 节进行操作 7.41.4 实验现象 将固件下载到神舟III号后,复位,神舟III号正常情况下将显示图片,不同的图片不停的 切换。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 606 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.42 开机TFT液晶屏图片自动左右移动实验 7.42.1 简要分析 我们已经知道如何显示图片,本实验开机显示图片的时候,我们让图片左右移动。 7.42.2 硬件设计 硬件设计同上 7.42.3 软件分析 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析 1:本实验通过 改变画图函数 LCD_Image2LcdDrawBmp565Pic()的第二个参数,使图片 左右移动。显示图片的时候,行坐标不变,列坐标左右移动,从而实现图片的左右移动。 代码分析 2:改变一个值,就使得图片先往一边移动,然后又往另一边移动。 7.42.4 下载与测试 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.42.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将看到下面的图片左右移动。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 607 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.43 TFT触摸屏实验 在上一节的TFT彩屏显示实验中,我们对于TFT LCD屏显示已经有了一定程度的掌握。这节我们 将在TFT彩屏显示实验的基础上,加上TFT LCD屏的触摸功能,将触摸采样到的数据在LCD屏上进行 显示,主要是借助SPI1总线实现对触摸芯片ADS7843的控制。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 608 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.43.1 实验的意义与作用 触摸屏逐渐取代键盘成为通信常用的人机交互工具,手机支持触摸功能、PDA手持设备等等的 运用。本节实验,我们将针对LCD的触摸功能进行详解,剖析触摸采样到LCD屏显示间的处理过程。 7.43.2 实验原理 触摸屏一般分为电阻、电容、表面声波、红外线扫描和矢量压力传感等,其中使用最多的是四 线或无线电阻触摸屏。四线电阻触摸屏是由两个透明电阻膜构成的,在它的水平和垂直电阻网上施 加电压,就可以通过A/D转换面板在触摸点测量出电压,从而对应出坐标值。 神舟I号的触摸屏附在LCD屏的表面上,与LCD屏相配合使用,主要是用的触摸芯片是ADS7843, 业界上与ADS7843芯片相兼容的触摸芯片还有ADS7846、AK4182、XPT2046以及TSC2046等,驱动 基本上一致。 ADS7843是一款4线式触摸屏控制器,内含12位分辨率,125KHz转换速率,逐步逼近型的A/D转 换器。 下面我们将通过ADS7843芯片讲解触摸原理。ADS7843内部有一个由多个模拟开关组成的供电 测量电路网络和12位的A/D转换器。其可以根据处理器(stm32f103RTB6通过SPI总线)发来的不同 测试命令导通不同的模拟开关,以便向工作面电极对提供电压,并把相应测量电极上的触点坐标位 置所对应的电压模拟量引入到A/D转换器。在触摸点X、Y坐标的测试过程中,测试电压与测量点的 等效电路如下图所示:(P为测量点) 当触摸屏受到点击或是挤压的时,ADS7843通过中断请求通知处理器(STM32F103RBT6)有触 摸发生。如“中断请求”图所示,当没有触摸时,MOSFET①和②打开、③关闭,则中断输出引脚 通过外加的上拉电阻输出为高,当有触摸时,①和③打开,②关闭,则中断输出引脚通过③内部的 连接到地,输出为低,从而向处理器发出中断请求。 7.43.3 硬件设计 TFTLCD 模块自带的触摸屏控制芯片为 XPT2046。XPT2046 是一款 4 导线制触摸屏控制器,内 含 12 位分辨率 125KHz 转换速率逐步逼近型 A/D 转换器。XPT2046 支持从 1.5V 到 5.25V 的低电压 I/O 接口。XPT2046 能通过执行两次 A/D 转换查出被按的屏幕位置, 除此之外,还可以测量加在触 摸屏上的压力。内部自带 2.5V 参考电压可以作为辅助输入、温度测量和电池监测模式之用,电池监 测的电压范围可以从 0V 到 6V。XPT2046 片内集成有一个温度传感器。 在 2.7V 的典型工作状态下, 关闭参考电压,功耗可小于 0.75mW。XPT2046 采用微小的封装形式:TSSOP-16,QFN-16(0.75mm 厚 度)和 VFBGA-48。工作温度范围为-40℃~+85℃。 触摸芯片现位于 TFT LCD 屏上,处理器通过 SPI2 总线控制触摸芯片。X+、X-、Y+和 Y-则连接 到 LCD 触摸屏上。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 609 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.43.4 软件设计 打开神舟 III 号触摸屏例程。以下我们学习代码的设计,主要是与 ADS7843 相关的代码。至于 TFT LCD 屏相关的显示代码在上节已经讲解过,在此不重复说明。同时,STM32F103 对 ADS7843 通过 GPIO 模拟 SPI 接口的方式进行访问。 首先,ADS7843芯片的初始化函数: 其中ADS7843的片选CS以及中断管脚的配置如下所示: ADS7843芯片的中断管脚的声明 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 610 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 EXTI中断线上的中断映射关系 详细的中断说明,可参考文档《【中文】STM32F系列ARM内核32位高性能微控制器参考手册 V10_1.pdf》中第137页的资料。 芯片以及中断管脚的宏定义: 接下来,我们看看中断的处理函数,打开stm32f10x_it.c文件,找到“EXTI9_5_IRQHandler”函 数: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 611 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 处理器接收到PG7管脚的中断请求后,响应中断,处理ARMJISHU_TouchScreen_ADS7843() 函数,此函数的处理程序如下所示: 处理器响应中断后,读取采样数据,并将采样数据进行转换,得到显示的坐标,并将结果进行 显示。那么,读取采样数据过程的实现,则是通过4次采样,确定采样结果,进行A/D转换。下面了 解读取采样数据的函数。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 612 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下面我们看看主程序的循环处理是如何实现的: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 613 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中值得一提的有两点:一、延时函数Delay_ARMJISHU();二、则是DrawPicture_Center(); 1、 延时函数Delay_ARMJISHU(): 在延时函数中,对中断管脚的判断,如果有效时,则在延时的过程对触摸进行响应。当然,在 延迟时,如果触摸了,也可以采用中断进行响应,但是,这样在图片的刷新过程中可能会导致 图片的混乱。 2、 绘制图片的函数DrawPicture_Center(): 通过此函数可以将自己喜欢的图片,通过转换放在picture.h文件后,进行显示。 7.43.5 下载与现象 现象:将固件下载到神舟III号后,复位,LCD屏就可以写字,我们写上“神舟III号”字样,如 下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 614 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.44 图片跟触摸点移动实验 7.44.1 简要分析 我们已经知道如何显示图片,本实验我们先显示图片,然后让图片跟随触摸点移动。 7.44.2 硬件设计 硬件设计同上 7.44.3 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析 1:本实验我们这里添加了触摸的功能。通过函数 ARMJISHU_TouchScreen_ADS7843( ), 读取触摸点的信息。然后通过触摸信息,调用 LCD_Image2LcdDrawBmp565Pic(0, TSC_Value_X, gImage_C)函数显示图片,从而实现图片的移动。 7.44.4 下载与测试 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按 如何通过 MDK 编译和在线调试 小 节进行操作 7.44.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将看到图片跟随触摸点移 动。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 615 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.45 点击图片小图标显示小图标外框实验 7.45.1 简要分析 本实验中,我们点击图片中的小图标的时候,小图标变颜色 7.45.2 硬件设计 硬件设计同上 7.45.3 软件分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 下面开始具体分析程序代码: 代码分析 1:ili9320_Initializtion( ),彩屏初始化函数。前面我们已经讲了,我们就不再重复,这里它 的主要是将彩屏初始化,并将彩屏刷成绿色。 代码分析 2:ADS7843_Init( )函数,初始化触摸功能。大家可以参考触摸屏的章节。这里就不重复。 代码分析 3:点击小图标后,显示小图标。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 616 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们首先,显示一个全屏的程序。通过函数 ARMJISHU_TouchScreen_ADS7843( )读取触摸点的 信息。通过 for 语句判断触摸点是否在所限定的范围内,如果在的话,在原来图片上显示一个预先做 好的小图片,将原来图片中的小图标覆盖,从而实现显示小图标外框功能。 7.45.4 下载与测试 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按 如何通过 MDK 编译和在线调试 小 节进行操作。 7.45.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将正常显示如下图片,我 们点击图片中央的小图标,小图标变色。 7.46 点击图片小图标触发事件实验 7.46.1 简要分析 本实验中,我们点击图片中间的小图标的时候,刷屏程序和显示字符程序得予运行。 7.46.2 硬件设计 硬件设计同上 7.46.3 软件分析 进入例程的文件夹,然后打开\MDK-ARM \ Project.uvproj 文件 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 617 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下面开始具体分析程序代码: 代码分析 1:本实验,初始化触摸屏,调用函数 LCD_Image2LcdDrawBmp565Pic(0, 0, gImage_image), 显示图片。 代码分析 2:点击小图标后,触发显示事件。 我们首先,显示一个有 9 个图标的图片。通过函数 ARMJISHU_TouchScreen_ADS7843( )读取触 摸点的信息。通过 if 语句判断触摸点是否在所限定的范围内,如果在的话,执行触发事件将屏刷成 黑色,。大家可以在此添加自己的触发事件。 7.46.4 下载与测试 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按 如何通过 MDK 编译和在线调试 小 节进行操作 7.46.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将正常显示如下图片,我 们点击图片中央的小图标,小图标变色。随后屏幕变成黑色。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 618 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.47 双击小图标触发实验 7.47.1 简要分析 本实验中,我们点击两次图片中间的小图标的时候,刷屏程序和显示字符程序得予运行 7.47.2 硬件设计 硬件设计同上 7.47.3 软件分析 进入例程的文件夹,然后打开\Project \ Project.uvproj 文件 下面开始具体分析程序代码: 代码分析 1:本实验,初始化触摸屏,调用函数 LCD_Image2LcdDrawBmp565Pic(0, 0, gImage_image), 显示图片。 代码分析 2:点击两次小图标后,触发显示事件。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 619 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们首先,显示一个有 9 个图标的图片。再通过两次读取触摸信息,实现点击两次图标,触发 刷屏程序和显示字符串程序。 while(1)大循环里面有两个 while 循环。大循环中程序进入第一个 while 循环。判断触摸点的 位置,如果是在中间的小图标的范围内的话,使小图标底色变色,并跳出本循环。而后,进入第二 个 while 循环,等待下一个触摸的到来。如果又发生触摸,并且范围还在中间的小图标的范围内,则 触发刷屏程序。 7.47.4 实验现象 将固件下载到神舟 III 号开发板后,复位,神州 III 号开发板正常情况下将正常显示如下图片,我 们点击图片中央的小图标两次。随后屏幕变成黑色。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 620 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.48 TFT彩色液晶屏显示英文字 7.48.1 什么是字模 液晶屏其实就是一个由许多像素点组成的点阵,若要在上面显示一个字符,则需要很多像素 点共同构成,比如 8*16 的 ASCII 码字符,或者 16*16 的点阵显示的汉字。 如果每个 8*16 或者 16*16 的点阵区域来显示一个字符,把黑色的像素点以 1 来表示,空白 以 0 表示,每个像素点的状态以一个二进制位来记录,用 8*16/8=16 个字节或者 16*16/8=32 个 字节就可以把这个字记录下来。这个 16 字节或者 32 字节就被称之为该字符的字模,当然还有 其他常用的字模是 24*24,32*32 的。 可以把这个‘字模’两个字转化成以下的 32 个字节的字模: 比如看下,开头的 0x02 和 0x00,就是显示’字’的最上面那一点,显示第一行;比如下面这一行黑体, 可以数一下,从上面往下数是第 10 行,那么可以看到第 10 行是 0x7F 和 0xFE,确实是一个正确的 字模显示;在这样的字模中,以两个字节表示一行像素点,16 行构成一个字模: 7.48.2 ASCII码的字符解释 下图是 ASCII 码字符表 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 621 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 现在将这些 ASCII 字符表转化成 8x16 的数组,也就是说一个字符的高度是 8,宽度是 16,16 也就是两个字节,那么一个字符就是 8 行,每行都是 16 个 bit,等于是 8*16/8 = 16 个字节大小。可 以看到下面的 ASCII 字符,红框框住的是 16 个字节,显示一个字符。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 622 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到整个数组 ascii_8x16[1536]总共有 1536 个成员,每个成员就是一个单独的字节,而 16 个字节就是一个字符,那么这个数组总共能描述多少个字符呢?总共是 1536/16 = 96 个字符,从下 面的这张表来看,这个 96 个字符就是描述的是从 ASCII 值 32 到 127 这 96 个字符。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 623 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 比如我们希望显示 www.armjishu.com 到液晶屏上,那么这个LOGO所有的字符都能在ASCII码 表中通过查表获得,接下来的软件分析会进一步分析如何用具体的软件代码来显示字符到LCD液晶 屏上。 7.48.3 硬件设计 硬件设计同上 7.48.4 软件分析 进入例程的文件夹,然后打开\Project \ MDK-ARM \ Project.uvproj 文件 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 624 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到工程已经被打开,下面开始具体分析程序代码: 我们主要讲解:屏方面的代码,串口打印部分参考前面的相关串口章节内容。 代码分析 1:ili9320_Initializtion()函数中的 ili9320_PutChar()函数就是显示英文字符的,该函数 完成的是在指定座标显示一个 8x16 点阵的 Ascii 字符,ili9320_PutChar(u16 x,u16 y,u8 c,u16 charColor,u16 bkColor)函数的 x 是行座标;y 是列座标;charColor 是字符的颜色;bkColor 是字符背 景颜色。 代码分析 2: 符是黄色的字符颜色,背景色是红色的。 可以看到显示的字 str[] = " Welcome jesse to www.armjishu.com ! "这个是希望显示的字符,这里需要注意的是,字 符是一个 一 个来显示 的 ,str[i]表示 需要显示 的 那个字符 , 这个字符 显 示的位置 在 X 坐标是 (StartX.+8*i),y 坐标是 60。 代码分析 3:接下来详细分析一下 ili9320_PutChar()函数,看看到底如何显示一个字符的 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 625 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 a) str[] = " Welcome jesse to www.armjishu.com ! ",str[i]是一个 ASCII 字符,可以参考上面进行 查表得知 b) tmp_char = Ascii_8x16[((c-0x20)*16)+i] 首先数组 Ascii_8x16[1536]每 16 个成员是一个字符,因为 ASCII 码是从 32 开始的,而数组是从 0 开始的,所以首先要减掉一个 32(16 进制 0x20 化成二进制就是 32);然后(c-0x20)*16 是因为 Ascii_8x16[]数组中每经过 16 个字节就会真正指向下一个字符的首地址。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 626 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 c) for (i=0;i<16;i++)一个 for 循环,把显示一个字符的 16 个字节都循环到位 d) 接下来,把显示一个字符的 16 个字节里,每个字节都是 8 个 bit 都循环到位,并且判断这个 bit 是 1 还是 0,如果是 1,就显示字符的颜色,表示这个字符这里是黑体的;如果是 0,就 显示预先设置好的背景的颜色。 7.48.5 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 627 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 节进行操作。 7.48.6 实验现象 将固件下载到神舟 III 开发板后,复位,神舟 III 号开发板正常情况下将显示一串英文字符。 7.49 TFT彩色液晶屏显示中文字 7.49.1 使用工具将中文字转换成二进制码 进入光盘打开神舟 I 号的软件工具中,找到’神舟开发板汉字生成软件工具’文件夹: 第一步:打开 第二步: 第三步: 打开这个软件 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 628 页,共 788 第四步:把结果复制进去 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.49.2 硬件设计 硬件设计同上 7.49.3 软件分析 进入例程的文件夹,打开例程 进入到 main()函数中: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 629 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:液晶屏的初始化等细节前面的例程都有详细介绍,这个例程中主要是这个函数用来显示 中文字符的 LCD_DisplayWelcomeStr(0x60);它显示了这个数组中所有的字符 用 一 个 for 循 环 来 显 示 WelcomeStr[13][] 中 的 13 个 字 符 : 具体的每个字符显示是通过 LCD_DrawChinaChar()这个函数进行显示的 代码分析 2:LCD_DrawChinaChar(X, Y, const u8 *c)函数是显示一个字符到 LCD 上,X 和 Y 分别是 嵌入式专业技术论坛 (www.armjishu.com)出品 第 630 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 LCD 横坐标和纵坐标,const u8 *c 是需要显示的字符的字模,就是一些二进制数,这个函数的具体 实现如下: a) 首先先设置好光标,就是字符显示的起始点,这个在代码中也是由用户确定的位置,你 想到 LCD 哪个位置显示都可以自己灵活的去通过修改参数来达到目的 b) 因为这里转的字符的字模是 72 个字节,每个字节可以描述 8 个点,每个点显示到 LCD 上需要一个一个来描述,所以可以计算一下 72 个字节分成 24 组,每组 3 个字节,每个 字节可以描述 LCD 显示 8 个点,每个点调用如果是 1 就显示字体的颜色,如果是为 0 就显示字体背景的颜色,这里颜色的显示是通过调用 LCD_WriteRAM()函数来完成的 c) 在写颜色之前,每次都调用一下 LCD_WriteRAM_Prepare()这个函数,告诉液晶屏准备 写 GRAM,写 GRAM 就是写 LCD,LCD 的颜色实际上是通过写 GRAM,再由 LCD 内 部的控制器去从 GRAM 中抓取显示内容,显示到 LCD 上的。 7.49.4 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.49.5 实验现象 将固件下载到神舟 III 号开发板后,复位,神舟 III 号开发板正常情况下将显示一串中文字符。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 631 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.50 TFT彩色液晶屏显示中英文字 7.50.1 硬件设计 硬件设计同上。 7.50.2 软件分析 软件设计参考 TFT 液晶屏显示英文章节和 TFT 液晶屏显示英文章节。 7.50.3 下载与测试 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.50.4 实验现象 将固件下载到神舟III号后,复位,神舟III号正常情况下将显示一串英文字符和中文字 符 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 632 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.51 SD卡读卡器实验 7.51.1 SD卡读卡器实验的意义与作用 神舟III号开发板资源丰富,关于USB部分,除了前一个例程介绍的,如何通过USB接口访问神 舟III号板载的NAND Flash以外,本节将介绍,如何通过USB接口访问神舟III号上插入的SD卡。即用 STM32处理器实现我们常说的SD卡读卡器。 通过本实验,我们将对前一例程中使用的USB接口更进一步的认识,同时,我们还可以对SD卡 有一个更深入的了解。本实验参考ST的Mass_Storage例程,针对神舟III号的硬件修改代码设计,使用 SDIO方式来读写SD卡,实现SD读卡器功能。 7.51.2 试验原理 SD卡读卡器实验原理简介:首先程序运行后,初始化实验需要使用的到串口和GPIO管脚,然后 初始化访问SD卡要使用的SDIO接口与USB接口。检测SD卡在,待SD卡插入之后,就开始USB的配 置,在配置成功之后既可以在电脑上发现可移动磁盘了。 其中DS2和DS3 LED用于指示初始化过程,DS1用来指示USB正在读写SD卡。 7.51.3 硬件设计 SD卡读卡器实验要用到的硬件资源有: ¾ 串口 1:串口 1 在本实验中打印程序运行过程中的提示信息。关于串口,在前面的实验已经 进行了详细的讲解,在这里就不在重复。 具体见 4.5 串口 1 的发送与接收实验。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 633 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ LED 指示灯:LED 指示灯主要用于指示程序运行状态。 ¾ SD 卡座:神舟 III 号最大支持 2G 的 SD 卡 ¾ USB 接口:使用 USB 接口与电脑连接,将 SD 卡插入神舟 III 号 SD 卡座后,运行程序,可 以在电脑上检测到一个 U 盘设备。并可以进行读写操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 634 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 SD 卡读卡器实验使用的资源主要是 USB 接口和 SD 卡座两部分,分别如下图所示: 4.20.3.1.USB接口硬件原理 上图中的 J6 为神舟 III 号上的 USB 接口 B 型座。U11 为 USB 接口 ESD 防护器件。,满足 ESD 防护 标准 IEC61000-4-2(ESD 15kV air, 8kV Contact) 。 STM32F103ZET处理器管脚功能具体如下 管脚 功能描述 PA11 USB 接口差分信号的负端 PA12 USB 接口差分信号的正端 PG11 USB 接口上拉控制管脚,用于判断是否有设备插入,当 PG11 输出高电平时,电 脑上检测到一个全速 USB 设备。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 635 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.20.3.2.SD卡座硬件原理 神舟III号开发板载标准的SD卡座,采用SDIO接口通信,通过这个接口,我们就可以外扩大容量 存储设备,可以用来记录数据,存放音乐文件等。其原理图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 636 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 STM32F103ZET6 处理器的 SD/SDIO MMC 卡主机模块(SDIO)在 AHB 外设总线和多媒体卡 (MMC)、SD 存储卡、SDIO 卡和 CE-ATA 设备间提供了操作接口。 SDIO 的主要功能如下: — 与多媒体卡系统规格书版本 4.2 兼容。支持三种不同数据总线模式:1 位(默认)、4 位和 8 位。 — 与较早的多媒体卡系统规格版本全兼容(向前兼容)。 — 与 SD 存储卡规格版本 2.0 全兼容。 — 与 SD I/O 卡规格版本 2.0 全兼容:支持良种不同的数据总线模式:1 位(默认)和 4 位。 — 完全支持 CE-ATA 功能(与 CE-ATA 数字协议版本 1.1 全兼容)。 — 8 位总线模式下数据传输速率可达 48MHz。 — 数据和命令输出使能信号,用于控制外部双向驱动器。 SDIO 的逻辑框图如下: 在神舟 III 号中,使用的是 SDIO 接口来读写访问 SD 卡,其中 SDIO 工作在 4 位数据模式 ,具体的 管脚功能如下表。 管脚 功能 描述 PC6 SC_NCD SD 卡在位检测 PC8 SDIO_D0 多媒体卡/SD/SDIO 卡数据。双向数据总线 PC9 SDIO_D1 PC10 SDIO_D2 PC11 SDIO_D3 PC12 SDIO_CK 多媒体卡/SD/SDIO 卡时钟。从主机至卡的时钟线 PD2 SDIO_CMD 多媒体卡/SD/SDIO 卡命令。双向的命令/响应信号线 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 637 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.20.3.3.SD卡介绍 SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器 的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体 播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。大小犹如一张 邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及 很好的安全性。 SD卡一般支持2种操作模式: 1,SD卡模式; 2,SPI模式; 主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。SPI模式允许 简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。 在神舟III号中,是使用SDIO接口来访问SD卡,即所说的SD卡模式。 SD卡的引脚排序如下图所示: SD卡引脚功能描述如下表所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 638 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.51.4 软件设计 4.20.4.1.GPIO与串口初始化 在SD卡读卡器实验中,使用了神舟III号的LED灯指示程序运行状态,而串口则输出提供信息,这一 些硬件资源,再前面已经详细讲解过,因此在这里,只是简单的介绍他们的初始化程序。 串口 1 初始化 — GPIO 初始化程序 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 639 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.20.4.2.MAL(媒体接入层)初始化 MAL初始化函数MAL_Init(uint8_t lun)主要实现SD接口的初始化,获取SD卡的信息等。 SD卡的典型初始化过程如下: ¾ 初始化与SD卡连接的硬件条件; ¾ 上电延时(>74个CLK); ¾ 复位卡; ¾ 激活卡,内部初始化并获取卡类型; ¾ 查询OCR,获取供电状况(; ¾ 是否使用CRC; ¾ 设置读写块数据长度; ¾ 读取CSD,获取存储卡的其他信息); ¾ 发送8CLK后,禁止片选; 这样我们就完成了对SD卡的初始化,这里面我们一般设置读写块数据长度为256个字节,并禁止 使用CRC。在完成了初始化之后,就可以开始读写数据了。 4.20.4.3.中断配置 在SD读卡器实验中,使用到了USB接口和SDIO接口,程序运行时,需要对他们的中断组和中断 优先级进行配置,一般来说,越需要及时响应的中断设置的中断组级别越高(0级最高),同一组内 的中断优先级也越高(0是同一组中断内的最高优先级)。如下为SD卡读卡器的中断优先级配置。 如上设计中,SDIO_IRQn的优先级最高,当SDIO_IRQn产生中断时,可以抢占其他中断,优选 执行,主要是它的NVIC_IRQChannelPreemptionPriority比其他的中断要高。而另两个USB的中断,他 们 的 优 先 级 在 相 同 的 组 里 , USB 的 两 个 中 断 同 时 产 生 时 , 处 理 器 自 动 优 先 执 行 USB_HP_CAN1_TX_IRQn中断。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 640 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.20.4.4.USB接口初始化 USB接口初始化在前面已经进行了详细的实验,在本实验中,就不再详细描述,相关的初始化 代码如下: 当USB接口初始化完成以后,LED灯DS3将常亮。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 641 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.20.4.4.SD卡数据读写 SD卡部分,最重要的就是2个函数,一个MSD_WriteBuffer函数,用于向SD卡写入数据,当你要 COPY文件到SD卡的时候,就是由这个函数完成的。另外一个是MSD_ReadBuffer函数,该函数用于 读取SD卡上面的数据。 SD卡读取数据,具体过程如下: ¾ 发送MSD_READ_SINGLE_BLOCK(CMD17); ¾ 接收卡响应R1; ¾ 接收数据起始令牌0XFE; ¾ 接收数据; ¾ 接收2个字节的CRC,如果没有开启CRC,这两个字节在读取后可以丢掉。 ¾ 8CLK之后禁止片选; 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 642 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下: ¾ 发送MSD_WRITE_BLOCK(CMD24); ¾ 接收卡响应R1; ¾ 发送写数据起始令牌0XFE; ¾ 发送数据; ¾ 发送2字节的伪CRC; ¾ 8CLK之后禁止片选; 以上是一个典型的写SD卡过程。关于SD卡的介绍,我们就介绍到这里,更详细的介绍请参考SD卡 的参考资料。 7.51.5 下载与测试 在 神舟III号光盘\编译好的固件\20.USB读卡器实验目录下的USB读卡器.hex文件即为前面我们 分析的USB读卡器实验编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板中, 观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调 试 小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 643 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.51.6 实验现象 将程序下载到神舟III号后,插入SD卡(最大支持2G),将神舟III号的USB接口与电脑的电脑连 接后,重新上电运行,电脑上将提示发现USB设备。 进入电脑的设备管理器,可以看到USB SD读卡器的详细信息。 与此同时,神舟III号的串口1(波特率115200)将打印如下信息。 神舟III号的LED灯也将指示USB读卡器的状态。 LED指示灯 含义 DS1闪烁 USB读卡器正在进行读写操作, 当我们往SD卡内拷贝数据或者从SD卡读取数 据,将看到DS1闪烁。 DS2亮 MAL配置完成指示灯,正常情况下,DS2亮。 DS3亮 USB接口初始化完成指示灯,正常情况下,DS3亮。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 644 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 645 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.52 音频播放试验 7.52.1 实验原理 本实验主要是初始化DA芯片PCM1770后,处理器读取预先放置在处理器内部的音频文件,判断 音频文件是否合法,并依据音频文件的格式设置I2S3接口的参数,然后处理器采用中断方式通过I2S3 接口重复播放该音频文件。 7.52.2 硬件设计 SD卡读卡器实验要用到的硬件资源有: ¾ 串口 1:串口 1 在本实验中打印程序运行过程中的提示信息。关于串口,在前面的实验已经 进行了详细的讲解,在这里就不在重复。 具体见 4.5 串口 1 的发送与接收实验。 ¾ PCM1770:将从 I2S3 接口传过来的音频音频信号输出到耳麦接口。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 646 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 D/A 芯片 PCM1770 通过 I2S3 接口与 STM32F103ZET6 处理器连接。音频信号通过 I2S3 接口传 到 D/A 芯片,转换成音频信号播出。相关管脚定义如下: GPIO 管脚 功能描述 说明 PA15 I2S3_WS 左右通道时钟,频率和音频采样速率一致。该信 号与 JTAG 接口的 JTDI 信号复用同一个管脚。 PB3 I2S3_CK 串行比特时钟。该信号与 JTAG 接口的 JTDO 信 号复用同一个管脚。 PB5 I2S_SD 串行音频信号。 PC7 I2S3_MCK 系统时钟输入 STM32F103ZET6 处理器通过 SPI2 接口访问 DA 芯片 PCM1770,对它内部数据进行读取和配置。相 关管脚定义如下: GPIO 管脚 功能描述 说明 PB11 SPI2_NSS SPI2 接口片选信号 PB13 SPI2_SCK SPI2 接口 SCK 时钟信号 PB15 SPI2_MOSI SPI2 接口的 MOSI 信号 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 647 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 4.21.2.1.DAC芯片说明 在神舟 III 号中,使用了 TI 公司推出的低电压,低功耗带耳机放大的 DAC 芯片 PCM1770,来实现音 频的 DA 转换。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 648 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.52.3 软件设计 在本实验中,采用的是 I2S 中断方式来播放音乐,主程序实现如下 在上面程序中,I2S_Codec_init()函数主要是实现音源文件是否正确,并设置合适的频率播放 音源文件。在此就不进行详细讲解,有兴趣的朋友可以查阅工程文件,了解函数的具体实现,接下 来我们对一些基本的函数进行分析。 ¾ LED GPIO 与串口初始化 在音频播放实验中,LED 主要用于指示程序运行状态,因此,我们首先运行 LED_Config 函数,将 LED 使用的 GPIO 接口配置成推挽输出。 为了从串口输出程序运行提示信息,我们需要初始化串口 1,关于串口 1 的配置在前面的例程中已经 进行了详细的讲解,在这里,我们就不在进行分析。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 649 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ I2S 接口初始化 查看神舟 III 号原理图可知, D/A 芯片 PCM1770 通过 I2S3 接口与 STM32F103ZET6 处理器连接。 音频信号通过 I2S3 接口传到 D/A 芯片,转换成音频信号播出。相关管脚定义如下: GPIO 管脚 功能描述 说明 PA15 I2S3_WS 左右通道时钟,频率和音频采样速率一致。 该信号与 JTAG 接口的 JTDI 信号复用同一个 管脚。 PB3 I2S3_CK 串行比特时钟。该信号与 JTAG 接口的 JTDO 信号复用同一个管脚。 PB5 I2S_SD 串行音频信号。 PC7 I2S3_MCK 系统时钟输入 由 于 SPI3/I2S3 的 部 分 管 脚 与 JTAG 管 脚 共 享 (SPI3_NSS/I2S3_WS 与 JTDI , SPI3_SCK/I2S3_CK 与 JTDO),因此这些管脚不受 IO 控制器控制,他们(在每次复位后)被默认保留 为 JTAG 用途。如果用户想把管脚配置给 SPI3/I2S3,必须(在 DEBUG 时)关闭 JTAG 并切换至 SWD 接口,或者(在标准应用时)同时关闭 JTAG 和 SWD 接口。 在初始化 I2S 接口的时候,使用 Remap 功能,关闭了 JTAG 功能。在使用本程序时,JTAG 接口 就不能使用,但 SWD 调试接口可以正常使用。因此,在本实验中,在 MDK 中调试或者使用 J-FLASH 烧录固件的时候,必须配置成 SWD 模式。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 650 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ SPI 接口初始化 查看神舟 III 号原理图可知, STM32F103ZET6 处理器通过 SPI2 接口访问 DA 芯片 PCM1770,对 它内部数据进行读取和配置。相关管脚定义如下: GPIO 管脚 功能描述 说明 PB11 SPI2_NSS SPI2 接口片选信号 PB13 SPI2_SCK SPI2 接口 SCK 时钟信号 PB15 SPI2_MOSI SPI2 接口的 MOSI 信号 相关的初始化程序如下,SPI2_Config 函数主要是初始化 SPI2 接口使用的 GPIO 管脚。 初始化 PCM1770 使用的 SPI2 接口 CS 信号,输出高电平。 初始化 SPI 接口,设置 SPI2 接口的工作模式。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 651 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ¾ SysTick 初始化 其中SysTick主要是初始化硬件SysTick定时器,定时产生中断,在本程序中,初始化SysTick为10mS, 相关程序如下。 在 本 实 验 中 , SysTick 定 时 器 的 时 钟 源 是 72M, 即 SystemCoreClok 为 72000000Hz , 所 以 SysTick_Config(SystemCoreClok/ 100) 就是10ms时基。 在音频播放实验中,我们采用的是 I2S3 中断方式的方式来实现音频播放。当 I2S3 产生中断时, 就进入 I2S3 的中断服务程序,调用音频播放程序 I2s_CODEC_DataTransfer(),因此,我们可以重复 听到相同的音频。 InterruptConfig函数按照中断的重要性,进行中断组设置和中断优先级设计,相关代码如下: 在本实验中,相关的中断之后SPI3中断,因此设置中断组为0,中断优先级也为0即可。 I2S3 的中断服务程序如下。当 I2S3 进入中断服务程序时,就调用 I2S_CODEC_DataTransfer()程序播 放音乐。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 652 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.52.4 下载与测试 在 神舟III号光盘\编译好的固件\21音频播放实验目录下的音频播放实验.hex文件即为前面我们 分析的音频播放实验编译好的固件,我们可以直接通过JLINK V8将固件下载到神舟III号开发板中, 观察运行效果。 如果使用JLINK下载固件,请按 如何使用JLINK V8下载固件到神舟III号开发板 小节进行操作。 如果使用串口下载固件,请按 如何使用串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调 试 小节进行操作。 注意:由于本实验中,I2S3与JTAG功能接口有复用,为了使用I2S3接口,我们需要禁止JTAG接 口,在调试和下载时,请使用SWD接口。 7.52.5 试验现象 将程序下载到神舟III号后,将耳机插入音频口(J2)以后,重新上电运行,正常情况下,从耳 机里可以听到悦耳的歌声。同时串口1(波特率115200)输出如下打印信息,提示程序运行情况。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 653 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.53 硬件CRC循环冗余检验实验 CRC 是(Cyclic Redundancy Check)的缩写,意思是循环冗余校验。CRC 循环冗余校验技术主要 应用于核实数据远程传输或者数据存储的正确性和完整性。神舟系列开发板使用的 STM32 芯片都内 置了一个硬件的 CRC 计算模块,本章节我们讲述该硬件模块的使用。 7.53.1 意义与作用 CRC 校验可以硬件完成,可以软件实现。本多处理器内部没有硬件 CRC 校验电路,只能使用软 件实现,但是软件实现需要占用 CPU 和 RAM 资源,而且速度稍慢。神舟系列开发板使用的 STM32 芯片内置了一个硬件的 CRC 计算模块,可以在通信的检测错误和数据完整性方面发挥优异的性能, 本章节我们讲述该硬件模块的使用。 7.53.2 实验原理 CRC 循环冗余校验计算单元是根据固定的生成多项式得到任一 32 位全字的 CRC 计算结果。在 其他的应用中, CRC 技术主要应用于核实数据传输或者数据存储的正确性和完整性。标准 EN/IEC 60335-1 即提供了一种核实闪存存储器完整性的方法。CRC 计算单元可以在程序运行时计算出软件 的标识,之后与在连接时生成的参考标识比较,然后存放在指定的存储器空间。 所有的 STM32 芯片都内置了一个硬件的 CRC 计算模块,可以很方便地应用到需要进行通信的 程序中,这个 CRC 计算模块使用常见的、在以太网中使用的计算多项式: X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1 写成十六进制就 是:0x04C1 1DB7。STM32 芯片的硬件 CRC 计算单元框图如下: 图表 18 CRC 计算单元框图 使用这个内置 CRC 模块的方法非常简单,既首先复位 CRC 模块(设置 CRC_CR=0x01),这个操 作把 CRC 计算的余数初始化为 0xFFFFFFFF;然后把要计算的数据按每 32 位分割为一组数据字,并 逐个地把这组数据字写入 CRC_DR 寄存器(既上图中的绿色框),写完所有的数据字后,就可以从 CRC_DR 寄存器(既下图中的兰色框)读出计算的结果。 注意:虽然读写操作都是针对 CRC_DR 寄存器,但实际上是访问的不同物理寄存器。 下面是用 C 语言描述的这个计算模块的算法,大家可以把它放在通信的另一端,对通信的正确 性进行验证: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 654 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 有几点需要说明: 1)上述算法中变量 CRC,在每次循环结束包含了计算的余数,它始终是向左移位(既从最低位向最 高位移动),溢出的数据位被丢弃。 2)输入的数据始终是以 32 位为单位,如果原始数据少于 32 位,需要在低位补 0,当然也可以高位 补 0。 3)假定输入的 DWORD 数组中每个分量是按小端存储。 4)输入数据是按照最高位最先计算,最低位最后计算的顺序进行。 例如: 如果输入 0x44434241,内存中按字节存放的顺序是:0x41, 0x42, 0x43, 0x44。计算的结果是: 0xCF534AE1 如果输入 0x41424344,内存中按字节存放的顺序是:0x44, 0x43, 0x42, 0x41。计算的结果是: 0xABCF9A63 7.53.3 硬件设计 CRC 计算单元是 STM32 处理器内部硬件组件,这部分不需要硬件电路,这里仅将计算结果在串口 打印出来。 7.53.4 软件设计 本实验循环重复计算一段已知数据的 CRC 校验结果并打印,这段已知数据如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 655 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 关于串口打印相关知识请查看“串口 2 的 Printf 输出实验”章节。 本实验比较简单,下面我们之间看 MAIN 主函数,MAIN 主函数开始首先是初始化串口 2,如下: 首 先 调 用 SZ_STM32_SysTickInit(1000) 函 数 初 始 化 系 统 定 时 器 , 调 用 RCC_AHBPeriphClockCmd( )使能 CRC 时钟。 最后是 while 循环,循环内首先给 CRC 寄存器置初值,CRC_ResetDR 置初值很关键,否则循环 打印出的 CRC 结果一次和一次不同,最后是计算已知数据的 CRC 校验结果并打印,如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 656 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.53.5 下载与验证 如果使用JLINK下载固件,请按3.2如何使用JLINK软件下载固件到神舟III号开发板小节进行 操作。 如果使用串口下载固件,请按3.3如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.5如何在MDK开发环境中使 用JLINK在线调试小节进行操作。 7.53.6 实验现象 将固件下载在神舟III号STM32开发板后,用随板配置的串口线连接神舟III号串口1与电脑的串 口,打开超级终端,并按如下参数配置串口。 图表 19 超级终端串口参数配置 以下是下载固件后上电运行神舟 III 号时串口的打印信息,每次校验得到相同结果: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 657 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 658 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.54 PVD电源电压监测实验 7.54.1 意义与作用 相信大家都有这样的经历,使用 PC 电脑做文档编辑时突然停电而没有保存文档,重新开机后可 能刚才的辛苦付之东流。工业控制领域的主控系统突然断电可能会造成无法挽回的经济损失甚至造 成严重的安全事故,这样的意外时一个可靠的工控系统无法容忍的。如果在主控掉电的瞬间能及时 执行一些操作,比如及时存盘或者及时关闭正在高速运转的机械设备等,神舟系列 STM32 开发板的 处理器内部集成了 PVD,可以帮您实现这个应用。 PVD 是 Power supply supervisor 的缩写,意思是可编程电压监测器。 用户可以利用 PVD 对 VDD 电压与电源控制寄存器(PWR_CR)中的 PLS[2:0]位进行比较来监控电 源,这几位选择监控电压的阀值。通过设置 PVDE 位来使能 PVD。电源控制/状态寄存器(PWR_CSR) 中的 PVDO 标志用来表明 VDD 是高于还是低于 PVD 的电压阀值。该事件在内部连接到外部中断的 第 16 线,如果该中断在外部中断寄存器中是使能的,该事件就会产生中断。当 VDD 下降到 PVD 阀 值以下和(或)当 VDD 上升到 PVD 阀值之上时,根据外部中断第 16 线的上升/下降边沿触发设置,就 会产生 PVD 中断。例如,这一特性可用于用于执行紧急关闭任务。 7.54.2 实验原理 本实验演示神舟系列 STM32 开发板处理器内部的 PVD 电压监控功能,当检测到电压低于 2.9V (可以灵活设置这个阈值)时,将产生 PVD 中断,我们在中断中以串口打印“Bye!”来演示“执行 紧急处理任务”。 电源管理器(PVD) 图表 20 STM32 的 PVD 的门限示意图 1)PVD = Programmable Votage Detector 可编程电压监测器 它的作用是监视供电电压,在供电电压下降到给定的阀值以下时,产生一个中断,通知软件做 紧急处理。在给出表格的上半部分就是可编程的监视阀值数据。当供电电压又恢复到给定的阀值以 上时,也会产生一个中断,通知软件供电恢复。供电下降的阀值与供电上升的PVD阀值有一个固定 的差值,这就是表中的VPVDhyst(PVD迟滞)这个参数,通过列出的PVD阀值数据可以看到这个差别。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 659 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 引入这个差值的目的是为了防止电压在阀值上下小幅抖动,而频繁地产生中断。 电源管理器(PVD)寄存器的值与电压阈值之间的关系: 用户可以利用PVD对VDD电压与电源控制寄存器中的PLS[2:0]位进行比较来监控电源,这几位 选择监控电压的阀值。通过设置PVDE位来使能PVD。 电源控制/状态寄存器中的PVDO标志用来表明VDD是高于还是低于PVD的电压阀值。该事件在 内部连接到外部中断的第16线。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时, 根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。这一特性可用于用于执行紧急 关闭任务。 7.54.3 硬件设计 PVD 可编程电压监测器单元是 STM32 处理器内部硬件组件,这部分不需要硬件电路,这里仅将计 算结果在串口打印出来。 7.54.4 软件设计 我们先从 MAIN 函数看起,如下所示,第一部分是初始化串口等,这部分知识在前面章节已经 讲解过,请回顾相关章节的知识。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 660 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 接下来是使能 PVD 相关的寄存器和相关参数,其中监控电压的阈值就是下面这个函数决定的 “PWR_PVDLevelConfig(PWR_PVDLevel_2V9)”。 你可以根据你的实际需要更改参数来设置不同的监控电压的阈值,可选的参数有: 最后是循环打印提示信息等待 PVD 中断,用户可以使用关闭神舟开发板电源的方式来产生 PVD 中断: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 661 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 MAIN 中的 SZ_STM32_PVDConfiguration( )函数配置使能外部中断第 16 线的上升/下降边沿触发: 设置外部中断第 16 线的中断优先级: 中断处理函数如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 662 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.54.5 下载与验证 如果使用JLINK下载固件,请按3.3如何使用JLINK软件下载固件到神舟III号开发板小节进行 操作。 如果使用串口下载固件,请按3.4如何通过串口下载一个固件到神舟III号开发板小节进行操作。 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按3.8如何在MDK开发环境中使 用JLINK在线调试小节进行操作。 7.54.6 实验现象 本实验演示神舟系列 STM32 开发板处理器内部的 PVD 电压监控功能,当检测到电压低于 2.9V (可以灵活设置这个阈值)时,将产生 PVD 中断,我们在中断中以串口打印“Bye!”来演示“执行 紧急处理任务”。 将固件下载在神舟 III 号 STM32 开发板后,用随板配置的串口线连接神舟 III 号串口 1 与电脑的 串口,打开超级终端,串口参数配置为 。用户可以使用关闭神舟开发板电源的方式来产生 PVD 中断。 连接好串口,按下复位键之后,开发板一直向串口打印数据。断电,串口打印“Bye!”。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 663 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.55 STM32低功耗之--STANDBY待机模式 7.55.1 意义与作用 在系统或电源复位以后,微控制器处于运行状态。当 CPU 不需继续运行时,可以利用多种低功 耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可 用的唤醒源等条件,选定一个最佳的低功耗模式。 7.55.2 STM32低功耗模式介绍 STM32 有一个低功耗模式,在系统或电源复位以后,微控制器处于运行状态。运行状态下的 HCLK 为 CPU 提供时钟,内核执行程序代码。当 CPU 不需继续运行时,可以利用多个低功耗模 式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗,最快速启动时间和可用的 唤醒源等条件,选定一个最佳的低功耗模式。STM32 的 3 种低功耗模式;STM32 的低功耗模式有 3 种: 1)睡眠模式(CM3 内核停止,外设仍然运行) 2)停止模式(所有时钟都停止) 3)待机模式(1.8V 内核电源关闭) 7.55.3 待机模式 待机模式可实现系统的最低功耗。该模式是在 Cortex-M3 深睡眠模式时关闭电压调节器。整个 1.8V 供电区域被断电。PLL、HSI 和 HSE 振荡器也被断电。SRAM 和寄存器内容丢失,只有备份的 寄存器和待机电路维持供电。 在这三种低功耗模式中,最低功耗的是待机模式,在此模式下,最低只需要 2uA 左右的电流。 停机模式是次低功耗的,其典型的电流消耗在 20uA 左右。最后就是睡眠模式了。用户可以根据自 己的需求来决定使用哪种低功耗模式。 我们仅对 STM32 的最低功耗模式-待机模式,来做介绍。待机模式可实现 STM32 的最低功耗。 该模式是在 CM3 深睡眠模式时关闭电压调节器。整个 1.8V 供电区域被断电。PLL、HSI 和 HSE 振 荡器也被断电。SRAM 和寄存器内容丢失。仅备份的寄存器和待机电路维持供电。 待机模式下的输入/输出端口状态在待机模式下,所有的 I/O 引脚处于高阻态,除了以下的引 脚: ● 复位引脚(始终有效) 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 664 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ● 当被设置为防侵入或校准输出时的 TAMPER 引脚 ● 被使能的唤醒引脚 7.55.4 进入待机模式 关于如何进入待机模式,详见表 12。 可以通过设置独立的控制位,选择以下待机模式的功能: ● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动 IWDG。一旦启动了独立 看门狗,除了系统复位,它不能再被停止。 ● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的 RTCEN 位来设置。 ● 内部 RC 振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的 LSION 位来设置。 ● 外部 32.768kHz 振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的 LSEON 位设置。 WFI = wait for interrupt 等待中断,即下一次中断发生前都在此 hold 住不干活 WFE = wait for event 等待事件,即下一次事件发生前都在此 hold 住不干活 上表还列出了退出待机模式的操作,从上表可知,我们有 4 种方式可以退出待机模式,即当一 个外部复位(NRST 引脚)、IWDG 复位、WKUP 引脚上的上升沿或 RTC 闹钟事件发生时,微控制器 从待机模式退出。从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位。从待 机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚,读取复位向量等)。电源控制/状 态寄存器(PWR_CSR)将会指示内核由待机状态退出。 说明:进入待机模式,JTAG 是无法仿真和下载程序的,如果你写这个程序的时候不小心使系统一直 进待机模式,也不要怕。可以通过切换 BOOT 引脚,使用串口 ISP 下载程序,清除 FLASH 就可以 啦。 7.55.5 待机模式寄存器介绍 上面我们已经说明了进入待机模式的通用步骤,其中涉及到 2 个寄存器,电源控制寄存器 (PWR_CR)和电源控制/状态寄存器(PWR_CSR)。下面我们介绍一下这两个寄存器: 电源控制寄存器(PWR_CR),该寄存器的各位描述如下 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 665 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这里我们通过设置 PWR_CR 的 PDDS 位,使 CPU 进入深度睡眠时进入待机模式,同时我们通 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 666 页,共 788 过 CWUF 位,清除之前的唤醒位。 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 电源控制/状态寄存器(PWR_CSR)的各位描述如下 这里,我们通过设置 PWR_CSR 的 EWUP 位,来使能 WKUP 引脚用于待机模式唤醒。WUF 位 也可以用来检查是否发生了唤醒事件。 7.55.6 待机唤醒步骤 1)使能电源时钟。 因为要配置电源控制寄存器,所以必须先使能电源时钟。 2)设置 WK_UP 引脚作为唤醒源。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 667 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 因为要配置电源控制寄存器,所以必须先使能电源时钟。然后再设置 PWR_CSR 的 EWUP 位,使能 WK_UP 用于将 CPU 从待机模式唤醒。 3)设置 PDDS 位,执行 WFI 指令,进入待机模式。 接着我们通过 PWR_CR 设置 PDDS 位,使得 CPU 进入深度睡眠时进入待机模式,最后执行 WFI 指 令开始进入待机模式,并等待 WK_UP 中断的到来。 4)最后编写 WK_UP 中断函数。 因为我们通过 WK_UP 中断来唤醒 CPU,所以我们有必要设置一下该中断函数,同时我们也通过该 函数里面进入待机模式。 通过以上几个步骤的设置,我们就可以使用 STM32 的待机模式了,并且可以通过 WK_UP 来唤醒 CPU。 7.55.7 硬件设计 本实验中,我们使用了 LED 指示灯与两个按键完成本次的实验,配置 USER2 按键作为进入待 机模式按键,WAKEUP 按键作为唤醒按键即可,程序实现的功能是:按下 USER2 进入待机模式, LED 都灭了。再按下 WAKEUP 唤醒进入工作模式,LED 灯全部闪烁。使用的按键、指示灯请参考 前面的相关章节。 7.55.8 软件设计 我们先从 MAIN 函数看起,如下所示,第一部分是初始化按键、LED 指示灯等等,这部分知识 在前面章节已经讲解过,请回顾相关章节的知识 接下来是对 WakeUp 管脚唤醒处理器函数,系统定时器与 RTC 时钟的初始化,相关函数在后面 讲解 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 668 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 循环工作等待按键中断进入待机模式或者重新运行程序。中间并对 LED 进行一个延时闪烁的操 作。 深入分析程序代码 RTC 待 机 模 式 初 始 化 函 数 , 该 函 数 是 对 一 些 时 钟 使 能 与 寄 存 器 配 置 的 函 数 , 通 过 函 数 “PWR_GetFlagStatus”的返回值判断是否是等于“RESET”。无论返回值是否等于“RESET”,都各 种进行了一个对 RTC 配置操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 669 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 当 函 数 “ PWR_GetFlagStatus ” 的 返 回 值 不 等 于 “ RESET ” 的 话 , 进 行 一 个 PWR_ClearFlag(PWR_FLAG_SB)的操作,这个函数的目的是使电源控制寄存器(PWR_CR)的第四位 置 1,清除待机位,从而退出待机模式。而 PWR_FLAG 是等于 0x00000002 的; 当函数“PWR_GetFlagStatus”的返回值等于“RESET”的话则是对我们的 RTC 进行配置操作了, 从运行模式复位。 根据实验现象得到,我们按下 USER2 按键的时候,STM32 进入待机模式,那么我们看下它是 如何实现的,首先我们看下对 KEY 进行初始化的函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 670 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据原理图可得到我们的按键 USER2 为上拉输入的一个按键,我们对这个按键进行了一个中断的配 置,按键按下的时候产生中断信号,而由于它是上拉输入的,按键按下的时候,由高电平变为低电 平,所以我们要把它配置为下降沿触发中断。 KEY1 的中断函数为:EXTI3_IRQn,该函数中,判断“EXTI_GetITStatus();”函数返回值是 否是等于“RESET”,如果不等于的话,执行该函数“EXTI3_IRQHandler()”否则退出。 通过判断按键产生的中断信号,使得 EXTI_Line3 中断线产生触发请求,进入中断服务函数后,执行 “PWR_EnterSTANDBYMode()”函数。 嵌入式专业技术论坛 (www.armjishu.com)出品 第 671 页,共 788 页 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 “PWR_EnterSTANDBYMode()”函数的目的是配置我们的 STM32 进入我们的待机模式 先是对我们的 STM32 进行一个清除唤醒位的操作 然后是进入待机模式 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 672 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 这样,我们的 STM32 即可进入了我们的待机模式 那么 STM32 是如何退出待机模式的呢? 我们通过前面的描述中可知,退出待机模式的方法有 四种,分别是: 我们这里用到的是 WKUP 引脚控制,通过这个引脚的地址,使得按键按下去的时候,产生一个上升 沿唤醒我们的 STM32,在这里我们使用的是 PWR_WakeUpPinCmd(FunctionalState NewState);函数实 现。 到这里,我们已经能实现通过按键使得 STM32 进入待机模式与退出待机模式的实验。 7.55.9 下载与验证 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错 误!未找到引用源。小节进行操作。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 673 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.55.10 实验现象 将固件程序下载到神舟 III 号 STM32 开发板后,按下复位键。神舟 III 号开发板上的 LED 灯不 断的闪烁。按下按键 USER2,进入待机模式,LED 灯停止闪烁。按下按键 WAKEUP,唤醒,LED 灯恢复闪烁状态。 7.56 STM32低功耗之--STOP停止模式实验 7.56.1 意义与作用 在系统或电源复位以后,微控制器处于运行状态。当 CPU 不需继续运行时,可以利用多种低功 耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可 用的唤醒源等条件,选定一个最佳的低功耗模式。 本实现通过神舟V号STM32开发板学习STM32的低功耗模式中的STOP停止模式。 7.56.2 实验原理 停止模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压 调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。 在停止模式下,所有的I/O引脚都保持 它们在运行模式时的状态。 进入停止模式: 关于如何进入停止模式,详见表11。 在停止模式下,通过设置电源控制寄存器(PWR_CR)的 LPDS位使内部调节器进入低功耗模式,能够降低更多的功耗。 如果正在进行闪存编程,直到对内 存访问完成,系统才进入停止模式。 如果正在进行对APB的访问,直到对APB访问完成,系统才进 入停止模式。 可以通过对独立的控制位进行编程,可选择以下功能: ● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了独立看 门狗,除了系统复位,它不能再被停止。 ● 实时时钟(RTC):通过备份域控制寄存器 (RCC_BDCR)的RTCEN位来设置。 ● 内部RC振荡器(LSI RC):通过控制/状态寄存器 (RCC_CSR)的LSION位来设置。 ● 外部32.768kHz振荡器(LSE):通过备份域控制寄存器((RCC_BDCR)的LSEON位设置。 在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。通 过设置寄存器ADC_CR2的ADON位和寄存器DAC_CR的ENx位为0可关闭这2个外设。 退出停止模式 关于如何退出停止模式,详见下表。 当一个中断或唤醒事件导致退出停止模式时,HSI RC振荡 器被选为系统时钟。 当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段额外 的启动延时。如果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会 增加。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 674 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下面的表格说明如何进入和退出停止模式: 7.56.3 硬件设计 STOP 停止模式是 STM32 处理器的一种低功耗模式,这部分不需要特殊硬件电路,只要最小系统 运行正常即可,本实验使用的按键、指示灯和串口电路请参考前面的相关章节。 7.56.4 软件设计 我们先从 MAIN 函数看起,如下所示,第一部分是初始化按键、LED 指示灯等等,这部分知识 在前面章节已经讲解过,请回顾相关章节的知识。 接下来是 RTC 中断、系统定时器初始化,相关函数在后面讲解 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 675 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 最后是循环进入 STOP 停止模式(PWR_EnterSTOPMode)等待按键中断或中 RTC 闹钟中断来 唤醒处理器回到正常的工作模式: 深入分析实验代码 MAIN 函数中的 EXTI_Configuration 函数是配置使能外部中断第 17 线的上升边沿触发,这样才 能产生 RTC 闹钟报警中断: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 676 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 配置嵌套中断向量表,外部中断第 17 线中断函数,使能并设置外部中断第 17 线的 RTC 闹钟报 警中断优先级: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 677 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 MAIN 函数中的 SysTick_Configuration 函数是系统滴答中断及其中断优先级:这样在运行模式时使 4 个 LED 闪烁。系统滴答中断时使 4 个 LED 闪烁 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 678 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据 USER2 初始化后的按键中断函数,我们看下对 KEY 进行初始化的函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 679 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据原理图可得到我们的按键 USER2 为上拉输入的一个按键,我们对这个按键进行了一个中断 的配置,按键按下的时候产生中断信号,而由于它是上拉输入的,按键按下的时候,由高电平变为 低电平,所以我们要把它配置为下降沿触发中断。 按 键 USER2 的 中 断 线 为 : EXTI3_IRQn , 处 理 函 数 EXTI3_IRQHandler ( ); 中 , 判 断 “EXTI_GetITStatus();”函数 返回 值是否 是等 于“RESET ”,如果 不 等于的 话, 执行该 函数 “EXTI3_IRQHandler()”否则退出。 进入中断函数后,通话函数 EXTI_GetITStatus(EXTI_Line3)判断它的返回值是否等于 RESET, 不等于则执行“EXTI_ClearITPendingBit()”函数。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 680 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 根据寄存器 EXTI_PR 寄存器的定义,为该中断信号产生触发请求 外部中断第 17 线产生中断后进入该函数,当函数“RTC_GetITStatus”的返回值不等于“RESET”的 话,执行该中断函数,RTC 闹钟中断唤醒处理器。 并且进行一个 EXTI_ClearITPendingBit (EXTI_Line17);的操作产生中断 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 681 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 当函数“PWR_GetFlagStatus”的返回值不等于“RESET”的话,执行“PWR_ClearFlag();” 这 个 函 数 的 目 的 是 使 电 源 控 制 寄 存 器 (PWR_CR) 的 第 3 位 置 1 , 清 除 WUF 唤 醒 位 , 而 PWR_FLAG_WU= PWR_FLAG 是等于 0x00000001 的; 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 682 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.56.5 下载与验证 如果在 MDK 开发环境中,下载编译好的固件或者在线调试,请按错误!未找到引用源。错 误!未找到引用源。小节进行操作。 7.56.6 实验现象 本实验使 STM32 进入停止模式,并利用 KEY2 按键产生的外部中断线或者 RTC 闹钟报警来唤 醒 STM32。通过指示灯来指示处理器的当前模式。 将固件下载到程序后,按下复位按键。4 个 LED 闪烁不停的闪烁,进入停止模式后,LED 灯停 止闪烁。如果不按下按键,一段时间后 RTC 闹钟报警来唤醒 STM32,板载的 4 个 LED 灯恢复闪烁 状态,如此循环。当 STM32 进入停止模式后,可以通过按下按键 USER2 来唤醒 STM32,使得 4 个 LED 灯恢复闪烁状态。 7.57 DMA传输实验 本章我们将向大家介绍神舟III号STM32的DMA。在本章中,我们将利用STM32的DMA来实现串 口2数据传送,并在TFTLCD彩屏上显示当前的传送进度。本章分为如下几个部分: 1 STM32 DMA简介 2 实验原理 3 硬件设计 4 软件设计 5 下载验证 7.57.1 STM32 DMA简介 DMA,全称为:Direct Memory Access,即直接存储器访问。 根据 ST 公司提供的相关信息,DMA 是 STM32 中一个独立与 Cortex-M3 内核的模块,有点类似 与 ADC、PWM、TIMER 等模块;主要功能是通信“桥梁”的作用,可以将所有外设映射的寄存器 “连接”起来,这样就可以高速问各寄存器,其传输不受 CPU 的支配,传输还是双向的。 DMA 传输将数据从一个地址空间复制到另外一个地址空间。当 CPU 初始化这个传输动作,传 输动作本身是由 DMA 控制器 来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部 更快的内存区。像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。 DMA 传输对于高效能嵌入式系统算法和网络是很重要的。DMA 传输方式无需 CPU 直接控制传输, 也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传 送数据的通路,能使 CPU 的效率大为提高。 STM32最多有2个DMA控制器(DMA2仅存在大容量产品中),DMA1有7个通道。DMA2有5个 通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起来协调 各个DMA请求的优先权。 STM32的DMA有以下一些特性: ● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通 过软件来配置。 ● 在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),假如在 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 683 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 相等优先权时由硬件决定(请求0优先于请求1,依此类推) 。 ● 独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目 标地址必须按数据传输宽度对齐。 ● 支持循环的缓冲器管理 ● 每个通道都有3个事件标志(DMA 半传输,DMA传输完成和DMA传输出错),这3个事件 标志逻辑或成为一个单独的中断请求。 ● 存储器和存储器间的传输 ● 外设和存储器,存储器和外设的传输 ● 闪存、SRAM、外设的SRAM、APB1 APB2和AHB外设均可作为访问的源和目标。 ● 可编程的数据传输数目:最大为65536 神舟 III 号的主芯片 STM32F103ZET6 有两个 DMA 控制器,DMA1 和 DMA2,本章,我们仅针对 DMA1 进行介绍。 7.57.2 实验原理 本实验的原理:串口 1 以 DMA 方式发送数据。我们先定义 5200 个字节的数组 SendBuff[ ],即开辟 了一个空间,空间用于存放要发送的数据。将这个空间和串口用 DMA 方式绑定。DMA 传输是将数 据从一个地址空间复制到另外一个地址空间。当 CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器来实行和完成。如本实验中,我们先将要发送的数据送入开辟的 SendBuff[ ]地址空间, 初始化从这个地址空间向串口 1 发送数据这个动作。初始化完成后,传输动作本身是由 DMA 控制 器来实行和完成,不用 CPU 直接控制传输。我们只需要开启 DMA 传输即可。 接下来我们就介绍本实验的基本实现步骤: 1)对串口进行初始化。STM32_Shenzhou_COMInit ( ),我们这里用到的是串口1,我们将波特率 配置成2400。 2)调用函数MYDMA_Config()配置DMA。MYDMA_Config()函数初始化 串口1以DMA方 式发送数据这个动作动作。具体配置的内容有:使能DMA传输、传入串口1使用的通道4等,详细的 配置我们在代码部分进行分析。 3)将待发送的数据传入我们开辟的空间SendBuff[ ],即定义的数组。 4)调用USART_DMACmd()函数,使能串口1的DMA发送 。 5)经过上面的配置,我们调用MYDMA_Enable( )函数,开始一次DMA传输。 6)开始一次传输后,我们通过函数DMA_ClearFlag(DMA1_FLAG_TC4),清除通道7传输完成标 志。为下一次DMA传输做准备。 到此我们实验的基本流程就完成了。 下面我们来看一下 DMA 的 6 个寄存器: 寄存器 1:DMA 中断状态寄存器(DMA_ISR) 如果开启了 DMA_ISR 中这些中断,在达到条件后就会跳到中断服务函数里面去,即使没开启, 我们也可以通过查询这些位来获得当前 DMA 传输的状态。这里我们常用的是 TCIFx,即通道 DMA 传输完成与否的标志。注意此寄存器为只读寄存器,所以在这些位被置位之后,只能通过其他的操 作来清除 寄存器 2:DMA 中断标志清除寄存器(DMA_IFCR) DMA_IFCR 的各位就是用来清除 DMA_ISR 的对应位的,通过写 0 清除。在 DMA_ISR 被置位 后,我们必须通过向该位寄存器对应的位写入 0 来清除。 寄存器 3:DMA 通道 x 配置寄存器(DMA_CCRx)(x=1~7,下同) 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 684 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 该寄存器的我们在这里就不贴出来了,见《【中文】STM32F 系列 ARM 内核 32 位高性能微控制 器参考手册 V10_1.pdf》第 150 页 10.4.3 一节。该寄存器控制着 DMA 的很多相关信息,包括数据宽 度、外设及存储器的宽度、通道优先级、增量模式、传输方向、中断允许、使能等都是通过该寄存 器来设置的。所以 DMA_CCRx 是 DMA 传输的核心控制寄存器。 寄存器:DMA 通道 x 传输数据量寄存器(DMA_CNDTRx) 这个寄存器控制 DMA 通道 x 的每次传输所要传输的数据量。其设置范围为 0~65535。并且该寄 存器的值会随着传输的进行而减少,当该寄存器的值为 0 的时候就代表此次数据传输已经全部发送 完成了。所以可以通过这个寄存器的值来知道当前 DMA 传输的进度。 寄存器 5:DMA 通道 x 的外设地址寄存器(DMA_CPARx) 该寄存器用来存储 STM32 外设的地址,比如我们使用串口 1,那么该寄存器必须写入串口 1 的 地址(其实就是&USART2_DR)。如果使用其他外设,就修改成相应外设的地址就行了。 寄存器 6:DMA 通道 x 的存储器地址寄存器(DMA_CMARx) 该寄存器和 DMA_CPARx 差不多,但是是用来放存储器的地址的。比如我们使用 SendBuf[ ]数 组来做存储器,那么我们在 DMA_CMARx 中写入&SendBuff 就可以了。 寄存器的详细分析大家可以参考《【中文】STM32F 系列 ARM 内核 32 位高性能微控制器参考手 册 V10_1.pdf》DMA 的章节,我们这里就分析到这里。 7.57.3 硬件设计 DMA属于STM32内部来连接好串口 1 7.57.4 软件设计 进入例程的文件夹,然后打开\ MDK-ARM\ Project.uvproj 文件 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 685 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:调用STM32_Shenzhou_COMInit ( )函数初始化才串口,配置串口的波特率为2400, 前面已经有介绍。 代码分析2:调用SZ_STM32_SysTickInit()函数初始化定时器。 代码分析3:调用MYDMA_Config()函数初始化内部温度传感器。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 686 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 函数 MYDMA_Config()传入 4 个参数。第一个参数是 DMA1_Channel4。我们这里用到的是 串口 1 的传送(USART1_TX),它对应的是通道 4。通道的选择要参考手册《【中文】STM32F 系列 ARM 内核 32 位高性能微控制器参考手册 V10_1.pdf》。如下图: 第二、第三个参数分别是外设串口 1 的地址&USART1_DR、我们开辟的存储器 SendBuff【】。 我们预先将要发送的数据送入 SendBuff【】,设定串口以 DMA 方式传输数据后,数据从 SendBuff【】 发送到串口。第四个参数是要传输的数据量。 代码分析 4:将要传输的数据送入存储空间 SendBuff【】。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 687 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代 码 中 5168 是 我 们 要 传 输 的 数 据 量 。 TEXT_TO_SEND[] 是 我 们 定 义 的 要 传 输 的 数 据 , TEXT_TO_SEND[]={"www.armjishu.comAa STM32 DMA 串口实验"}。上面提过 SendBuff【】是我 们开辟的存储器。这段代码的意思是将 EXT_TO_SEND 定义的语句复制到我们开辟的空间中。 代码分析 5:进入 while(1)循环 在 while 循环中,调用函数 USART_DMACmd()使能串口 1 的 DMA 发送,它配置的是串口 1 的 USART_CR3 寄存器。使能完后,调用 MYDMA_Enable()函数, DMA 开始传输数据。这时候 串口 1 就开始有数据了。传输完成后,调用 DMA_ClearFlag(DMA1_FLAG_TC4),清除通道 4 传输 完成标志,为下一次传输做准备。 7.57.5 下载验证 在代码编译成功之后,我们通过下载代码到 STM32 神舟 III 号开发板上,按下复位键,STM32 通过 DMA 方式不断的往串口发送数据,串口显示如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 688 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.58 STM32内部温度传感器实验 本章我们将向大家介绍STM32的内部温度传感器。在本章中,我们将利用STM32的内部温度传 感器来读取温度值,并在彩屏上显示出来。本章分为如下几个部分: 1 STM32 内部温度传感器简介 2 实验原理 3 硬件设计 4 软件设计 5 下载验证 7.58.1 STM32内部温度传感器简介 STM32 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。该温度传感器在内部 和 ADCx_IN16 输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推 荐采样时间是 17.1μs。 STM32 的内部温度传感器支持的温度范围为:-40~125 度。精度比较差,为 ±1.5℃左右。 STM32 内部温度传感器的使用很简单,只要设置一下内部 ADC,并激活其内部通道就差不多了。 关于 ADC 的设置,我们在前面已经进行了详细的介绍,这里就不再多说。 接下来我们介绍一下和温度传感器设置相关的 2 个地方。 第一个地方,我们要使用 STM32 的内部温度传感器,必须先激活 ADC 的内部通道,这里通过 ADC_CR2 的 AWDEN 位(bit23)设置。设置该位为 1 则启用内部温度传感器。 第二个地方,STM32 的内部温度传感器固定的连接在 ADC 的通道 16 上,所以,我们在设置好 ADC 之后只要读取通道 16 的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当 前温度。 7.58.2 实验原理 本实验的实验原理:通过内部温度 ADC,将内部温度传感器的电压值取出。通过电压值转换为 对应的温度。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 689 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 怎么通过 ADC 读取温传感器的值? 温度传感器在内部和 ADC1_IN16 输入通道相连接,此通道把传感器输出的电压值转换为数字 值。所以通过获取通道 ADC1_IN16 的转换值,就可得到我们想要的温度传感器的电压值。 现在,我们就可以总结一下 STM32 内部温度传感器使用的步骤了,如下: 1)设置 ADC,开启内部温度传感器。 关于如何设置ADC,在ADC实验已经介绍了,我们采用与上一节相似的设置。不同的是上一节 温度传感器是读取外部通道的值,而内部温度传感器相当与把通道端口连接在内部温度传感器上。 所以这里,我们要开启内部温度传感器功能:ADC_TempSensorVrefintCmd(ENABLE); 2)读取通道 16 的 AD 值,计算结果。 在设置完之后,我们就可以读取温度传感器的电压值了,得到该值就可以用上面的公式计算温 度值。从 ADC 实验的 ADC 通道与 GPIO 对应表可以知道,内部温度传感器是通过对应的是 ADC 的 通道 16。其它的跟上一节的讲解是一样的。 怎么转换电压值为温度值? 在官方提供的手册《【中文】STM32F 系列 ARM 内核 32 位高性能微控制器参考手册 V10_1.pdf》 169 页 11.10 章节中,给出了转换的公式及说明,根据这个公式可以实现电压值和温度值间的转换。 我们对,温度的计算公式进行说明: V25=Vsense 在 25 度时的数值(典型值为:1.43)。 VSENSE 温度传感器输出当前的电压值的计算方法: VSENSE=ADC_ConveredValue*Vdd/Vdd_convert_value(0xFFF) ADC_ConveredValue 是 ADC_DR 寄存器中的结果。Vdd 是参考电压。Vdd_convert_value 是 4096, 因为我们这个 STM32 它的转换的精度是 12 位的。 Avg_Slope=温度与 Vsense 曲线的平均斜率(单位为 mv/℃或 uv/℃)(典型值为 4.3Mv/℃)。 有了这些数据,就可以利用以上公式,计算出当前温度传感器的温度了。 7.58.3 硬件设计 本实验用到的硬件资源有: 2) ADC 3) 内部温度传感器 前两个之前均有介绍,而内部温度传感器也是在STM32内部,不需要外部设置,我们只需要软件 设置就OK了 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 690 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.58.4 软件设计 入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 代码分析1:对串口的参数进行配置。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 691 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析2:调用函数STM32_Shenzhou_COMInit(&USART_InitStructure)初始化串口。 代码分析3:调用T_Adc_Init()函数初始化内部温度传感器。 在初始化函数T_Adc_Init()中,对内部温度传感器进行了一系列的初始化后,调用函数 ADC_TempSensorVrefintCmd()开启内部温度传感器。还进行使能指定的ADC等其它设置,这些设 置主要用到了寄存器ADC_CR2。比如函数ADC_TempSensorVrefintCmd() 而,CR2_TSVREFE_Set=((uint32_t)0x00800000)刚好对寄存器ADC_CR2进行置位,启动温 度传感器。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 692 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析4:通过函数T_Adc_Init()进行初始化ADC,启动温度传感器等设置后,我们就可以对内部 温度传感器进行操作了。 代码中函数T_Get_Adc_Average(ADC_CH_TEMP,10)获取ADC的值。温度传感器在 内部和ADC1_IN16输入通道相连接, 我们通过通道ADC1_IN16,多次取数求平均值得 到我们所想要的温度传感器的ADC数据。 代码分析 5:获取 ADC 的值后,我们对它进行串口打印对应的数据。 代码分析 6:通过公式“温度={(V25-VSENSE)/Avg_Slope}+25”,计算出我们想要的温度值。并通过 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 693 页,共 788 串口显示出来。 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.58.5 下载验证 在代码编译成功之后,我们通过下载代码到 STM32 神舟 III 号开发板上,可以看到串口打印如 图所示: 7.59 温度传感器(DS18B20)实验 7.59.1 意义与作用 温度传感在现代检测技术中,传感器占据着不可动摇的重要位置。主机对数据的处理能力已经 相当的强,但是对现实世界中的模拟量却无能为力。如果没有各种精确可靠的传感器对非电量和模 拟信号进行检测并提供可靠的数据,那计算机也无法发挥他应有的作用。传感器把非电量转换为电 量,经过放大处理后,转换为数字量输入计算机,由计算机对信号进行分析处理。从而传感器技术 与计算机技术结合起来,对自动化和信息化起重要作用。 在本章节,我们以 DS18B20 温度传感器做为我们的一个测温器件,检测我们的外界温度,得到较为 准确的环境温度。在本章中,我们将学习使用单总线技术,通过它来实现 STM32 和外部温度传感器 (DS18B20)的通信,并把从温度传感器得到的温度显示出来。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 694 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.59.2 温度传感器的介绍 温度传感器市场的需求 能快速测出温度的工具我们可以称为温度计,温度计的核心部件是温度传感器。为什么会出现 温度传感器呢?因为它可以代替人体去感受外界的温度,并且能够把一个温度数字化,具体化,避 免了人体去直接接触感觉温度,过低或者过高的温度可能会冻伤或者是烧伤人体,方便人类去管理 和控制调整温度的变化。日常生活中各个领域中都使用到温度传感器,像家庭中的电子温度计、工 厂检测机器温度的仪器、交通工具上的等等。它为人类带来了很大的便利。 什么是温度传感器 温度传感器是指能感受温度并转换成可用输出信号的传感器,我们都知道温度理论上是无上限, 也无下限的;例如火山或者太阳的温度可以非常高,南北极的冰雪温度也可以非常低;所以温度范 围是非常广乏的,小到零下几十摄氏度,大到上千摄氏度;根据温度变化的灵敏度和精度,又有很 多不同温度传感器的种类。像家庭用的大多是 0 到 100 摄氏度的温度计,有些工厂用到的是几千度 摄氏度的温度计,像那些钢筋铁厂的,单片机中我们一般使用的是 18B20 的一种温度传感器,在这 个章节我们就以它为例。下图为它的实物图和封装图 单线数字温度传感器实物图(左)与外部封装图(右) DS18B20 内部结构 DS18B20 采用 3 脚 PR35 封装或 8 脚 SOIC 封装,其内部结构主要由四部分组成,如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 695 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 I/O C GND VDD ● VD1 ● 内部 VDD VD2 ● 电源检测 64 位ROM 和 单线接口 存储器与控制逻 温度传感器 高 速 缓 高温触发器 TH 存 高温触发器 TL 配置寄存器 8 位 CRC 寄存器 (1)64 位光刻 ROM DS18B20 内部结构 (2)温度传感器 (3)非挥发的温度报警触发器 TH 和 TL (4)高速暂存器。 18B20 的管脚排列如下图所示: 序号 名称 DS18B20 引脚分布图 引脚功能描述 1 GND 地信号 2 DQ(I/O) 数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生 电源下,也可以向器件提供电源。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 696 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 3 VDD(Vcc) 可选择的 VDD 引脚。当工作于寄生电源时,此引脚必须接地。 灵敏度与精度 前面我们说了灵敏度和精度,那什么是灵敏度呢?灵敏度就是温度变化了,可能人体需要 1 秒 钟才能感知,但有的毕竟灵敏的温度传感器只需要零点几秒就可以感知;那什么是精度呢?有的传 感器精度是 0.5 摄氏度,有的传感器精度是 0.1 摄氏度,意思就是温度每升降这个单位值,就会被感 知的最小刻度。 18B20 温度传感器的通信方式 我们在这章节中讨论的 18B20 温度传感器是其中的一款普通的传感器,它能把读到的温度转成 二进制的格式发送给单片机,单片机收到它发过来的数据后再转换成比如十进制的方式让我们能知 道当前的温度是多少。这个我们会在下一节详细描述。它的测温范围是-55~125 ℃。固有测温分辨 率为 0.5 ℃。在这个范围内的温度它都能测试出来。 18B20 温度传感器只需要单线就能与单片机进行通信了,数据就是由这根信号线与单片机进行 连接的,加上电源与地,也就是说 18B20 温度传感器只有 3 根引脚就可以了。在这个单线上并不是 只能接一个 18B20 温度传感器的,能接多个 18B20 温度传感器,每个 18B20 温度传感器都有一个地 址,单片机访问哪个地址对应的那个 18B20 温度传感器就能与单片机进行通信。 那么温度传感器怎么能够感知温度的呢?这就要涉及温度传感器究竟是什么材料制作,以及制 作的原理了;比如有的材料可以感知常温下的温度,但是如果温度超过 300 摄氏度,这个材料有可 能会被融化,所以每个传感器的功能都是有所限制的,也就是说,温度可测范围是有限制的,但是 这个世界的传感器技术每天都在进步和发展,对于外界温度的感知技术也是在不断进步的,或许有 一天,我们能有一个传感器能进入到太阳的内部去检测它的温度也说不定。 DS18B20 性能特点 (1)独特的单线接口方式:DS18B20 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。 (2)在使用中不需要任何外围元件。 (3)可用数据线供电,电压范围: 3.0~5.5 V。 (4)测温范围:-55~125 ℃。固有测温分辨率为 0.5 ℃。 (5)通过编程可实现 9~12 位的数字读数方式。 (6)用户可自设定非易失性的报警上下限值。 (7)支持多点组网功能,多个 DS18B20 可以并联在唯一的三线上,实现多点测温。 (8)负压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。 它能直接读出被测温度,并且可根据实际要求通过简单的编程实现 9~12 位的数字值读数方式。 可以分别在 93.75ms 和 750ms 内完成 9 位到 12 位的数字量,并且从 18B20 读出的信息或写入 18B20 的信息仅需要一根口线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所 挂接的 18B20 供电,无需额为电源。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 697 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.59.3 DS18B20温度传感器的使用 DS18B20 的连接方式 在硬件上,DS18B20 与单片机的连接有两种方法,一种是 Vcc 接外部电源,GND 接地,I/O 与 单片机的 I/O 线相连;另一种是用寄生电源供电,此时 VDD、GND 接地,I/O 接单片机 I/O。无论是 内部寄生电源还是外部供电,I/O 口线接一个 4.7KΩ 左右的上拉电阻即可。 DS18B20 的延时问题 虽然 DS18B20 有诸多优点,但使用起来并非易事,由于采用单总线数据传输方式,DS18B20 的 数据 I/O 均由同一条线完成。因此,对读写的操作时序要求严格。为保证 DS18B20 的严格 I/O 时序, 需要做较精确的延时。在 DS18B20 操作中,有了比较精确的延时保证,就可以对 DS18B20 进行读 写操作、温度转换及显示等操作。 18B20 温度传感器的测温原理 我们先来看下 18B20 温度传感器内部的测温原理图,通过该图我们认识 18B20 温度传感器是 如何实现测温原理的。 上图中,低温度系数晶振的振荡频率受温度的影响很小,用于产生固定频率的脉冲信号送给减 法计数器 1,高温度系数晶振的振荡频率随温度变化而明显改变,所产生的信号作为减法计数器 2 的脉冲输入。图中还隐含着计数门,当计数门打开时,DS18B20 就对低温系数振荡器产生的时钟脉冲 进行计数,进而完成温度测量。计数门的开启时间由高温度系数振荡器决定,每次测量前,首先将 -55°C 所对应的基数分别置入减法计数器 1 和温度寄存器中,减法计数器 1 和温度寄存器被预置在 -55°C 所对应的一个基数值。减法计数器 1 对低温度系数晶振产生的脉冲信号进行减法计数,当减 法计数器 1 的预置值减到 0 时温度寄存器的值将加 1,减法计数器 1 的预置将重新被装入,减法计数 器 1 重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器 2 计数到 0 时, 停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 698 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 图中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正减法计数器的预置值, 只要计数们仍未关闭就重复上述过程,直到温度寄存器值达到被测温度值,这个就是 18B20 温度传 感器的测温原理。 另外,由于 DS18B20 单线通信功能是分时完成的,它有严格的时隙概念,因此读写时序很重要。 系统对 DS18B20 的各种操作必须按协议进行。操作协议为:初始化 DS18B20(发复位脉冲)→发 ROM 功能命令→发存储器操作命令→处理数据。 DS18B20 控制方法 单片机是如何控制温度传感器的呢?我们来看下 CPU 对温度传感器的控制命令 DS18B20 有六条控制命令,如下表所示: 指令 温度转换 读暂存器 写暂存器 复制暂存器 重新调 E2RAM 读电源供电方式 DS18B20 控制命令 约定代码 44H BEH 4EH 48H B8H B4H 操 作说 明 启动 DS18B20 进行温度转换 读暂存器 9 个字节内容 将数据写入暂存器的 TH、TL 字节 把暂存器的 TH、TL 字节写到 E2RAM 中 把 E2RAM 中的 TH、TL 字节写到暂存器 TH、TL 字节 启动 DS18B20 发送电源供电方式的信号给主 CPU DS18B20 的寄存器与操作指令 CPU 对 DS18B20 的访问流程是:先对 DS18B20 初始化,再进行 ROM 操作命令,最后才能对 存储器操作,数据操作。DS18B20 每一步操作都要遵循严格的工作时序和通信协议。如主机控制 DS18B20 完成温度转换这一过程,根据 DS18B20 的通讯协议,须经三个步骤:每一次读写之前都要 对 DS18B20 进行复位,复位成功后发送一条 ROM 指令,最后发送 RAM 指令,这样才能对 DS18B20 进行预定的操作。 那什么是 ROM 指令,什么又是 RAM 指令呢? (1)DS18B20 温度传感器 64 b 闪速 ROM 的结构如表 1-1,64 位光刻 ROM 是出厂前被光刻好 的,它可以看作是该 DS18B20 的地址序列号,相当于我们的身份证一样,不同的器件地址序列号不 同: 表 1-1 闪速 ROM 的结构 8b 检验 CRC 48b 序列号 8b 工厂代码(10H) 开始 8 位是产品类型的编号,接着是每个器件的惟一的序号,共有 48 位,最后 8 位是前 56 位 的 CRC 校验码,这也是多个 DS18B20 可以采用一线进行通信的原因。 (2)非易市失性温度报警触发器 TH 和 TL,可通过软件写入用户报警上下限。 (3)高速暂存存储器 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 699 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 DS18B20 温度传感器的内部存储器包括一个高速暂存 RAM 和一个非易失性的可电擦除的 E2RAM。后者用于存储 TH,TL 值。数据先写入 RAM,经校验后再传给 E2RAM。而配置寄存器为 高速暂存器中的第 5 个字节,他的内容用于确定温度值的数字转换分辨率,DS18B20 工作时按此寄 存器中的分辨率将温度转换为相应精度的数值。该字节各位的定义如表 1-2: 表 1-2 DS18B20 内部存储器 高速暂存存储器的低 5 位一直都是 1,TM 是测试模式位,用于设置 DS18B20 在工作模式还是 在测试模式。在 DS18B20 出厂时该位被设置为 0,用户不要去改动,R1 和 R0 决定温度转换的精度 位数,即是来设置分辨率,如表 1-3 所示(DS18B20 出厂时被设置为 12 位)。 表 1-3 R1 和 R0 模式表 R1 R0 分辨率 温度最大转换时间/mm 0 0 9位 93.75 0 1 10 位 187.5 1 0 11 位 275.00 1 1 12 位 750.00 由表 1-3 可见,设定的分辨率越高,所需要的温度数据转换时间就越长。因此,在实际应用中要 在分辨率和转换时间权衡考虑。 高速暂存存储器除了配置寄存器外,还有其他 8 个字节组成,其分配如下所示。其中温度信息 (第 1,2 字节)、TH 和 TL 值第 3,4 字节、第 6~8 字节未用,表现为全逻辑 1;第 9 字节读出的 是前面所有 8 个字节的 CRC 码,可用来保证通信正确。 表 1-4 R1 和 R0 模式表 温度低位 温度高位 TH TL 配置 保留 保留 保留 8位 CRC 当 DS18B20 接收到温度转换命令后,开始启动转换。转换完成后的温度值就以 16 位带符号扩展的 二进制补码形式存储在高速暂存存储器的第 1,2 字节。单片机可通过单线接口读到该数据,读取时 低位在前,高位在后,数据格式以 0.625 ℃/LSB 形式表示。温度值格式如表 1-5:  表 1-5 温度值格式 23 22 21 20 2-1 2-2 2-3 2-4 S S S S S 26 25 24 对应的温度计算:当符号位 S=0 时,直接将二进制位转换为十进制;当 S=1 时,先将补码变换为原 码,再计算十进制值。表 1-6 是对应的一部分温度值。  表 1-6 部分温度值 温度/℃ 二进制表示 十六进制表示 +125 00000111 11010000 07D0H +25.0625 00000001 10010001 0191H 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 700 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 +0.5 0 -0.5 -25.0625 -55 00000000 00000000 11111111 11111110 11111100 00001000 00000000 11111000 01101111 10010000 0008H 0000H FFF8H FE6FH FC90H DS18B20 完成温度转换后,就把测得的温度值与 TH,TL 作比较,若 T>TH 或 T<TL,则将该器 件内的告警标志置位,并对主机发出的告警搜索命令作出响应。因此,可用多只 DS18B20 同时测量 温度并进行告警搜索。 (4)CRC 的产生在 64 b ROM 的最高有效字节中存储有循环冗余校验码(CRC)。主机根据 ROM 的前 56 位来计算 CRC 值,并和存入 DS18B20 中的 CRC 值做比较,以判断主机收到的 ROM 数据是 否正确。 7.59.4 软件设计 根据实验现象初步分析主函数 STM32 神舟 I 号通过与 DS18B20 的连接,烧录对应的例程,能把温度传感器检测到的温度经 过各种显示器件显示出来,如串口打印、数码管、显示屏或者是彩屏等,用户能通过这些显示设备 查看当前的温度,有的例程还能检测多点的温度。温度传感器只需要一根引脚即可完成单片机与它 之间的通信。 初始化 初始化函数中,我们对 LED、系统定时器、延时函数与串口进行了初始化,这样我们才能正常 使用这些功能。 串口打印——“WWW.ARMJISHU.COM” 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 701 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 初始化温度传感器,并检测,如果初始化通过,检测没问题的话,跳过该循环,如果失败,则 串口打印:神舟 III 号开发板提示:18b20 err. 假设检测到 18B20 则进入 while 循环。从温度传感器得到温度,并打印出来 进一步分析关联代码函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 702 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 下面我们主要看下与温度传感器关联的函数 a) 温度传感器复位初始化函数 我们看下温度传感器的复位时序图 我们能通过上面温度传感器工作的时序图看出,数据输入/输出引脚电平由高变低,延时 480us 到 960us 后(我们的程序中是 750us)把数据输入/输出引脚拉高,等待 15 到 60us 后(我们的程序中 是 15us)接收到 60—240us 的存在脉冲,再判断 x 是否等于 0,不等于 0 表示初始化失败,反之则初 始化成功,我们可以看到等待 60—240us 过后,应该是拉高的了。 读取温度传感器数据函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 703 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 我们看下温度传感器读时序图 在发出读暂存器命令后,主机必须立即产生读时隙以便 DS18B20 提供所需数据。DS18B20 只有 在检测到主设备启动读时序后才向主设备传输数据。所以一般在主设备发送了读数据命令后,必须 马上产生读时序,以便 DS18B20 能够传输数据。所有的读时序都至少需要 60μS,且在两次独立的 读时序之间至少需要 1μS 的恢复时间。每个读时序都由主设备发起,先使数据线为高电平,然后拉 低数据线至少 1μS,再释放数据线。在主设备发出读时序之后,DS18B20 开始在数据线上发送数据 0 或 1。若其发送 1,则保持数据线为高电平。若发送 0,则 DS18B20 拉低数据线,在该时序结束后 释放数据线。DS18B20 发出的数据在起始时序之后 15μS 内保证可靠有效。因而主设备在读时序期 间必须释放数据线,并且要在时序开始后的 15μS 之内读取数据线状态 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 704 页,共 788 读取一个字节数据 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 累积读取 8 位为一个字节 写函数——写数据到温度传感器 我们看下写数据的时序图: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 705 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 当单片机将总线从高拉至低电平时,就产生写时间隙, 15us 之内应将所需写的位送到总线上 DS18B20 会在其后的 15 到 60us 的一个时间窗口内采样单总线。在采样的时间窗口内,如果总线为 高电平,主机会向 DS18B20 写入 1;如果总线为低电平,主机会向 DS18B20 写入 0。所有的写时隙 必须至少有 60us 的持续时间。相邻两个写时隙必须要有最少 1us 的恢复时间。所有的写时隙(写 0 和写 1)都由拉低总线产生 温度转换与读取温度函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 706 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 707 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 温度转换时,我们需要经过 3 个步骤,分别是: ¾ 初始化 ¾ ROM 操作指令(Skip ROM) 在单点总线系统中此命令通过允许总线主机不提供 64 位 ROM 编码而访问存储器操作节省时间。 (在多于一个的从属器件责不可以使用该命令。 ¾ 存储器操作指令(Convert T[44h]启动温度变换) 而读取温度时需要经过 5 个步骤: ¾ 复位 DS18B20 ¾ 发出 Skip ROM 命令(CCH) ¾ 发出 Read 命令(BEH) ¾ 读两字节的温度 ¾ 温度格式转换 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 708 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.59.5 硬件设计与实验现象 硬件连接 本实验只要接 18B20 温度传感器的数据线接到处理器的 I/O 口上即可,另外电源与地引脚分别 接到开发板的电源与地,在这个实验中,我们把温度传感器的数据引脚接到了 PA0 上,所以相对应 的代码我们也会根据控制 PA0 进行编写,有兴趣的用户可自己尝试修改管脚控制温度传感器。 实验现象 烧录程序到开发板上,接上串口线到电脑终端或者串口助手打印数据,串口 1 打印数据如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 709 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 判断是否连接到温度传感器,识别产品编码与校验 CRC 没问题后读出温度传感器读到的温度值。 7.60 DHT11数字温湿度传感器实验 7.60.1 简介 DHT11 是一款湿温度一体化的数字传感器。 该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。 通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11 与单片机之间能 采用简单的单总线进行通信,仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次 性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低, 5V 电源电压下,工作平均最大电流 0.5mA。 7.60.2 DHT11的工作原理 DHT11 的湿度检测运用电容式结构,并采用具有不同保护的“微型结构”检测电极系统与聚合物 覆盖层来组成传感器芯片的电容,除保护电容湿敏感件的原有特性外,还可以抵御来自外来界的影 响。由于它将温度传感器与湿度传感器结合在一起而构成了一个单一的个体,因为测量精度较高且 可精确的得出露点,同时不会产生由于温度与湿度之间随温度变化引起的误差。CMOSensTM 技术 不仅将湿度传感器结合在一起,而且还将信号放大器、模数转换器、校准数据存储器、标准 IIC 总线 等电路全部集成在一个芯片内。 DHT11 的每一个传感器都是在极为精确的湿度室中校准的,DHT11 传感器的校准系数预先存储在 OTP 内存中。经校准湿度和温度传感器与一个 14 位的 A/D 转换器相连,可将转换后的数字温湿度 值送给二线 IIC 总线器件,从而将数字信号转换位符合 IIC 总线协议的串行数字信号。  工作电压范围:3.3V-5.5V  工作电流 :平均 0.5mA  输出:单总线数字信号 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 710 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0  测量范围:湿度 20~90%RH,温度 0~50℃  精度 :湿度±5%,温度±2℃  分辨率 :湿度 1%,温度 1℃ DHT11 的管脚排列如图所示; 7.60.3 硬件连接与温度协议分析 典型电路 虽然 DHT11 与 DS18B20 类似,都是单总线访问,但是 DHT11 的访问,相对 DS18B20 来 说要简单很多。下面我们来看看 DHT11 的数据结构。 DHT11 数字湿温度传感器采用单总线数据格式。即单个数据引脚端口完成输入输出双向传输。 其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为 40bit,高位 先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度 小数数据+8bit 校验和。其中校验和数据为前四个字节相加。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 711 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 DHT11 的值的转换也非常简单直接将值的高 8 位的二进制转换为十进制表示其整数部分,第八位 表示小数部分,如上图示列一中的数据; 湿度=湿度的高八位.湿度的低八位=53.0% 温度=温度的高八位.温度的低八位=24.0 ( ℃) 校验=湿度的高八位+湿度的低八位+温度的高八位+温度的低八位=77(=湿度+温度)(校验正确) 可以看出,DHT11 的数据格式是十分简单的,DHT11 和 MCU 的一次通信最大为 3ms 左右, 建议主机连续读取时间间隔不要小于 100ms。 DHT11 时序 下面,我们介绍一下 DHT11 的传输时序。DHT11 的数据发送流程如下图所示; 首先主机发送开始信号,即:拉低数据线,保持 t1(至少 18ms)时间,然后拉高数据线 t2(20~40us) 时间,然后读取 DHT11 的相应,正常的话,DHT11 会拉低数据线,保持 t3(40~50us)时间,作 为响应信号,然后 DHT11 拉高数据线,保持 t4(40~50us)时间后,开始输出数据。 DHT11 输出数字‘0’的时序如图所示; 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 712 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 DHT11 输出数字‘1’的时序如图所示; 7.60.4 实验现象 我们将 DHT11 连接到 STM32 神舟 3 号开发板上 神州 3 号开发板 连接线 DJT11 线色 功能 3.3V 杜邦线 VDD 红色 供电 PA11 杜邦线 DATA 蓝色 串行数据 单总线 GND 杜邦线 NC 白色 悬空 GND 杜邦线 GND 绿色 接地 同时用串口连接电脑,在电脑上的超级终端上显示当前温度和湿度的值如下图所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 713 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.61 三轴加速度模块实验 7.61.1 三轴加速传感器有什么用 我们现在的智能手机能够自动切换横竖屏、玩游戏和切歌等,人们感觉非常的方便和智能,其实 这个是由于手机里面我们用到了一个传感器,那就是加速传感器,就是通过这个传感器实现我们的 这些功能的,下面我们这章就对这个传感器做一个详细的介绍与使用。而这章中,我们使用到的是 三轴加速度传感器中的一种——ADXL345 传感器。 7.61.2 ADXL345简介 ADXL345 是 ADI 公司生产的一款超低功耗 3 轴加速度计,广泛应用于手机、医疗仪器、游戏和 定点设备、工业仪器仪表及个人导航设备领域,它的分 辨率高达 13 位,测量范围达± 16g。数字输 出数据为 16 位二进制补码格式,可通过 SPI(3 线或 4 线)或 I2C 数字接口访问。ADXL345 非常适合 移动设备应用。它可以在倾斜检测 应用中测量静态重力加速度,还可以测量运动或冲击导致的动态 加速度。其高分辨率(3.9mg/LSB),能够测量不到 1.0°的倾斜角度变化。 ADXL345 实物图与引脚图: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 714 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ADXL345 实物图 ADXL345 引脚图 该加速度传感器的特点有: ¾ 分辨率高。最高 13 位分辨率。 ¾ 量程可变。具有+/-2g,+/-4g,+/-8g,+/-16g 可变的测量范围。 ¾ 灵敏度高。最高达 3.9mg/LSB,能测量不到 1.0°的倾斜角度变化。 ¾ 功耗低。40~145uA 的超低功耗,待机模式只有 0.1uA。 ¾ 尺寸小。整个 IC 尺寸只有 3mm*5mm*1mm,LGA 封装。 ADXL 支持标准的 I2C 或 SPI 数字接口,自带 32 级 FIFO 存储,并且内部有多种运动状态检 测和灵活的中断方式等特性。 7.61.3 ADXL345工作原理 ADXL345 是一款完整的 3 轴加速度测量系统,可选择的测量范围有±2 g,±4 g,±8 g 或±16 g。 既能测量运动或冲击导致的动态加速度,也能测量静止加速度,例如重力加速度,使得器件可作为 倾斜传感器使用。 该传感器为多晶硅表面微加工结构,置于晶圆顶部。由于应用加速度,多晶硅弹簧悬挂于晶圆 表面的结构之上,提供力量阻力。 差分电容由独立固定板和活动质量连接板组成,能对结构偏转进行测量。加速度使惯性质量偏 转、差分电容失衡,从而传感器输出的幅度与加速度成正比。相敏解调用于确定加速度的幅度和极 性。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 715 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 当 ADXL345 沿轴正向加速时,它对正加速度进行检测。在检测重力时用户需要注意,当检测轴 的方向与重力的方向相反时检测到的是正加速度。下图所示为输出对重力的响应。 7.61.4 ADXL345的通信方式实验原理 加速度传感器会接受外界传递的物理性输入,通过感测器转换为电子信号,在最终转换为可用 的信息。主要感应方式是对微小物理量的变化进行测量,在通过电压信号来表示这些变化量。 ADXL345 可通过 SPI(3 线或 4 线)或 I2C 数字接口访问,因为我们这里主要用到的是 I2C 通信方 式,所以在这里我主要是介绍 I2C 的方式,SPI 我们就暂且略过。如下图所示,CS 引脚拉高至 VDD I/O, ADXL345 处于 I2C 模式,需要简单 2 线式连接。ADXL345 符合《UM10204 I2C 总线规范和用户手 册》03 版(2007 年 6 月 19 日,NXP Semiconductors 提供)。如果满足了表 11 和表 12 列出的总线参数, 便能支持标准(100 kHz)和快速(400 kHz)数据传输模式。如图 40 所示,支持单个或多个字节的读取/ 写入。ALT ADDRESS 引脚处于高电平,器件的 7 位 I2C 地址是 0x1D,随后为 R/W 位。这转化为 0x3A 写入,0x3B 读取。通过 ALT ADDRESS 引脚(引脚 12)接地,可以选择备用 I2C 地址 0x53(随后 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 716 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 为 R/W 位)。这转化为 0xA6 写入,0xA7 读取。 从上图可看出,ADXL345 的连接十分简单,外围需要的器件也极少(就 2 个电容),如上连接 (SDO/ALT ADDRESS 接地),则 ADXL345 的地址为 0X53(不含最低位),如果 SDO/ALT ADDRESS 接高,那么 ADXL345 的地址将变为 0X1D(不含最低位)。IIC 通信的时序我们在之前已经介绍过, 这里就不再细说了。 对于任何不使用的引脚,没有内部上拉或下拉电阻,因此,CS 引脚或 ALT ADDRESS 引脚悬空 或不连接时,任何已知状态或默认状态不存在。使用 I2C 时, CS 引脚必须连接至 VDD I/O, ALT ADDRESS 引脚必须连接至任一 VDD I/O 或接地。 I2C 通信时序图如下: 7.61.5 ADXL345的寄存器说明 1)DATA_FORMAT 寄存器: DATA_FORMAT 寄存器功能作用:自测力应用至传感器,造成输出数据转换;器件模式选择; 中断高低电平选择;器件分辨率模式选择;左右对齐位选择;范围位选择;各轴数据的输出控制等 操作功能; 2)BW_RATE 寄存器: BW_RATE 寄存器功能作用:正常与低功率操作选择;器件带宽和输出数据速率等操作功能; 3)POWER_CTL 寄存器: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 717 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 POWER_CTL 寄存器功能作用:活动和静止功能的连接位设置;自动休眠功能;待机模式与测 量模式选择;工作与休眠模式选择;唤醒功能等控制操作; 4)INT_ENABLE 寄存器: INT_ENABLE 寄存器功能作用:使能与阻止相应功能中断选择操作; 5)OFSX、OFSY、OFSZ 寄存器: OFSX、OFSY、OFSZ 寄存器功能作用:这三个寄存器都为 8 位寄存器,在二进制补码格式中提 供用户设置偏移调整。 ADXL345 有关寄存器就介绍到这里,详细的介绍,请参考 ADXL345 的数据手册。 以上几个寄存器做了简单功能介绍,而要对 ADXL345 这几个寄存器要进行数据读写操作都是与 IIC 通信操作有关完成的,只要 ADXL34 配置好管脚和有关的寄存器定义就可以使用。 7.61.6 ADXL345内部结构与管脚连接 ADXL345 传感器的检测轴如图: 当 ADXL345 沿检测轴正向加速时,它对正加速度进行检测。在检测重力时用户需要注意, 当检测轴的方向与重力的方向相反时检测到的是正加速度。输出对重力的响应,下图所示: 以上图所示列出了 ADXL345 在不同摆放方式时的输出,以便后续分析。接下来看看 ADXL345 的引脚图,如图: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 718 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 ADXL345 支持 SPI 和 IIC 两种通信方式,为了节省 IO 口,采用的是 IIC 方式连接,官方推 荐的 IIC 连接电路如图: 从上图可看出,ADXL345 的连接十分简单,外围需要的器件也极少(就 2 个电容),如上 连接(SDO/ALT ADDRESS 接地),则 ADXL345 的地址为 0X53(不含最低位),如果 SDO/ ALTADDRESS 接高,那么 ADXL345 的地址将变为 0X1D(不含最低位)。IIC 通信的时序在这里 就不再细说了(可以参考 IIC 通信章节)。 ADXL345 的初始化: 介绍一下 ADXL345 的初始化步骤。ADXL345 的初始化步骤如下: 1) 上电 2) 等待 1.1ms 3) 初始化命令序列 4) 结束 其中上电这个动作发生在开发板第一次上电的时候,在上电之后,等待 1.1ms 左右,就可 以开始发送初始化序列了,初始化序列一结束,ADXL345 就开始正常工作了。这里的初始化序列, 最简单的只需要配置 3 个寄存器,如表所示: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 719 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 发送以上序列给 ADXL345 以后,ADXL345 即开始正常工作,ADXL345 就介绍到这里,详细 的介绍,请参考 ADXL345 的数据手册。 7.61.7 实验原理 本章将使用 STM32 来驱动 ADXL345,读取 3 个方向的重力加速度值,并转换为角度,显示在 串口上。 7.61.8 硬件设计 本实验采用 STM32 的 2 个普通 IO 连接 ADXL345 模块,模块详细资料可参考模块用户手 册。本章实验功能简介:主函数不停的查询 ADXL345 的转换结果,得到 x、y 和 z 三个方向的加 速度值(读数值),然后将其换为与自然系坐标的角度,并将结果通过串口打印出来。 模块接线图: 我们使用 2 个普通的 I/O 口 PB6 和 PB7 作为我们的 I2C 通信接口,利用板子上的电源与地给模 块供电 7.61.9 软件设计 我们来看下 main 主函数部分的代码,首先是初始化部分,在这里我们对串口进行了一个初始化 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 720 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 初始化完后对我们的 ADXL345 模块进行一个初始化,通过“ADXL345_Init()”函数的返回值 判断我们的模块 ID 是否正确,初始化成功后返回一个 0,否则返回一个 1,初始化失败后串口打印 出我们读到的 ID,并一直循环打印。初始化成功后同样打印我们的读到的 ID,初始化成功后的 ID 为“229”十六进制数为“0xE5”。 初始化失败后执行的函数: 初始化成功后串口输出我们的模块 ID 并继续往下执行: 成功后打印的 ID 为: 其中红色方框为读到的 ID,蓝色方框为串口初始化时串口输出的数据。可以看到,我们现在读到的 ID 为“229”十六进制数为“0xE5”是该模块正确的 ID。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 721 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 读完 ID 后读取我们模块上的速度原始值与角度值,并通过串口打印出来: 深入分析程序代码 ADXL345 初始化函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 722 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 该函数是用来初始化 ADXL345 的,采用查询的方式来读取数据的,所以在这里并没有开启中断。 另外 3 个偏移寄存器,都默认设置为 0。初始化成功后返回 0 值,识别时返回 1 值,通过读取模块 ID 判断是否正确 ADXL345_RD_XYZ 函数 该函数用于从 ADXL345 读取数据,通过该函数可以读取 ADXL345 的转换结果,得到三个轴的 加速度值(仅是数值,并没有转换单位)。 ADXL345_AUTO_Adjust 函数 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 723 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 该函数用于 ADXL345 的校准,ADXL345 有偏移校准的功能,该功能的详细介绍请参考 ADXL345 数据手册的第 29 页,偏移校准部分。这里我们就不细说了,如果不进行校准的话,ADXL345 的读数可能会有些偏差,通过校准,我们可以讲这个偏差减少甚至消除。 ADXL345_Get_Angle 函数 该函数根据 ADXL345 的读值,转换为与自然坐标系的角度。计算公式如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 724 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 其中 Ax,Ay,Az 分别代表从 ADXL345 读到的 X,Y,Z 方向的加速度值。通过该函数,我们 只需要知道三个方向的加速度值,就可以将其转换为对应的弧度值,再通过弧度角度转换,就可以 得到角度值了。 7.61.10 实验现象 将模块连接到开发板上,接线方式如下表: 模块上的引脚 3.3V GND SCL SDA 开发板上的引脚 3.3V GND PB6 PB7 功能 电源 地 时钟线 数据线 程序代码编译下载到我们的神舟 III 号板子上,连接 USB 转串口线。根据前面介绍过的串口设 置方法,可以看到在板子复位后,串口把我们模块的数据打印出来了,这些数据就是我们模块的角 度值和速度初始值,移动模块的方向位置时,可看到对应的数值相对应的发生变化。串口打印的数 据如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 725 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.62 红外遥控器实验 7.62.1 什么是红外?红外的历史 在了解红外收发前,我们先来了解一下什么是红外,在日常生活中,我们通过眼睛能看到各种 颜色的光。那我们是否了解各种颜色的光之间有什么区别的呢?难道就只是颜色不一样?那为什么 光又分为那么多种颜色呢? 其实,光的颜色是由它的波长来决定的,那么波长又是什么呢?为了能让用户更能理解它的定 义,我们不是科学家,不深入研究,只是了解一下它的定义就行了,我们前面知道了知道光的颜色 是由波长决定的。光的波长就是光在单位时间内通过的位移(位移是从空间的一个位置运动到另一 个位置,它的位置变化叫做在这一运动过程中的位移)。光的本质是电磁波,所以就会有频率的产生。 光的频率在传播中保持不变,意思是在光通过不同介质的时候,频率不变而波长发生改变。因此, 光的波长由光的频率(颜色),以及传播的介质决定。 波长的单位我们可以用 nm 或者 um 来表示,各种颜色有各自的波长,人的眼睛能看到的可见光 按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为 620~760nm; 紫光的波长范围为 380~440nm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线。在 1800 年 4 月 24 日英国伦敦皇家学会(ROYAL SOCIETY)的威廉·赫歇尔发表太阳光在可见光谱的红 光之外还有一种不可见的延伸光谱,具有热效应。他所使用的方法很简单,用一支温度计测量经过 棱镜分光后的各色光线温度,由紫到红,发现温度逐渐增加,可是当温度计放到红光以外的部分, 温度仍持续上升,因而断定有红外线的存在。红外线遥控就是利用波长为 760nm~400um 之间的近 红外线来传送控制信号的。下图为各种光的波长示意图,红光外的为红外光,紫色光以外的为紫外 光。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 726 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 7.62.2 红外的特点和用途 红外的特点具有很强热效应、易于被物体吸收、穿透能力比可见光强、小角度(30 度锥角以内), 短距离、点对点直线数据传输,保密性强、传输速率较高。 红外的用途有非常多,例如在通讯领域的技术,常被应用在计算机及其外围设备、移动电话、数 码相机、工业设备、网络接入设备,如调制解调器等,像我们这章所用到的红外收发,还有深海探 测等无线通讯方面的技术;还可以被用于医疗用途,红外线对人体皮肤、皮下组织具有强烈的穿透 力。外界红外线辐射人体产生的一次效应可以使皮肤和皮下组织的温度相应增高,促进血液的循环 和新陈代谢,促进人的健康,红外线还有杀菌的能力。 因为我们这章用到的是红外通讯技术,所以它的其他用途我们就不作说明了,主要说下用作红 外收发通讯的用途。红外通讯就是通过红外线传输数据。在电脑技术发展早期,数据都是通过线缆 传输的,线缆传输连线麻烦,需要特制接口,颇为不便。无线通信技术逐渐发展起来 7.62.3 红外的功能参数 工作电压:2.7~5.5V 左右 接收距离:15~30M(米)左右 载波频率:37.9KHz 接收角度:+/-35° BMP 宽度:3.5~8.5KHz 静态电流:0.9~1.5mA 坑干扰能力:综合能力较强,灵敏度较高 应用范围:通讯、医疗方面广泛应用 7.62.4 红外的工作原理 红外遥控有发送和接收两个组成部分。发送端将待发送的二进制信号编码调制为一系列的脉冲 串信号,通过红外发射管发射红外信号。红外接收完成对红外信号的接收、放大、检波、整形,并 解调出遥控编码脉冲,流程图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 727 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 红外发送原理: 把需要发送的信号编码调制为一系列的脉冲串信号由红外 LED 发送出去。 二进制信号的调制由单片机来完成,它把编码后的二进制信号调制成一定频率的间断脉冲串, 相当于用二进制信号的编码乘以这个间断脉冲信号得到的间断脉冲串,即是调制后用于红外发射二 极管发送的信号,如下图所示,要使红外发光二极管产生调制光,只需在它的驱动管上加上一定频 率的脉冲电压。一般由键盘电路、红外编码芯片、电源和红外发射电路组成 在同一个遥控电路中通常要使用实现不同的遥控功能或区分不同的机器类型,这样就要求信号 按一定的编码传送,编码则会由编码芯片或电路完成。通过对用户码的检验,每个遥控器只能控制 一个设备动作,这样可以有效地防止多个设备之间的干扰。就像是电视机、空调有专门的遥控器, 遥控器上的按键各有各自的功能。 红外遥控发射芯片采用 PPM 编码方式(脉冲位置调制,又称脉位调制,由头码+脉冲数组成,称为 PPM 编码方式) , 当发射器按键按下后 , 将发射一组 108ms 的编码脉冲。遥控编码脉冲由前导码、 16 位地址码(8 位地址码、 8 位地址码的反码)和 16 位操作码(8 位操作码、 8 位操作码的反码) 组成, 反码表示正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。由一个 9ms 的高电 平 ( 起始码 ) 和一个 4. 5ms 的低电平 ( 结果码 ) 组成作为接受数据的准备脉冲。解码的关键是如何识 别“0”和“1”,从位的定义我们可以发现“0”、“1”均以以脉宽为 0. 56ms 的电平开始、周期为 1. 12ms 的 组合表示二进制的 “0” ;以脉宽为 1. 68ms 、周期为 2. 24ms 的组合表示二进制的 “1”,根据这样的 定义,我们就能读出发送的数据是什么了。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 728 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 红外接收原理: 了解了红外接收头后,我们再来了解下它是如何工作的,它的原理是什么。红外接收头内置接 收管将红外发射管发射出来的光信号转换为微弱的电信号,此信号经由 IC 内部放大器进行放大,然 后通过接收管的处理将波形整形后还原为遥控器发射出的原始编码,经由接收头的信号输出脚输入 到电器上的编码识别电路,红外解码的关键就是识别 0 和 1。 我们前面介绍过红外接收是完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉 冲的,这个是由接收头内部完成的。经过它的接收放大和解调会在输出端直接输出原始的信号 红外接收头一般是接收、放大、解调一体头,一般红外信号经接收头解调后,数据 “0”和“1” 的区别通常体现在高低电平的时间长短或信号周期上,这个我们上面有介绍。单片机解码时,通常 将接收头输出脚连接到单片机的外部中断,结合定时器判断外部中断间隔的时间从而获取数据。重 点是找到数据“0”与“1”间的波形差别。 在这里特别强调:编码与解码是一对逆过程,不仅在原理上是一对逆过程,在码的发收过程也 是互反的,即以前发射端原始信号是高电平,那接收头输出的就是低电平,反之亦然。因此为了保证 解码过程简单方便,在编码时应该直接换算成其反码。如下图为红外发送与红外接收头接收的电平 对比情况 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 729 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 红外接收过程: 接收电路的红外接收管是一种光敏二极管,使用时要给红外接收二极管加反向偏压,它才能正 常工作而获得高的灵敏度。红外接收二极管一般有圆形和方形两种。由于红外发光二极管的发射功 率较小,红外接收二极管收到的信号较弱,所以接收端就要增加高增益放大电路。然而现在不论是 业余制作或正式的产品,大都采用成品的一体化接收头,红外线一体化接收头是集红外接收、放大、 滤波和比较器输出等的模块,性能稳定、可靠。所以,有了一体化接收头,人们不再制作接收放大 电路,这样红外接收电路不仅简单而且可靠性大大提高。 红外接收头包含两个芯片,一个是 PD(即红外接收管),一个是 IC。其中 PD 接收来自发射管的光信 号(该信号已被调制),将光信号转换为电信号,即光电转换,常用于光接收器中。PD 芯片属于典 型的 PIN 结构光电二极管。由 PD 接收转换而来的电信号通过 IC 进行放大,自动增益控制,滤波, 解调,波形整形,比较器输出交由后面的电路进行识别还原。以上就是红外接收头的接收过程。 7.62.5 实验原理 从上面了解了红外的收发原理后知道红外发送是以脉宽为 0. 56ms 的电平开始、周期为 1. 12ms 的 组合表示二进制的 “0” ;以脉宽为 1. 68ms 、周期为 2. 24ms 的组合表示二进制的 “1”,而编码与解 码是一对逆过程因此我们就可以用定时器的输入捕获来进行脉宽的检测从而得出二进制信号。 7.62.6 硬件设计 本实验串口显示红外的信息。用到红外遥控器红外接头。我们主要看一下,红外接收头的实物 图和管脚图如下: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 730 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 红外接收头有 3 个管脚,VCC、GND、OUT。分别是电源、地、数据引脚。 这 3 个管脚和神州 3 号开发板上的引脚的连接关系如下表。这里需要焊接将开发板上将对应的引脚 引出。 神州 3 号开发板 连接线 DJT11 功能 3.3V 杜邦线(绿色) VDD 供电 PB9 杜邦线(白色) DATA/OUT 串行数据 单总线 GND 杜邦线(红色) GND 接地 7.62.7 代码分析 进入例程的文件夹,然后打开\ MDK-ARM \ Project.uvproj 文件 可以看到工程已经被打开,下面开始具体分析程序代码: 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 731 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析 1:STM32_Shenzhou_COMInit( )函数初始化串口。 代码分析 2:Remote_Init()函数初始化红外遥控。 初始化函数用于初始化 IO 口,并配置 TIM4_CH4 为输入捕获。输入捕获,比如捕获一个高电平 的时候,首先检查到一个上升沿,启动定时器计时,一段时间后来一个下降沿,定时器停止计时。 这样我们就可以知道高电平持续的时间了。捕获一个低电平的时候,也是一样的道理。 本初始化设置 TIM4_CH4 相关参数,这里的配置跟输入捕获实验的配置基本接近,大家可以参 考输入捕获实验的讲解。 代码分析 4:定时器 TIM4 的中断服务函数,TIM4_IRQHandler( )。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 732 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 在这个函数里实现对红外接收头接收到的红外信号的高电平脉冲的捕获,同时根据我们之前简 介的协议内容来解码。这里主要是如何识别传输进来的数据是“1”还是“0”。 这两个数据的判别可以通过高电平脉冲持续的时间长度来判断。“0”、“1”均以脉宽为 0. 56ms 的 电平开始、但第二个电平的时候数据“0”的脉宽大约是 0.56ms,数据“1”的是 1.685ms。代码中 判别数据是根据的是这样的思路。 在此中断函数里面用全局变量存储解码结果,以便其它函数调用。 代码分析 5:函数 Remote_Scan()扫描解码结果。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 733 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 输入捕获解码的红外数据,通过该函数传送给其它函数。扫描的时候判断扫描的地址码,和地 址反码中的数据是否一致。一致的话,再判断键值是否一致,一致的话将键值取出做为返回值 (sta=t1)。最后,我们通过返回的键值判断我们按下遥控器上的那个按键,并通过串口输出按下的 按键值。 7.62.8 下载与测试 如果在MDK开发环境中,下载编译好的固件或者在线调试,请按 如何通过MDK编译和在线调试 小 节进行操作。 7.62.9 实验现象 我们将红外遥控连接到神州 3 号开发板上,连线方法如下: 神州 3 号开发板 连接线 DJT11 功能 3.3V 杜邦线(绿色) VDD 供电 PB9 杜邦线(白色) DATA 串行数据 单总线 GND 杜邦线(红色) GND 接地 将代码烧录到神州 3 号开发板上后,用串口连接电脑,复位,在电脑上的超级终端上也会显示下 图所示; 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 734 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 按下红外遥控器的按键,超级终端上打印按键的对应信息,比如按下按键“1”,串口打印信息如下: 7.63 UCOSII操作系统之单任务运行 7.63.1 UCOSII简单介绍 UCOSII的前身是UCOS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在 《嵌入式系统编程》杂志的5月和6月刊上刊登的文章连载,并把UCOS 的源码发布在该 杂志的BBS 上。目前最新的版本:UCOSIII已经出来,但是现在使用最为广泛的还是 UCOSII,本章我们主要针对UCOSII进行介绍。在学习本章之前,UOCS相关的知识比较多, 我们实验也知识指点一下大家入门,详细了解建议大家先看看任哲老师的《嵌入式实时 操作系统ucosII原理及应用》。 UCOSII是一个可以基于ROM运行的、可裁减的、抢占式、实时多任务内核,具有高度 可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作 系统(RTOS)。为了提供最好的移植性能,UCOSII最大程度上使用ANSI C语言进行开发, 并且已经移植到近40多种处理器体系上,涵盖了从8位到64位各种CPU(包括DSP)。 UCOSII是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度, 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 735 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有 汇编器、连接器等软件工具,就可以将UCOSII嵌人到开发的产品中。UCOSII具有执行效 率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。 UCOSII已经移植到了几乎所有知名的CPU 上。 UCOSII构思巧妙。结构简洁精练,可读性强,同时又具备了实时操作系统的全部功 能,虽然它只是一个内核,但非常适合初次接触嵌入式实时操作系统的朋友,可以说是 麻雀虽小,五脏俱全。UCOSII(V2.91版本)体系结构如下图所示: 注意本章我们使用的是UCOSII的最新版本:V2.91版本,该版本UCOSII比早期的 UCOSII(如V2.52)多了很多功能(比如多了软件定时器,支持任务数最大达到255个等), 而且修正了很多已知BUG。不过,有两个文件:os_dbg_r.c和os_dbg.c,我们没有在上 图列出。 7.63.2 UCOSII的学习方法 打算学习一个嵌入式操作系统,需要先研究一下UCOSII的学习方法,一方面权当学习C语言,另 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 736 页,共 788 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 一方面UCOSII的代码比较小,比如2.52版本代码只有5500行左右,还是一个能接受的范围。 对于新手,入门选书是最重要的了。用了几天研究了一下参考书,和大家分享一下。 1.嵌入式实时操作系统μC/OS-II(第2版) 邵贝贝 等译 北京航空航天大学出版社 应该说每一个学习UCOSII的人都应该知道这本书,也都应该看一下这本书,但是不建议作为 入门书籍。这本书是UCOSII的作者原著的翻译本,必然是很详细,必然是权威,然而书中分析UCOSII 内核原理是核心内容,应用则不多。想要快速上手的应当选用其他书籍,这本书应该当做手册。 2.嵌入式实时操作系统μC/OS-II原理及应用(第2版) 任哲 北京航空航天大学出版社 这本书和第一本书比在讲述UCOSII原理的同时,配备了一些很简单的例子,可以在PC上调试代 码。这是一本可以反复阅读的书本,感觉不错,适合入门。当然书中有一些原理讲的不清楚,这个 时候翻一下邵贝贝那本书就懂了。 3. UCOSII标准教程 杨宗德 人民邮电出版社 这本书我只翻了一下,看了看目录和前面一点内容。用的模拟环境是VC++6.0对于那些搞软件的 朋友看这本书应该合适,书中的内核是2.8版本。 7.63.3 神舟官方团队点破操作系统的学习精妙之处 STM32神舟团队的工程师也对此给出了学习建议,例如51单片机我们要运行一个点LED灯亮灭的 任务,还有一个要显示液晶屏两行字的任务;通常情况,可以用一个while循环来轮询这2个任务, 但是如果任务多了怎么办呢?比如变成了200个任务,那么while循环将怎么管理呢?怎么样合理配 置CPU资源呢?难道平均分配吗? 其实平均对每个任务分配CPU资源的方法是可行的,但是并不是最优的,比如比较重要的事情需 要抢先办理,那么就逐渐有了优先级的概念;比如同时开启200个任务,有的任务执行了一下之后, 需要过比较长的时间后再执行,这样的话,就可以使得下次while循环不用理睬这个任务,把这个空 闲时间转让给其他需要执行的任务,这个需要等待的任务可以挂起,可以记录一下,什么时候开始 执行这样的信息,这样就有了任务的其他状态,比如挂起的任务,比如预备好的任务进入等待队列 等。 比如CPU同时运行200个任务,那么其中有个看门狗任务,主要负责监督CPU是否是正常的,如果 出现异常,看门狗任务就会对CPU进行复位,像这样的任务重要性一定是最高的,因为CPU工作都已 经不正常了,你还要它继续运行干什么,已经没有意义了,直接复位时最合适的解决办法。所以这 样就形成了优先级的概念,有的任务的优先级比较高,如果这样的优先级高的任务出现了之后,就 要先执行,我们可以人为来配置这些任务的优先级。 大家看到上面我们神舟工程师所描述的,可以慢慢的了解到,一个操作系统实际上是自然衍生 出来的结果,一切都是有必要的,而不是枯燥无味或者故意加上去的。如果从这样的切入点思路进 去学习操作系统,我想是事半功倍的。多一些思考,比多看一些书,会更加的务实,功力提高也就 越快。 7.63.4 实验原理 通过 UCOSII 操作系统创建一个简单任务,这个任务的工作就是实现 LED 灯闪烁操作。 7.63.5 硬件设计 本节实验功能简介:本章我们在 UCOSII 里面创建 1 个任务,使得 LED 灯进行闪烁,LED 灯的 原理图同 LED 流水灯一样。 嵌入式专业技术论坛 (www.armjishu.com)出品 页 第 737 页,共 788 7.63.6 软件设计 ARM 技术论坛 www.armjishu.com 神舟 III 号用户手册 V4.0 代码分析: 1. 首先开始初始