ARM之旅 概述 选择合适的ARM芯片 充分了解该ARM芯片 ARM的特性 了解ARM内部结构 设计最小系统 建立开发环境 (软件、硬件) HelloWorld程序 概述 产品开发 ARM的特性 了解ARM内部结构 ARM程序的组成 了解ARM指令系统 掌握部分ARM指令 选择合适的ARM芯片 充分了解该ARM芯片 入门级别 了解级别 当前位置
主题: ARM开发流程
ARM嵌入式系统开发常用工具 仿真调试工具-Keil ULINK仿真器 批量生产工具-SmartPRO系列通用编程器 分析纠错工具-LA1032逻辑分析仪
Keil ULINK仿真器 支持内核: ARM7 ARM9 Cortex-M3 支持片内外设模拟调试 支持片内Flash下载/调试,片外Flash USB接口
SmartPRO系列通用编程器 支持ARM芯片编程,速度快,适合于批量生产 SmartPRO 5000U X5 X8
支持ARM芯片列表(Philips所有带片内Flash的芯片,需要适配器) LPC2101 LPC2102 LPC2103 LPC2104 LPC2105 LPC2106 LPC2114 LPC2119 LPC2124 LPC2129 LPC2131 LPC2132 LPC2134 LPC2136 LPC2138 LPC2141 LPC2142 LPC2144 LPC2146 LPC2148 LPC2194 LPC2212 LPC2214 LPC2292 LPC2294
LA1032逻辑分析仪 分析、纠错好帮手,五大功能: 逻辑分析仪+总线分析仪+协议分析+频率计+逻辑笔
LA1032逻辑分析仪 功能特点 100M采样频率。 32路数字通道. 边缘、电平、总线等多种触发方式。 UART、SPI、I2C、SSI、CF卡等总线分析。 功能强大的测量内核,无须依赖于高性能计算机。 USB2.0高速接口,即插即用。 动态升级的硬件算法使您的测量手段与时并进。
ARM开发流程 6.1 引言 6.2 最小系统设计 6.3 软件开发平台 6.4 启动代码 6.5 GPIO模块
6.1 引言 (一) 为什么要学ARM? (二) 学ARM要学什么? (三) 学ARM难吗? (四) 如何学ARM?
6.1 引言 (一) 为什么要学ARM? 技术要以市场为导向。 学习主流技术和先进技术。 规划个人职业生涯。 提升公司平台和核心竞争力。
6.1 引言 (二) 学ARM要学什么? 学ARM要学核心的东西,而不是花哨的外设。 结合自己的专长进行发挥。 ARM7还是ARM9?ARM和操作系统?
6.1 引言 (三) 学ARM难吗? 学ARM不难,只要有电子基础、有一定的C/汇编语言能力即可,能懂或者了解某一个体系的CPU架构则更好。 电子、自动化、机电一体化、仪器仪表、计算机、机械甚至物理等基础学科的学生都可以学习。
6.1 引言 (四) 如何学ARM? 良好的学习态度+ 合适的开发套件+ 正确的学习方法
6.1 引言 (四) 如何学ARM? 前提条件:选择一款合适的芯片和开发套件。 嵌入式开发是一个实战性很强的行业。 选一个最简单的芯片、最简单的开发板,可以加快入门的速度。简单的芯片和开发板可以降低门槛,减少障碍。
6.1 引言 (四) 如何学ARM? 对于初学者,推荐EasyARM2131开发套件。 (1)EasyARM2131开发板 (2)EasyJTAG仿真器 (3)《深入浅出ARM7-LPC213x/214x(上下册)》 (4)原理图、源代码、分析文档 (5)其它资料 (6)强大、完善的技术支持。 提供了一个完善的开发平台。
6.1 引言 (四) 如何学ARM? 选择开发套件的标准: (1)配套资料是否齐全? 原理图、源程序、文档等。 (2)是否提供技术支持? 强大、完善的技术支持能够加快学习进度。 (3)能否提供开发平台? 现代嵌入式系统的开发要以平台为基础。平台是公司和个人迅速发展的保证。
6.1 引言 推荐使用 EasyARM2131开发套件
6.1 引言 配套资料 EasyARM2131开发套件
6.1 引言 全面支持10种型号的64 PIN小管脚ARM7微控制器: -LPC213x(LPC2131/2132/2134/2136/2138) -内置USB接口的LPC214x(LPC2141/2142/2144/2146/2148) 多种免费商业化软件包及其详细的开发文档: * 移植μC/OS-II到ARM7软件包 * 数据队列软件包 * 串口驱动软件包 * MODEM接口软件包 * SPI总线软件包 * I2C总线软件包 * ZLG/FS V1.0版本文件管理系统软件包 * ZLG/GUI图形用户界面软件包 * ZLG/SD卡读写软件包 * ZLG/USB固件程序及其驱动程序软件包 功能特点 EasyARM2131开发套件
6.1 引言 多种可选配置适配器: -各种型号的CPU PACK,用户可按需求和喜好配置主ARM芯片 -MG12864点阵图型液晶模块 所有I/O口全部引出,方便用户连接外部电路的开发与使用; 可进行GPIO的控制实验,如键盘输入、蜂鸣器控制、模拟SPI等; 6个独立按键(可用于外部中断、定时器捕获输入),8个LED指示灯; 具有RS232转换电路,可与上位机进行通讯,完成UART通讯实验; 可以与标准串行modem直接接口,方便远程通讯; 具有I2C接口和SPI/SSP接口输出; 提供基于PC的人机界面,方便调试实时时钟、串口通信等功能; 可进行外部中断实验,学习向量中断控制器(VIC); 定时器控制实验,如定时控制LED、定时器捕获等; 使用板内的CAT1025(内含复位功能),完成I2C总线的实验; 使用74HC595芯片,实现SPI接口数据发送、接收实验; 功能特点 EasyARM2131开发套件
6.1 引言 功能特点 EasyARM2131开发套件 A/D转换实验; DAC转换实验(更换CPU为LPC2132及以上); 实时时钟控制实验; WDT及低功耗控制实验; 54个基础实验及其大量的中间件软件包,完整地验证了几乎所有的硬件功能资源; 详细的配套资料(《深入浅出ARM7—LPC213x/214x》(上/下册),北航出版社,其中上册为标准配置)。 功能特点 EasyARM2131开发套件
6.1 引言 (四) 如何学ARM? (1)动手实践 不要将光盘配套程序直接运行,而要逐行输入代码,并理解代码,写文档。 (2)使用网络 周立功网站:www.zlgmcu.com 中国电子网:www.21IC.com ZLG-ARM论坛 (3)学会投资 舍得为学知识投资,如买书、资料和工具等。
6.2 最小系统设计 6.2.1 最小系统概述 6.2.2 电源设计 6.2.3 时钟电路设计 6.2.4 复位电路设计 6.2.5 调试接口设计 6.2.6 存储系统设计 6.2.7 最小系统示例
6.2.1 最小系统概述 设计一个最小系统是学习ARM的好方法 6.2.1 最小系统概述 设计一个最小系统是学习ARM的好方法 一个嵌入式处理器自己是不能独立工作的,必须给它供电、加上时钟信号、提供复位信号,如果芯片没有片内程序存储器,则还要加上存储器系统,然后嵌入式处理器芯片才可能工作。这些提供嵌入式处理器运行所必须的条件的电路与嵌入式处理器共同构成了这个嵌入式处理器的最小系统。而大多数基于ARM7处理器核的微控制器都有调试接口,这部分在芯片实际工作时不是必需的,但因为这部分在开发时很重要,所以也把这部分也归入最小系统中。
6.2.1 最小系统概述 最小系统框图 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 6.2.1 最小系统概述 最小系统框图 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 可选,但是在样品阶段通常都会设计这部分电路 可选,因为许多面向嵌入式领域的微控制器内部集成了程序和数据存储器
6.2.2 电源设计 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 供电系统 (电源) 电源系统为整个系统提供能量,是整个系统工作的基础,具有极其重要的地位,但却往往被忽略。如果电源系统处理得好,整个系统的故障往往减少了一大半。
6.2.2 电源设计 设计电源时要考虑的因素: 1.输出的电压、电流、功率; 2.输入的电压、电流; 3.安全因素; 4.输出纹波; 6.2.2 电源设计 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 设计电源时要考虑的因素: 1.输出的电压、电流、功率; 2.输入的电压、电流; 3.安全因素; 4.输出纹波; 5.电磁兼容和电磁干扰; 6.体积限制; 7.功耗限制; 8.成本限制。
6.2.2 电源设计 1.分析需求 (1)LPC2000系列微控制所需要的电源类型 LPC210x V3.3 无 V1.8 6.2.2 电源设计 1.分析需求 (1)LPC2000系列微控制所需要的电源类型 电压 型号 3.3V 1.8V 数字电源 模拟电源 LPC210x V3.3 无 V1.8 LPC213x/214x V3.3D V3.3A LPC22xx/21xx V1.8D V1.8A
6.2.2 电源设计 1.分析需求 (2)系统需求 主要考虑是否需要将数字电源和模拟电源分开。 6.2.2 电源设计 1.分析需求 (2)系统需求 主要考虑是否需要将数字电源和模拟电源分开。 (1)如果不使用芯片的A/D或者D/A功能,可以不区分数字电源和模拟电源。 (2)如果使用了A/D或者D/A,还需考虑参考电源设计。
6.2.2 电源设计 1.分析需求 (3)电源电路的前级和末级 电源前级 电源末级
6.2.2 电源设计 2.设计末级电源电路 LPC2000系列微控制1.8V消耗电流的极限值为70mA。为了保证可靠性并为以后升级留下余量,则电源系统1.8V能够提供的电流应当大于300mA。 整个系统在3.3V上消耗的电流与外部条件有很大的关系,这里假设电流不超过200mA,这样,电源系统3.3V能够提供600mA电流即可。 分析得到以下参数: 3.3V电源设计最大电流:600mA; 1.8V电源设计最大电流:300mA。
6.2.2 电源设计 2.设计末级电源电路 因为系统对这两组电压的要求比较高,且其功耗不是很大,所以不适合用开关电源,应当用低压差模拟电源(LDO)。合乎技术参数的LDO芯片很多,Sipex 半导体SPX1117是一个较好的选择,它的性价比高,且有一些产品可以与它直接替换,减少采购风险。
6.2.2 电源设计 SPX1117主要特点: 0.8A稳定输出电流; 1A稳定峰值电流; 3V可调节; 低静态电流; 6.2.2 电源设计 SPX1117主要特点: 0.8A稳定输出电流; 1A稳定峰值电流; 3V可调节; 低静态电流; 0.8A时低压差为1.1V; 0.1%线形调整率; 0.2%负载调整率; 过流及温度保护; 多种封装供选择。
6.2.2 电源设计 末级电源 电路实例
6.2.2 电源设计 模数隔离实例
6.2.2 电源设计 3.设计前级电源电路 尽管SPX1117允许的输入电压可达20V(参考芯片数据手册),但太高的电压使芯片的发热量上升,散热系统不好设计,同时影响芯片的性能。这样,就需要前级电路调整一下。如果系统可能使用多种电源(如交流电和电池),各种电源的电压输出不一样,就更需要前级调整以适应末级的输入。通过之前的分析,前级的输出选择为5V。选择5V作为前级的输出有两个原因: 这个电压满足SPX1117的要求; 目前很多器件还是需要5V供电的,这个5V可以兼做前级和末级了。
6.2.2 电源设计 3.设计前级电源电路 根据系统在5V上消耗的电流和体积、成本等方面的考虑,前级电路可以使用开关电源,也可以使用模拟电源。 它们的特别如下: 开关电源:效率较高,可以减少发热量,因而在功率较大时可以减小电源模块的体积; 模拟电源:电路简单,输出电压纹波较小,并且干扰较开关电源小得多。
6.2.2 电源设计 前级电源 电路实例 模拟电源 开关电源
6.2.3 时钟电路设计 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 时钟系统 目前所有的微控制器均为时序电路,需要一个时钟信号才能工作,大多数微控制器具有晶体振荡器。简单的方法是利用微控制器内部的晶体振荡器,但有些场合(如减少功耗、需要严格同步等情况)需要使用外部振荡源提供时钟信号。
6.2.3 时钟电路设计 LPC2000 LPC2000 使用内部振荡器 使用外部时钟源 6.2.3 时钟电路设计 LPC2000 X1 X2 C Xtal LPC2000 X1 X2 C Clock 可以使用稳定的时钟信号源,如有源晶振等。 使用内部振荡器 使用外部时钟源 目前所有的微控制器均为时序电路,需要一个时钟信号才能工作,大多数微控制器具有晶体振荡器。简单的方法是利用微控制器内部的晶体振荡器,但有些场合(如减少功耗、需要严格同步等情况)需要使用外部振荡源提供时钟信号。
6.2.4 复位电路设计 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 复位及其 配置系统 微控制器在上电时状态并不确定,这造成微控制器不能正确工作。为解决这个问题,所有微控制器均有一个复位逻辑,它负责将微控制器初始化为某个确定的状态。这个复位逻辑需要一个复位信号才能工作。一些微控制器自己在上电时会产生复位信号,但大多数微控制器需要外部输入这个信号。这个信号的稳定性和可靠性对微控制器的正常工作有重大影响。
6.2.4 复位电路设计 复位电路可以使用简单的阻容复位,这个电路成本低廉,但不能保证任何情况产生稳定可靠的复位信号,所以一般场合需要使用专门的复位芯片。 最好避免使用! 阻容复位
6.2.4 复位电路设计 常用的复位专用芯片有CATALYST公司的CAT800系列,Sipex公司的SP700系列和SP800系列。为了适应嵌入式系统的应用,这些公司还推出带有EEPROM存储器和看门狗的复位芯片,这可以降低系统成本和缩小产品体积,减少元件数量也有利于系统的稳定性。 如果系统不需要手动复位功能,可以选择CAT809。如果需要手动复位功能,可以选择SP705/706、SP708SCN。 种类繁多的复位芯片可以满足不同工作电压和不同复位方式的系统,这里仅介绍其中部分。 注意:复位芯片的复位门槛的选择至关重要,一般应当选择微控制器的IO口供电电压范围为标准。LPC2000这个范围为:3.0V~3.6V,所以选择复位门槛电压为2.93V,即电源电压低于2.93V时产生复位信号。
6.2.4 复位电路设计 复位电路实例CAT809 低有效复位; 在工业级温度范围的应用中可直接代替MAX809; 6.2.4 复位电路设计 复位电路实例CAT809 低有效复位; 在工业级温度范围的应用中可直接代替MAX809; Vcc低至1.0V时,复位信号仍然有效; 6uA的电源电流; 抗电源的瞬态干扰; 紧凑的3脚SOT23和SC70封装; 工业级温度范围:-40℃~+85℃ 。
6.2.4 复位电路设计 复位电路实例SP708/R/S/T 2.63V:SP708R;2.93V:SP708S;3.08V:SP708T; 6.2.4 复位电路设计 复位电路实例SP708/R/S/T 2.63V:SP708R;2.93V:SP708S;3.08V:SP708T; 复位脉冲宽度-200ms; 最大电源电流40uA; 支持开关式TTL/CMOS手动复位输入; Vcc下降至1V时,nRESET信号仍然有效; SP708/R/S/T支持高/低电平两种方式。
6.2.4 复位电路设计 复位电路实例SP6200/6201 适用于要求高精度、快速操作和方便使用的应用; 极低的关断电流:最大为1uA; 6.2.4 复位电路设计 复位电路实例SP6200/6201 适用于要求高精度、快速操作和方便使用的应用; 极低的关断电流:最大为1uA; 低压差:160mV@100mA。输出电压高精度: 2% ; 逻辑控制的电子使能; 复位输出(VOUT良好); 1uF的陶瓷电容就可保持器件无条件稳定工作。 电压输出使能 复位输出
6.2.4 复位电路设计 复位电路实例CAT1024/1025 具有2K字节EEPROM存储器,数据保存时间长达100年; 6.2.4 复位电路设计 复位电路实例CAT1024/1025 具有2K字节EEPROM存储器,数据保存时间长达100年; 存储器采用400KHz的I2C总线接口,16字节的页写缓冲区; CAT1025具有高、低电平复位信号,CAT1024具有低电平复位信号。Vcc低至1V时复位仍有效; 工作电压范围:2.7V~5.5V; 手动复位输入。
P2.26和P2.27决定复位后存储器的来源以及存储器的宽度 6.2.4 复位电路设计 微控制器在复位后可能有多种初始状态,具体复位到哪种初始状态是在复位的过程中决定的。复位逻辑可能通过片内只读存储器中的数据决定具体的初始状态,但更多的是通过复位期间的引脚状态决定,也可能通过两者共同决定。用引脚状态配置复位后的初始状态没有统一的方法,需要根据相关芯片的手册决定。 P0.14决定复位后是否进入ISP状态 P1. 20决定复位后是否使用P1.25~P1.16作为跟踪端口 P2.26和P2.27决定复位后存储器的来源以及存储器的宽度 P1.26决定复位后是否使用P1.31~P1.26作为调试端口
6.2.5 调试接口设计 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 调试测试接口 调试与测试接口不是系统运行必须的,但现代系统越来越强调可测性,调试、测试接口的设计也要重视了。LPC2000有一个内置JTAG调试接口,通过这个接口可以控制芯片的运行并获取内部信息。
6.2.5 调试接口设计 RTCK必须接4.7K下拉电阻。 调试接口电路一 标准20针JTAG 6.2.5 调试接口设计 标准20针JTAG RTCK必须接4.7K下拉电阻。 ETM功能仅在高级仿真器中具有,用户如果没有使用,可以将其省略,同时把TRACESYNC信号上的电阻也去掉。 调试接口电路一
6.2.5 调试接口设计 在该电路中,复位电路与前面介绍电路有所不同。它在复位信号和CPU之间插入了三态门74HC125。使用三态门主要是为了复位芯片和JTAG(ETM)仿真器都可以复位芯片。如果没有74HC125,当复位芯片输出高电平时,JTAG(ETM)仿真器就不可能把它拉低,这不但不能实现需要的功能,还可能损坏复位芯片或JTAG(ETM)仿真器。 调试接口电路一
6.2.5 调试接口设计 因为这种电路JTAG(ETM)仿真器对LPC2000有完全的控制,其仿真性能最好。不过,由于74HC125工作的电压范围低于复位芯片的工作电压范围,所以此电路一般用于样机。正式产品中可以不需要这部分电路。
6.2.5 调试接口设计 标准20针JTAG RTCK必须接4.7K下拉电阻。 调试接口电路二 ETM跟踪接口
6.2.6 存储系统 嵌入式控制器 时钟系统 调试测试接口 复位及其 配置系统 存储器系统 供电系统 (电源) 存储器系统 大部分LPC2000芯片都有片内Flash,可以不用再设计额外的存储器系统。如果微控制器没有片内存储器,就必须设计存储器系统,这一般通过微控制器的外部总线接口实现。
6.2.6 存储系统 如果需要外扩存储系统,需要考虑: (1)总线宽度 (2)总线速度 6.2.6 存储系统 如果需要外扩存储系统,需要考虑: (1)总线宽度 (2)总线速度 尽量避免使用8位总线,推荐使用16和32位总线,器件选型尽量选择高速存储器。 如果使用16位总线,使用Thumb指令集可获得更高的性能。
6.2.6 存储系统 示例:LPC2210存储器系统 16位SRAM 16位FLASH 复位后使用外部16位宽度存储器 SRAM FLASH 6.2.6 存储系统 LPC2210 SRAM FLASH 16位SRAM 16位FLASH 复位后使用外部16位宽度存储器 示例:LPC2210存储器系统
6.2.7 最小系统实例 LPC2100系列没有外部总线接口的最小系统; LPC2130系列没有外部总线接口的最小系统; 6.2.7 最小系统实例 LPC2100系列没有外部总线接口的最小系统; LPC2130系列没有外部总线接口的最小系统; LPC2200系列使用内部存储器的最小系统; LPC2200系列使用外部存储器的最小系统。
决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 6.2.7 最小系统实例 时钟电路 3.3V电源 1.8V电源 复位电路 决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 完整的最小系统LPC2100系列
决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 6.2.7 最小系统实例 时钟电路 3.3V电源 复位电路 决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 完整的最小系统LPC2130系列
决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 6.2.7 最小系统实例 时钟电路 3.3V电源 1.8V电源 复位电路 决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 复位后使用内部存储器 完整的最小系统LPC2200不使用外部存储器
决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 6.2.7 最小系统实例 时钟电路 3.3V电源 SRAM 1.8V电源 复位电路 FLASH 决定是否进入ISP状态,如果该引脚悬空将影响程序脱机运行 复位后使用外部16位宽度存储器 完整的最小系统LPC2200使用外部存储器
6.3 软件开发平台 6.3.1 ISP下载软件 6.3.2 ADS集成开发环境 6.3.3 EasyJTAG使用 6.3.4 LPC2000工程模板
6.3.1 ISP下载软件 简介 ISP下载软件是Philips为LPC2000系列芯片编写的一款程序下载软件,全称是LPC2000 Flash Utility,最新版本为V2.2.3,支持LPC2000所有芯片。 常用于批量生产时下载程序,亦可用于检测最小系统。
6.3.1 ISP下载软件 界面
6.3.1 ISP下载软件 设置 设定串口 波特率 设定晶振
6.3.1 ISP下载软件 操作 查空 擦除 下载 校验 芯片型号 读取ID
6.3.1 ISP下载软件 重点提示 设计好最小系统后,最好先用ISP软件对最小系统进行测试,如果能进行ISP连接操作(如读取ID),则才能进行下一步的工作,如JTAG调试。如果ISP测试不能工作,则需要先检查最小系统硬件电路。 系统可以没有JTAG调试电路,但不能没有UART0电路/接口。
6.3.1 ISP下载软件 UART0电路(ISP电路)
6.3.1 ISP下载软件 ISP不成功常见原因和解决办法 (1)确保各路电源正常 (2)确保UART0电路正常,可用PC检测 (3)确保晶振正常 (4)确保复位电路正常 (5)检测PCB是否存在短路/断路
6.3.2 ADS集成开发环境 简介 ADS是目前国内使用最广泛的ARM开发环境。 ADS为ARM公司所有,全称为ARM Developer Suite,成熟版本为ADS1.2,支持ARM10之前的所有ARM控制器,支持软件调试和JTAG硬件仿真调试,支持汇编、C、C++源程序;编译效率高、系统功能强,可以在Win98/2000/XP和RedHat上运行。
6.3.2 ADS集成开发环境 简介 ADS1.2 集成开发环境组成部分 名称 描述 使用方式 代码生成工具 ARM汇编器 ARM C/C++编译器 Thumb C/C++编译器 ARM 链接器 由Code Warrior调用 集成开发环境 Code Warrior 工程管理,编译链接 调试器 AXD/ADW/ADU/armsd 仿真调试 指令模拟器 ARMulator 由AXD调用 ARM开发包 一些底层的例程,实用程序(如fromELF) ARM应用库 C/C++等函数库 用户程序调用
Code Worriar IDE界面 6.3.2 ADS集成开发环境 源程序编辑窗口 工程管理窗口
AXD调试器界面 6.3.2 ADS集成开发环境 调试控制快捷图标 源代码查看区
6.3.2 ADS集成开发环境 ADS使用注意: 最好不要将ADS工程放在有中文的路径下。
6.3.3 EasyJTAG使用 (一)简介 EasyJTAG是是广州致远电子有限公司开发的一款简易JTAG仿真器,支持ADS1.2开发环境,支持Philips所有ARM7芯片。
6.3.3 EasyJTAG使用 (二)驱动安装 (1)将光盘提供或者网上下载的驱动复制到ADS安装目录的BIN目录。
6.3.3 EasyJTAG使用 (二)驱动安装 (2)进入AXD调试环境,在目标环境配置的时候添加BIN下的EasyJTAG.dll。
6.3.3 EasyJTAG使用 (二)驱动安装 (3)选择Configure,对JTAG进行配置。
6.3.4 LPC2000工程模板 (一)简介 LPC2000系列模板都是以广州致远电子有限公司生产的LPC系列ARM板为原型设计的,但是很容易移植到其它用户板上。目前有下列模板可用: (1)LPC2100系列模板 (2)LPC2200系列模板 每系列模板都包含如下具体模板: -asm for lpc2100/2200 -ARM Executable Image for lpc2100/2200 -Thumb ARM Interworking Image for lpc2100/2200 -Thumb Executable Image for lpc2100/2200 -ARM Executable Image for UCOSII(for lpc2100/2200) -Thumb Executable Image for UCOSII(for lpc2100/2200)
6.3.4 LPC2000工程模板 (一)简介 (1)LPC2000系列启动代码 (2)Demo板的分散加载文件 (3)不同生成目标的配置 -Remap设置 -资源配置:分散加载,存储器资源 -优化等级和加密等 注意:如果使用LPC2200系列,但没有外扩存储器,请使用LPC2100系列模板。
6.3.4 LPC2000工程模板 (一)简介 生成目标 分散加载文件 系统配文件 启动文件 用户文件
6.3.4 LPC2000工程模板 (二)分散加载文件 如果用户希望将不同的代码/数据存放在不同存储器空间,也就是希望生成的目标映象文件有多个域,每个域在加载和运行的时候有不同的地址。简单的控制可在ADS的集成开发环境中设置,但复杂的设置只能通过分散加载机制实现。 实现分散加载机制的文件称为分散加载文件。
6.3.4 LPC2000工程模板 (二)分散加载文件 在LPC2000工程模板中,提供了3个不同的分散加载文件(以LPC2100为例): mem_a.scf-对应于RelInFlash生成目标。 mem_b.scf-对应于DebugInRAM生成目标。 mem_c.scf-对应于DebugInFlash生成目标。 在LPC2100的模板中,mem_a.scf和mem_c.scf相同。
6.3.4 LPC2000工程模板 (1)mem_a.scf mem_c.scf ROM_LOAD 0x00000000 { ROM_EXEC 0x00000000 Startup.o (vectors, +First) * (+RO) } IRAM 0x40000000 Startup.o (MyStacks) * (+RW,+ZI) HEAP +0 UNINIT Startup.o (Heap) STACKS 0x40002000 UNINIT Startup.o (Stacks) 6.3.4 LPC2000工程模板 (1)mem_a.scf mem_c.scf 栈底位置需要根据所选择的芯片进行更改。更改为芯片RAM的最高端+1。
6.3.4 LPC2000工程模板 (2)mem_b.scf 如果出现区域交叠的错误,请适当修改IRAM起始地址的值。 ROM_LOAD 0x40000000 { ROM_EXEC 0x40000000 Startup.o (vectors, +First) * (+RO) } IRAM 0x40001900 Startup.o (MyStacks) * (+RW,+ZI) HEAP +0 UNINIT Startup.o (Heap) STACKS 0x40002000 UNINIT Startup.o (Stacks) 6.3.4 LPC2000工程模板 (2)mem_b.scf 如果出现区域交叠的错误,请适当修改IRAM起始地址的值。 栈底位置需要根据所选择的芯片进行更改。更改为芯片RAM的最高端+1。
6.3.4 LPC2000工程模板 (三)系统配置文件 一些和目标板紧密相关的配置信息,如晶振、系统时钟等设置,还有一些需要包含的头文件。 config.h-系统配置文件 target.h-target.c的头文件。
6.3.4 LPC2000工程模板 config.h typedef unsigned char uint8; /*无符号8位整型变量*/ typedef signed char int8; /*有符号8位整型变量*/ typedef unsigned short uint16; /*无符号16位整型变量*/ typedef signed short int16; /*有符号16位整型变量*/ typedef unsigned int uint32; /*无符号32位整型变量*/ typedef signed int int32; /*有符号32位整型变量*/ typedef float fp32; /*单精度浮点数(32位长度)*/ typedef double fp64; /*双精度浮点数(64位长度)*/ #include "LPC2294.h" /* 系统设置, Fosc、Fcclk、Fcco、Fpclk必须定义*/ #define Fosc 11059200 /*应当与实际晶振频率一致*/ #define Fcclk (Fosc * 4) /*系统频率*/ #define Fcco (Fcclk * 4) /*CCO频率*/ #define Fpclk (Fcclk / 4) * 1 /*VPB时钟频率*/ #include “target.h” /*这一句不能删除*/
6.3.4 LPC2000工程模板 (四)模板的使用 将光盘或者网上下载的模板复制到ADS安装目录的Stationary目录下,在新建工程的时候选择该模板即可。
6.3.4 LPC2000工程模板 (四)模板的使用 将光盘或者网上下载的模板复制到ADS安装目录的Stationary目录下,在新建工程的时候选择该模板即可。
6.4 启动代码 6.4.1 启动代码内容 6.4.2 启动代码工作流程
6.4.1 启动代码内容 (1)启动代码简介 广州致远电子有限公司为LPC2000系列芯片编写的启动代码由3个文件组成。 (1)startup.s-异常向量表定义、各模式堆栈初始化、跳转到C程序main入口等。 (2)target.c-目标板初始化,如时钟分频、PLL设置、VIC设置等。 (3)irq.s-用于管理中断嵌套。
6.4.1 启动代码内容 (1)startup.s 汇编入口 异常向量表 地址跳转表 CODE32 AREA vectors,CODE,READONLY ENTRY ;中断向量表 Reset LDR PC, ResetAddr LDR PC, UndefinedAddr LDR PC, SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr DCD 0xb9205f80 LDR PC, [PC, #-0xff0] LDR PC, FIQ_Addr ResetAddr DCD ResetInit UndefinedAddr DCD Undefined SWI_Addr DCD SoftwareInterrupt PrefetchAddr DCD PrefetchAbort DataAbortAddr DCD DataAbort Nouse DCD 0 IRQ_Addr DCD 0 FIQ_Addr DCD FIQ_Handler 6.4.1 启动代码内容 汇编入口 异常向量表 地址跳转表
6.4.1 启动代码内容 (1)startup.s 异常处理程序 FIQ处理程序,在target.c中实现 ;未定义指令 Undefined B Undefined ;软中断 SoftwareInterrupt B SoftwareInterrupt ;取指令中止 PrefetchAbort B PrefetchAbort ;取数据中止 DataAbort B DataAbort ;快速中断 FIQ_Handler STMFD SP!, {R0-R3, LR} BL FIQ_Exception LDMFD SP!, {R0-R3, LR} SUBS PC, LR, #4 6.4.1 启动代码内容 异常处理程序 FIQ处理程序,在target.c中实现
6.4.1 启动代码内容 (1)startup.s 设置各模式堆栈 InitStack MOV R0, LR MSR CPSR_c, #0xd3 ;设置管理模式堆栈 LDR SP, StackSvc MSR CPSR_c, #0xd2 ;设置中断模式堆栈 LDR SP, StackIrq MSR CPSR_c, #0xd1 ;设置快速中断模式堆栈 LDR SP, StackFiq MSR CPSR_c, #0xd7 ;设置中止模式堆栈 LDR SP, StackAbt MSR CPSR_c, #0xdb ;设置未定义模式堆栈 LDR SP, StackUnd MSR CPSR_c, #0xdf ;设置系统模式堆栈 LDR SP, =StackUsr MOV PC, R0 ResetInit BL InitStack ;初始化堆栈 BL TargetResetInit ;目标板基本初始化 B __main ;跳转到c语言入口 (1)startup.s 6.4.1 启动代码内容 设置各模式堆栈
6.4.1 启动代码内容 (1)startup.s 定义各模式堆大小 计算并分配各模式栈空间 分散加载 文字池: 各模式栈起点 SVC_STACK_LEGTH EQU 0 FIQ_STACK_LEGTH EQU 0 IRQ_STACK_LEGTH EQU 256 ABT_STACK_LEGTH EQU 0 UND_STACK_LEGTH EQU 0 AREA MyStacks, DATA, NOINIT, ALIGN=2 SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;管理模式栈空间 IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;中断模式栈空间 FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;快速中断模式栈空间 AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;中止义模式栈空间 UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;未定义模式栈 StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4 StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4 StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4 StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4 AREA Heap, DATA, NOINIT bottom_of_heap SPACE 1 AREA Stacks, DATA, NOINIT StackUsr 定义各模式堆大小 6.4.1 启动代码内容 计算并分配各模式栈空间 分散加载 文字池: 各模式栈起点 堆空间,分散加载 用户堆栈空间,分散加载
6.3.4 LPC2000工程模板 (1)mem_a.scf mem_c.scf ROM_LOAD 0x00000000 { ROM_EXEC 0x00000000 Startup.o (vectors, +First) * (+RO) } IRAM 0x40000000 Startup.o (MyStacks) * (+RW,+ZI) HEAP +0 UNINIT Startup.o (Heap) STACKS 0x40002000 UNINIT Startup.o (Stacks) 6.3.4 LPC2000工程模板 (1)mem_a.scf mem_c.scf
6.4.1 启动代码内容 (2)target.c FIQ处理程序 调试时,根据用户选择的目标设置Remap void FIQ_Exception(void) { while(1); // 这一句替换为自己的代码 } void TargetResetInit(void) #ifdef __DEBUG_RAM MEMMAP = 0x2; //remap #endif #ifdef __DEBUG_FLASH MEMMAP = 0x1; //remap #ifdef __IN_CHIP /* 设置系统各部分时钟 */ PLLCON = 1; #if (Fpclk / (Fcclk / 4)) == 1 VPBDIV = 0; 6.4.1 启动代码内容 FIQ处理程序 调试时,根据用户选择的目标设置Remap 根据config.h用户定义的时钟自动设定VPB分频值
6.4.1 启动代码内容 (2)target.c 根据config.h用户定义的时钟自动设定VPB分频值 /* 设置系统各部分时钟 */ PLLCON = 1; #if (Fpclk / (Fcclk / 4)) == 1 VPBDIV = 0; #endif #if (Fpclk / (Fcclk / 4)) == 2 VPBDIV = 2; #if (Fpclk / (Fcclk / 4)) == 4 VPBDIV = 1; #if (Fcco / Fcclk) == 2 PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5); #if (Fcco / Fcclk) == 4 PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5); #if (Fcco / Fcclk) == 8 PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5); #if (Fcco / Fcclk) == 16 PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5); 6.4.1 启动代码内容 根据config.h用户定义的时钟自动设定VPB分频值 根据config.h用户定义的时钟自动设定PLL的P和M
6.4.1 启动代码内容 (2)target.c 设定MAM 设定VIC 留给用户使用 /* 设置存储器加速模块 */ MAMCR = 0; #if Fcclk < 20000000 MAMTIM = 1; #else #if Fcclk < 40000000 MAMTIM = 2; MAMTIM = 3; #endif MAMCR = 2; /* 初始化VIC */ VICIntEnClr = 0xffffffff; VICVectAddr = 0; VICIntSelect = 0; /* 添加自己的代码 */ /* …… */ } 6.4.1 启动代码内容 设定MAM 设定VIC 留给用户使用
6.4.2 启动代码工作流程 复位后,启动代码工作及内容: (1)复位后,PC=0,根据异常向量表,跳转到复位处理程序。 (2)执行复位程序。 -堆栈初始化 -目标板初始化 -跳到C程序main入。 (3)执行用户程序。
6.4.2 启动代码工作流程 复位 (1)ResetInit的地址转入PC (3)各模式堆栈初始化 (2)程序跳转到ResetInit
6.4.2 启动代码工作流程 (1)ResetInit的地址转入PC (3)各模式堆栈初始化 (2)程序跳转到ResetInit (4)进行目标板初始化
6.4.2 启动代码工作流程 (5)跳转到main入口 (1)ResetInit的地址转入PC (3)各模式堆栈初始化 (4)进行目标板初始化
参考资料 启动代码和分散加载在《深入浅出ARM7-LPC213x/ LPC214x(上册)》中有详细描述。 详见3.9《启动代码综述》一节。
ARM之旅 概述 选择合适的ARM芯片 充分了解该ARM芯片 ARM的特性 了解ARM内部结构 设计最小系统 建立开发环境 (软件、硬件) HelloWorld程序 概述 产品开发 ARM的特性 了解ARM内部结构 ARM程序的组成 了解ARM指令系统 掌握部分ARM指令 选择合适的ARM芯片 充分了解该ARM芯片 入门级别 了解级别 当前位置
6.5 GPIO模块 (一)特性 LPC2000的GPIO具有如下的特性: 可以独立控制每个GPIO口的方向(输入/输出模式)
6.5 GPIO模块 (二)应用 驱动LED或其它指示器 检测数字输入,如键盘或开关信号 控制片外器件
6.5 GPIO模块 (三)引脚描述 LPC2114/2124微控制器具有两个端口——P0和P1,可以作为GPIO使用的引脚数为46个。 LPC2210/2212/2214微控制器还包含另外两个端口——P2和P3,这个两个端口与外部存储器总线复用,当它们全部作为GPIO使用时,GPIO引脚数多达112个。
6.5 GPIO模块 (四)内部结构 GPIO内部结构示意 引脚 PINSELx IOxDIR IOxCLR IOxPIN IOxSET out 1 引脚 GPIO内部结构示意
6.5 GPIO模块 (五)GPIO操作 除了设定管脚连接之外,GPIO还有如下操作: (1)设定GPIO方向 (2)控制GPIO (3)读取管脚电平 (4)读取GPIO设置
6.5 GPIO模块 (1)设定GPIO方向 通过GPIO方向寄存器IODIR进行控制。 方向控制: 1-输出 0-输入 IOxDIR 描述 复位值 31 : 0 IOxDIR[0]对应于Px.0 … IOxDIR[31]对应于Px.31引脚 未定义 方向控制: 1-输出 0-输入 每个P口都有自己的IODIR寄存器。IOxDIR 和相应的Px口对应。
6.5 GPIO模块 (2)控制GPIO 拉高某位口线通过置位相应的IO置位寄存器IOSET中对应位实现。 置位控制:写入1-输出高电平 IOxSET 描述 复位值 31 : 0 IOxSET[0]对应于Px.0 … IOxPIN[31]对应于Px.31引脚 未定义 置位控制:写入1-输出高电平 写0无效
6.5 GPIO模块 (2)控制GPIO 拉低某位口线通过置位相应的IO清零寄存器IOCLR中对应位实现。 清零控制:写入1-输出低电平 IOxCLR 描述 复位值 31 : 0 IOxCLR[0]对应于Px.0 … IOxCLR[31]对应于Px.31引脚 未定义 清零控制:写入1-输出低电平 写0无效 写该寄存器会清除IOSET寄存器/输出寄存器中对应位。
6.5 GPIO模块 (2)控制GPIO 同时拉高/拉低某些口线通过写相应的IO管脚值寄存器IOPIN中对应位实现。 IOxPIN 描述 复位值 31 : 0 IOxPIN[0]对应于Px.0 … IOxPIN[31]对应于Px.31引脚 未定义 清零控制:写入1-输出高电平 写入0-输出低电平
6.5 GPIO模块 (3)读取管脚电平 读取管脚电平通过读取相应的IO管脚值寄存器IOPIN实现。 管脚电平:1-管脚为高电平 IOxPIN 描述 复位值 31 : 0 IOxPIN[0]对应于Px.0 … IOxPIN[31]对应于Px.31引脚 未定义 管脚电平:1-管脚为高电平 0-管脚为低电平
6.5 GPIO模块 (4)读取GPIO设置 读取管脚设置通过读取相应的IO管脚置位寄存器IOSET实现。 IOxSET 描述 复位值 31 : 0 GPIO管脚设置状态 未定义 管脚设置:仅反映程序设定状态,不反映外部实际情况。
6.5 GPIO模块 (六) 注意要点 引脚设置为输出方式时,输出状态由IOxSET和IOxCLR中最后操作的寄存器决定; 大部分GPIO输出为推挽方式(个别引脚为开漏输出),正常拉出/灌入电流均为4mA(短时间极限值40mA); 复位后默认所有GPIO为输入模式。
6.5 GPIO模块 GPIO应用示例1——设置P0.0输出高电平 C代码: P0.0 ... PINSEL0 &= 0xFFFFFFFC; IO0SET out 1 1 in P0.0 IO0DIR IO0CLR IO0PIN PINSEL0 C代码: ... PINSEL0 &= 0xFFFFFFFC; IO0DIR |= 0x00000001; IO0SET = 0x00000001; (1) 设置引脚连接模块,P0.0为GPIO (2) 设置P0.0口方向,设置为输出 (3) 设置P0.0口状态,输出高电平
6.5 GPIO模块 GPIO应用示例2——读取P0.0引脚状态 C代码: P0.0 ... uint32 PinStat; IO0SET out 1 in P0.0 IO0DIR IO0CLR IO0PIN IO0PIN PINSEL0 C代码: ... uint32 PinStat; PINSEL0 &= 0xFFFFFFFC; IO0DIR &= 0xFFFFFFFE; PinStat = IO0PIN; (1) 设置引脚连接模块,P0.0为GPIO (2) 设置P0.0口方向,设置为输入 (3) 从IO0PIN读取引脚状态
6.5 GPIO模块 GPIO应用示例3——输出多位数据至IO口 在需要将多位数据同时输出到某几个IO口线时,通常使用IOxSET和IOxCLR来实现,在某些情况下也可以使用IOxPIN寄存器实现。后者可以在多个IO口上直接输出0和1电平。 本例将8位无符号整数变量Data的值输出到P0.0~P0.7。 使用IOxSET和IOxCLR实现: #define DataBus 0xFF PINSEL0 &= 0xFFFF0000; IO0DIR |= DataBus; IO0CLR = DataBus; IO0SET = Data; ... (1) 设置引脚连接模块,P0.0~7为GPIO (2) 设置P0.0口方向,设置为输出 (3) 清零8位IO口的输出状态 (4) Data变量中为1的位将输出高电平 0x?? 0x00 Data 数据输出线:
6.5 GPIO模块 GPIO应用示例4——输出多位数据至IO口 在需要将多位数据同时输出到某几个IO口线时,通常使用IOxSET和IOxCLR来实现,在某些情况下也可以使用IOxPIN寄存器实现。后者可以在多个IO口上直接输出0和1电平。 本例将8位无符号整数变量Data的值输出到P0.0~P0.7。 使用IOxPIN实现: #define DataBus 0xFF PINSEL0 &= 0xFFFF0000; IO0DIR |= DataBus; IO0PIN = (IO0PIN & 0xFFFFFF00) | Data; ... (1) 设置引脚连接模块,P0.0为GPIO (2) 设置P0.0口方向,设置为输出 (3) 写IO0PIN,输出数据 0x?? Data 数据输出线: 0x?? 0x00 Data 与前者对比:
6.5 GPIO模块 GPIO实验 演示GPIO控制蜂鸣器
6.5 GPIO模块 实验电路 蜂鸣器控制电路
6.5 GPIO模块 实验流程图 开始 设置P0.7为GPIO 设置P0.7为输出模式 拉高P0.7,关闭蜂鸣器 延时
6.5 GPIO模块 实验代码 #include "config.h" #define BEEP 1 << 7 // P0.7控制蜂鸣器 void DelayNS (uint32 dly) { uint32 i; for ( ; dly>0; dly--) for (i=0; i<50000; i++); } int main (void) PINSEL0 = 0x00000000; //设置管脚连接GPIO IO0DIR = BEEP; //设置BEEP控制口为输出 while (1) IO0SET = BEEP; //BEEP停止蜂鸣 DelayNS(50); IO0CLR = BEEP; //BEEP蜂鸣 return 0; 6.5 GPIO模块 实验代码
结束 谢谢大家 再见!