标题:
51单片机电话键盘拨号
[打印本页]
作者:
593719
时间:
2017-12-27 21:45
标题:
51单片机电话键盘拨号
#include<reg51.h> // 包含单片机寄存器的头文件
#include<intrins.h>//包含_nop_()函数定义的头文件
typedef unsigned int uint;
typedef unsigned char uchar;
uchar temp;
uchar key=16;
sbit rs=P2^0; //LCD1602数据/命令选择
sbit rw=P2^1; //LCD1602读/写选择
sbit lcden=P2^2; //LCD1602使能端
uchar idata table[18]="ATD+86";
uchar idata table[18]; //LCD1602所显示的号码缓存数组
uchar idata table_int[18]="ATD+86";
uchar idata receive[7];
uchar idata erro[7]="erronum";
uchar num=6,a=0,b=0; //b接收,a发送,num表示table[]第几位
#define delayNOP();{_nop_();_nop_();_nop_();_nop_();};//宏定义,方便写代码
/*延时子程序*/
void delay(uchar x)
{
uchar i;
while(x--)
{
for(i=0;i<125;i++)
{
{;}
}
}
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据 */
bit busy()//LCD忙检测
{
bit result;
rs=0;
rw=1;
lcden=1;
delayNOP();
result=(bit)(P0&Ox80);
lcden=0;
return result;
}
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
void lcd_com(uchar cmd)
{
while(busy());
rs=0;
rw=0;
lcden=0;
_nop_();
P0=cmd;
delayNOP();
lcden=1;
delayNOP();
lcden=0;
}
void lcd_pos(uchar pos)
{ //设定显示位置
lcd_com(pos|0x80); //数据指针=80+地址变量
}
/*写显示数据到LCD RS=H,RW=L,E=高脉冲,D0-D7=数据。*/
void lcd_dat(uchar dat)
{
while(busy());
rs=1;
rw=0;
lcden=0;
P0=dat;
delayNOP();
lcden=1;
delayNOP();
lcden=0;
}
/*LCD初始化设定*/
void lcd_init()
{
delay(15);
lcd_com(0x38);//16*2显示,5*7点阵,8位数据
delay(5);//延时
lcd_com(ox38);
delay(5);
lcd_com(ox38);
delay(5);
lcd_com(0x0c); //显示开,关光标
delay(5);
lcd_com(0x38); //移动光标
delay(5);
lcd_com(0x38); //清除LCD的显示内容
delay(5);
}
/* LCD 显示 */
void display()
{
uchar a=0;
lcd_pos(0);
delay(30);
while(table[a]!='\0'); //判断下一位是否为空
{
lcd_dat(table[a]); //显示字符
a++;
if(a==16)
{
lcd_pos(0x40); //设置显示位置为第二行第1个字符
}
}
}
void keyscan()
{
temp=0;
P1=0xf0; //高四位输入 行为高电平 列为低电平
delay(50);
temp=P1;
temp=temp&0xf0; //屏蔽低四位
temp=~((temp>>4)0|xF0);
if(temp==1) //p1.4被拉低
key=0;
else if(temp==2) //p1.5被拉低
key=1;
else if(temp==4) //p1.6被拉低
key=2;
else if(temp==8) //p1.7被拉低
key=3;
else
key=16;
P1=0x0f; //低四位输入 列为高电平 行为低电平
delay(50);
temp=P1; //读P1口
temp=temp&0xf0;
temp=~(temp|0xf0);
if(temp==2) //p1.1被拉低
key=key+0;
else if(temp==4) //p1.2被拉低
key=key+4;
else if(temp==8) //p1.3被拉低
key=key+8;
else
key=16;
P1=0x0f;
temp=P1;
if(key==0) //以下是判断按键,显示相应的号码
{
table[num]='1';
num++;
}
if(key==1)
{
table[num]='2';
num++;
}
if(key==2)
{
table[num]='3';
num++;
}
if(key==3)
{
table[num]='4';
num++;
}
if(key==4)
{
table[num]='5';
num++;
}
if(key==5)
{
table[num]='6';
num++;
}
if(key==6)
{
table[num]='7';
num++;
}
if(key==7)
{
table[num]='8';
num++;
}
if(key==8)
{
table[num]='9';
num++;
}
if(key==9)
{
table[num]='0';
num++;
}
if(key==10)
{
table[--num]='\0'; //删除上一位
lcd_com(oxo1); //清除LCD的所有显示内容
}
if(key==11)
{
while(table[a]!='\0')
{
if(num==17)
{
tab[a]=SBUF=table[a]; //显示输入数据
while(!TI); //等特数据传送
TI=0; //清除数据传送标志
a++;
}
else
{ //发送下一位字符
tab[a]=SBUF=erro[a]; //显示输入数据
while(!TI); //等特数据传送
TI=0; //清除数据传送标志
a++;
}
}
}
}
/* 串口初始化 */
void uart_int()
{
TMOD=0x20; //工作方式2,为常数自动重新装入的8位定时器
TH1=0xf3; //装定时器初值
TL1=0xf3;
TR1=1; //开启定时器1
SM0=0; //串口方式0
SM1=1; //串口方式1
REN=1; //允许接收
ES=1; //是开启串口中断
EA=1; //开中断总开关
}
void main()
{
uart_int();
lcd_int();
while(num<=17)
{
keyscan(); //键盘扫描
display(); //LCD显示
if(receive[4]=='E') //判断PC机返回的是否是ATD+ERR
{
P2=0xfe;
while(tab[a]!='\0')
{
SBUF=tab[a]; //串口发送
while(!TI); //等特数据传送(TI发送中断标志)
TI=0; //清除数据传送标志
a++; //下一个字符
}
a=0;
receive[4]='\0'; // PC机返回ATD+OK
}
else if(receive[4]=='0') //判断PC机返回的是否是ATD+OK
{
P2=0xfd;
receive[4]='\0';
}
if((receive[5]='K'||(receive[6]=='R')) //判断PC机返回的是否是ATD+K或ATD+R
{
b=0;
receive[5]='\0'; //PC机返回ATD+OK
receive[6]='\0';
}
}
}
/* 串口接收 */
void ser() interrupt 4 //串行口中断子函数
{
if(RI==1) //中断允许标志位,为0时允许
{
receive[ b]=SBUF;
b++;
RI=0;
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1