《于基arm7的电压检测系统设计课程设计--本科毕业设计.doc》由会员分享,可在线阅读,更多相关《于基arm7的电压检测系统设计课程设计--本科毕业设计.doc(23页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、嵌入式系统设计导论课程设计题目: 基于ARM7的电压检测系统设计 物联网工程 学院 班 级 学 号 姓 名 摘要 近年来随着科学技术的发展,人们趋向于电压检测方式的多样化,智能化,它对软硬件的体积大小、成本、功耗和可靠性都提出了严格的要求。传统的模拟形式的电压检测方式逐步被数字化的处理芯片所替代。本设计采用了飞利浦的32位ARM微处理器LPC2138作为核心处理器。利用A/D转换、定时器、按键等模块,实现电压(可用滑动电阻)的检测、显示、阈值设置,以及超过阈值能声光报警。该检测装置工作时,电压信号经电压检测模块采样得到模拟信号,该信号送到AD转换模块处理成数字信号。CPU接收到该信号送给LCD
2、模块显示输出,同时通过UART通信送给显示终端实时显示数据变化情况。与此同时,还可通过按键设置报警门值电压。当被测信号超出门值电压时,会发出声光报警信号。实现了电压数据的自动采集、传输、处理与显示等功能,解决了传统的数据采集系统由于存在响应慢、精度低、可靠性差、效率低、操作繁琐等弊端。 关键字:ARM微处理器、电压检测、AD转换目录:一、 引言-3二、 设计目的-3三、 设计要求-3四、 系统总方案-3五、 硬件设计-4 1、电压检测模块设计-4 2、键盘设计-43、 显示模块设计-54、A/D转换模块设计-75、串行口通信模块设计-76、声光报警模块设计-9六、 软件流程图-10七、 程序代
3、码设计-11八、 设计结果演示-21九、 设计体会-22十、 附录-22一、引言 近年来随着科学技术的发展,人们趋向于电压检测方式的多样化,智能化,它对软硬件的体积大小、成本、功耗和可靠性都提出了严格的要求。所以市场上涌现出多种多样的智能电压传感器。电压监测系统在工业生产和科学研究等各个行业开辟了更为广阔的发展空间。也为嵌入式系统的进一步发展奠定良好的基础。电压监测系统不论在哪个应用领域中,数据采集与处理越及时,工作效率就越高,取得的经济效益也越高而且比较价格低,在工农业中得到了广泛的应用。 本文设计的报警系统对电路电压进行实时的采样 ,一旦电压高于设定的正常阈值,系统就会触发报警动作,提醒人
4、们做出相应措施。 本设计采用了飞利浦的32位ARM微处理器LPC2138作为核心处理器。实现了电压数据的自动采集、传输、处理与显示等功能,解决了传统的数据采集系统由于存在响应慢、精度低、可靠性差、效率低、操作繁琐等弊端。二、设计目的 1. 通过本课程设计,熟悉嵌入式系统开发方法和流程。 2. 能结合课堂所学自主设计实现一个简单的监测报警系统。 3. 进一步学会应用定时器、A/D、显示等模块功能。三、设计要求 1. 要求能利用学过的A/D转换、定时器、按键等模块,实现电压(可用滑动电阻)的检测、显示、阈值设置,以及超过阈值能声光报警。 2. 扩展功能:将电压数据通过串行通信(UART)发送到PC
5、上位机显示。四、系统总体方案 本系统设计框图如下图1:液晶显示 声光报警图1:系统总框图电压信号经电压检测模块采样得到模拟信号,该信号送到AD转换模块处理成数字信号。CPU接收到该信号送给LCD模块显示输出,同时通过UART通信送给显示终端实时显示数据变化情况。与此同时,还可通过按键设置报警门值电压。当被测信号超出门值电压时,会发出声光报警信号。五、硬件设计1、电压检测模块设计通过滑动变阻器的滑动,改变采样电阻所分电压值,此值可以通过采样引脚实时传送给CPU,这样便可通过AD转换模块将采得的电压值转换成数字信号,经处理后送显示输出模块。本系统采用1K的电阻作为采样电阻,以最高采样电压为3.3v
6、为例,实际应用中可根据情况更改其他阻值。其结构设计如下图2:图2:电压检测模块2、键盘设计本系统设置两个机械按键,一个是控制门值电压的增加,另一个控制门值电压的减少。每按下一次,门值电压值加0.1v或减0.1v。这样可以控制检测电压的阀值得大小,其设计电路图如下3:图3:按键设计3、显示模块设计本模块采用液晶显示屏,具有显示质量高,数字式接口,体积小、重量轻,功耗低等特点。 因1602液晶屏并未做系统学习,现对采用的1602字符型LCD做如下简介:字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。下面以长沙太阳人电子有
7、限公司的1602字符型液晶显示器为例,介绍其用法1602LCD的基本参数及引脚功能1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图5所示:图5 1602LCD尺寸图 引脚功能说明 1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所示:编号符号引脚说明编号符号引脚说明1VSS电源地9D2数据2VDD电源正极10D3数据3VL液晶显示偏压11D4数据4RS数据/命令选择12D5数据5R/W读/写选择13D6数据6E使能信号14D7数据7D0数据15BLA背光源正极8D1
8、数据16BLK背光源负极表1:引脚功能说明 仿真图如下图5:图5:LCD显示模块4、A/D转换模块设计 在设计时应考虑A/D转换模块的如下特性: 1. 本系统芯片是10 位逐次逼近式模数转换器 2. 4 个(LPC2114/2124)或8 个(LPC2210/2212/2214)引脚复用为A/D 输入脚,本系统设计只采用一路A/D采样通道。 3. 测量范围:03.3V 4. 10 位转换时间=2.44us A/D 转换器的基本时钟由VPB 时钟提供。可编程分频器可将时钟调整至逐步逼近转换所需的4.5MHz(最大)。
9、10 位精度要求的转换需要11 个A/D 转转换时钟。ADC 转换时钟分频值计算:5、串行口通信模块设计 LPC2114/2124/2210/2212/2214 的两个UART,均具有16 字节的收发FIFO,寄存器位置符合16C550 工业标准,内置波特率发生器,两个串口具有基本相同的寄存器,其中UART1带有完全的调制解调器控制握手接口。在使用UART 与上位机PC 通讯时,需要一个RS232电平转换电路,在本系统中直接采用虚拟终端。UART0 的基本寄存器功能框图如下图6:图6 :UART0 的基本寄存器功能框图 其中,寄存器U0RBR 与U0THR 是同一地址,但物理上是分开的,读操作
10、时为U0RBR,而写操作时为U0THR;寄存器U0DLL 与U0RBR/U0THR、U0DLM 与U0TER 具有同样的地址,如果要访问U0DLM、U0DLL,除数访问位DLAB 必须为1,若要访问U0RBR/U0THR、U0IER,则除数访问位DLAB 必须为0。图5.34 中,U0DLM 和U0DLL 寄存器是波特率发生器的除数锁存寄存器,用于设置合适的串口波特率;U0RBR 为数据接以缓冲,用于读取接收到的数据,若FIFO 使能,串口接收到的数据会压入FIFO 缓冲;U0THR 为发送保存,向此寄存器写入数据时,将会引起串口数据发送,若FIFO 使能,数据会压入FIFO 缓冲。波特率的除
11、数计算如下: 其中,baud 为所需要的波特率。 在PROTEUS仿真中采用如下虚拟终端: 在仿真过程中可得到如下显示现象:图7:虚拟终端6、声光报警模块设计 声光报警模块可以在被测信号超过规定值时,发出蜂鸣以示警告,同时LED灯发出视觉信号。具体操作时,可使用按键设置报警门值电压,当被测信号超出门值电压时,会发出声光报警信号,提醒操作者采取措施。其设计图如下图8:图8:声光报警模块设计 图9:报警效果图六、软件流程图 开始初始化门值设置电压检测小于门值大于门值比较 不报警声光报警 显示七、程序代码设计1、主程序设计:#include #include NXP/iolpc2138.h#incl
12、ude cry1602.c#include cry1602.h#include uart.h#define uint unsigned int#define uchar unsigned charvoid adcini();void Time0init(void);uint v_gate=120,v_now,v_nows; void main() PINSEL0 = 0; PINSEL0 = 0x00000005; / 设置I/O连接到UART0 PINSEL1=0x00000000; PINSEL2=0x00000000; IO1DIR=IO1DIR|0xffffffff; IO0DIR &
13、= (0x0000380016); IO0DIR |= 1256) v_gate=256; show_num1(v_gate); if(IO0PIN&0x00002000)=0) Delay5ms(); if(IO0PIN&0x00002000)=0) while(IO0PIN&0x00002000)=0); if(v_gate10) v_gate=10; v_gate-=10; show_num1(v_gate); AD0CR = AD0CR |(18; v_nows=v_now*330/255; show_num(v_nows); if(T0IR & 0X01)=0x01) T0IR=1;
14、 send_num(v_nows); if(v_nowsv_gate) IO0SET |= 116; else IO0CLR |= 116; void adcini() PINSEL1=0x00400000; AD0CR=(10) |(118) |(016)|(017)|(121)|(022) |(124)|(027); Delay5ms(); v_now=AD0DR;void Time0init(void) T0TC = 0; T0PR = 99; T0MCR = 0X03; T0MR0 = 30000; T0TCR = 0X03; T0TCR = 0X01; VICIntSelect=0;
15、 VICVectCntl0 = 0x24; VICIntEnable = 0X00000010;2、液晶显示部分:#include NXP/iolpc2138.h#include cry1602.htypedef unsigned char uchar;typedef unsigned int uint;/*宏定义*/#define Busy 0x8016#define CLR_RS IO1CLR|=0x010016; /RS = P3.0#define SET_RS IO1SET|=0x010016;#define CLR_RW IO1CLR|=0x020016;/RW = P3.1#def
16、ine SET_RW IO1SET|=0x020016;#define CLR_EN IO1CLR|=0x040016;/EN = P3.2#define SET_EN IO1SET|=0x040016;/*函数名称:DispStr功 能:让液晶从某个位置起连续显示一个字符串参 数:x-位置的列坐标 y-位置的行坐标 ptr-指向字符串存放位置的指针返回值 :无*/void DispStr(uchar x,uchar y,uchar *ptr) uchar *vol; uchar i,n = 0; vol = ptr; while(*ptr+ != 0) n+; /计算字符串有效字符的个数 f
17、or (i=0;in;i+) Disp1Char(x+,y,voli); if (x = 0x0f) x = 0; y = 1; /*函数名称:DispNchar功 能:让液晶从某个位置起连续显示N个字符参 数:x-位置的列坐标 y-位置的行坐标 n-字符个数 ptr-指向字符存放位置的指针返回值 :无*/void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) uchar i; for (i=0;in;i+) Disp1Char(x+,y,ptri); if (x = 0x0f) x = 0; y = 1; /*函数名称:LocateXY功 能:
18、向液晶输入显示字符位置的坐标信息参 数:x-位置的列坐标 y-位置的行坐标返回值 :无*/void LocateXY(uchar x,uchar y) uchar vol; vol = x&0x0f; y &= 0x01; if(y) vol |= 0x40; /如果在第2行 vol |= 0x80; LcdWriteCommand(vol,1);/*函数名称:Disp1Char功 能:在某个位置显示一个字符参 数:x-位置的列坐标 y-位置的行坐标 data-显示的字符数据返回值 :无*/void Disp1Char(uchar x,uchar y,uchar data) LocateXY(
19、 x, y ); LcdWriteData( data );/*函数名称:LcdReset功 能:对1602液晶模块进行复位操作参 数:无返回值 :无*/void LcdReset(void) IO1DIR |= 0X7FF; / CtrlDir |= 0x07; /控制线端口设为输出状态 / DataDir = 0xFF; /数据端口设为输出状态 LcdWriteCommand(0x38, 0); /规定的复位操作 Delay5ms(); LcdWriteCommand(0x38, 0); Delay5ms(); LcdWriteCommand(0x38, 0); Delay5ms(); L
20、cdWriteCommand(0x38, 1);/显示模式设置 LcdWriteCommand(0x08, 1);/显示关闭 LcdWriteCommand(0x01, 1); /显示清屏 LcdWriteCommand(0x06, 1);/写字符时整体不移动 LcdWriteCommand(0x0c, 1);/显示开,不开游标,不闪烁/*函数名称:LcdWriteCommand功 能:向液晶模块写入命令参 数:cmd-命令, chk-是否判忙的标志,1:判忙,0:不判返回值 :无*/void LcdWriteCommand(uchar cmd1,uchar chk) if (chk) Wai
21、tForEnable(); / 检测忙信号? uint cmd; cmd=cmd116; CLR_RS; CLR_RW; asm (NOP); IO1SET |= cmd; IO1CLR |=(cmd)&(0xff16); /DataPort = cmd; /将命令字写入数据端口 asm (NOP); SET_EN; /产生使能脉冲信号 asm (NOP); asm (NOP); CLR_EN;/*函数名称:LcdWriteData功 能:向液晶显示的当前地址写入显示数据参 数:data-显示字符数据返回值 :无*/void LcdWriteData( uchar data1 ) WaitFo
22、rEnable(); /等待液晶不忙 uint data; data=data116; SET_RS; CLR_RW; asm (NOP); IO1SET |= data; IO1CLR |=(data)&(0xff16); /DataPort = data; /将显示数据写入数据端口 asm (NOP); SET_EN; /产生使能脉冲信号 asm (NOP); asm (NOP); CLR_EN;/*函数名称:WaitForEnable功 能:等待1602液晶完成内部操作参 数:无返回值 :无*/void WaitForEnable(void) IO1DIR &= (0x000000FF1
23、6); /将P4口切换为输入状态 CLR_RS; SET_RW; asm (NOP); SET_EN; asm (NOP); asm (NOP); asm (NOP); asm (NOP); while(IO1PIN & Busy & (0xff16)!=0); /检测忙标志 CLR_EN; IO1DIR |= 0xFF16; /将P4口切换为输出状态 /*函数名称:Delay5ms功 能:延时约5ms参 数:无返回值 :无*/void Delay5ms(void) uint i=4000; while (i != 0) i-; void show_num(int x) Disp1Char(0
24、,1,0x30+x/100); Disp1Char(1,1,46); Disp1Char(2,1,0x30+x%100/10); Disp1Char(3,1,0x30+x%10); Disp1Char(4,1,v);void show_num1(int x) Disp1Char(10,1,0x30+x/100); Disp1Char(11,1,46); Disp1Char(12,1,0x30+x%100/10); Disp1Char(13,1,0x30+x%10); Disp1Char(14,1,v);3、UART部分程序:#include NXP/iolpc2138.h#include ua
25、rt.htypedef 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位
26、长度) */typedef double fp64; /* 双精度浮点数(64位长度) */#define Fosc 11059200 /晶振频率,10MHz25MHz,应当与实际一至#define Fcclk (Fosc * 1) /系统频率,必须为Fosc的整数倍(132),且0; dly-) for(i=0; i5000; i+);#define UART_BPS9600/* 定义通讯波特率 */* 名称:UART0_Ini()* 功能:初始化串口0。设置为8位数据位,1位停止位,无奇偶校验,波特率为115200* 入口参数:无* 出口参数:无*/void UART0_Ini(void)
27、 uint16 Fdiv; U0LCR = 0x83; / DLAB = 1,可设置波特率 Fdiv = (Fpclk / 16) / UART_BPS; / 设置波特率 U0DLM = Fdiv / 256; U0DLL = Fdiv % 256; U0LCR = 0x03;/* 名称:UART0_SendByte()* 功能:向串口发送字节数据,并等待发送完毕。* 入口参数:data要发送的数据* 出口参数:无*/void UART0_SendByte(uint8 data) U0THR = data; / 发送数据 while( (U0LSR&0x40)=0 ); / 等待数据发送完毕/
28、* 名称:UART0_SendStr()* 功能:向串口发送一字符串* 入口参数:srt要发送的字符串的指针* 出口参数:无*/void UART0_SendStr(uint8 const *str) while(1) if( *str = 0 ) break; UART0_SendByte(*str+); / 发送数据 void send_num(int x) UART0_SendByte(0x30+x/100); UART0_SendByte(.); UART0_SendByte(0x30+x%100/10); UART0_SendByte(0x30+x%10); UART0_SendBy
29、te(0x0d); UART0_SendByte(0x0a); 八、设计结果演示被测信号尚未超过门值电压时,效果图如下图10:图10:信号尚未超过门值电压时被测信号超过门值电压时,效果图如下图11:图11:被测信号超过门值电压时串行通信效果图12:图12:实时数据显示九、设计体会在这过程中我们都收获颇丰,从这学期学习ARM嵌入式系统这门课程开始,到课程设计结束,我们将以往书本上的知识成功应用到实践中去了,并且我们也对keil、proteus、ADS等软件进一步熟悉,掌握得更加牢固,对LPC2000系列ARM7的芯片有所了解,并可以初步的去运用它做一些小的程序编写,在编程的过程中,可以说是比较曲折,稍有不慎,程序调试结果就会出现偏差,因此花了比较长的时间。这次的课程设计让我把ARM的理论知识用在实践中,实现了理论和实践相结合,从中更懂得理论的是实践的基础,实践有能检验理论的正确性,对我以后参加工作或者继续学习将会产生巨大的帮助和影响。同时也发现个人能力还不足,还需更加努力地学习,特别是在编程方面还需要提高和进步,希望自己能再接再厉,不断提高个人能力。十、附录 系统总图如图13:图13:系统总图
限制150内