📄 mt8870.c
字号:
/*=======================================================================
基于DTMF制式的来电显示设计(暂时不支持FSK模式) YRF_2005/7
-------------------------------------------------------------------------
以下硬件组成:
MCU:51内核各系列单片机
DTMF双音频信号解码芯片:MT8870
显示:带中文字库的128*64点阵形液晶模块
(注:MCU使用12M晶振,以本C51程序的算法,编译后,程序约占用2K字节,
电话本每组约占用20~40字节,每组信息包括电话号码,姓名,单位)
===============================================================*/
#include <AT89X52.H> //头文件
#include <intrins.h>
#include <stdio.h>
//引脚定义-------------------------------------------------------
#define LCM_Data P0
#define LCM_RS P2_5 //定义LCM128*64引脚
#define LCM_RW P2_6
#define LCM_EN P2_7
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define STD P1_0 //定义MT8870引脚
#define b1 P1_4
#define b2 P1_3
#define b3 P1_2
#define b4 P1_1
#define Bell P3_5 //蜂鸣器
#define key1 P2_4 //键盘1
#define key2 P2_3 //键盘2
//数据类型--------------------------------------------------------
unsigned char Number = 0; //单个音频号码
unsigned long TEL = 0; //完整电话号码
unsigned char Receiving=0; //正在接收来电号码识别定义
unsigned char Receiving2=0; //拨号识别定义
unsigned char Record=1; //是否有记录识别定义
unsigned char Record2=1; //是否有记录识别定义
unsigned char k=0; //K用于控制拨号的显示范围
unsigned char ReadStatusLCM(void); //读数据从LCD
//----------------------------------------------------------------
unsigned char code Test[] = {"1234567890ABCDEF"};
//各功能函数----------------------------------------------------------
void Signal_CID_Start(); //来电DTMF音频信号"D"启动
void Signal_CID_END(); //来电DTMF音频信号"C"结束
void Signal_Read(); //读取DTMF音频信号
void Signal_BoHao_Start(); //拨号
//LCM功能函数---------------------------------------------------------
void LCMInit(void); //LCD初始化
void WriteDataLCM(unsigned char WDLCM); //写数据到DDRAM,写入ASCII码即显示单个字符,如0x41是A)
void WriteCommandLCM(unsigned char WCLCM,BuysC); //写指令到LCM,BuysC为"1"为检测忙信号
void Display_XY(unsigned char X, unsigned char Y); //用于128x64光标定位
//说明:第一行从(0,0)到(7,0),第二行(0,1)~(7,1),第三行(8,0)~(15,0),第四行(8,1)~(15,1)
void Display( unsigned char code *DData); //直接写入字符串
void Delay(unsigned int delay); //延时,微妙级,0~65535
void Delay_S(unsigned char delay1); //延时,秒级,0~65535
//---------------------------------------------------------------------------
//==========主函数===========================================================
main()
{
Delay(2000); //启动等待,等LCM进入工作状态
LCMInit(); //LCM初始化
//---------显示开机信息(第一屏)----------------------------
Display_XY(0,0); Display("┌──────┐"); //光标定位第二行第一列,//显示字符串
Display_XY(0,1); Display("│中文来电显示┃");
Display_XY(8,0); Display("└━━━━━━┛");
Display_XY(8,1); Display("YRF 2005-7-14");
Delay_S(5); //延时几秒
WriteCommandLCM(0x01,1); //显示清屏,CLS
Bell=0;
Delay(600);
Bell=1;
Delay(14000);
Bell=0;
Delay(600); //响铃
Bell=1;
//---------开机信息(第二屏)-----------------------------------------
//进入正常待机状态----------------------------------------------------
Display_XY(0,0); Display("来电: 【待机】"); //光标定位第一行第三列
Display_XY(0,1); Display("单位: ┄┄┄┄┄");
Display_XY(8,0); Display("姓名: ┄┄┄┄┄");
Display_XY(8,1); Display("备注: ┄┄┄┄┄");
Display_XY(7,0); //光标定位第一行第八列
//-------------------------------------------------------------------
while(1) //进入来电信号和拨号信号扫描
{
if (key1==0) //按键盘1进入查询电话号码功能。
{
Display_XY(0,0); Display(" 【查询号码】 ");
Display_XY(0,1); Display(" 请按 * 键,再");
Display_XY(8,0); Display("输入电话号码,最");
Display_XY(8,1); Display("后按 #号键结束。");
while(1)
{
if (STD==1) //如果检测到有DTMF音频
{
_nop_();
Signal_Read(); //读取DTMF号码值
if (Number==11) //如果是信号"*",则开始读电话号码
{
TEL=0; //号码清零
Receiving=1 ; //接收识别开始
Receiving2=0; //拨号识别复位
WriteCommandLCM(0x0D,1); // 显示开及光标设置,0x0C关光标,0x0D开光标,0x0E光标不闪
Display_XY(2,0); //光标定位"查询"后面
Display_XY(0,0); Display("查询: ");
Display_XY(0,1); Display(" ");
Display_XY(8,0); Display("注:按 #号键结束");
Display_XY(8,1); Display(" 按* 键重新输入");
Display_XY(2,0); //光标定位"查询"后面
Display(":");
Signal_CID_Start(); //开始读取完整来电号码
}
else if ( Number==12) //如果信号是"#"
{
Signal_CID_END();break;
}
else Signal_CID_Start(); //继续读取号码
}
}
}
if (STD==1) //如果检测到有DTMF音频
{
_nop_();
Signal_Read(); //读取DTMF号码值
if (Number==13) //如果是信号"D",则开始读来电电话号码
{
TEL=0; //号码清零
Receiving=1 ; //接收识别开始
Receiving2=0; //拨号识别复位
Bell=0; //开蜂鸣器提示音
//------------------以下刷屏--------------------------
WriteCommandLCM(0x01,1); //显示清屏,CLS
WriteCommandLCM(0x0D,1); // 显示开及光标设置,0x0C关光标,0x0D开光标,0x0E光标不闪
Display_XY(0,0);
Display("来电:");
Display_XY(1,1); Display("┌────┐");
Display_XY(9,0); Display("│接收中…┃");
Display_XY(9,1); Display("└━━━━┛");
//------------------以上刷屏--------------------------
Display_XY(2,0); //光标定位"来电"后面
Display(":");
Signal_CID_Start(); //开始读取完整来电号码
}
else if ( Number==14) //如果信号是"C"
{
Signal_CID_END();
}
else Signal_CID_Start(); //继续读取号码
}
}
}
//----------主函数结束------------------------------------------
//读取完整来电号码===============================================
void Signal_CID_Start()
{
Signal_Read(); //读取一个号码
if (Receiving==0 ) //如果不是正在接收,即正在拨号
{
if(Receiving2==0) //如果是首次拨号
{
k=0;
WriteCommandLCM(0x0D,1); // 显示开及光标设置,0x0C关光标,0x0D开光标,0x0E光标不闪
if(Record2==0) //如果来电没有记录
{ Display_XY(0,1); Display(" "); } //清空这行
Display_XY(8,0); Display("拨号: ");
Display_XY(8,1); Display(" ");
Display_XY(8,1);
Receiving2=1; //注明已经拨号
}
if (k>15) //如果显示一行已满
{
k=0;
Display_XY(8,1); //循环显示
Receiving2=1; //注明已经拨号
}
Signal_BoHao_Start(); //
Receiving2=1;
}
if (Receiving==1 ) //如果是正在接收
{
switch (Number) //判断电话号码
{
case 14: Signal_CID_END(); break; //信号"C"
case 1: WriteDataLCM(0x31); TEL=TEL*10+Number ; break;
case 2: WriteDataLCM(0x32); TEL=TEL*10+Number ; break;
case 3: WriteDataLCM(0x33); TEL=TEL*10+Number ; break;
case 4: WriteDataLCM(0x34); TEL=TEL*10+Number ; break;
case 5: WriteDataLCM(0x35); TEL=TEL*10+Number ; break;
case 6: WriteDataLCM(0x36); TEL=TEL*10+Number ; break;
case 7: WriteDataLCM(0x37); TEL=TEL*10+Number ; break;
case 8: WriteDataLCM(0x38); TEL=TEL*10+Number ; break;
case 9: WriteDataLCM(0x39); TEL=TEL*10+Number ; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -