本帖最后由 杜安安 于 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;
|