⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bo hao.c

📁 用89S52作的远程序电话拨号系统
💻 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 + -