📄 bo hao.c
字号:
/*******************************************************************/
/* */
/* ME500B片机开发系统演示程序 - 电话拨号器 */
/* */
/* LCD1602显示 */
/* */
/* 版本: V1.0 (2006/11/20) */
/* 作者: gguoqing (Email: gguoqing@willar.com) */
/* 网站: www.willar.com(伟纳电子) www.mcusj.com(伟纳单片机世界) */
/* 邮箱: support@willar.com */
/* */
/*【版权】Copyright(C)伟纳电子 www.willar.com All Rights Reserved */
/*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息! */
/* */
/*******************************************************************/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit BEEP = P3^7; //蜂鸣器驱动线
uchar dis_buf=0x00; //显示缓存
uchar dis_buf1[ ] = {0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00};
//电话号码存储单元
uchar temp,m;
uchar key,keynum; //键顺序吗
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
sbit MT_RS = P2^3;
sbit MT_RW = P2^4;
sbit MT_CS = P2^5;
sbit MT_CK = P2^6;
sbit TEL = P2^7; //电话摘挂机控制线
uchar code cdis1[ ] = {"TELEPHONE DIALER"};
uchar code cdis2[ ] = {"TEL: "};
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*************************************************************
* *
* 延时子程序 *
* 晶振 11.0592MHz 延时为1ms *
* *
*************************************************************/
void delay(uint x)
{ uchar j;
while((x--)!=0)
{
for(j=0;j<115;j++)
{;}
}
}
/*************************************************************
* *
*检查LCD忙状态 *
*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据 *
* *
*************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*************************************************************
* *
*写指令数据到LCD *
*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 *
* *
*************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/************************************************************
* *
*写显示数据到LCD *
*RS=H,RW=L,E=高脉冲,D0-D7=数据。 *
* *
************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/************************************************************
* *
* LCD初始化设定 *
* *
************************************************************/
void lcd_init()
{
delay(15);
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
/************************************************************
* *
* 设定显示位置 *
* *
************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/************************************************************
* *
* 矩阵键盘扫描函数 *
* 键值保存在key *
* *
************************************************************/
uchar keyscan(void)
{
P1=0x0F; //低四位输入
delay(1);
temp=P1; //读P1口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1)
key=0;
else if(temp==2)
key=1;
else if(temp==4)
key=2;
else if(temp==8)
key=3;
else
key=16;
P1=0xF0; //高四位输入
delay(1);
temp=P1; //读P1口
temp=temp&0xF0;
temp=~((temp>>4)|0xF0);
if(temp==1)
key=key+0;
else if(temp==2)
key=key+4;
else if(temp==4)
key=key+8;
else if(temp==8)
key=key+12;
else
key=16;
return(key);
}
/************************************************************
* *
* 延时 x*0.14ms *
* *
************************************************************/
void delay0(uchar x)
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
/************************************************************
* *
* 蜂鸣器响一声 *
* *
************************************************************/
void beep()
{
unsigned char i;
for (i=0;i<180;i++)
{
delay0(6);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay(250); //延时
}
/************************************************************
* *
* 键入电话号码函数 *
* *
************************************************************/
void key_input ()
{
P1=0xF0;
if(P1!=0xF0) //判是否有健按下
{
keyscan();
beep();
if(key==0x0f) //是否为发送键
return;
if(key==0) //0转换为电话码"a"
key=0x0a;
dis_buf1[keynum]=key; //健值送存储单元
dis_buf =dis_buf1[keynum]; //健值送显示单元
if(dis_buf==0x0a) //数据转换
dis_buf=0x00;
dis_buf = dis_buf & 0x0f;
if(dis_buf>9) //转换为ASCII码
dis_buf = dis_buf+0x37;
else
dis_buf = dis_buf+0x30;
lcd_pos(0x44+keynum);
lcd_wdat(dis_buf); //显示健值
keynum++; //按键次数计数
}
}
/*************************************************************
* *
* MT8880 写状态函数 *
* RS=1,RW=0,写状态寄存器 *
* *
*************************************************************/
void write_status(uchar value)
{
MT_RS=1;
MT_RW =0;
MT_CK =0;
P1 = value; //写 8880CRA和CRB.
MT_CK =1;
delayNOP();
MT_CK =0;
}
/*************************************************************
* *
* MT8880 初始化函数 *
* *
*************************************************************/
void MT_INIT()
{
MT_CS=0; //MT8880使能
delayNOP();
write_status(0x10); //写 8880CRA,CRA=0000.
write_status(0x10); //写 8880CRA,CRA=0000.
write_status(0x18); //写 8880CRA,CRA=1000,允许选择CRB.
write_status(0x10); //写 8880CRB,CRB=0000
MT_CS=1; //禁止MT8880工作
}
/*************************************************************
* *
* MT8880 发码程序 *
* *
* RS=1,RW=0,写状态寄存器 *
* RS=1,RW=1,读状态寄存器 *
* RS=0,RW=0,写发送寄存器 *
* *
*************************************************************/
void MT_TRAN()
{
uchar i;
lcd_pos(0x40); //设置显示位置为第二行
for(m=0;m<16;m++)
lcd_wdat(cdis2[m]);
MT_CS=0;
delayNOP();
write_status(0x1d); //写 8880CRA,CRA=1101.
write_status(0x10); //写 8880CRB,CRB=0000.
//8880模式2为TONE,DTMF,IRQ,BURST
MT_RS=0; //写发送寄存器
MT_RW =0;
MT_CK =0;
for(i=0;i<keynum;i++)
{
dis_buf1[i]=dis_buf1[i]&0x0f; //取数据低4位
P1 = dis_buf1[i];
MT_CK =1; //发送号码
delayNOP();
MT_CK =0;
if(dis_buf1[i]==0x0a)
dis_buf1[i]=0x00;
dis_buf1[i]=dis_buf1[i]+0x30; //转换为ASCII码
lcd_pos(0x44+i);
lcd_wdat(dis_buf1[i]); //显示拨号码
delay(300); //调整拨号速率
}
MT_CS=1;
}
/************************************************************
* *
* 主程序 *
* *
************************************************************/
void main()
{
P0=0xFF; //置P0口
P2=0xFF; //置P2口
delay(10); //延时
MT_CS=1; //禁止MT8880工作
lcd_init(); //初始化LCD
lcd_pos(0); //设置显示位置为第一行
for(m=0;m<16;m++)
lcd_wdat(cdis1[m]);
lcd_pos(0x40); //设置显示位置为第二行
for(m=0;m<16;m++)
lcd_wdat(cdis2[m]);
while(1)
{
key_input(); //输入拨号号码
if(key==0x0f) //拨号
{
TEL = 0; //摘机
delay(2000); //延时等待拨号音出现
MT_INIT(); //MT8880初始化
MT_TRAN(); //MT8880拨号
delay(5000); //调整在线时间
delay(5000);
delay(5000);
TEL = 1; //挂机
MT_CS=1; //禁止MT8880工作
key=0x00;
keynum=0x00;
lcd_pos(0x40); //设置显示位置为第二行
for(m=0;m<16;m++)
lcd_wdat(cdis2[m]);
delay(1000);
}
}
}
/************************************************************
使用说明:
先使用矩阵键盘输入你要拨的电话号码,LCD显示你输入的电话
号码,可以输入12位。检查号码输入无误后,按"F"健即可进行拨号。
************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -