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