找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1888|回复: 0
收起左侧

基于51单片机的医院病房紧急呼叫系统(无线+语音)

[复制链接]
ID:582867 发表于 2019-7-17 19:25 | 显示全部楼层 |阅读模式
本帖最后由 杜安安 于 2019-7-17 19:26 编辑

#include < reg52.h >
#include < intrins.h >
#define uchar unsigned char
#define uint  unsigned int
void  Ok_Menu ();
void data_chuli();
void fangyin(uchar addr);
void ISD4004_Stop();
void ISD4004_Powerdown();
//bit result  ;
uchar data chs;
sbit LCD_RS = P2^5 ;            
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^7 ;
sbit Led=P3^0;
sbit sendd=P2^4;

sbit add=P3^7;         //上翻
sbit sub=P3^6;         //下翻                                                                                                   
sbit affirm=P3^5; //应答
uchar code  cdis1[ ] = {"         "} ;
unsigned char data  shuju_sbit[6] ={0x00,0x00,0x00,0x00,0x00,0x00} ;
uchar data shuju[][4]={  {0x00,0x00,0x00,0x00},//组号,房号(地址),次数,是否应答
                                         {0x01,0x00,0x00,0x00},
                                         {0x02,0x00,0x00,0x00},
                                         {0x03,0x00,0x00,0x00},
                                                 {0x04,0x00,0x00,0x00},                 
                                         {0x05,0x00,0x00,0x00},
                                         {0x06,0x00,0x00,0x00},
                                         {0x07,0x00,0x00,0x00}
                       };
/**********************************************
flag为组号标志                     flag1         为收到信号置位           flag5用来判断数据是否有效
flag3为 应答标志          flag2  用来判断是否为同一个病房呼叫         flag4 用来标志收到信号
********************************************/
uchar  flag2=0,flag=1,flag1,flag4,flag5,Flag_ReqSend,jieshou=0;
uint flag3;   
uint a=0;
uchar temp;
//语音所用的口        

sbit K_luying=P3^4;
sbit K_fangyin=P3^3;         
sbit K_Tingzhi=P3^1;

sbit ISD4004_SS=P1^4;          //语音
sbit ISD4004_MOSI=P1^5;
sbit ISD4004_SCLK=P1^6;
//sbit ISD4004_INT=P1^7;//  要换回来

code unsigned char table1[]={0,1,2,3,4,5,6,7,8,9,10,11}         ;

code unsigned char table[]={0x00,0x00,0x00,0x65,           //语音地址表
                            0x00,0xc9,0x01,0x2d,
                            0x01,0x91,0x01,0xf5,
                            0x02,0x59,0x02,0xbd,
                                   0x03,0x21,0x03,0x85,
                                   0x03,0xb7,0x03,0xe8,
                                    0x04,0x1a,0x04,0x4c,
                            0x04,0x7e,0x04,0xb0,
                                    0x04,0xe2,0x05,0x14,
                            0x05,0x46,0x05,0x78,
                                    0x05,0xaa,0x05,0xdc,
                            0x06,0x0e,0x06,0x40,
                                    0x06,0x72,0x06,0xa4,
                                    0x06,0xd6,0x07,0x08,
                                    0x07,0x3a,0x07,0x6c };

#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;

  void delay10ms(uchar hehe)
{
    uint i;
        for(hehe;hehe>0;hehe--)
                for(i=1240;i>0;i--);
}

/*******************************************************************/
void delay1(int ms)
{
unsigned char y ;
  while(ms--)
{
  for(y = 0 ; y<25; y++)
  {
   _nop_() ;
   _nop_() ;
   _nop_() ;
   _nop_() ;
  }
}
}

/******************************************************************/
/*检查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()
{
    delay1(15) ;   
    lcd_wcmd(0x01) ;      //清除LCD的显示内容            
    lcd_wcmd(0x38) ;      //16*2显示,5*7点阵,8位数据
    delay1(5) ;
    lcd_wcmd(0x38) ;         
    delay1(5) ;
    lcd_wcmd(0x38) ;         
    delay1(5) ;

    lcd_wcmd(0x0c) ;      //显示开,关光标
    delay1(5) ;
    lcd_wcmd(0x06) ;      //移动光标
    delay1(5) ;
    lcd_wcmd(0x01) ;      //清除LCD的显示内容
    delay1(5) ;
}

/*  设定显示位置                                    */
/*******************************************************************/
void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80) ;  //数据指针=80+地址变量
}

///数据位分离
void sbitseparate(uchar a,uchar b,uchar c,uchar d)
{
   shuju_sbit[0]=a;
   shuju_sbit[1]=b/10;                   //房号
   shuju_sbit[2]=b%10;
   shuju_sbit[3]=c/10;                        //次数
   shuju_sbit[4]=c%10;
   shuju_sbit[5]=d;
}
///显示数据
  void display(flag)
  {
           sbitseparate(shuju[flag][0],shuju[flag][1],shuju[flag][2],shuju[flag][3]);

       lcd_pos(0x03) ;            
     lcd_wdat(shuju_sbit[0]+'0') ;        //组号
       lcd_pos(0x05) ;            
     lcd_wdat(shuju_sbit[1]+0x30) ;        // 房号
       lcd_pos(0x06) ;            
     lcd_wdat(shuju_sbit[2]+0x30) ;        //
       lcd_pos(0x08) ;            
     lcd_wdat(shuju_sbit[3]+0x30) ;        //呼叫次数
           lcd_pos(0x09) ;            
     lcd_wdat(shuju_sbit[4]+0x30) ;        //
       lcd_pos(0x0B) ;            
     lcd_wdat(shuju_sbit[5]+0x30) ;        // 是否应答
  }


void fasong()
{
  Led=0;
  P2=0x00;
  EA=0;                  //保证数据发送完  
  P2=shuju[flag-1][1]&0x0f;         //要是这样就把sendd变为0了,没有电源就不能发送了
  sendd=1;
  delay10ms(10);//延时100ms
  sendd=0;                           
  EA=1;
  Led=1;
}


//数据初使化
void data_init()
{
  TCON = 0x00;        
  IT0=1;    //负边沿触发
  IE = 0x00;
  EA=1;        
  EX0=1;
  flag=1;
  Led=1;
  sendd=0;
Ok_Menu ();                                 
}

   void jieshou_dat()
   {
     uchar a,b,c,d;  
         Led=0;
        temp=P1&0x0f;
    delay10ms(50);
        Led=1;
    a=(temp<<3)&0x08;        //数据位的第四位和第一位反了,第二位和第三位反了
        b=(temp<<1)&0x04;
        c=(temp>>1)&0x02;
        d=(temp>>3)&0x01;
        temp=a|b|c|d;               
   }

//**************************************
// INT0中断
//**************************************
void int00(void) interrupt 0
                {
                       EX0=0;
                           jieshou_dat();
                           data_chuli();                         //有信号则进行对信号的处理        
                          // display(flag-1);
                           
                       EX0=1;        
                }
/**********************************************
                         对于有呼叫的时候对信号的处理
**************************************************/
void data_chuli()
{
   uchar i,j;
         if((0x00==temp)||(0x0f==temp))                 //防干扰
                goto  abc;
                  
                jieshou=1;

                if(0==shuju[0][0])
                 {
                  for(i=1;i<9;i++)
                    shuju[i-1][0]=shuju[i-1][0]+1;
                 }
                 
                                       
           for(i=1;i<8;i++)                                     //i从1到7变化         temp为收到的数据  对了
            {
                  if(shuju[i-1][1]==temp)                //判断呼叫的地址是否与已有的地址相同 即房号  ////////////////////////////////
                           {
                          flag=i;                    //保存地址相同的数组的标号
                          flag2=1;                        
                         }                                 
                }

          if(flag2==1)                                  //有地址相同就呼叫加一
             {
                    shuju[flag-1][2]=shuju[flag-1][2]+1;           //呼叫次数加1
                        shuju[flag-1][3]=0;                     //对应答进行清零
                        flag2=0;                                                                //标志清零
                 }
           else                                                //如果房号没有,数据往后移
            {
                          for(i=8;i>1;i--)                            //数据转移
                            for(j=1;j<4;j++)
                                      shuju[i-1][j]=shuju[i-2][j];
        
                //         for(i=1;i<4;i++)                             //测试用的移入数据,实际用时是传过来的数据(房号)
                            //  shuju[1][1]=temp;                        // 存入房号

                  flag=1;                        //当前显示呼叫的病房的信息
                          shuju[0][1]=temp;            //存入房号          /////////////////////////////////////////////////
                          shuju[0][2]=0x01;                 //呼叫次数存入1           不用对应答清零,初始化时就是0x00了
                }
                                                                  
           abc:        ;
}
/***************************************************
//         语音部分的程序
//
**************************************************/
//============================================================
//函数名称:void delay25ms()
//函数功能:延迟25ms
//日期:2007.03.31
//============================================================
void delay25ms()
{
    unsigned int i;
    for(i=0;i<=5000;i++);
}  


//===========================================================
//函数名称:void ISD4004_ISD4004_Send(unsigned char m)
//函数功能:给ISD4004送命令
//日期:2007.03.31
//===========================================================
void ISD4004_Send(unsigned char m)
{
    unsigned char i,j;
    for(i=0;i<8;i++)
    {
        ISD4004_SCLK = 0;
        for(j=0;j<5;j++);

        if(m&0x01)
            ISD4004_MOSI=1;
        else
            ISD4004_MOSI=0;

                ISD4004_SCLK=1;
        for(j=0;j<5;j++);
        m=m>>1;
    }
}


//===========================================================
//函数名称:void ISD4004_Powerup()
//函数功能:ISD4004上电
//日期:2007.03.31
//===========================================================
void ISD4004_Powerup()
{
    ISD4004_SS=0;                        //开片选
    ISD4004_Send(0x20);                  //上电:等待TPUD后器件可以工作
    delay25ms();
    ISD4004_SS=1;                        //关片选
}


//============================================================
//函数名称:void ISD4004_Stop()
//函数功能:ISD4004停止
//日期:2007.03.31
//============================================================
void ISD4004_Stop()
{
    ISD4004_SS=0;
    ISD4004_Send(0x30);                //停止当前操作
    ISD4004_SS=1;
}


//===========================================================
//函数名称:void ISD4004_Powerdown()
//函数功能:下电  停止并掉电
//日期:2007.03.31
//===========================================================
void ISD4004_Powerdown()
{
    ISD4004_SS=0;
    ISD4004_Send(0x10);
    ISD4004_SS=1;
}


//==========================================================
//函数名称:void ISD4004_Play(unsigned char addr_h,unsigned char addr_l)
//函数功能:放音
//日期:2007.03.31
//==========================================================
void ISD4004_Play(unsigned char addr_h,unsigned char addr_l)
{

    ISD4004_SS=0;
    ISD4004_Send(addr_l);
    ISD4004_Send(addr_h);
    ISD4004_Send(0xe0);           //从指定地址开始放音。
    ISD4004_SS=1;
        
    ISD4004_SS=0;
    ISD4004_Send(0xf0);          //从当前地址开始放音(直至EOM或OVF)
    ISD4004_SS=1;
}

//================================================================
//函数功能:录音
void ISD4004_Rec(unsigned char addr_h,unsigned char addr_l)
{
    ISD4004_SS=0;
    ISD4004_Send(addr_l);       //传送地址
    ISD4004_Send(addr_h);
    ISD4004_Send(0xa0);         //从指定地址开始录音。
    ISD4004_SS=1;

    ISD4004_SS=0;
    ISD4004_Send(0xb0);         //从当前地址开始录音(直至OVF或停止)
    ISD4004_SS=1;
}


//================================================================
//函数名称:void fangyin()
//函数功能:语音 addr为地址
//日期:2007.03.31
//================================================================
void fangyin(uchar addr)
{
    uchar a;
        Led=0;
    ISD4004_Powerup();
    delay25ms();
    a = addr * 2;   
    ISD4004_Play(table[a],table[a+1]);
        Led=1;   
}

//================================================================
//函数名称:void luyin()
//函数功能:语音 addr为地址
//日期:2007.03.31
//================================================================
void luyin(uchar addr)
{
    uchar a;
    ISD4004_Powerup();     //上电
    delay25ms();
        delay25ms();
    a = addr * 2;          //对地址进行处理
    ISD4004_Rec(table[a],table[a+1]);     
}


/**************************************
  键盘处理及相应的数据处理
***************************************/

void keyscan()
{                                                                          
    if(add==0)        //上翻
         {
           delay1(5);
                   while(!add) ;
                         flag++;
                         if(flag==9)
                          flag=1;
          }


         if(sub==0)                //下翻                           
          {
           delay1(5);  
                        while(!sub) ;
                        flag--;        
                        if(flag==0)
                          flag=8;                                                                          
           }
                                                           
         if(affirm==0)         //应答
         {
           delay1(5);
           while(!affirm);
                 flag3++;
        //         shuju[flag-1][3]=flag3%2;
           shuju[flag-1][3]=1;
                 fasong();
         }
         
             if(K_fangyin==0)               //放音
                 {        
                   delay1(5);
                   if(K_fangyin==0)
                    {          P1=0xff;
                        fangyin(a);
                           delay25ms();
                           delay25ms();
                         }                                                   
                  }                  

                if(K_luying==0)                        //录音
                  {                    
                         delay1(5);
                        if(K_luying==0)
                          {          P1=0xff;
                                 ISD4004_Powerup();
                                 delay25ms();
                             luyin(a);                                
                            }
                  }        

                 if(K_Tingzhi==0)
                  {         
                      delay1(5);
                   if(K_Tingzhi==0)
                      {     P1=0xff;
                              ISD4004_Stop();
                                  delay25ms();
                      ISD4004_Powerdown();
                          }
                  }         
}


void  Ok_Menu ()
{
    uchar  m ;
    lcd_init() ;                //初始化LCD

    lcd_pos(0) ;                //设置显示位置为第一行的第1个字符
     m = 0 ;
    while(cdis1[m] != '\0')
     {                         //显示字符
       lcd_wdat(cdis1[m]) ;
       m++ ;
     }
}




/* 主函数     */
/************************************/
void main()
{
   data_init();
        
  while(1)
  {         
   keyscan();
   if(1==jieshou)
   {         
                EA=0;  //防止中断影响语音
                     Led=0;                       //亮灯
                        fangyin(a);
                           delay25ms();
                           delay25ms();                                                         
                                 EA=1;         
                                 jieshou=0;
   }                           
   display(flag-1);
  }
}



二、从机程序:
#include<AT89X52.H>
#define uchar unsigned char
#define uint unsigned int
sbit sing=P2^7;
sbit key=P2^5;
sbit sendd=P1^4;//电源控制
sbit led=P2^6;
uchar temp=0x03;        //本机地址

uchar th[]={0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,
            0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,
            0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff};
uchar tl[]={0x8c,0x5b,0x15,0x67,0x04,0x90,0x0c,   //低音1-7
            0x44,0xac,0x09,0x34,0x82,0xc8,0x06,  //中音1-7
            0x22,0x56,0x85,0x9a,0xc1,0xe4,0x03}; // 高音1-7

uchar  i,timer;
uint a,sum=0;
uchar code song[]={10,12,                                           //2
                    13,13,13,13,13,13,13,15,14,13,12,10,12,  //16    13,13,13,
                    10,10,10,10,10,10,10,10,10,6,8,          //14  10,10,10,
                    9,9,9,9,9,9,9,10,9,8,9,8,7,                 //16    9,9,9,
                    6,6,6,6,6,6,6,6,6,6,          //14     6,6,6,6,
                    6,6,10,10,10,10,9,8,7,7,8,8,7,7,6,5,             //16
                    6,6,6,6,6,6,6,6,6,6,         //14      6,6,6,6,
                    8,8,8,8,6,8,9,9,9,9,10,11,10,9,              //16  8,8,
                    10,10,10,10,10,10,10,10,10,12,       //14   10,10,10,10,
                    13,13,13,13,12,10,9,9,9,9,8,9,         //16  9,9,13,13,   4*30+2
                    10,10,10,10,9,10,6,6,6,6,6,          //16  10,10,6,6,6,
                    7,7,7,6,5,5,7,7,7,7,5,3,8,8,7,7,             //16
                                         //14 6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,                 //16
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,   //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,      //16   10,10,
                    8,6,6,6,6,6,6,6,10,9,10,10,10,10,12,13,           //16
                    10,9,10,10,10,10,10,10,10,10,10,10,    //16  10,10,10,10,
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,     //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,         //16  10,10,   160-2
                    8,6,6,6,6,6,6,6,10,9,10,10,10,10,12,13,             //16
                    10,9,10,10,10,10,10,10,10,                //12   10,10,10,
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,      //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,         //16   10,10,
                    8,6,6,6,6,6,6,6,8,6,6,6,6,6,6,6,                    //16
                    10,9,10,10,10,10,10,9,10,10,10,10,      //16  110,10,0,10,
                    10,10,12,12,12,12,5,5,                            //8
                    6,6,6,6,6,6,6,6              //12    ,6,6,6,6 160-32
                    };//歌谱       408-64  


void delay10ms(uchar hehe)
{
    uint i;
        for(hehe;hehe>0;hehe--)
                for(i=1240;i>0;i--);
}


  void send()
{        
    P0=0x00;
          led=0;
        sendd=1;
    P0=temp&0x0f;
    delay10ms(10);//延时50ms
    sendd=0;                        
    led=1;
}

void dat_init()
{
    sing=1;          //变量初始化
    timer=0;
    i=1;
    a=0;
    sendd=0;
            
    TH1=(65536-50000)/256;   //定时器1初始化
    TL1=(65536-50000)%256;

        TCON = 0x00;
    TMOD=0x11;  //两个定时器都工作在方式1
    IT0=1;    //负边沿触发
    EA=1;    //开总中断
    ET0=1;   //定时器允许
    ET1=1;
        EX0=1;
}



void main()           //主函数
{   
    dat_init();
    while(1)
    {           sendd=0;
                 if(0==key)
                  {         delay10ms(5);
                     while(!key);
                     send();
                   }
        }      
}


void time1() interrupt  1     //定时器0中断作音频控制器   
{
    TH0=th[i-1];
    TL0=tl[i-1];
    sing=!sing;
        sum++;
        if(15000==sum)
        {
                   TR0=0;   //关定时器中断   #include < reg52.h >
#include < intrins.h >
#define uchar unsigned char
#define uint  unsigned int
void  Ok_Menu ();
void data_chuli();
void fangyin(uchar addr);
void ISD4004_Stop();
void ISD4004_Powerdown();
//bit result  ;
uchar data chs;
sbit LCD_RS = P2^5 ;            
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^7 ;
sbit Led=P3^0;
sbit sendd=P2^4;

sbit add=P3^7;         //上翻
sbit sub=P3^6;         //下翻                                                                                                   
sbit affirm=P3^5; //应答
uchar code  cdis1[ ] = {"         "} ;
unsigned char data  shuju_sbit[6] ={0x00,0x00,0x00,0x00,0x00,0x00} ;
uchar data shuju[][4]={  {0x00,0x00,0x00,0x00},//组号,房号(地址),次数,是否应答
                                         {0x01,0x00,0x00,0x00},
                                         {0x02,0x00,0x00,0x00},
                                         {0x03,0x00,0x00,0x00},
                                                 {0x04,0x00,0x00,0x00},                 
                                         {0x05,0x00,0x00,0x00},
                                         {0x06,0x00,0x00,0x00},
                                         {0x07,0x00,0x00,0x00}
                       };
/**********************************************
flag为组号标志                     flag1         为收到信号置位           flag5用来判断数据是否有效
flag3为 应答标志          flag2  用来判断是否为同一个病房呼叫         flag4 用来标志收到信号
********************************************/
uchar  flag2=0,flag=1,flag1,flag4,flag5,Flag_ReqSend,jieshou=0;
uint flag3;   
uint a=0;
uchar temp;
//语音所用的口        

sbit K_luying=P3^4;
sbit K_fangyin=P3^3;         
sbit K_Tingzhi=P3^1;

sbit ISD4004_SS=P1^4;          //语音
sbit ISD4004_MOSI=P1^5;
sbit ISD4004_SCLK=P1^6;
//sbit ISD4004_INT=P1^7;//  要换回来

code unsigned char table1[]={0,1,2,3,4,5,6,7,8,9,10,11}         ;

code unsigned char table[]={0x00,0x00,0x00,0x65,           //语音地址表
                            0x00,0xc9,0x01,0x2d,
                            0x01,0x91,0x01,0xf5,
                            0x02,0x59,0x02,0xbd,
                                   0x03,0x21,0x03,0x85,
                                   0x03,0xb7,0x03,0xe8,
                                    0x04,0x1a,0x04,0x4c,
                            0x04,0x7e,0x04,0xb0,
                                    0x04,0xe2,0x05,0x14,
                            0x05,0x46,0x05,0x78,
                                    0x05,0xaa,0x05,0xdc,
                            0x06,0x0e,0x06,0x40,
                                    0x06,0x72,0x06,0xa4,
                                    0x06,0xd6,0x07,0x08,
                                    0x07,0x3a,0x07,0x6c };

#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;

  void delay10ms(uchar hehe)
{
    uint i;
        for(hehe;hehe>0;hehe--)
                for(i=1240;i>0;i--);
}

/*******************************************************************/
void delay1(int ms)
{
unsigned char y ;
  while(ms--)
{
  for(y = 0 ; y<25; y++)
  {
   _nop_() ;
   _nop_() ;
   _nop_() ;
   _nop_() ;
  }
}
}

/******************************************************************/
/*检查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()
{
    delay1(15) ;   
    lcd_wcmd(0x01) ;      //清除LCD的显示内容            
    lcd_wcmd(0x38) ;      //16*2显示,5*7点阵,8位数据
    delay1(5) ;
    lcd_wcmd(0x38) ;         
    delay1(5) ;
    lcd_wcmd(0x38) ;         
    delay1(5) ;

    lcd_wcmd(0x0c) ;      //显示开,关光标
    delay1(5) ;
    lcd_wcmd(0x06) ;      //移动光标
    delay1(5) ;
    lcd_wcmd(0x01) ;      //清除LCD的显示内容
    delay1(5) ;
}

/*  设定显示位置                                    */
/*******************************************************************/
void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80) ;  //数据指针=80+地址变量
}

///数据位分离
void sbitseparate(uchar a,uchar b,uchar c,uchar d)
{
   shuju_sbit[0]=a;
   shuju_sbit[1]=b/10;                   //房号
   shuju_sbit[2]=b%10;
   shuju_sbit[3]=c/10;                        //次数
   shuju_sbit[4]=c%10;
   shuju_sbit[5]=d;
}
///显示数据
  void display(flag)
  {
           sbitseparate(shuju[flag][0],shuju[flag][1],shuju[flag][2],shuju[flag][3]);

       lcd_pos(0x03) ;            
     lcd_wdat(shuju_sbit[0]+'0') ;        //组号
       lcd_pos(0x05) ;            
     lcd_wdat(shuju_sbit[1]+0x30) ;        // 房号
       lcd_pos(0x06) ;            
     lcd_wdat(shuju_sbit[2]+0x30) ;        //
       lcd_pos(0x08) ;            
     lcd_wdat(shuju_sbit[3]+0x30) ;        //呼叫次数
           lcd_pos(0x09) ;            
     lcd_wdat(shuju_sbit[4]+0x30) ;        //
       lcd_pos(0x0B) ;            
     lcd_wdat(shuju_sbit[5]+0x30) ;        // 是否应答
  }


void fasong()
{
  Led=0;
  P2=0x00;
  EA=0;                  //保证数据发送完  
  P2=shuju[flag-1][1]&0x0f;         //要是这样就把sendd变为0了,没有电源就不能发送了
  sendd=1;
  delay10ms(10);//延时100ms
  sendd=0;                           
  EA=1;
  Led=1;
}


//数据初使化
void data_init()
{
  TCON = 0x00;        
  IT0=1;    //负边沿触发
  IE = 0x00;
  EA=1;        
  EX0=1;
  flag=1;
  Led=1;
  sendd=0;
Ok_Menu ();                                 
}

   void jieshou_dat()
   {
     uchar a,b,c,d;  
         Led=0;
        temp=P1&0x0f;
    delay10ms(50);
        Led=1;
    a=(temp<<3)&0x08;        //数据位的第四位和第一位反了,第二位和第三位反了
        b=(temp<<1)&0x04;
        c=(temp>>1)&0x02;
        d=(temp>>3)&0x01;
        temp=a|b|c|d;               
   }

//**************************************
// INT0中断
//**************************************
void int00(void) interrupt 0
                {
                       EX0=0;
                           jieshou_dat();
                           data_chuli();                         //有信号则进行对信号的处理        
                          // display(flag-1);
                           
                       EX0=1;        
                }
/**********************************************
                         对于有呼叫的时候对信号的处理
**************************************************/
void data_chuli()
{
   uchar i,j;
         if((0x00==temp)||(0x0f==temp))                 //防干扰
                goto  abc;
                  
                jieshou=1;

                if(0==shuju[0][0])
                 {
                  for(i=1;i<9;i++)
                    shuju[i-1][0]=shuju[i-1][0]+1;
                 }
                 
                                       
           for(i=1;i<8;i++)                                     //i从1到7变化         temp为收到的数据  对了
            {
                  if(shuju[i-1][1]==temp)                //判断呼叫的地址是否与已有的地址相同 即房号  ////////////////////////////////
                           {
                          flag=i;                    //保存地址相同的数组的标号
                          flag2=1;                        
                         }                                 
                }

          if(flag2==1)                                  //有地址相同就呼叫加一
             {
                    shuju[flag-1][2]=shuju[flag-1][2]+1;           //呼叫次数加1
                        shuju[flag-1][3]=0;                     //对应答进行清零
                        flag2=0;                                                                //标志清零
                 }
           else                                                //如果房号没有,数据往后移
            {
                          for(i=8;i>1;i--)                            //数据转移
                            for(j=1;j<4;j++)
                                      shuju[i-1][j]=shuju[i-2][j];
        
                //         for(i=1;i<4;i++)                             //测试用的移入数据,实际用时是传过来的数据(房号)
                            //  shuju[1][1]=temp;                        // 存入房号

                  flag=1;                        //当前显示呼叫的病房的信息
                          shuju[0][1]=temp;            //存入房号          /////////////////////////////////////////////////
                          shuju[0][2]=0x01;                 //呼叫次数存入1           不用对应答清零,初始化时就是0x00了
                }
                                                                  
           abc:        ;
}
/***************************************************
//         语音部分的程序
//
**************************************************/
//============================================================
//函数名称:void delay25ms()
//函数功能:延迟25ms
//日期:2007.03.31
//============================================================
void delay25ms()
{
    unsigned int i;
    for(i=0;i<=5000;i++);
}  


//===========================================================
//函数名称:void ISD4004_ISD4004_Send(unsigned char m)
//函数功能:给ISD4004送命令
//日期:2007.03.31
//===========================================================
void ISD4004_Send(unsigned char m)
{
    unsigned char i,j;
    for(i=0;i<8;i++)
    {
        ISD4004_SCLK = 0;
        for(j=0;j<5;j++);

        if(m&0x01)
            ISD4004_MOSI=1;
        else
            ISD4004_MOSI=0;

                ISD4004_SCLK=1;
        for(j=0;j<5;j++);
        m=m>>1;
    }
}


//===========================================================
//函数名称:void ISD4004_Powerup()
//函数功能:ISD4004上电
//日期:2007.03.31
//===========================================================
void ISD4004_Powerup()
{
    ISD4004_SS=0;                        //开片选
    ISD4004_Send(0x20);                  //上电:等待TPUD后器件可以工作
    delay25ms();
    ISD4004_SS=1;                        //关片选
}


//============================================================
//函数名称:void ISD4004_Stop()
//函数功能:ISD4004停止
//日期:2007.03.31
//============================================================
void ISD4004_Stop()
{
    ISD4004_SS=0;
    ISD4004_Send(0x30);                //停止当前操作
    ISD4004_SS=1;
}


//===========================================================
//函数名称:void ISD4004_Powerdown()
//函数功能:下电  停止并掉电
//日期:2007.03.31
//===========================================================
void ISD4004_Powerdown()
{
    ISD4004_SS=0;
    ISD4004_Send(0x10);
    ISD4004_SS=1;
}


//==========================================================
//函数名称:void ISD4004_Play(unsigned char addr_h,unsigned char addr_l)
//函数功能:放音
//日期:2007.03.31
//==========================================================
void ISD4004_Play(unsigned char addr_h,unsigned char addr_l)
{

    ISD4004_SS=0;
    ISD4004_Send(addr_l);
    ISD4004_Send(addr_h);
    ISD4004_Send(0xe0);           //从指定地址开始放音。
    ISD4004_SS=1;
        
    ISD4004_SS=0;
    ISD4004_Send(0xf0);          //从当前地址开始放音(直至EOM或OVF)
    ISD4004_SS=1;
}

//================================================================
//函数功能:录音
void ISD4004_Rec(unsigned char addr_h,unsigned char addr_l)
{
    ISD4004_SS=0;
    ISD4004_Send(addr_l);       //传送地址
    ISD4004_Send(addr_h);
    ISD4004_Send(0xa0);         //从指定地址开始录音。
    ISD4004_SS=1;

    ISD4004_SS=0;
    ISD4004_Send(0xb0);         //从当前地址开始录音(直至OVF或停止)
    ISD4004_SS=1;
}


//================================================================
//函数名称:void fangyin()
//函数功能:语音 addr为地址
//日期:2007.03.31
//================================================================
void fangyin(uchar addr)
{
    uchar a;
        Led=0;
    ISD4004_Powerup();
    delay25ms();
    a = addr * 2;   
    ISD4004_Play(table[a],table[a+1]);
        Led=1;   
}

//================================================================
//函数名称:void luyin()
//函数功能:语音 addr为地址
//日期:2007.03.31
//================================================================
void luyin(uchar addr)
{
    uchar a;
    ISD4004_Powerup();     //上电
    delay25ms();
        delay25ms();
    a = addr * 2;          //对地址进行处理
    ISD4004_Rec(table[a],table[a+1]);     
}


/**************************************
  键盘处理及相应的数据处理
***************************************/

void keyscan()
{                                                                          
    if(add==0)        //上翻
         {
           delay1(5);
                   while(!add) ;
                         flag++;
                         if(flag==9)
                          flag=1;
          }


         if(sub==0)                //下翻                           
          {
           delay1(5);  
                        while(!sub) ;
                        flag--;        
                        if(flag==0)
                          flag=8;                                                                          
           }
                                                           
         if(affirm==0)         //应答
         {
           delay1(5);
           while(!affirm);
                 flag3++;
        //         shuju[flag-1][3]=flag3%2;
           shuju[flag-1][3]=1;
                 fasong();
         }
         
             if(K_fangyin==0)               //放音
                 {        
                   delay1(5);
                   if(K_fangyin==0)
                    {          P1=0xff;
                        fangyin(a);
                           delay25ms();
                           delay25ms();
                         }                                                   
                  }                  

                if(K_luying==0)                        //录音
                  {                    
                         delay1(5);
                        if(K_luying==0)
                          {          P1=0xff;
                                 ISD4004_Powerup();
                                 delay25ms();
                             luyin(a);                                
                            }
                  }        

                 if(K_Tingzhi==0)
                  {         
                      delay1(5);
                   if(K_Tingzhi==0)
                      {     P1=0xff;
                              ISD4004_Stop();
                                  delay25ms();
                      ISD4004_Powerdown();
                          }
                  }         
}


void  Ok_Menu ()
{
    uchar  m ;
    lcd_init() ;                //初始化LCD

    lcd_pos(0) ;                //设置显示位置为第一行的第1个字符
     m = 0 ;
    while(cdis1[m] != '\0')
     {                         //显示字符
       lcd_wdat(cdis1[m]) ;
       m++ ;
     }
}




/* 主函数     */
/************************************/
void main()
{
   data_init();
        
  while(1)
  {         
   keyscan();
   if(1==jieshou)
   {         
                EA=0;  //防止中断影响语音
                     Led=0;                       //亮灯
                        fangyin(a);
                           delay25ms();
                           delay25ms();                                                         
                                 EA=1;         
                                 jieshou=0;
   }                           
   display(flag-1);
  }
}



二、从机程序:
#include<AT89X52.H>
#define uchar unsigned char
#define uint unsigned int
sbit sing=P2^7;
sbit key=P2^5;
sbit sendd=P1^4;//电源控制
sbit led=P2^6;
uchar temp=0x03;        //本机地址

uchar th[]={0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,
            0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,
            0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff};
uchar tl[]={0x8c,0x5b,0x15,0x67,0x04,0x90,0x0c,   //低音1-7
            0x44,0xac,0x09,0x34,0x82,0xc8,0x06,  //中音1-7
            0x22,0x56,0x85,0x9a,0xc1,0xe4,0x03}; // 高音1-7

uchar  i,timer;
uint a,sum=0;
uchar code song[]={10,12,                                           //2
                    13,13,13,13,13,13,13,15,14,13,12,10,12,  //16    13,13,13,
                    10,10,10,10,10,10,10,10,10,6,8,          //14  10,10,10,
                    9,9,9,9,9,9,9,10,9,8,9,8,7,                 //16    9,9,9,
                    6,6,6,6,6,6,6,6,6,6,          //14     6,6,6,6,
                    6,6,10,10,10,10,9,8,7,7,8,8,7,7,6,5,             //16
                    6,6,6,6,6,6,6,6,6,6,         //14      6,6,6,6,
                    8,8,8,8,6,8,9,9,9,9,10,11,10,9,              //16  8,8,
                    10,10,10,10,10,10,10,10,10,12,       //14   10,10,10,10,
                    13,13,13,13,12,10,9,9,9,9,8,9,         //16  9,9,13,13,   4*30+2
                    10,10,10,10,9,10,6,6,6,6,6,          //16  10,10,6,6,6,
                    7,7,7,6,5,5,7,7,7,7,5,3,8,8,7,7,             //16
                                         //14 6,6,6,6,6,6,6,6,6,6,6,6,6,6,
                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,                 //16
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,   //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,      //16   10,10,
                    8,6,6,6,6,6,6,6,10,9,10,10,10,10,12,13,           //16
                    10,9,10,10,10,10,10,10,10,10,10,10,    //16  10,10,10,10,
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,     //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,         //16  10,10,   160-2
                    8,6,6,6,6,6,6,6,10,9,10,10,10,10,12,13,             //16
                    10,9,10,10,10,10,10,10,10,                //12   10,10,10,
                    6,6,13,13,13,13,12,12,10,12,10,12,13,13,13,13,      //16
                    12,12,9,9,9,9,10,12,10,9,10,10,10,10,         //16   10,10,
                    8,6,6,6,6,6,6,6,8,6,6,6,6,6,6,6,                    //16
                    10,9,10,10,10,10,10,9,10,10,10,10,      //16  110,10,0,10,
                    10,10,12,12,12,12,5,5,                            //8
                    6,6,6,6,6,6,6,6              //12    ,6,6,6,6 160-32
                    };//歌谱       408-64  


void delay10ms(uchar hehe)
{
    uint i;
        for(hehe;hehe>0;hehe--)
                for(i=1240;i>0;i--);
}


  void send()
{        
    P0=0x00;
          led=0;
        sendd=1;
    P0=temp&0x0f;
    delay10ms(10);//延时50ms
    sendd=0;                        
    led=1;
}

void dat_init()
{
    sing=1;          //变量初始化
    timer=0;
    i=1;
    a=0;
    sendd=0;
            
    TH1=(65536-50000)/256;   //定时器1初始化
    TL1=(65536-50000)%256;

        TCON = 0x00;
    TMOD=0x11;  //两个定时器都工作在方式1
    IT0=1;    //负边沿触发
    EA=1;    //开总中断
    ET0=1;   //定时器允许
    ET1=1;
        EX0=1;

基于51单片机的医院病房紧急呼叫系统(无线 语音).zip

511.33 KB, 下载次数: 44, 下载积分: 黑币 -5

基于51单片机的医院病房紧急呼叫系统(无线+语音)

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表