电控学院
课程设计(论文)
课程名称: ARM嵌入式系统
题 目: ARM数字电压表
院 (系): 测控技术与仪器
专业班级: 测控1001班
姓 名: 屈豆 王朵
学 号: 1006070115 1006070105
指导教师: 黄梦涛 李红岩
20##年12月29日
目录
摘要... 2
第一章 绪论... 2
1.1设计背景... 2
1.2设计要求... 2
第二章系统介绍... 2
2.1系统简述... 2
2.2上位机简述... 3
2.3下位机简述... 3
第三章 硬件设计... 4
3.1系统电路原理图... 4
3.2A/D转换器... 5
3.3报警电路... 5
3.5 LPC2131最小系统... 6
第四章软件设计... 7
4.1系统功能流程图... 7
4.2程序... 8
第五章 设计心得... 15
致谢... 17
参考文献... 18
基于LPC2131的数字电压表设计
摘要
本设计介绍了一种基于LPC2131的数字电压表。根据数据数据采集的工作原理,设计实现数字电压表,然后完成微控制器与上位机EasyARM的通信,将所测量的电压值传送给EasyARM的显示界面,进行显示。该电压表的主控芯片LPC2131内部有一个10位8路A/D转换器,这个A/D转换器即可单路软件启动也可对某几路信号逐个循环采样。这种电压表不仅整个电路结构简单、明了,直观的显示测量结果,而且具有精度高,性价比高,使用方便等特点。
【关键词】 电压测量,LPC2131,LED,蜂鸣器报警
第一章 绪论
1.1设计背景
随着电子科学技术不断发展,电子测量也变得越来越普遍,并且对测量的精度和功能的要求也是越来越高,而电压的测量尤为突出,因为电压的测量最为普遍。而且随着电子技术的日益发展,更是经常需要测量高精度的电压,数字电压表就成为一种必不可少的测量仪器。
数字电压表(Digital Voltmeter)简称DVM,它是采用数字化测量技术,把连续的模拟量(直流或交流输入电压)转换成不连续的、离散的数字形式并加以显示的仪表。由于数字是仪表具有读书准确方便、精度高、误差小、灵敏度高和分辨率高、测量速度快等特点而倍受青睐。
1.2设计要求
以ARM为控制器,采用中断方式,对2路0-5v的模拟电压进行循环采集,每路连续采集16次,取平均值。采集的数据送LED显示,并存入内存。超过界限时指示灯闪烁10次后一直亮,指示灯闪烁时喇叭发声,以示警告。
第二章系统介绍
2.1系统简述
数字电压表主要由模数转换部分、串口数据发送部分、上线报警部分三部分组成。其中LPC2131自带的10位ADC作为转换电路,将输入的模拟信号进行采样、转换、然后将转换的数字信号送入MCU进行处理,得出测量结果送入上位机进行显示。
2.2上位机简述
为了给系统提供更友好的人机界面,我们可以通过上位机软件实现各种显示输出或操作输入,EasyARM软件是上位机人机界面软件,通过RS232串口通讯完成各种功能控制。全仿真的DOS字符窗口是具有25行80列的字符显示窗(显示字符的前景/背景颜色可设置),具有8个仿真LED数码管和8个仿真发光二极管,还有20个模拟按键(按键名可重新定义)。串口模式可设置,具有单独的数据发送/接收调试窗,方便地监视串口接收到的数据或调试串口。
2.3下位机简述
LPC2131/2132/2138是基于一个支持实时仿真和跟踪的16/32位ARM7TDMI-STMCPU,并带有32kB、64kB和512kB嵌入的高速Flash存储器。128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行。对代码规模有严格控制的应用可使用16位Thumb模式将代码规模降低超过30%,而性能的损失却很小。
较小的封装和很低的功耗使LPC2131/2132/2138特别适用于访问控制和POS机等小型应用中;由于内置了宽范围的串行通信接口和8/16/32kB的片内SRAM,它们也非常适合于通信网关、协议转换器、软件modem、语音识别、低端成像,为这些应用提供大规模的缓冲区和强大的处理功能。多个32位定时器、1个或2个10位8路的ADC、10位DAC、PWM通道、47个GPIO以及多达9个边沿或电平触发的外部中断使它们特别适用于工业控制应用以及医疗系统。
主要特性:
1)16/32位ARM7TDMI-S核,超小LQFP64封装。
2)8/16/32kB的片内静态RAM和32/64/512kB的片内Flash程序存储器。128位宽度接口/加速器可实现高达60MHz工作频率。
3)通过片内boot装载程序实现在系统编程/在应用编程(ISP/IAP)。单扇区或整片擦除时间为400ms。256字节行编程时间为1ms。
4)EmbeddedICE®RT和嵌入式跟踪接口通过片内RealMonitorTM软件对代码进行实时调试和高速跟踪。
5)1个(LPC2131/2132)或2个(LPC2138)8路10位的A/D转换器,共提供16
路模拟输入,每个通道的转换时间低至2.44us。
6)1个10位的D/A转换器,可产生不同的模拟输出。(仅适用LPC2132/2138)
7)2个32位定时器/计数器(带4路捕获和4路比较通道)、PWM单元(6路输出)和看门狗。
8)实时时钟具有独立的电源和时钟,可在节电模式中极大地降低功耗。
9)多个串行接口,包括2个16C550工业标准UART、2个高速I2C接口(400kbit/s)、SPITM和具有缓冲作用和数据长度可变功能的SSP。
10)向量中断控制器。可配置优先级和向量地址。
11)小型的LQFP64封装上包含多达47个通用I/O口(可承受5V电压)。
12)多达9个边沿或电平触发的外部中断管脚。
13)通过片内PLL(100us的设置时间)可实现最大为60MHz的CPU操作频率。
14)片内晶振频率范围:1~30MHz。
15)低功耗模式:空闲和掉电。
16)可通过个别使能/禁止外部功能和外围时钟分频来优化功耗。
17)通过外部中断将处理器从掉电模式中唤醒。
18)单电源,具有上电复位(POR)和掉电检测(BOD)电路。
19)CPU操作电压范围:3.0V~3.6V(3.3V±10﹪),I/O口可承受5V的电压。
第三章 硬件设计
3.1系统电路原理图
图3-1系统原理图
系统功能:
该系统主要实现对电压的测量,经测试端输入的电压,分压采样后送到 LPC2131 程序处理,最后将测量结果在EasyARM显示界面显示,由于ADC本身的输入范围的限制,我们这里输入信号最大值为+3.3V,采样率达到 100Hz,精度高于 0.9%,在实际应用中,可以增加前级信号调理电路使输入信号的范围扩大。
3.2A/D转换器
特性:
1)10位逐次逼近式A/D转换器
2)测量范围0~3.3V
3)10位转换时间≥2.44μs
4)一路或多路输入的Burst转换模式
5)转换触发信号可选择:输入引脚的跳变或定时器的匹配
6)具有掉电模式
A/D转换器的基本时钟由VPB时钟提供,可编程分频器可将时钟调整至44.5MHz(逐步逼近转换的最大时钟),10位精度要求的转换需要11个A/D转换器。
图3-2 A/D转换电路
3.3报警电路
使用GPIO的P0.7控制蜂鸣器鸣叫报警
图3-3蜂鸣器报警电路
LED发光二极管闪烁十次后一直亮(LED1表示通道1,LED2表示通道2)
图3-4LED报警电路
3.5 LPC2131最小系统
最小系统包含时钟电路和复位电路
图3-5最小系统
第四章软件设计
4.1系统功能流程图
根据设计要求,结合硬件原理图与LPC2131的使用手册,为采样频率达到 100Hz,把电压测量结果直观显示出来,软件程序流程图如图4-1
图4-1系统功能流程图
4.2程序
/**************************************************************************
* 文 件 名:main.c
* 功 能:使用ADC模块的通道0、1进行电压的测量,然后将转换结果从串口输出,
* 上位机使用EasyARM软件全仿真的DOS字符窗口观察。
* 说 明:跳线JP8、JP30短接。由W1、W2调节测量电压值。
* 通讯格式:8位数据位,1位停止位,无奇偶校验,波特率为115200。
**************************************************************************/
#include "config.h"
#define LED1 1<<16 // P2.16
#define LED2 1<<17 // P2.17
#define BEEPCON 1<<20
// P0.7引脚控制B1,低电平蜂鸣
#define LEDCON 0x00000000
/**************************************************************************
* 名 称:DelayNS()
* 功 能:长软件延时
* 入口参数:dly 延时参数,值越大,延时越久
* 出口参数:无
***********************************************************************/
void DelayNS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
{
for(i=0; i<5000; i++);
}
}
/**************************************************************************
* 名 称:UART0Init()
* 功 能:初始化串口0。设置为8位数据位,1位停止位,无奇偶校验
* 入口参数:bps 通讯波特率
* 出口参数:无
**************************************************************************/
void UART0Init(uint32 bps)
{ uint16 Fdiv;
PINSEL0 = (PINSEL0 & (~0x0F)) | 0x05; // 不影响其它管脚连接,设置I/O连接到UART0
U0LCR = 0x83; // DLAB = 1,可设置波特率
Fdiv = (Fpclk / 16) / bps; // 设置波特率
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03;
}
/**************************************************************************
* 名 称:UART0SendByte()
* 功 能:向串口发送字节数据,并等待发送完毕。
* 入口参数:data 要发送的数据
* 出口参数:无
**************************************************************************/
void UART0SendByte(uint8 data)
{
U0THR = data; // 发送数据
while( (U0LSR&0x40)==0 ); // 等待数据发送完毕
}
/**************************************************************************
* 名 称:UART0SendStr()
* 功 能:向串口发送一字符串
* 入口参数:srt 要发送的字符串的指针
* 出口参数:无
*************************************************************/
void UART0SendStr(char *str)
{
while(1)
{
if( *str == '\0' ) break;
UART0SendByte(*str++); // 发送数据
}
}
/**************************************************************************
* 名 称:PCDispChar()
* 功 能:向PC机发送显示字符。
* 入口参数:x 显示位置的纵坐标,0-79
* y 显示位置的横坐标,0-24
* chr 显示的字符,不能为0xff
* color 显示的状态包括前景色、背景色、闪耀位。它与dos的字符显示状态一样。
* 即0~3位:前景色,4~6位:背景色,7位:闪耀位。
* 出口参数:无
**************************************************************************/
void PCDispChar(uint8 x, uint8 y, uint8 chr, uint8 color)
{
UART0SendByte(0xff); // 发送起始字节
UART0SendByte(x); // 发送字符显示坐标(x,y)
UART0SendByte(y);
UART0SendByte(chr); // 发送显示字符
UART0SendByte(color);
}
/**************************************************************************
* 名 称:ISendStr()
* 功 能:向PC机发送字串,以便显示。
* 入口参数:x 显示位置的纵坐标,0-79
* y 显示位置的横坐标,0-24
* color 显示的状态包括前景色、背景色、闪耀位。它与dos的字符显示状态一样。
* 即0~3位:前景色,4~6位:背景色,7位:闪耀位。
* str 要发送的字符串,字串以'\0'结束
* 出口参数:无
****************************************************************************/
void ISendStr(uint8 x, uint8 y, uint8 color, char *str)
{
while(1)
{
if(*str=='\0') break; // 若为'\0',则退出
PCDispChar(x++, y, *str++, color); // 发送显示数据
if(x>=80)
{
x = 0;
y++;
}
}
}
/**************************************************************************
* 名 称:main()
* 功 能:进行通道0、1电压ADC转换,并把结果转换成电压值,然后发送到串口。
* 说 明:在CONFIG.H文件中包含stdio.h。
**************************************************************************/
int main(void)
{
uint32 ADC_Data;
char str[20];
UART0Init(115200); // 初始化UART0
PINSEL1 = 0x01400000; // 设置P0.27、P0.28连接到AIN0、AIN1
IO1DIR = BEEPCON; // 设置I/O为输出
IO2DIR = 0x00000000;
IO1SET = BEEPCON;
/* 进行ADC模块设置,其中x<<n表示第n位设置为x(若x超过一位,则向高位顺延) */
ADCR = (1 << 0) | // SEL = 1 ,选择通道0
((Fpclk / 1000000 - 1) << 8) | // CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
(0 << 16) | // BURST = 0 ,软件控制转换操作
(0 << 17) | // CLKS = 0 ,使用11clock转换
(1 << 21) | // PDN = 1 , 正常工作模式(非掉电转换模式)
(0 << 22) | // TEST1:0 = 00 ,正常工作模式(非测试模式)
(1 << 24) | // START = 1 ,直接启动ADC转换
(0 << 27); // EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
DelayNS(10);
ADC_Data = ADDR; // 读取ADC结果,并清除DONE标志位
while(1)
{ ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24); // 设置通道1,并进行第一次转换
while( (ADDR&0x80000000)==0 ); // 等待转换结束
ADCR = ADCR | (1 << 24); // 再次启运转换
while( (ADDR&0x80000000)==0 ); // 等待转换结束
ADC_Data = ADDR; // 读取ADC结果
ADC_Data = (ADC_Data>>6) & 0x3FF; // 提取AD转换值
ADC_Data = ADC_Data * 3300; // 数值转换
ADC_Data = ADC_Data / 1024;
sprintf(str, "%4dmV at VIN1", ADC_Data);
ISendStr(30, 23, 0x30, str);
if( ADC_Data>=3000)
{ uint32 i;
for(i=0;i<10;i++)
{ IO1SET = BEEPCON;
IO2DIR = 0x00010000; // BEEPCON = 1
DelayNS(15);
IO1CLR = BEEPCON; // BEEPCON = 0
IO2DIR = 0x00000000;
DelayNS(15);
}
IO2DIR = 0x00010000;
DelayNS(150);
}
else
{ IO1SET = BEEPCON; // BEEPCON = 0
IO2DIR = 0x00000000;}
ADCR = (ADCR&0x00FFFF00)|0x02|(1 << 24); // 设置通道2,并进行第一次转换
while( (ADDR&0x80000000)==0 ); // 等待转换结束
ADCR = ADCR | (1 << 24); // 再次启运转换
while( (ADDR&0x80000000)==0 ); // 等待转换结束
ADC_Data = ADDR; // 读取ADC结果
ADC_Data = (ADC_Data>>6) & 0x3FF; // 提取AD转换值
ADC_Data = ADC_Data * 3300; // 数值转换
ADC_Data = ADC_Data / 1024;
sprintf(str, "%4dmV at VIN2", ADC_Data);
ISendStr(30, 21, 0x30, str);
if( ADC_Data>=2500)
{ uint32 i;
for(i=0;i<10;i++)
{ IO1SET = BEEPCON;
IO2DIR = 0x00020000; // BEEPCON = 1
DelayNS(15);
IO1CLR = BEEPCON; // BEEPCON = 0
IO2DIR = 0x00000000;
DelayNS(15);
}
IO2DIR = 0x00020000;
DelayNS(150);
}
else
{ IO1SET = BEEPCON; // BEEPCON = 0
IO2DIR = 0x00000000;}
}
return(0);
}
第五章 设计心得
【硬件】王朵
这次的课程设计是基于LPC2131的数字电压表设计,实现的主要功能:以ARM为控制器,采用中断方式,对2路0-5V的模拟电压进行循环采集,采集的数据送LED显示,并存入内存,超过界限时指示灯闪烁。
在做数字电压表的设计时,开始时遇到不少的问题,比如我们想电压是如何采集的,数字电压表到底是什么设计原理呢,毕竟还没有接触过实际设计和开发,所以在考虑问题的时候往往是不全面的,也就是说这次设计还有不少的方面没有考虑周全,也一定存在着这样那样的问题。
经过这一个星期的实习,从开始时充满激情,到最后差点有想放弃的冲动,这之间的复杂心情,点点滴滴无不令我回味无长。特别是在设计程序的过程中,我明白到做一个好程序的不易,做一个好的编程者就更加艰难,突然就很佩服那些编程者。我们组一个两个人,整体上是我们两个人都在做,但个人的侧重点不同,我主要负责查询资料和硬件设计方面,屈豆主要负责软件编程及调试,通过这次课程设计,加强了我们动手、思考和解决问题的能力。在整个设计过程中主要是软件调试,这个我们花了好长时间,在调试过程中稍微有点错误就出现问题,这个真是对我们耐心的大挑战,不过最后还是没达到预期的效果,感觉有点遗憾。
我觉得做课程设计是对课本知识的巩固和加强,平时看课本,有时问题老是弄不懂,做完课程设计后,那些问题就迎刃而解了。
认识来源于实践,实践是认识的动力和最终目的。这次课程设计对我们有很大的帮助,在课程设计过程中,我们真正体会到了理论与实践之间的差距,更重要的是让我们感受到了团队合作的重要性,让我们懂得,我们必须得各尽所长才能解决各种困难。
【软件】屈豆
这次的课程设计是基于LPC2131的数字电压表设计,实现的主要功能:以ARM为控制器,采用中断方式,对2路0-5V的模拟电压进行循环采集,采集的数据送LED显示,并存入内存,超过界限时指示灯闪烁。
当老师在之前给我们选题目时,我就开始在网上、图书馆查找资料,当接触到数字电压表设计这个题目时,我很迷茫,不知从何下手,虽说这学期已经开ARM课了,但是
自认为学的一点都不好。随后我们去网上查找各种相关资料,去图书馆查找文献,但是
都没有找到类似的课题,最后经过我与组员的讨论,勉强有些许思绪,虽说最后我们没能很完善的做出课题,但这个过程是值得高兴地,在模拟硬件电路部分,我们查了很多相关的资料,其中遇到了很多繁琐的问题,但经过同学帮忙都得以解决;在软件方面,我按照书上的资料,逐步学习,逐步推敲,最终写出了部分程序,虽然功能没有完全实现,但是我们都很认真的去动手做了。
事实上,我们遇到的问题远不止这些,但是,无论怎样,我们都没有放弃,有困难就查资料,请教同学,一起解决困难,从中我们学到了很多知识,从原来不太熟悉的LPC2131到最后的每一部分都有所了解,我觉得这就是我们坚持到最后的最大成果,其实在很多事情来临时,我们不仅仅关心的是最后的结果,更重要的是拥有其中的过程。
在整个动手过程中,既加深了我们对ARM的理论认识,又通过LPC2131这个很有意思的载体,实现了对ARM的应用。同时,这次课程设计使我对ARM制作产生了浓厚的兴趣,个人希望在以后的工作学习中,加强这方面的训练,多制作出自己感兴趣的ARM作品。
致谢
通过本次课程设计,使我们对ARM开发有了一定的掌握和理解,巩固了我们在《ARM嵌入式系统基础教程》课程中所学的基本理论知识和实践技能,也使我们对这门课程有了更深入的了解,熟悉了GPIO的使用,了解ARM芯片的内部功能模块,及内核架构,进一步激发了我对所学专业的兴趣,提高了我们的思考和实践能力。
在本次的设计过程和设计说明书的撰写过程中,李宏岩老师和黄梦涛老师给予了我们热心的帮助和大力的支持,给我们提供了诸多的宝贵意见,拓宽了我的思路,在此,我们向两位老师致以崇高的敬意和衷心的感谢!
在我们学习的过程中,班里的许多同学也给我们做了耐心和详细的指导,让我们再一次深深地感受到同学之间的互相学习是多么的重要,在此我对帮助我们的老师和同学表示诚挚答感谢!
参考文献:
[1]ARM嵌入式系统基础教程[M].2版.周立功主编.北京;北京航空航天大学出版社,2008.9
[2]ARM嵌入式系统实验+实训指导书[M].李红岩,杨学存编写.西安安科技大学