標題:
51單片機電話鍵盤撥號
[打印本頁]
作者:
593719
時間:
2017-12-27 21:45
標題:
51單片機電話鍵盤撥號
#include<reg51.h> // 包含單片機寄存器的頭文件
#include<intrins.h>//包含_nop_()函數(shù)定義的頭文件
typedef unsigned int uint;
typedef unsigned char uchar;
uchar temp;
uchar key=16;
sbit rs=P2^0; //LCD1602數(shù)據(jù)/命令選擇
sbit rw=P2^1; //LCD1602讀/寫選擇
sbit lcden=P2^2; //LCD1602使能端
uchar idata table[18]="ATD+86";
uchar idata table[18]; //LCD1602所顯示的號碼緩存數(shù)組
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發(fā)送,num表示table[]第幾位
#define delayNOP();{_nop_();_nop_();_nop_();_nop_();};//宏定義,方便寫代碼
/*延時子程序*/
void delay(uchar x)
{
uchar i;
while(x--)
{
for(i=0;i<125;i++)
{
{;}
}
}
}
/*檢查LCD忙狀態(tài) */
/*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數(shù)據(jù) */
bit busy()//LCD忙檢測
{
bit result;
rs=0;
rw=1;
lcden=1;
delayNOP();
result=(bit)(P0&Ox80);
lcden=0;
return result;
}
/*寫指令數(shù)據(jù)到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); //數(shù)據(jù)指針=80+地址變量
}
/*寫顯示數(shù)據(jù)到LCD RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。*/
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位數(shù)據(jù)
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]; //顯示輸入數(shù)據(jù)
while(!TI); //等特數(shù)據(jù)傳送
TI=0; //清除數(shù)據(jù)傳送標志
a++;
}
else
{ //發(fā)送下一位字符
tab[a]=SBUF=erro[a]; //顯示輸入數(shù)據(jù)
while(!TI); //等特數(shù)據(jù)傳送
TI=0; //清除數(shù)據(jù)傳送標志
a++;
}
}
}
}
/* 串口初始化 */
void uart_int()
{
TMOD=0x20; //工作方式2,為常數(shù)自動重新裝入的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]; //串口發(fā)送
while(!TI); //等特數(shù)據(jù)傳送(TI發(fā)送中斷標志)
TI=0; //清除數(shù)據(jù)傳送標志
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 //串行口中斷子函數(shù)
{
if(RI==1) //中斷允許標志位,為0時允許
{
receive[ b]=SBUF;
b++;
RI=0;
}
}
復制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1