单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx

上传人:b****2 文档编号:3284350 上传时间:2023-05-05 格式:DOCX 页数:46 大小:834.12KB
下载 相关 举报
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第1页
第1页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第2页
第2页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第3页
第3页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第4页
第4页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第5页
第5页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第6页
第6页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第7页
第7页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第8页
第8页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第9页
第9页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第10页
第10页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第11页
第11页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第12页
第12页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第13页
第13页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第14页
第14页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第15页
第15页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第16页
第16页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第17页
第17页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第18页
第18页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第19页
第19页 / 共46页
单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx_第20页
第20页 / 共46页
亲,该文档总共46页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx

《单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx》由会员分享,可在线阅读,更多相关《单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx(46页珍藏版)》请在冰点文库上搜索。

单片机开发板 计算器 电梯 密码锁 万年历 交通灯课程设计宝贝及程序.docx

单片机开发板计算器电梯密码锁万年历交通灯课程设计宝贝及程序

开发板

 

设计课题:

基于单片机的简易计算器

指导老师:

班级:

学号:

姓名:

一设计内容和目的

本次实验的任务就是要以51系列单片机为核心实现一个简易计算器计算器,它的结构非常简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89C51单片机构成,通过软件编程可实现简单加减乘除。

目的:

做自己喜欢的实验,提高自学能力。

二方案论证

经分析,计算器电路包括三个部分:

显示电路、4*4键扫描电路、单片机微控制电路。

具体如下:

1)LCD显示电路

LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时序图来完善初始化程序。

又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.

2)4*4键盘扫描电路(中断式,扫描式,反转式)

用户设计行列键盘接口,一般常采用3种方法读取键值。

一种是中断式,外两种是扫描法和反转法。

中断式:

在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地

址读取数据线上的状态,判断哪个案件被按下。

本实验采用中断式实现用户键盘接口。

扫描法:

对键盘上的某一行送低电平,其他行为高电平,然后读取列值。

若列值中有一

位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。

反转法:

先将所有行扫描线输出低电平,读列值。

若列值有一位是低,则表明有键按下,

读列值;然后所有列扫描线输出低电平,再读行值。

根据读到的值组合就可以查表1得到的

键码。

这个就仁者见仁智者见智了,不过如果熟悉了扫描式,建议果断升级自己的硬件(很简单加个74LS08与门),故采用节省CPU的中断式扫描电路。

⒊)单片机微控制电路

微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。

三硬件电路的设计

2.1硬件设计电路框图

2.2硬件设计电路的元件清单

器件名称

数量

AT89C51

1

按键

17

74LS08

1

10K电阻

9

电容22uF

1

LCD1602

1

晶振12MHz

1

电容30pF

2

5K电位器

1

2.3硬件设计电路图

将4*4的键盘直接接在P1口上,用P0口作为LCD的显示输出,P3.2口的INT0作为外部中断位。

2.4硬件设计的补充说明

四软件设计程序及描述

本程序组成可分为3个模块:

矩阵键盘模块,LCD显示模块,和运算模块(源程序见底页)

五硬软件的调试及方法

我个人遇到的主要问题出现在LCD1602上,要不是我自己买了块新的LCD恐怕我的结论,就只能在软件仿真实现了。

硬件上:

在不加芯片调试时,LCD1602只显示一排全黑,一般说明该元件是好的。

(但也不一定,我那时就一直认为我的元件没坏);给15,16管脚分别接上+5v和0v,测试背光是否完好;给VEE接上电位器,检查对比度是否可调;

一般LCD易出现的现象,我再做实验的时候遇到过以下几种情况:

状态1

上电之后,1602的第一行全黑,即16个5x7黑块

产生原因:

液晶根本就没有进行初始化操作,需要检查连线或者程序。

运气不好的情况下就是整块LCD是坏的。

状态2

屏上显示两排灰格

产生原因:

程序中对液晶初始化不正常,应是部分初始化指令没有正常接收,建议按照标准初始化步骤调整程序,或者调整指令之间的延时(加大一些试试)----补充:

也有可能是对比度太大,建议优先调整对比度电阻

状态3

显示乱码

这是我在实验室组合版上做的,原因是接线问题

状态3

正确显示

六实验结果与性能达标

我的计算器只能准确进行得数为0~9的四则运算。

1.加法计算

2.减法计算

3.乘法计算

4.除法计算

5.字符显示

实物与仿真不一致。

这就是传说中的BUG了。

我不明白。

七实验改进与心得体会

很明显我的计算器处理数据及显示存在太大的局限性,我觉得主要还是我对程序中的运算模块理解不深,这点仍需大大加强。

这个实验给我的感觉,硬件和软件上都不是很难。

我的焊工也不马虎,即使难看了点,但只要软件能行,就能完美运行。

可惜,我就败在LCD1602,从学校拿了两块,幸好最后实在没办法,自己买了一块。

最终证实我之前的实验就是LCD的损坏。

没知识真可怕,我不懂真正排查LCD的好坏。

不过也因祸得福,我在磕磕碰碰中,固执的认为LCD是好的,反而使我对LCD初始化,LCD字符显示,3种不同的矩阵键盘扫描的方法,及软件上的巧妙技巧有了更好的了解。

我在这次实验上,感觉收获的更多.

 

下面是源代码:

#include

#defineCLEARSCREENLCD_write_command(0x01)

#defineuintunsignedint

#defineucharunsignedchar

/**************定义接口************************/

#defineLCDIOP0

#defineKEYBOARDP1//保留

sbitLCD1602_RS=P2^0;

sbitLCD1602_RW=P2^1;

sbitLCD1602_EN=P2^2;

/************************************************/

codeucharmayuan[16]={'0','1','2','3','4','5','6','7','8','9','0','/','*','-','+','='};//不错,这个比较明了

unsignedcharcodekeycode[]={0x11,0x21,0x41,0x81,0x12,0x22,0x42,0x82,

0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88};//键盘编码值()

inti,j,k=1,s;//

intt,t1,t2,a[];//

voiddelay(uchar);//延时

/**************定义函数************************/

voidLCD_init(void);//初始化函数

voiddelay_nms(unsignedintn);//延时函数

voidLCD_write_command(unsignedcharcommand);//写入指令函数

voidLCD_write_dat(unsignedchardat);//写入数据函数

voiddelay_10ms();

initial();

ucharkeyscan();//键盘扫描函数

calc(uchar);//计算函数

ucharnum,temp,key,keynum;

voidmain()//主函数

{

LCD_init();

delay_nms(100);

while

(1)

{

initial();//有中断

KEYBOARD=0xf0;//键盘的列值全置高电平

}

}

/**********************************开中断***************************************/

initial()

{

EA=1;//总开关

EX0=1;//中断方式0开启

IT0=0;

}

/*******************************************************************************/

/*********************************中断函数************************************/

voidinter0()interrupt0

{

unsignedcharn;

delay_10ms();//延时

if(INT0==0)//没键按下

{

EX0=0;//关中断

n=keyscan();

calc(n);

EX0=1;//开中断

KEYBOARD=0xf0;//键盘的列值全置高电平

}

}

/************************************************************************/

calc(ucharn)

{

if(n<10)//键值小于10

{

t1=t1*10+n;

LCD_write_command(0x00);//写命令语句

LCD_write_dat(mayuan[n]);//写数据函数

}

else

{

if(n==10){LCD_init();t1=0;t2=0,t=0;k=1;}

else{

if(n<15){

t2=t1;t1=0;j=n;

LCD_write_command(0x00);

LCD_write_dat(mayuan[n]);}

else{

LCD_write_command(0x00);

LCD_write_dat(mayuan[n]);

switch(j){

case11:

t=t2/t1;

break;

case12:

t=t2*t1;

break;

case13:

t=t2-t1;

break;

case14:

t=t2+t1;

break;

}

if(t<=9){LCD_write_command(0x00);

LCD_write_dat(t+48);}

if(t>9)

{

while(t>9)

{

s=t%10;

t=t/10;

a[k]=s;

k++;

}

if(t<=9){

LCD_write_command(0x00);

LCD_write_dat(t+48);}

for(i=k-1;i>=1;i--)

{

LCD_write_command(0x00);

LCD_write_dat(a[i]+48);

}

}

}

}

}

}

/*****************************************键盘扫描函数************************************/

ucharkeyscan()//键盘扫描

{

KEYBOARD=0xf0;//键盘的列值全置高电平

delay_10ms();//延时

if(KEYBOARD!

=0xf0)//有键按下

{

temp=KEYBOARD;//保存键盘此刻的键植

delay_10ms();//延时

if(KEYBOARD==temp)//再次确认键盘是否被按下

{

uchari;

KEYBOARD=0x0f;//键盘的行值全置高电平

delay_10ms();//10MS时间延时

keynum=temp|KEYBOARD;//保存键盘的行值

while(KEYBOARD!

=0x0f);//松手检测

for(i=0;i<16;i++)

if(keycode[i]==~keynum)

return(i);

}

}

return-1;

}

/******************************************************************************/

/**********延时**********************/

voiddelay_nms(unsignedintn)

{

unsignedinti=0,j=0;

for(i=n;i>0;i--)

for(j=0;j<10;j++);

}

voiddelay_10ms()//10MS延时

{

unsignedchari,j;

for(i=0;i<10;i++)

for(j=0;j<120;j++);

}

/**************************************/

/**************写指令函数********************************/

voidLCD_write_command(unsignedcharcommand)

{

LCDIO=command;

LCD1602_RS=0;

LCD1602_RW=0;

LCD1602_EN=0;

LCD1602_EN=1;

delay_nms(10);

}

/***************************************************/

/****************写数据函数************************/

voidLCD_write_dat(unsignedchardat)

{

LCDIO=dat;

LCD1602_RS=1;

LCD1602_RW=0;

LCD1602_EN=0;

delay_nms

(1);

LCD1602_EN=1;

}

/****************************************************/

/************初始化函数****************/

voidLCD_init(void)

{

CLEARSCREEN;//clearscreen

LCD_write_command(0x38);//set8bitdatatransmissionmode

LCD_write_command(0x0c);//opendisplay(enablelcddisplay)

LCD_write_command(0x80);//setlcdfirstdisplayaddress

CLEARSCREEN;//clearscreen

}

/****************************************************/

 

为了方便初学者学习LCD,特留下字符显示代码,电路图与本实验一致。

已通过实物测试,绝对没问题。

#include

unsignedchartable1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,

0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,

0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,

0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,

0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,

0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,

0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,

0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00};//心图案

unsignedchartable[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃

#defineCLEARSCREENLCD_write_command(0x01)

/**************定义接口************************/

#defineLCDIOP0

sbitLCD1602_RS=P2^0;

sbitLCD1602_RW=P2^1;

sbitLCD1602_EN=P2^2;

/**************定义函数************************/

voidLCD_write_command(unsignedcharcommand);//写入指令函数

voidLCD_write_dat(unsignedchardat);//写入数据函数

voidLCD_set_xy(unsignedcharx,unsignedchary);//设置显示位置函数

voidLCD_dsp_char(unsignedx,unsignedchary,unsignedchardat);//显示一个字符函数

voidLCD_dsp_string(unsignedcharX,unsignedcharY,unsignedchar*s);//显示字符串函数

voidLCD_init(void);//初始化函数

voiddelay_nms(unsignedintn);//延时函数

/********************************************/

/************初始化函数****************/

voidLCD_init(void)

{

CLEARSCREEN;//clearscreen

LCD_write_command(0x38);//set8bitdatatransmissionmode

LCD_write_command(0x0c);//opendisplay(enablelcddisplay)

LCD_write_command(0x80);//setlcdfirstdisplayaddress

CLEARSCREEN;//clearscreen

}

/****************************************************/

/**************写指令函数********************************/

voidLCD_write_command(unsignedcharcommand)

{

LCDIO=command;

LCD1602_RS=0;

LCD1602_RW=0;

LCD1602_EN=0;

LCD1602_EN=1;

delay_nms(10);

}

/***************************************************/

/****************写数据函数************************/

voidLCD_write_dat(unsignedchardat)

{

LCDIO=dat;

LCD1602_RS=1;

LCD1602_RW=0;

LCD1602_EN=0;

delay_nms

(1);

LCD1602_EN=1;

}

/****************************************************/

/***************设置显示位置**************************/

voidLCD_set_xy(unsignedcharx,unsignedchary)

{

unsignedcharaddress;

if(y==1)

address=0x80+x;

else

address=0xc0+x;

LCD_write_command(address);

}

/***************************************************/

/****************显示一个字符**********************/

voidLCD_dsp_char(unsignedx,unsignedchary,unsignedchardat)

{

LCD_set_xy(x,y);

LCD_write_dat(dat);

}

/**********************************************/

/***************显示字符串函数***************/

voidLCD_dsp_string(unsignedcharX,unsignedcharY,unsignedchar*s)

{

LCD_set_xy(X,Y);

while(*s)

{

LCD_write_dat(*s);

s++;

}

}

/***********************************************/

/**********延时**********************/

voiddelay_nms(unsignedintn)

{

unsignedinti=0,j=0;

for(i=n;i>0;i--)

for(j=0;j<10;j++);

}

/**************************************/

/***********主函数**************/

voidmain(void)

{

unsignedchari,j,k,tmp;

LCD_init();

delay_nms(100);

tmp=0x40;//设置CGRAM地址的格式字

k=0;

for(j=0;j<8;j++)

{

for(i=0;i<8;i++)

{

LCD_write_command(tmp+i);//设置自定义字符的CGRAM地址

delay_nms

(2);

LCD_write_dat(table1[k]);//向CGRAM写入自定义字符表的数据

k++;

delay_nms

(2);

}

tmp=tmp+8;

}

LCD_dsp_string(1,1,"LCDTEST");//在第一行第一列显示"LCDTEST"

LCD_dsp_string(1,2,"SUCCESSFUL");//在第二行第一列显示"SUCCESSFUL"

for(i=0;i<4;i++)

{

LCD_dsp_char(12+i,1,i);//在第一行第12列

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2