




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、题目: 嵌入式系统课程作业 学 号: 姓 名: 专 业: 课程名称:嵌入式系统原理与应用课程老师: 二零一一年十二月基于lpc2214的简易计算器设计一 设计任务及要求1.设计任务:利用lpc2214来控制液晶显示器和矩阵式键盘,实现了简易的计算器功能。2.设计要求:(1) 电路包括46键盘,能够通过按键编辑数据。(2) 显示部件使用lcd,显示内容不少于4个字符。(3) 能够完成4位以上十进制整数的加、减、乘、除功能。(4) 能完成小数的加、减、乘、除功能。(5) 能够连续进行运算。(6) 完整计算式选择。二 引言本设计利用lpc2214来控制液晶显示器和矩阵式键盘,实现了简易的计算器功能。
2、通过键盘输入需要计算的计算式子,该式子会显示在液晶的第一行,当键入等于号后,计算结果会显示在液晶的第二行。本设计中液晶选用1602字符型液晶显示器,键盘采用4*6矩阵式键盘。lpc2200系列mcu基于一个支持实时仿真和嵌入式跟踪的16/32位arm7tdmi-s cpu,处理器时钟高达60m/75mhz,片内集成8kb、16kb、32kb、64kb、128kb、256kb和512kb的高速flash存储器,128位宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行。此外,片内集成大量外设:外部存储器控制器(emc)、uart接口、can-bus接口、spi接口、ssp接口、
3、i2c接口、adc、dac、usb 2.0接口、通用定时器、外部中断、pwm、实时时钟、lcd驱动器等等。通过外部存储器接口可以扩展64mb的异步静态存储器设备。近几年,随着大规模集成电路的发展,各种便携式嵌入式设备,具有十分广阔的市场前景。在嵌入式系统中,数据和命令通过网络接口或串行口经过arm程序处理后,或显示在lcd上,或传输到远端pc上。本文通过周立功的lpc2214芯片完成的简易计算器,正式对嵌入式应用的学习和探索。三 硬件设计1.芯片介绍lpc2214是一款基于16/32位arm7tdmi-s,并支持实时仿真和跟踪的cpu,并带有128/256 k字节(kb)嵌入的高速flash存
4、储器。128位 宽度的存储器接口和独特的加速结构使32位代码能够在最大时钟速率下运行。对代码规模有严格控制的应用可使用16位thumb模式将代码 规模降低超过30%,而性能的损失却很小。 lpc2214采用144脚封装、极低的功耗、多个32位定时器、8路10位adc、pwm输出以及多达9个的外部中断,这款微控制器特别适合工业控制、医疗系统、收款机控制等应用领域。其可用gpio范围为76脚(外部存储区)到112脚(单片).由于内置了宽范围的串行通信接口,它们也非常适合于通信网关、协议转换器、嵌入式软件调制解调器以及其它各种类型的应用。管脚图: 2. 完整电路仿真图如下:2.1键盘设计键盘的设计可
5、以有多种方案,相比之下,矩阵式键盘所需要的硬件资源少,控制灵活,操作简单。因此,本设计中采用矩阵式键盘来控制。键盘工作原理:特别说明:io0口悬空时为低电平,故用高电平扫描。(1)判断键盘中有无键按下 将全部行线po0-po3置高电平,然后检测列的状态。只要有一列的电平为高,则表示键盘中有键被按下,而且闭合的键位于高电平线与4根行线相交叉的4个按键之中。若所有列线均为低电平,则键盘中无键按下。 (2)判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为高电平,即在置某根行线为高电平时,其它线为低电平。在确定某根行线位置为高电平后,再逐行检测各列线的电平
6、状态。若某列为高,则该列线与置为高电平的行线交叉处的按键就是闭合的按键。 2.2显示电路设计 选择理由:1602液晶模块内部的字符发生存储器(cgrom)已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“a”的代码是01000001b(41h),显示时模块把地址41h中的点阵字符图形显示出来,我们就能看到字母“a”。因为1602识别的是ascii码,试验可以用ascii码直接赋值,在单片机编程中还可以用字符型常量或变量赋值,如a。总体来说,操作简单,价格便宜。四 软件设计4.1设计中的键盘、
7、显示等驱动函数:*键盘扫描程序 :uint8 keyscan(void)*lcd初始化函数:lcd_init()*检查总线是否忙:void chkbusy() *写命令函数:void lcd_writecontrol (uint8 dat) *写数据函数:void wrdat(uint8 dat)*显示文本函数:distext()(驱动函数见附录)4.2整体设计流程图如下初始化时钟显示键盘扫描当前键为数字lastkey=数字date_temp清零键值存入date_temp将键值存入date_tempcbm、hl、e、d=+清除前一位参考程序见附录。五 总结与体会:通过本次设计,我对arm的c语
8、言编程方法有了很深刻的理解。通过自己亲自编程实践,我学会了控制1602字符型液晶及矩阵式键盘的方法。这次设计是对我们在课堂上所学知识的一次检验,虽然在理论课上学习了很多关于单片机的知识,但都没有经过具体的实践,很多东西都不能得到验证。这次设计使我体会到了实践的乐趣(虽然只是仿真)。由于是夸专业生,在这次设计碰到了不少困难;但都通过查阅相关资料,请教老师和同学,以及自己的努力把问题解决掉了。在这次的设计中,让我们发自内心的明白一些道理,我将好好地记录下这次设计的点点滴滴,我想,这不单是我的经历,更是我的一笔财富。千里之行,始于足下。这次学习,让我对arm有了大概的了解,可以说,坐而言不如立而行,
9、对于这些编程设计还是应该自己动手实际操作才会有深刻理解。六 参考文献:1. arm嵌入式系统基础教程周立功2. c语言程序设计3. mcs-51单片机应用系统设计4. 网上有关计算器方面的程序附录:结果仿真:四位以上带小数的加减乘除, 完整算式输出,右上角显示时钟。程序/* file: main.c* 功能: 计算器基本程序*/#include "config.h"#include "stdlib.h"#include "string.h"/memset hanshu#include "math.h"#define
10、 rs (1<<13)#define rw (1<<14)#define en (1<<15)#define busy (1<<23)uint8 txt0="hello! "uint8 time2=12,34; / 时、分、秒计数void timeshow(void);void timer0_init(void);void _irq timerint(void);/* 名称:函数及变量声明* 功能:显示文本*/void port_init(void) ;void cov(long int b,uint8 *p);void lc
11、d_cursor (char row, char column);void showint(uint8 addr,uint16 num);void deal_date(void);void deal_ope(void); double calculate(void);double calculate1(void);uint8 keyscan(void); uint8 keycode124= 'c','7','8','9','*','/', 'h','4','5
12、','6','-','l', 'm','1','2','3','+','e', 'b','0','.','=','+','d' ; /*ascii码*/long int re_temp1=0,re_temp2=0; uint8 bcd7=0; uint8 show7=0; char keypressed; char last_keypres='
13、;=' double date5=0,0; double *date_pt=&date1; char operater5='n' char *oper_pt=operater;uint8 place=1; char date_temp17; char *temp_pt=date_temp;/* 名称delayns* 功能延时函数*/ void delayns(uint32 dly) uint32 i; for(;dly>0;dly-) for(i=0;i<50000;i+);/* 名称:void port_init(void)* 功能:端口初始化*/
14、void port_init(void) pinsel0=0x00000000; pinsel1=0x00000000; io0dir=0x00fff00f;io0clr=0x0000000f; /* 名称:cov(long int b,unsigned char *p)* 功能:数据拆分*/void cov(long int b,unsigned char *p)unsigned char j=8;while(-j) pj=b%10;b=b/10; pj=b;/* 名称:chkbusy()* 功能:检查总线是否忙*/void chkbusy()io0dir=0xf000;/700while(
15、1)io0clr=rs;io0set=rw;io0set=en;if(!(io0pin & busy)break;io0clr=en;io0dir=0xfff000;/* 名称:wrop()* 功能:写命令函数*/void lcd_writecontrol (uint8 dat) chkbusy();io0clr=rs;/全部清零io0clr=rw;io0clr=0xff0000;/先清零io0set=dat<<16;/再送数io0set=en;io0clr=en;/* 名称cd_cursor ()* 功能:光标定位*/void lcd_cursor (char row,
16、char column)switch (row) case 1: lcd_writecontrol (0x80 + column - 1); break;case 2: lcd_writecontrol (0xc0 + column - 1); break;case 3: lcd_writecontrol (0x94 + column - 1); break;case 4: lcd_writecontrol (0xd4 + column - 1); break;default: break;/* 名称:wrdat()* 功能:写数据函数*/void wrdat(uint8 dat)chkbus
17、y();io0set=rs;io0clr=rw;io0clr=0xff0000;/先清零io0set=dat<<16;/再送数io0set=en;io0clr=en;/* 名称:lcd_init()* 功能:lcd初始化函数*/void lcd_init(void) lcd_writecontrol(0x38);lcd_writecontrol(0x06); /光标加1lcd_writecontrol(0x0c); /开显示/* 名称:distext()* 功能:显示文本函数*/void distext(uint8 addr,uint8 *p)lcd_writecontrol(ad
18、dr);while(*p !='0')wrdat(*(p+);/* 名称showint(uint8 addr,uint16 num)* 功能:数字显示程序*/ void showint(uint8 addr,uint16 num)/在addr处显示数字num uint8 i;for(i=8;i>0;i-) bcdi-1=(uint8)(num%10+0x30); num/=10; i=0;while(bcdi =0x30 && i<7) bcdi+=' ' /num转换成数组存放,但还没有加上小数点distext(addr,bcd);
19、/* 名称timeshow(void)* 功能:时间显示程序*/void timeshow(void) uint8 i,j=0; uint8 timebuff5=2,3,4,5,6; for (i=0;i<5;i+) timebuffj+ = timei / 10; timebuffj+ = timei % 10; j+; for(i=0;i<2;i+) lcd_cursor(1,i+15); wrdat(timebuffi+'0'); lcd_cursor(1,i+15); wrdat(0x3a);i+; for(i=3;i<5;i+) lcd_cursor
20、(1,i+15); wrdat(timebuffi+'0'); lcd_cursor (1, place); /* 名称timer0_init(void)* 功能:中断定时初始化程序*/void timer0_init(void) vicintselect=0x00000000;vicintenable=0x00000010;vicvectcntl0=0x00000024;vicvectaddr0=(int)timerint; t0pr=1000;/预分频寄存器t0mr0=60000; t0mcr=0x00000003;t0tcr=0x00000003;t0tcr=0x0000
21、0001;/* 名称irq timerint(void)* 功能:中断处理程序*/void _irq timerint(void) time1+;/fen if(time1>=60) time1=0; time0+;/xiaoshi if(time0>=24) time0=0; vicvectaddr=0;t0ir=0x00000001; /* 名称ate_or_ope()* 功能:判断是数值还是计算符*/int date_or_ope(char key)if (key >= '0' && key <= '9')|(key
22、='.')return 1;return 0; /* 名称:main()* 功能:显示文本*/int main(void) uint8 keyvalue1,keyvalue2; uint8 flag;lcd_init();port_init(); timer0_init();/时钟初始化 distext(0x80,txt0); while(1) timeshow(); keyvalue1=keyscan(); if(keyvalue1!=0xff) /有键按下 dokeyvalue2=keyscan(); while(keyvalue1=keyvalue2); /作按键释放检查
23、 keypressed=keycode1keyvalue1; else keypressed=0xff; /得到键符 /* if(keypressed!=0xff) flag = date_or_ope(keypressed); if (flag = 1) deal_date(); else deal_ope(); /while end /main 函数结束/* 名称:deal_date(void)* 功能:数值处理*/void deal_date(void)if (date_or_ope(last_keypres) = 1) /如果上一个键值是数字字符 *temp_pt+=keypresse
24、d; else memset(date_temp,0,15); /用字符0填充date_temp的前15个字节temp_pt=date_temp; *temp_pt+=keypressed; last_keypres = keypressed; wrdat(keypressed);/显示字符可以在主函数中place+;return;/* 名称void deal_ope(void) * 功能:符号处理*/void deal_ope(void) /符号处理 double date_value;double date_result; uint8 i;if (keypressed = 'c
25、39;) memset(date_temp,0,15); last_keypres = '=' date0=0; date1=0;date_pt=&date1; oper_pt=operater; operater0='n' lcd_writecontrol(0x01); lcd_cursor(2,9);wrdat('0'); place=1; return ; /返回什么? /else if else if (keypressed = 'b') /清除一位数或符号 if (date_or_ope(last_keypres
26、) = 1) int j; j=strlen(date_temp); date_tempj-1='0' lcd_cursor(1,place-1); wrdat(' '); lcd_cursor (1, place-); return ; else *oper_pt='0' oper_pt-; lcd_cursor(1,place-1); wrdat(' '); lcd_cursor (1, place-); /else if end else if (keypressed='m'|keypressed='
27、h') switch (keypressed) case 'h': time0+; if(time0=24) time0=0;break; case 'm': time1+; if(time1=60) time1=0;break; default:break; else if (keypressed = 'e'|keypressed = 'd'|keypressed = 'l') wrdat(keypressed);/显示 if (date_or_ope(last_keypres) = 0)return ;
28、else date_result= calculate1(); re_temp1=(longint)(date_result); re_temp2=(longint)(date_result-re_temp1)*100000000); if(date_result<1) re_temp1=0; re_temp2=(longint)(date_result)*100000000); showint(0xc1,re_temp1);/整数部分 lcd_cursor(2,10); wrdat('.'); cov(re_temp2,show); /小数部分显示 for(i=0;i&
29、lt;2;i+) lcd_cursor(2,i+11); wrdat(showi+'0'); last_keypres = '=' /else if endelse if (keypressed = '=') /如果是= wrdat(keypressed);/显示 date_value = atof(date_temp);/把date_temp中的数字字符转 数值*(+date_pt) = date_value;date_result=calculate(); re_temp1=(long int)(date_result); re_temp2=
30、(long int)(date_result-re_temp1)*100000000); if(date_result<1) re_temp1=0; re_temp2=(long int)(date_result)*100000000); showint(0xc1,re_temp1);/整数部分 lcd_cursor(2,10); wrdat('.'); cov(re_temp2,show); /小数部分显示 for(i=0;i<2;i+) lcd_cursor(2,i+11); wrdat(showi+'0'); last_keypres =
31、39;=' /还原 else /如果不是c也不是= switch (keypressed) case '*': case '/': case '+': case '-': wrdat(keypressed); date_value = atof(date_temp);*(+date_pt) = date_value;if(*(oper_pt)!='n') /判断前一个是=否! date_result=calculate(); *(+oper_pt) = keypressed; last_keypres =
32、keypressed; place+;break;/switch /else/deal-ope/* 名称double calculate1()* 功能:开平方等运算*/double calculate1(void) double res2,result;char oper;res2= atof(date_temp);/将转化为数值oper = keypressed;switch (oper) case 'l':result =log10(res2); break; case 'e':result = res2*res2; break; case 'd':result = sqrt(res2); break; /开方 default :break; *(+date_pt) = result;memset(date_temp,0,15); return result;/* 名称:double calculate(void)* 功能:基本四则运算*/double calculate(void)double res1,res2,result;char oper;oper = *(oper_pt);res2 = *(date_pt-);res1 = *(date_pt-);switc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论