电话键盘及拨的模拟Word格式.docx
《电话键盘及拨的模拟Word格式.docx》由会员分享,可在线阅读,更多相关《电话键盘及拨的模拟Word格式.docx(17页珍藏版)》请在冰点文库上搜索。
1.1AT89C51简介
AT89C51是一种带4K字节FLASH存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的低电压、高性能CMOS8位微处理器,俗称单片机。
AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。
1.2管脚说明
如图1为AT89C51引脚图,各引脚功能说明如下:
图1AT89C51引脚图
VCC:
电源
GND:
地
P0口:
P0口是一个8位漏极开路的双向I/O口。
作为输出口,每位能驱动8个TTL逻辑电平。
对P0端口写“1”时,引脚用作高阻抗输入。
当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。
在这种模式下,P0具有内部上拉电阻。
在flash编程时,P0口也用来接收指令字节;
在程序校验时,输出指令字节。
程序校验时,需要外部上拉电阻。
P1口:
P1口是一个具有内部上拉电阻的8位双向I/O口,P1输出缓冲器能驱动4个TTL逻辑电平。
对P1端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
此外,P1.0和P1.2分别作定时器/计数器2的外部计数输入(P1.0/T2)和时器/计数器2的触发输入(P1.1/T2EX)
P2口:
P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4个TTL逻辑电平。
对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOVX@DPTR)时,P2口送出高八位地址。
在这种应用中,P2口使用很强的内部上拉发送1。
在使用8位地址(如MOVX@RI)访问外部数据存储器时,P2口输出P2锁存器的内容。
在flash编程和校验时,P2口也接收高8位地址字节和一些控制信号。
P3口:
P3口是一个具有内部上拉电阻的8位双向I/O口,对P3端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
P3口亦作为AT89C51特殊功能(第二功能)使用,如表1所示。
表1AT89C51引脚号第二功能
P3.0
RXD(串行输入)
P3.1
TXD(串行输出)
P3.2
INT0(外部中断0)
P3.3
P3.4
T0(定时器0外部输入)
P3.5
T1(定时器1外部输入)
P3.6
WR(外部数据存储器写选通)
P3.7
RD(外部数据存储器读选通)
RST:
复位输入,晶振工作时,RST脚持续2个机器周期高电平将使单片机复位。
看门狗计时完成后,RST脚输出69个晶振周期的高电平。
特殊寄存器AUXR(地址8EH)上的DISRTO位可以使此功能无效。
DISRTO默认状态下,复位高电平有效。
ALE/PROG:
地址锁存控制信号(ALE)是访问外部程序存储器时,锁存低8位地址的输出脉冲。
在flash编程时,此引脚(PROG)也用作编程输入脉冲。
在一般情况下,ALE以晶振六分之一的固定频率输出脉冲,可用来作为外部定时器或时钟使用。
然而,特别强调,在每次访问外部数据存储器时,ALE脉冲将会跳过。
如果需要,通过将地址为8EH的SFR的第0位置“1”,ALE操作将无效。
这一位置“1”,ALE仅在执行MOVX或MOVC指令时有效。
否则,ALE将被微弱拉高。
这个ALE使能标志位(地址为8EH的SFR的第0位)的设置对微控制器处于外部执行模式下无效。
3、流程图
N
Y
3、电路设计
3.1电路原理图
3.2程序清单
#include<
reg51.h>
//包含单片机寄存器的头文件
intrins.h>
//包含_nop_()函数定义的头文件
typedefunsignedintuint;
typedefunsignedcharuchar;
uchartemp;
ucharkey=16;
sbitrs=P2^0;
//LCD1602数据/命令选择
sbitrw=P2^1;
//LCD1602读/写选择
sbitlcden=P2^2;
//LCD1602使能端
ucharidatatable[18]="
ATD+86"
;
ucharidatatable[18];
//LCD1602所显示的号码缓存数组
ucharidatatable_int[18]="
ucharidatareceive[7];
ucharidataerro[7]="
erronum"
ucharnum=6,a=0,b=0;
//b接收,a发送,num表示table[]第几位
#definedelayNOP();
{_nop_();
_nop_();
};
//宏定义,方便写代码
/*延时子程序*/
voiddelay(ucharx)
{
uchari;
while(x--)
{
for(i=0;
i<
125;
i++)
{
{;
}
}
/*检查LCD忙状态*/
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据*/
bitbusy()//LCD忙检测
bitresult;
rs=0;
rw=1;
lcden=1;
delayNOP();
result=(bit)(P0&
Ox80);
lcden=0;
returnresult;
/*写指令数据到LCD*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*/
voidlcd_com(ucharcmd)
while(busy());
rw=0;
_nop_();
P0=cmd;
voidlcd_pos(ucharpos)
{//设定显示位置
lcd_com(pos|0x80);
//数据指针=80+地址变量
/*写显示数据到LCDRS=H,RW=L,E=高脉冲,D0-D7=数据。
*/
voidlcd_dat(uchardat)
rs=1;
P0=dat;
/*LCD初始化设定*/
voidlcd_init()
{
delay(15);
lcd_com(0x38);
//16*2显示,5*7点阵,8位数据
delay(5);
//延时
lcd_com(ox38);
lcd_com(0x0c);
//显示开,关光标
//移动光标
//清除LCD的显示内容
/*LCD显示*/
voiddisplay()
uchara=0;
lcd_pos(0);
delay(30);
while(table[a]!
='
\0'
);
//判断下一位是否为空
lcd_dat(table[a]);
//显示字符
a++;
if(a==16)
lcd_pos(0x40);
//设置显示位置为第二行第1个字符
voidkeyscan()
temp=0;
P1=0xf0;
//高四位输入行为高电平列为低电平
delay(50);
temp=P1;
temp=temp&
0xf0;
//屏蔽低四位
temp=~((temp>
>
4)0|xF0);
if(temp==1)//p1.4被拉低
key=0;
elseif(temp==2)//p1.5被拉低
key=1;
elseif(temp==4)//p1.6被拉低
key=2;
elseif(temp==8)//p1.7被拉低
key=3;
else
key=16;
P1=0x0f;
//低四位输入列为高电平行为低电平
//读P1口
temp=~(temp|0xf0);
if(temp==2)//p1.1被拉低
key=key+0;
elseif(temp==4)//p1.2被拉低
key=key+4;
elseif(temp==8)//p1.3被拉低
key=key+8;
if(key==0)//以下是判断按键,显示相应的号码
table[num]='
1'
num++;
if(key==1)
2'
if(key==2)
3'
if(key==3)
4'
if(key==4)
5'
if(key==5)
6'
if(key==6)
7'
if(key==7)
8'
if(key==8)
9'
if(key==9)
0'
if(key==10)
table[--num]='
//删除上一位
lcd_com(oxo1);
//清除LCD的所有显示内容
if(key==11)
)
if(num==17)
tab[a]=SBUF=table[a];
//显示输入数据
while(!
TI);
//等特数据传送
TI=0;
//清除数据传送标志
{//发送下一位字符
tab[a]=SBUF=erro[a];
TI=0;
/*串口初始化*/
voiduart_int()
TMOD=0x20;
//工作方式2,为常数自动重新装入的8位定时器
TH1=0xf3;
//装定时器初值
TL1=0xf3;
TR1=1;
//开启定时器1
SM0=0;
//串口方式0
SM1=1;
//串口方式1
REN=1;
//允许接收
ES=1;
//是开启串口中断
EA=1;
//开中断总开关
voidmain()
uart_int();
lcd_int();
while(num<
=17)
keyscan();
//键盘扫描
display();
//LCD显示
if(receive[4]=='
E'
)//判断PC机返回的是否是ATD+ERR
P2=0xfe;
while(tab[a]!
SBUF=tab[a];
//串口发送
//等特数据传送(TI发送中断标志)
//下一个字符
a=0;
receive[4]='
//PC机返回ATD+OK
elseif(receive[4]=='
)//判断PC机返回的是否是ATD+OK
P2=0xfd;
if((receive[5]='
K'
||(receive[6]=='
R'
))//判断PC机返回的是否是ATD+K或ATD+R
b=0;
receive[5]='
//PC机返回ATD+OK
receive[6]='
/*串口接收*/
voidser()interrupt4//串行口中断子函数
if(RI==1)//中断允许标志位,为0时允许
receive[b]=SBUF;
b++;
RI=0;
}
4.1系统仿真电路图
4.2仿真结果分析
根据仿真的结果,设计的电路符合实验的要求
通过这次课程设计,Keilc51软件工作环境的熟悉以及掌握基本的操作,实现电路原理图的绘制及电路仿真的实现,我还认识到理论与实际相结合的重要性,理论知识再丰富,没有实际的操作经验是不行的,这样还可以锻炼我们的实际动手操作能力和独立思考能力。
单片机知识在电子领域越来越重要了,在这次课程设计中我又了解了更多单片机的知识,从而也对单片机仿真软件产生了兴趣,学到了书上没有的东西,为以后工作又做了一层铺垫。
在课程设计过程中遇到的一些问题,通过查询资料和结合平时学到的知识,当然还有和同学的讨论得到了解决。
6、参考文献
1.何桥主编;
段清明、邱春玲副主编;
单片机原理及应用;
中国铁道出版社;
2008年1月;
2.张毅刚,彭喜源,谭晓昀,曲春波;
MCS-51单片机原理设计.2版;
哈尔滨工业出版社;
1997;
3.赵晓安;
MCS-51单片机原理及应用;
天津大学出版社;
2001