LPC900 系列单片机凭借其功能强大、性能稳定,一直深受用户欢迎。P89LPC901(简称“LPC901”)是LPC900 系列单片机中的一员,性价比高,SO8/DIP8 封装,内含1 KB Flash,支持ICP,且具有6个I/O 口、4个TIMER、1路PWM输出、模拟比较器、键盘中断等众多功能部件。本文利用LPC901 单片机的强大功能实现ADC/DAC,并且通过模拟UART与PC机进行通信;通过PC 端软件可以显示D/A转换结果,及控制D/A输出电压;同时可以利用IAP(在线应用编程)技术实现Flash作EEPROM功能。
在嵌入式设计应用中,一般增强型8位都具备A/D、D/A、UART、EEPROM、I2C、SPI功能,但是如果在一般的小型微控制器中由于Flash容量的限制不具备这些功能,那么如何实现呢?根据LPC901芯片Flash和RAM的容量要求,下面主要讲述其模拟8位A/D、8位D/A,以及模拟UART功能和EEPROM功能的可靠实现。
1 连接测试
连接测试图如图1所示。本文重点介绍A/D或D/A、UART通信以及Flash实现EEPROM的功能实现。
图1 连接测试图
2 硬件电路及原理分析
LPC901引脚如图2所示。芯片采用SOIC8封装,本文所用的电路如图 3 所示。该电路比较简单,电路中仅包含2 片IC(分别为SP3232E、LPC901)和几个元器件。其中,SP3232E 及C1~C4 构成了RS232 电平转换电路;LPC901 和R1、C5 为本电路的核心部分,实现了D/A、A/D和UART 通信的功能。利用LPC901 定时器0的模式6,即可方便地实现PWM 波形的输出。8 位精度的PWM 波形从LPC901 的T0(第5 脚)输出,经R1 和C5 对信号进行整形滤波,即可在C5 正端输出稳定的电压,从而实现8 位精度的D/A 转换功能。利用LPC901 内部的模拟比较器,对外部输入电压(从第6 脚输入)与D/A转换电压进行逐次比较(从第7 脚输入),即可知道外部输入电压的大小,从而实现A/D 转换功能。
图2 P89LPC901 引脚图
图3 电路连接图
3 DAC的实现
3.1 输出公式
利用PWM 可方便地实现D/A 转换功能,优点是R1 和C5 的取值与转换结果无关。D/A转换输出电压可通过下式计算:
输出电压=PWM 波形的占空比×电源电压(1)
因此,实际电路中不必考虑RC的精度,也不必建立转换数据表,但需要注意RC 时间常数τ 的取值,因为τ 的取值将决定D/A 转换电压建立的稳定时间,以及稳定后电压变化的幅值。
一般认为对RC 电路进行充电,RC 电压上升到充电电压值需经过的时间为5τ。本实验电路中τ=4.7 kΩ×1 μF=4.7 ms,5τ=23.5 ms。但由于本电路是用PWM 方式对RC 充电实现D/A 转换,为了保证转换精度,所以该时间需适当延长。
3.2 仿真分析
借助PSPICE 对电路进行模拟仿真分析,以了解PWM 实现D/A 的整个过程。
在用PSPICE 对电路进行模拟仿真时,设置PWM 输出为50%占空比,电容从0 V开始充电,电源电压是3 V。仿真输出波形如图 4 所示。图中的测量点为C4 的正极性端,也就是D/A转换电压的输出端。左侧波形图是充电开始后23 ms 时的波形,右侧波形图是充电开始后37 ms时的波形。根据式1,D/A 输出电压=0.5×3=1.5 V。由图4可知,在5τ时输出电压为1.49 V,在接近37 ms时输出电压才达到1.5 V。可见为了达到设计精度,要完成一次充电约需37 ms。
图4 PSPICE 电路仿真
3.3 注意事项
本电路A/D 转换设计精度是8 位,在电源电压为3 V 时,最小分辨电压为3 V&pide;256≈0.012 V。通过观察PSPICE 仿真结果,在D/A输出的电压稳定时,电压的振幅为±0.01 V。但D/A输出电压抖动幅值理想值应该为可测量的最低电压,即±0.006 V 左右。要减小该电压的抖动,可增大τ值,但权衡充电时间,该RC 取值可基本达到设计精度要求。由于A/D 转换采用逐次比较的方式,因此PWM 作A/D 转换的速度比较慢,适用于低速场合。由于PWM 波形通过I/O 口推挽输出,即使I/O 一直输出高电平,该电压也比电源电压低一点,所以输出电压无法达到电源电压。
3.4 模拟UART
本实验通过I/O 模拟方式实现UART 通信(通过P3.1 和P3.0),波特率为9 600 bps。该功能以软件包的形式提供,可用于整个LPC900 系列单片机中。使用该软件包需要占用一个定时器。
3.5 模拟EEPROM
本实验通过Flash实现EEPROM,该功能通过IAP(在线应用编程)方法来实现。使用此功能可以将重要数据保存到芯片中,作为掉电保护参数和产品ID信息标识。
4 PC 端软件
为了方便读者观察A/D 转换结果和控制D/A 输出电压,笔者编写了一个PC 端软件,软件界面如图 5 所示。
图5 PC 端软件界面
软件的使用方法为: 在LPC901 复位后,按下“模数转换”或“数模转换”按钮选择相应模式。模式一经选定,只能在LPC901 再次复位后才能改变模式。在“模数转换”模式下,可直接读出A/D转换结果; 在“数模转换”模式下,可通过控制滑动条改变输出电压;参考电压(默认为3 V)、转换精度(默认为8 位)和通信端口(默认为COM1),可在菜单选项→设置中进行设置。
5 P89LPC901 程序的编写
5.1 PWM功能的实现
LPC901 利用其内部TIMER0 的工作模式6,即可方便地实现PWM 波型的输出。具体步骤为:设置TIMER0 为工作模式6,即设置寄存器TMOD 中[T0M1∶T0M0]为[1∶0],寄存器TAMOD 中T0M2 为1;设置AUXR1 中ENT0 为1,允许T0 溢出触发输出;最后置位TR0,启动PWM;在程序中可以随时更改TH0,改变PWM 占空比。PWM 波形的频率是相对CCLK 固定的,为CCLK/512。
5.2 A/D功能的实现
LPC901 内部比较器与PWM 输出电压逐次比较实现A/D功能。比较器的初始化可参考程序清单中的函数InitCmp()。在A/D 转换函数中,每次改变PWM的占空比,需要延时37 ms 使电压稳定(根据3.2小节中的分析)。如果读者在实际应用中使用不同的RC取值,则需重新确定RC充电延迟时间,并改变convert()中的延迟时间。
5.3 模拟UART的实现
由于模拟UART占用一个定时器资源,因此在使用前需初始化定时器1为模式1。在本实验中定义UART的RXD为P31,TXD为P30。如需改变,可在UART2.h中设置不同的I/O口为RXD 和TXD。软件包中发送/接收的波特率为9 600 bps。软件包提供2个函数: 发送函数void uart2send(unsigned char s)和接收函数 unsigned char uart2read(void)。实现代码请参考程序清单UART.h 和UART.c。
5.4 IAP代码的实现
通过IAP实现Flash擦除和编程操作的步骤如下:在LPC900寄存器FMCON寄存器中装载相应的读/写命令;向FMADRL寄存器写入需要向Flash编程的地址低字节;向FMADRH寄存器写入需要向Flash编程的地址高字节;向FMDATA寄存器中写入需要写入的数据;将擦除命令写入FMCON寄存器中。
这一系列操作步骤执行后,将执行擦除命令,同时将需要写入的数据写入Flash中。整个操作命令执行时间是4 ms,2 ms擦除操作,2 ms写入操作。