课程设计成绩
考勤成绩
实做成绩
报告成绩
总评成绩
指导教师签名:
嵌入式系统
课 程 设 计 报 告
文题目: 简易计算器设计
学院(系): 电子信息动化学院
班 级:
学生姓名: 学号
指导教师:
时间: 2016年6月20日 2016年7月8日
目录
前言 3
摘 3
原理总体方案 4
⒈总体方案 4
二硬件设计 5
⒈元器件 表21: 5
⒉键盘接口电路 5
3模块介绍功 7
三调试 9
⒈ GPIO特性 9
⒉ 硬件程序原理 9
四测试分析 10
五结束语 13
附件:程序代码 13
前言:年着规模集成电路发展应种便携式嵌入式设备具十分广阔市场前景嵌入式系统种专计算机系统作装置设备部分通常嵌入式系统控制程序存储ROM中嵌入式处理器控制板事实带数字接口设备手表微波炉录机汽车等嵌入式系统嵌入式系统包含操作系统数嵌入式系统单程序实现整控制逻辑嵌入式系统中数命令通网络接口串行口ARM程序处理显示LCD传输远端PC次课程设计通国LPC2138芯片完成简易计算器正嵌入式应学思考探索
摘 计算器般指电子计算器进行数学运算手持机器拥集成电路芯片嵌入式系统占资源少专性强汽车电子航空工控领域广泛应设计先KELL软件中进行相应程序编写运行导入PROTUES进行仿真利ARM中LPC2138芯片控制液晶显示器4X6矩阵式键盘实现简单加减等四运算功
关键字 中断 扫描 仿真 计算 显示
原理总体方案
⒈总体方案
程序初始化调键盘程序判断返回值数字0 9根键次数进行保存显示处理功键先判断次功键根代号执行功键次数清零程序中键盘部分行列式扫描原理键调动态显示程序继续检测键盘情况键键值通查表转换数字0—9功键清零键代号计算结果拆分成十百位返回程序继续检测键盘显示清零键返回程序开始电路设计原理通LPC2128芯片进行相应设置控制LCD显示器通键盘值进行扫描相应键值ARM芯片接收
开始
2.系统流程图:
端口初始化
引脚功初始化
量中断初始化
外部中断初始化
LCD初始化
时钟初始化
中断定时初始化
调显示模式设置
显示时间
键扫描
N
计算键值调参数设定子程序
Y
二硬件设计
⒈元器件 表21:
器件
数量
Lpc2138
1
LCD1602
1
KEYPAD
1
电缆线
1
USB电源线
1
电源
干
导线
干
表21 元器件表
⒉键盘接口电路
计算器输入数字功键键果采独立键方式种情况程会简单会占量IO 口资源情况采种方式采矩阵键盘方案次课程设计中矩阵键盘采四条IO 线作行线六条IO 线作列线组成键盘行线列线交叉点设置键样键盘键数4×6种行列式键盘结构效提高单片机系统中IO 利率
矩阵键盘工作原理图21:
图21 矩阵键盘工作原理
计算器键盘布局图2224键组成lpc2138芯片中芯片某引脚输出键盘4根行线6根列线接入P12 P21口作引键盘输入端口种行列式键盘结构效提高单片机系统中IO 口利率
图22 计算器键盘布局
显示模块:设计采LCD1液晶显示屏显示输出数通D0D7引脚LCD1写指令字写数LCD1实现功显示相应数
3模块介绍功
①Lpc2138特性引脚功:Philips公式32位ARM7微控制器lpc2138具强储存空间嵌32KB片静态ARM512KBFlash存储器实现系统编程(ISP)应编程(IAP)28路10位AD转换器1DA转换器转换迅速准确引脚资源丰富达47承受5V通IO口串行接口包括216C550工业标准UART2高速12C口SPI具缓作数长度变功SSP协议lpc2138移植u CCOII操偶做系统软件移植性工作(图23)
图23 LPC2138仿真图
脚说明:V3VBATVREP供电电压
VssVSSA接
XTAL反振荡放器输入部时钟工作电路入
XTAL反振荡器输出
P112P123作GPIO接口
P116—P126作LCD显示电路接口
②LCD特性说明:
LCD 显示屏(图24)采字符显示字符显示方式时直接外码作输入数显示屏动出显示字模数需微处理器提供字模
图24 LCD显示屏
③键盘特性:
数字式键盘(图25)实质行列式键盘4 根行线6 根列线通拉电阻接表面贴标示应键膜易观察操作更加贴者需求
图25 数字式键盘
设计中选LPC2138P116—P126口LCD 显示屏相连输出信号控制显示屏显示中P116P123 分接显示屏D0D7P124—P126分接显示屏RSRWE 接口选LPC2138P012—P021口连续10IO口计算器键盘相连通键检测键通查键盘应字符编码LCD 显示中P00—P03口次接键盘4根行线P04—P09口次接键盘6根列线
④脚说明:
P00 P03口行键扫描电输出端P04 P09口列键输入读取端
三调试
⒈ GPIO特性
LPC2000系列ARMGPIO具特性:
a 独立控制GPIO口方输入输出模式
b 独立设置GPIO输出状态高低电
c GPIO口复位默认输入状态
作GPIO功引脚受四寄存器控制分控制方IOxDIR控制输出电状态IOxSETIOxCLR反映引脚电状态IOxPIN四寄存器构成组组寄存器控制着端口P0P1P2P3
⒉ 硬件程序原理
键盘键产生中断KEYSCAN键盘进行扫描确定键果等号字符次存入数组LCD显示表达式果等号计算出数组中存入表达式值显示LCD中 计算表达式值方法:表达式中表示数值字符转成数值存入数值数组表达式中表示运算符字符存入运算符数组
关四运算优先级算法:次检索运算符数组遇 * 号者 号时候先计算法法算出结果存入数值数组相应位置然删运算符余数值重复检索直数值数组中数值止数值运算结果 调stdioh库里sprintf函数数值转化成字符数组然显示LCD中
次课程设计中简易算器基础进行拓展仅具加减功具开方开根求数功输入错误进行退格处理结束运算进行清零处理仅时间显示功通键调整时间
四测试分析
⒈ KEIL工程文件 见附件1
⒉ Proteus实时仿真图41
图41 Proteus实时仿真
⒊ Proteus实时仿真子功图42—47
图42 时钟显示 图43 数运算
图44 加法 图45减法
图46 法 图47 法
图48 方 图49 开根
⒋ 实物图图410
图410
五结束语
言知识收获重ARM处理系统更深刻认识挫折份财富:历份拥次实必成生旅途非常美回忆通次课程设计懂理实际相结合重理知识远远够:学理知识实践相结合起:理中出结:真正社会服务:提高实际动手力独立思考力设计程中遇问题例法载程序时通排查发现芯片某IO效通修改程序采端口解决时设计程中发现足处:前学知识理解够深刻:掌握够牢固
附件:程序代码
************************************
* File mainc
* 功 计算器基程序
*************************************
#include configh
#include stdlibh
#include stdioh
#include stringhmemset hanshu
#include mathh
#define LCD_RS (1<<24)
#define LCD_RW (1<<25)
#define LCD_E (1<<26)
#define nop() {__asm(nop)}
#define busy (1<<23)
uint8 txt0[]{Hello }
uint8 time[2]{1234} 时分秒计数
void timeshow(void)
void timer0_init(void)
void __irq timerInt(void)
***********************************
* 名称 函数变量声明
* 功 显示文
*********************************
void port_init(void)
void cov(long int buint8 *p)
void LCD_Cursor (char row char column)
void ShowInt(uint8 addruint16 num)
void deal_date(void)
void deal_ope(void)
double calculate(void)
double calculate1(void)
uint8 KEYSCAN(void)
uint8 KEYCODE1[24]{ 'C''7''8''9''*'''
'H''4''5''6''''L'
'M''1''2''3''+''E'
'B''0''''''+''D'
} *ASCII码*
long int re_temp10re_temp20
uint8 BCD[7]{0}
uint8 show[7]{0}
char keypressed
char last_keypres ''
double date[5]{00}
double *date_pt&date[1]
char operater[5]{'N'}
char *oper_ptoperater
uint8 place1
char date_temp[17]
char *temp_ptdate_temp
***********************************
* 名称 DelayNS
* 功 延时函数
**********************************
void DelayNS(uint32 dly)
{ uint32 i
for(dly>0dly)
for(i0i<50000i++)
}
***********************************
* 名称 void port_init(void)
* 功 端口初始化
*********************************
void port_init(void)
{
PINSEL00x00000000
PINSEL10x00000000
IO0DIR0x0000F000 键盘行输入
IO0CLR0x0000F000 初始化
PINSEL20x00000000 1111 1111 1100 0000 0000 0000 0000 0000
IO1DIR|0x7ff0000 0000 0111 1111 1111
IO1SET|0xff0000 1111 1111
}
***********************************
* 名称 cov(long int bunsigned char *p)
* 功 数拆分
*********************************
void cov(long int bunsigned char *p)
{unsigned char j8
while(j)
{
p[j]b10bb10
}
p[j]b
}
********************************
* 名称ChkBusy()
* 功 检查总线否忙
*********************************
void ChkBusy()
{
int status
IO1DIR0x7000000 0111 0000 0000 0X00等输入
do
{
IO1CLR|LCD_RS
IO1SET|LCD_RW
IO1SET|LCD_E
nop()nop()nop()nop()
status IO1PIN
IO1CLR | LCD_E
}
while (status & 0x800000)
IO1DIR0x7ff0000 0X00等输出
}
************************************
* 名称 WrOp()
* 功 写命令函数
**********************************
void LCD_WriteControl (uint8 dat)
{
ChkBusy()
IO1CLR|LCD_RS 全部清零
IO1CLR|LCD_RW
IO1CLR0xff0000 先清零
IO1SET|(dat<<16) 送数
nop()nop()nop()nop()
IO1SET|LCD_E
IO1CLR|LCD_E
}
*********************************
* 名称 CD_Cursor
* 功 光标定位
*********************************
void LCD_Cursor (char row 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)
{
ChkBusy()调检测繁忙函数
IO1SET|LCD_RS
IO1CLR|LCD_RW
IO1CLR0xff0000 先清零
IO1SET|(dat<<16) 送数
nop()nop()nop()nop()
IO1SET|LCD_E
IO1CLR|LCD_E
}
*************************************
* 名称 lcd_init()
* 功 lcd初始化函数
*********************************
void lcd_init(void)
{
LCD_WriteControl(0x38) 显示模式设置开始求次检测忙信号
LCD_WriteControl(0x08) 关闭显示
LCD_WriteControl(0x01) 显示清屏
LCD_WriteControl(0x06) 显示光标移动设置
LCD_WriteControl(0x0C) 显示开光标设置
}
*********************************
* 名称 DisText()
* 功 显示文函数
*********************************
void DisText(uint8 addruint8 *p)
{
LCD_WriteControl(addr)
while(*p '\0')WrDat(*(p++))
}
*********************************
* 名称 ShowInt(uint8 addruint16 num)
* 功 数字显示程序
********************************
void ShowInt(uint8 addruint16 num) addr处显示数字num
{
uint8 i
for(i8i>0i)
{
BCD[i1](uint8)(num10+0x30)
num10
}
i0
while(BCD[i] 0x30 && i<7) BCD[i++]' ' NUM转换成数组存放没加数点
DisText(addrBCD)
}
********************************************
名称 timeshow(void)
* 功 时间显示程序
*******************************************
void timeshow(void)
{ uint8 ij0
uint8 timebuff[5]{23456}
{
for (i0i<5i++)
{
timebuff[j++] time[i] 10
timebuff[j++] time[i] 10
j++
}
}
for(i0i<2i++)
{LCD_Cursor(1i+12) WrDat(timebuff[i]+'0')}
{LCD_Cursor(1i+12) WrDat(0x3A)i++}
for(i3i<5i++)
{LCD_Cursor(1i+12) WrDat(timebuff[i]+'0')}
LCD_Cursor (1 place)
}
**********************************
名称 timer0_init(void)
* 功 中断定时初始化程序
*********************************
void timer0_init(void)
{
VICIntSelect0x00000000 IRQ中断
VICIntEnable0x00000010 中断保留
VICVectCntl00x00000024 定时器0匹配通道优先级0
VICVectAddr0(int)timerInt
T0PR1000 预分频寄存器
T0MR060000 MR0TC值匹配
T0MCR0x00000003
T0TCR0x00000003 定时器控制复位
T0TCR0x00000001 定时器控制启动
}
*********************************
名称irq timerInt(void)
* 功中断处理程序
*********************************
void __irq timerInt(void)
{ time[1]++ min
if(time[1]>60)
{ time[1]0
time[0]++ hour
if(time[0]>24)
{ time[0]0}
}
VICVectAddr0
T0IR0x00000001 匹配通道0中断标志
}
************************************
* 名称 ate_or_ope()
* 功 判断数值计算符
*********************************
int date_or_ope(char key)
{
if ((key'')||(key > '0' && key < '9'))
{
return 1
}
else return 0
}
******************************************** 名称 main()
* 功 显示文
*********************************
int main(void)
{
uint8 keyvalue1keyvalue2
uint8 flag
port_init()
lcd_init()
timer0_init()时钟初始化
DisText(0x80txt0)
while(1)
{
timeshow()
keyvalue1KEYSCAN()
if(keyvalue10xff) 键
{
do{ keyvalue2KEYSCAN()
}
while(keyvalue1keyvalue2) 作键释放检查
keypressedKEYCODE1[keyvalue1]
}
else keypressed0xff 键符
if(keypressed0xff)
{
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++keypressed
}
else
{
memset(date_temp015) 字符0’填充date_temp前15字节
temp_ptdate_temp
*temp_pt++keypressed
}
last_keypres keypressed
WrDat(keypressed)显示字符函数中
place++
}
********************************************
名称 void deal_ope(void)
* 功 符号处理 ***************************
void deal_ope(void) 符号处理
{
double date_value
double date_result
uint8 i
if (keypressed 'C')
{
memset(date_temp015)
last_keypres ''
date[0]0
date[1]0
date_pt&date[1]
oper_ptoperater
operater[0]'N'
LCD_WriteControl(0x01)
LCD_Cursor(29)WrDat('0')
place1
}
else if
else if (keypressed 'B') 清位数符号
{
if (date_or_ope(last_keypres) 1)
{ int j
jstrlen(date_temp)
date_temp[j1]'\0'
LCD_Cursor(1place1)
WrDat(' ')
LCD_Cursor (1 place)
return
}
else{
*oper_pt'\0'
oper_pt
LCD_Cursor(1place1)
WrDat(' ')
LCD_Cursor (1 place)
}
}else if end
else if (keypressed'M'||keypressed'H')
{ switch (keypressed)
{
case 'H' time[0]++
if(time[0]24) time[0]0break
case 'M' time[1]++
if(time[1]60) time[1]0break
defaultbreak
}
}
else if (keypressed 'E'||keypressed 'D'||keypressed 'L')
{ WrDat(keypressed)显示
if (date_or_ope(last_keypres) 0)
{
return
}
else
{
date_result calculate1()
re_temp1 (long int)(date_result)
re_temp2 (long int)((date_resultre_temp1)*100000000)
if(date_result<1)
{ re_temp10
re_temp2(long int)((date_result)*100000000)
}
ShowInt(0xc1re_temp1)整数部分
LCD_Cursor(210)
WrDat('')
cov(re_temp2show) 数部分显示
for(i0i<4i++) jiwei
{
LCD_Cursor(2i+11)
WrDat(show[i]+'0')
}
}
last_keypres ''
} else if end
else if (keypressed '') 果’
{
WrDat(keypressed)显示
date_value atof(date_temp)date_temp中数字字符转 数值
*(++date_pt) date_value
date_resultcalculate()
re_temp1 (long int)(date_result)
re_temp2 (long int)((date_resultre_temp1)*100000000)
if(date_result<1)
{
re_temp10
re_temp2 (long int)((date_result)*100000000)
}
ShowInt(0xc1re_temp1)整数部分
LCD_Cursor(210)
WrDat('')
cov(re_temp2show) 数部分显示
for(i0i<4i++)
{
LCD_Cursor(2i+11)
WrDat(show[i]+'0')
}
last_keypres '' 原
}
else 果C’’
{
switch (keypressed)
{
case '*'
case ''
case '+'
case '' WrDat(keypressed)
date_value atof(date_temp)
*(++date_pt) date_value
if( *(oper_pt)'N') 判断前否
{
date_resultcalculate()
}
*(++oper_pt) keypressed
last_keypres keypressed place++
break
}switch
}else
}dealope
**************************************
* 名称 double calculate1()
* 功 开方等运算
*********************************
double calculate1(void)
{ double res2result
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_temp015)
return result
}
**********************************
名称 double calculate(void)
* 功 基四运算
*********************************
double calculate(void)
{
double res1res2result
char oper
oper *(oper_pt)
res2 *(date_pt)
res1 *(date_pt)
switch (oper)
{
case '+' result res1+res2 break
case '' if(res1>res2)
{ resultres1res2
LCD_Cursor(21)
WrDat(' ')
}
else
{
resultres2res1
LCD_Cursor(21)
WrDat('')
} break
case '*' result res1*res2 break
case '' result res1res2 break
}
*(++date_pt) result
memset(date_temp015)
return result
}
******************************************
* 名称KEYSCAN(void)
* 功键盘扫描程序*********************************
uint8 KEYSCAN(void)
{
uint8 itemptemp20xff
PINSEL00x00000000
PINSEL10x00000000
IO0DIR0x0000F000
IO0CLR0x0000F000
temp(IO0PIN&0x003F0000)>>16
for(i0i<16i++)
{
IO0SET((1< IO0CLR( (1< DelayNS(1) 等稳定
temp(IO0PIN&0x003F0000)>>16
if(temp0x00) 键
{
DelayNS(5) 延时消抖动
temp(IO0PIN&0x003F0000)>>16
temptemp&0x0000003F while(((IO0PIN&0x003F0000)>>16)0) 读键盘
if(temp0x00) 键
{
switch(temp) 计算键值
{
case 0x20temp229(16i)*6break
case 0x10temp228(16i)*6break
case 0x08temp227(16i)*6break
case 0x04temp226(16i)*6break
case 0x02temp225(16i)*6break
case 0x01temp224(16i)*6break
defaulttemp20xff
}
}
return temp2
}
}
return 0xff
}
文档香网(httpswwwxiangdangnet)户传
《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
该内容是文档的文本内容,更好的格式请下载文档