第1章 绪论
ARM公司的IP核已经由ARM7,ARM9发展到今天的ARM11版本。ARM11囊括了Thumb-2,CoreSight,TrusZone 等众多业界领先技术,同时由单一的处理器内核向多核发展,为高端的嵌入式应用提供了强大的处理平台。高集成度SOC芯片的采用可以带来一系列好处,诸如减少了外围器件和PCB面积,提高系统抗干扰能力,缩小产品体积,降低功耗等。
ARM 公司是一家IP供应商,其核心业务是IP核以及相关工具的开发和设计。半导体厂商通过购买ARM公司的IP授权来生产自己的微处理器芯片。由此以来,处理器内核来自ARM公司、各芯片厂商结合自身已有的技术优势以及芯片的市场定位等因数使芯片设计最优化,从而产生了一大批高度集成、各据特色的SOC芯片。例如Intel公司的XScale系列集成了LCD控制器、音频编/解码器,定位于智能PDA市场;Atmel公司的AT91系列片内集成了大容量 Flash和RAM、高精度A/D转换器以及大量可编程I/O端口,特别适合于工业控制领域;Philips公司的LPC2000系列片内集成了128位宽的零等待Flash存储器以及I2C, SPI,PWM,UART等传统接口,极高的性价比使它对传统的8/16位MCU提出了严峻的挑战。本次设计仍使用的ARM7系列。
1.2 ARM微处理器
1.2.1 ARM微处理器的特点
ARM微处理器采用RISC指令集、使用大量寄存器、ARM/THUMB指令支持、三/五级流水线具有低功耗、低成本、高性能等特点。
1.2.2 ARM微处理器LPC2131概述及其构造
LPC2131简介
LPC2131的内核是ARM7TDMI-S核,32位微处理器,采用冯·诺依曼结构(数据和指令混合编址)。
ARM7TDMI-S核采用三级流水线,还使用了一个被称为Thumb(16位指令长度)的独特结构化策略,适合那些对存储器有限制或者需要较高代码密度的大批量产品的应用。Thumb代码仅为ARM代码规模的65%,但是性能却是连接到16位存储器系统的相同ARM处理器性能的160%。
较小的封装(LQFP64)和极低的功耗使LPC2131可理想的应用于小型系统中,如通信网关、协议转换器、声音辨别、低端成像、工业控制和医疗系统。
1.2.3.LPC2131特性:
8KB片内SRAM;
32KB片内Flash,128位宽度接口/加速器实现高达60MHz的操作频率;
8路10位A/D转换器;
2个32位定时器(带4路捕获和4路比较通道),PWM单元(6路输出)和看门狗;
2个UART,2个高速IIC接口(400Kb/s),SPI,SSP;
向量中断控制器,可配置优先级和向量地址; 47个(P0.0-P0.23,P0.24-P0.31,P1.16-P1.31)可承受5V电压的通用I/O口;
9个边沿或者电平触发的外部中断引脚;
2个低功耗模式:空闲和掉电; ARM内部结构原理图
单电源供电,含有上电复位(POR)和掉电检测(BOD)电路,CPU操作电压3.0-3.6V。
1.2.4.LPC2131最小系统
在LPC2131中,存储系统为可以选择的,这是由于许多面向嵌入式领域的嵌入式的微控制器的内部设计好了程序与数据的存储器,存储器的系统无需自己来设计,调试和测试的接口也不一定是必需需要的。
最小系统原理图
第3章 硬件电路设计
4 .1控制模块
以ARM7LPC2131开发板为控制核心,无需再添加晶振及复位电路等外围电路,其运算速率非常快,并且ARM7-LPC2131有6路PWM脉冲输出,8路10位的A/D转换和1个D/A转换,2个带4路捕获和4路比较通道的32位定时器,1个2KB的Flash存储器、看门狗,实时时钟等,它不仅可以在系统编程,在内置的串行JTAG接口对存储器进行编程,也可以在应用编程的过程中对存储器进行编程。
晶显示模块12864具有四位或八位并行,两线或三线串行等多种接线方式,内部具有简体的中文字库,液晶显示的分辨率是128×64, 其内部含有8192个16 * 16点汉字和128个16 * 8点ASCII码字符集。通过灵活的接线方式以及利用简单的指令,能够很方便地产生全中文的人机交互界面,可以显示汉字,也可以显示图形。 液晶显示模块12864具有低电压以及低功耗的特点。该液晶模块同其它显示图形的点阵液晶模块相比,具有硬件电路简单,显示程序更简洁等诸多优点,并且该液晶显示模块价格较为便宜。可以采用热敏电阻来实现温度的测量,可满足40摄氏度至90摄氏度测量范围,但热敏电阻精度、重复性、可靠性较差,对于检测到的温度的精确度不能够得到保证。在本装置中,要实现精度为0.1摄氏度温度的车辆,采用热敏电阻不嫩够满足求,故考虑采用数字温度传感器DS18B20。DS18B20 测量温度,输出信号全数字化,便于单片机处理及控制,单总线的数据传输,省去传统的测温方法的很多外围电路,系统的结构可以做得较为紧凑
图3 DS18B20 电路
4.2.12864显示内部
第4章 软件设计
系统的软件设计包括程序的下载和调试,需要用到ADS集成开发环境和EASYJTAG-H仿真使用器。该仿真器是ARM公司开发出的标准的20脚JTAG仿真的简易仿真器,实现了全速,单步和断点等调试功能,采用ADS1.2集成开发的RDI协议,支持在AXD中直接固话程序到片内Flash。 EASYJTAG-H仿真器是符合ARM公司提出的标准20脚JTAG仿真调试接口的简易仿真器。该仿真器采用ADS1.2集成开发环境的RDI协议。实现了单步、全速及断点等调试功能,此外支持在AXD中直接固化程序到片内FLASH。H-JTAG 软件具有如下特点:支持ARM7/ARM9,支持自动检测和手动指定内核; 使用RDI 接口,支持SDT2.51、ADS1.2、REALVIEW 和IAR 集成开发环境;支持2 个硬件断点或数量不限的软件断点; 支持ARM/Thumb 模式; 支持Little Endian & BIG Endian 模式; 支持Semihosting 调试; 支持Wiggler、SDT JTAG 和自定义接口。将计算机并口与EASYJTAG-H仿真器连接,并将仿真器JTAG口接头插入EasyARM2131开发板的J3,再使用USB连接电缆与PC连接给开发板供电。通过H-JTAG Serve和 H-Flasher两个工具对仿真器进行配置就可以用AXD软件进行调试了。硬件调试及结果分析。硬件调试:硬件调试时,应先检查印制板及焊接的质量是否符合要求,有无虚焊点及线路间有无短路、断路。然后用万用表测试或通电检测,检查无误后,可通电检查LCD液晶显示器亮度情况,一般情况下取背光电压为4~5.5V即可得到满意的效果。采用编程器将程序写入单片机,给电路板供电,观察电路工作情况,再进行最终的处理。
4.1软件实现方框图
系统软件采用C语言编程,程序详情请参见附录。
程序的流程图如下:
第5章 心得
李呈斌1106050209
我们组做的课题是多路数据采集,我主要负责硬件的焊接及调试。我们课题的基本功能是电压的采集,拓展功能是将A/D转换器的本身测量范围0~3.3V扩展到10V,外加一个温度测量。虽然实现功能都是基本的拓展功能,但从最初的没有头绪,到查资料,和组员之间互相探讨学习,再到最后展现成品,整个过程都让我学到了很多。
当然,在此次课程设计中,遇到了一些问题,但经过和组员的共同检查,终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。通过此次课程设计使我更加扎实的掌握了有关ARM方面的知识,实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。在以后的工作中,我会更注意自己知识的不足,及时的充足自己各个方面。
鱼轮1106050218
数据采集系统是将采集传感器输出的温度,流量等模拟信号转换成计算机能识别的数字信号,我们组基于两路电压的采集之上扩展了A/D转化器的测量范围,以及温度的采集,本次课程设计我主要负责部分软件的编写,以及原理图的绘制。因为软件不是我的特别强项,刚开始也是无从下手,查资料,请教老师和同学,慢慢的从中学到了很多,在后期的拓展功能,也能稍微的得心应手。两周的时间,学到的东西很多,特别是此次软件的编写到功能的实现,让我明白一定要不懈努力,不能遇到问题就想到要退缩,不能知难而退,那样永远不可能得到自己期待的结果。
通过本次设计,能使自己对所学知识有一个系统的认识和理解,不仅能够熟练掌握绘图软件的基本操作,而且也让我对软件这一块有了更深的学习,使自己的兴趣大大提高,以后会多阅读这方面的资料和书籍来提高自己的能力和经验。
陈姣1106050201
两周的课程设计,我们组的任务算是比较完美的完成,在预期的基本功能上拓展了我们自己的想法:扩大A/D转换器的量程范围,温度的采集。此次的课设中,我们团队从查资料,原理图的绘制,硬件的焊接,软件的编辑,到最后的成品,四个人都付出了自己的一份努力。我从最初对课题的不解,到成品运转,整个流程,学到了很多的东西,当然,在设计的过程中遇到了很多问题,比如,焊接完成,在硬件检测的时候,发现所需的电阻阻值与焊接上的电阻阻值不相符;在加拓展功能时,调试量程的误差解决等等。总而言之,在此次ARM的课程设计中,知识的增长有很多,因为我们学到的东西不够深奥,所以要勤看课本,多查资料,从基础着手,一点一滴的积累,慢慢的应用到不同的领域中。还有,团队的互助,虽然有时候也会意见不统一,但我们的团队很有包容性,大家都很为对方考虑,努力把课题做到大家都满意的程度。
朱新甜1106050203
在这次为期两周课程设计的过程中,我深深的感触到了团队合作的重要性,尤其是在当今的社会工作中,一个人的力量在一个巨大的任务前是那么的渺小,必须靠多人合作才能共同完成。在设计规划过程,我们小组四个人亲密无间的合作,使得本次课程设计能够非常顺利地完成,在课程设计的过程中,每个人都能
按要求很好的完成分配给自己的任务,最后大家一起通过讨论把所有任务串连起来完成总的设计任务。
通过本次课程设计,让我很好的锻炼了理论联系实际,与具体项目、课题相结合开发、设计产品的能力。既让我们懂得了怎样将理论应用于实际,又让我们懂得了在实践中遇到的问题怎样用理论去解决。在设计过程中,总是会遇到这样或那样的问题。有时一个问题可能会需要大家集体去查阅资料,做大量的工作,花大量的时间才能解决。通过不断地发现问题,解决问题,自然而然,我的发现问题和解决问题的能力便在其中建立起来了。这都为以后的工作积累了经验,同时也增强了我们解决问题的能力。非常感谢老师的指导,和同学的帮忙。
第6章 调试及实物照片:
参考文献:
【1】周立功,ARM嵌入式系统基础教程【M】北京航空航天大学出版社,2008.9
【2】周明安,朱光忠,步进电机驱动技术发展及现状【J】机电工程技术,2005
【3】许大中、贺益康,电机控制【M】杭州:浙江大学出版社,2002
【4】周立功、陈明计、陈渝,ARM嵌入式Linux系统构建与驱动开发范例【M】: 北京航空航天大学出版社,2006
致谢
值此论文完成之际,我要代表全组成员衷心的感谢给予我们关心和帮助的所有师长,同学和朋友们。而且,我们要特别感谢此次课程设计的李红岩老师,在我们小组进行电路硬件和软件设计的时候悉心的指导和无微不至的关怀给予了我们很大的帮助,是我们受益匪浅。他渊博的学识和平易近人的风范、严谨的治学态度和以身作则的高贵品质,不断激励我们奋进,在这里我们小组全体成员在这表示诚挚的谢意!
最后,感谢我的母校西安科技大学电气与控制工程学院,希望她能越办越强大,培养出更多的优秀人才!
附程序:
- #include "config.h"
- #include "stdio.h"
- #include "18b20.h"
- #define CON_A (1<<8) ;
- #define CON_B (1<<9) ;
- #define E_CLK (1<<4) ; //clock input 同步时钟输入端
- #define RW_SID (1<<5) ; //data input/output 串行数据输入、输出端
- #define RS (1<<6) ;
- #define BEEP (1<<7) ;
- #define LED1 (1<<18) ;
- const uint32 KEY1 = 1 << 16;
- const uint32 KEY2 = 1 << 17;
- uint8 rcv_buf,rcv_new;
- char kcsj[] ="多路数据采集系统";
- char T[]="温度: 摄式度";
- char tonga[]="通道1:";
- char tongb[]="通道2: ";
- char str1[6],str2[6],tem[3];
- /************************以下是12864液晶显示器的子程序************************/
- void delay(uint32 dly)//延时函数
- {
- uint32 i;
- for ( ; dly>0; dly--)
- for (i=0; i<10; i++);
- }
- void SendByte(uint8 dat) //串行发送一字节数据
- {
- uint8 i;
- IO0SET|=RS;
- for(i=0;i<8;i++)
- {
- IO0CLR|=E_CLK ;
- delay(5);
- if(dat&0x80)
- {
- IO0SET|=RW_SID;delay(5);
- }
- else IO0CLR|=RW_SID;
- {
- IO0SET|=E_CLK;delay(5);
- }
- dat=dat<<1;
- }
- IO0CLR|=RS;
- }
- void SendCmd(uint8 dat) //写控制命令
- {
- SendByte(0xF8); //11111,00,0 RW=0,RS=0 同步标志
- SendByte(dat&0xF0); //高四位
- SendByte((dat&0x0F)<<4); //低四位
- }
- void SendDat(uint8 dat) //写显示数据或单字节字符
- {
- SendByte(0xFA); //11111,01,0 RW=0,RS=1
- SendByte(dat&0xF0); //高四位
- SendByte((dat&0x0F)<<4); //低四位
- }
- void display(uint8 x_add, char * word) //液晶显示函数
- {
- SendCmd(x_add); //1xxx,xxxx设定DDRAM7位地址xxx,xxxx到地址计数器AC
- while(*word!='')
- {
- SendDat(*(word++));
- }
- }
- void init_lcd(void) //初始化 12864_LCD
- {
- delay(100);
- SendCmd(0x30); //功能设置,一次送8位数据,基本指令集
- SendCmd(0x0C); //0000,1100 整体显示,游标off,游标位置off
- SendCmd(0x01); //0000,0001 清DDRAM
- SendCmd(0x02); //0000,0010 DDRAM地址归位
- }
- /****************以下是串口程序***************************************/
- void DelayNS (uint32 dly)
- {
- uint32 i;
- for ( ; dly>0; dly--)
- for (i=0; i<5000; i++);
- }
- /* 定义串口模式设置数据结构 */
- typedef struct UartMode
- {
- uint8 datab; // 字长度,5/6/7/8可选
- uint8 stopb; // 停止位,1/2可选
- uint8 parity; // 奇偶校验位,0-无校验,1-奇校验,2-偶校验
- }UARTMODE;
- void UART0_SendByte (uint8 dat)
- {
- U0THR = dat; // 要发送的数据
- }
- void UART0_SendBuf (char *ptr)
- {
- while(*ptr != '')
- {
- UART0_SendByte(*ptr++);
- }
- while ((U0LSR & 0x20) == 0); // 等待数据发送完毕
- }
- int8 UART0_Init (uint32 baud, UARTMODE set)
- {
- uint32 bak;
- /* 参数过滤 */
- if ((baud ==0 ) || (baud > 115200)) return (0);
- if ((set.datab <5) || (set.datab > 8)) return (0);
- if ((set.stopb == 0) || (set.stopb > 2)) return (0);
- if (set.parity > 4) return (0);
- /* 设置串口波特率 */
- U0LCR = 0x80; // DLAB = 1
- bak = (Fpclk >> 4) / baud;
- U0DLM = bak >> 8;
- U0DLL = bak & 0xFF;
- /* 设置串口模式 */
- bak = set.datab - 5; // 设置字长
- if (set.stopb == 2) bak |= 0x04; // 判断是否为2位停止位
- if (set.parity != 0)
- {
- set.parity = set.parity - 1;
- bak |= 0x08;
- }
- bak |= set.parity << 4; // 设置奇偶校验
- U0LCR = bak;
- U0FCR = 0x01; // 使能FIFO,并设置触发点为8字节
- U0IER = 0x01; // 允许RBR中断,即接收中断
- return (1);
- }
- void __irq IRQ_UART0 (void)
- {
- if ((U0IIR & 0x0F) == 0x04) // 设置接收到新的数据标志
- rcv_new = 1;
- rcv_buf = U0RBR; // 读取FIFO的数据,并清除中断
- if(rcv_buf=='1')
- UART0_SendBuf(str1);
- else if(rcv_buf=='2')
- UART0_SendBuf(str2);
- else if(rcv_buf=='3')
- UART0_SendBuf(tem);
- VICVectAddr = 0x00; // 中断处理结束
- }
- /****************以下是蜂鸣器程序***************************************/
- void beep(void)
- {
- uint8 i;
- for(i=0;i<3;i++)
- {
- DelayNS(100);
- IO0CLR|=BEEP;
- DelayNS(100);
- IO0SET|=BEEP;
- }
- }
- /****************以下是AD处理程序***************************************/
- uint32 ADC_vol(uint8 channel)
- {
- int flag;
- uint32 ADC_CE[20],ADC_Flag=0;
- for(flag=0;flag<20;flag++)
- {
- switch(channel)
- {
- case 1:AD0CR = (AD0CR&0x00FFFF00)|0x01|(1 << 24);break; // 设置通道1,并进行第一次转换
- case 2:AD0CR = (AD0CR&0x00FFFF00)|0x02|(1 << 24);break; // 设置通道2,并进行第一次转换
- }
- while ((AD0DR & 0x80000000) == 0); // 等待转换结束
- AD0CR |= 1 << 24; // 再次启动转换
- while ((AD0DR & 0x80000000) == 0); // 等待转换结束
- ADC_CE[flag] = AD0DR; // 读取ADC结果
- ADC_CE[flag] = (ADC_CE[flag] >> 6) & 0x3ff;
- ADC_CE[flag] = ADC_CE[flag] * 3280;
- ADC_CE[flag]=ADC_CE[flag]/1024;
- ADC_Flag+=ADC_CE[flag];
- }
- ADC_Flag=ADC_Flag/20;
- return ADC_Flag;
- }
- void deal(char *p,uint32 ADC_Data)
- {
- if(ADC_Data<10000)
- {
- p[0]=ADC_Data/1000+0x30;
- p[1]='.';
- p[2]=ADC_Data%1000/100+0x30;
- p[3]=ADC_Data%1000%100/10+0x30;
- p[4]='V';
- p[5]='';
- }
- else
- {
- p[0]=ADC_Data/10000+0x30;
- p[1]=ADC_Data%10000/1000+0x30;
- p[2]='.';
- p[3]=ADC_Data%10000%1000/100+0x30;
- p[4]=ADC_Data%10000%1000%100/10+0x30;
- p[5]='V';
- }
- }
- /*****************************以下为主程序*****************************************************************/
- int main (void)
- {
- UARTMODE set;
- int start=0;
- int temp;
- uint32 ADC_Data;
- set.datab = 8;
- set.stopb = 1;
- set.parity = 0;
- PINSEL0 = 0xFFFF00005; // 设置I/O连接
- PINSEL1 = 0x15400000; // 功能选择
- PINSEL2 = PINSEL2 & (~0x08);
- IO0SET = 0XFFFFFFFF;
- IO0DIR |= 0X00000FFF;
- IO1SET = 0XFFFF0000;
- IO1DIR = 0XFFFF0000; // 设置LED1控制口为输出
- UART0_Init(115200, set); // 串口初始化
- init_lcd(); //液晶初始化
- display(0x80,kcsj);
- display(0x90,tonga);
- display(0x88,tongb);
- display(0x98,T);
- IRQEnable(); // 使能IRQ中断
- /*使能UART0中断*/
- VICIntSelect = 0x00000000; // 设置所有的通道为IRQ中断
- VICVectCntl0 = 0x20 | 0x06; // UART0分配到IRQ slot0,即最高优先级
- VICVectAddr0 = (uint32)IRQ_UART0; // 设置UART0向量地址
- VICIntEnable = 1 << 0x06; // 使能UART0中断
- AD0CR = (1 << 1) | // SEL=8,选择通道3
- ((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); // 直接启动ADC转换时,此位无效
- DelayNS(10);
- ADC_Data = AD0DR; // 读取ADC结果,并清除DONE标志位
- while (1)
- {
- temp=Do1Convert1();
- tem[0]=temp/100000+0x30;
- tem[1]=temp%100000/10000+0x30;
- tem[2]='';
- display(0X9b,tem);
- if ( (IO0PIN & KEY1) == 0)
- {
- DelayNS(10);
- if((IO0PIN & KEY1) ==0)
- {
- while((IO0PIN & KEY1) ==0);
- start=1;
- }
- }
- if((IO0PIN & KEY2) == 0)
- {
- DelayNS(10);
- if((IO0PIN & KEY2)==0)
- {
- while((IO0PIN & KEY2)==0);
- start=0;
- }
- }
- if(start==1)
- {
- ADC_Data=ADC_vol(1); //通道1
- if(ADC_Data>3200)
- {
- beep();
- IO1SET|=LED1;
- }
- else IO1CLR|=LED1;
- deal(str1,ADC_Data);
- display(0x93,str1);
- ADC_Data=ADC_vol(2); //通道2
- if(ADC_Data>3015)
- {
- beep();
- IO1SET|=LED1;
- ADC_Data=ADC_Data*10/3;
- }
- else if(2700
- …………限于本文篇幅 余下代码请从电子发烧友下载附件…………
完整设计报告下载(word格式 可编辑):
基于ARM2331的多路双通道数据采集报告.doc
|