📄 baozhan_one.c
字号:
#include"intrins.h"
#include"STC89C58RD.h"
#include"baozhan_one.h"
unsigned char idata cur_state=0; //全局变量,指示当前站点状态信息
unsigned int xdata isd_addr[30]; //全局变量,指示当前录放音地址信息(行数)
unsigned char idata init_R_addr=1; //标志位,指示是否需要初始化录音地址,1是0否
void main()
{
init();
EA=0;
enable_in_ram(); //允许内部1024byteRAM,允许ALE.默认是允许的
dis_ale(); //禁止ale,允许内部扩展1024byteRAM
init_isd();
dis_low=1; //关数码管显示
dis_high=1;
EA=1;
while(1)
{
if(rec_ctrl==0) //录音键按下
{
delay_kb(10); //延时,消抖
if(rec_ctrl==0)
{
isd_rec();
init_R_addr=0;
}
else
break;
}
else
{
kbscan();
switch(kbscan())
{
case 0: cur_state=0;
isd_play(isd_addr);
break;
case 1: cur_state=1;
isd_play(isd_addr);
break;
case 2: cur_state=2;
isd_play(isd_addr);
break;
case 3: cur_state=3;
isd_play(isd_addr);
break;
case 4: cur_state=4;
isd_play(isd_addr);
break;
case 5: cur_state=5;
isd_play(isd_addr);
break;
case 6: cur_state=6;
isd_play(isd_addr);
break;;
case 7: cur_state=7;
isd_play(isd_addr);
break;
case 8: cur_state=8;
isd_play(isd_addr);
break;
case 9: cur_state--;
isd_play(isd_addr);
break;
case 10:isd_play(isd_addr);
break;
case 11:cur_state++;
isd_play(isd_addr);
break;
default:break;
}
}
}
}
void init(void) //初始化系统参数
{
PCON=0x00; //smod=0;
SCON=0x40; //串口工作方式1,8位UART,ren=0禁止接收
TMOD=0x21; //定时器1工作方式2,8位自动重载T/C
//定时器0工作方式1,16位定时器,用于定时产生中断进行显示扫描
TH1=253; //TH1=256-(28800/baudrate),9600bps
TL1=253;
TH0=0xf8; //定时器0定时2MS
TL0=0x30;
TR1=1; //启动T1
TR0=1; //启动T0
ET0=1; //开定时器0中断
ES=1; //开串口中断
EA=1; //开总中断
REN=1; //使能串口接收
}
void init_isd(void)
{
ss=1;
sclk=1;
rac=1;
int0=1;
}
void timer0(void) interrupt 1 using 2
{
unsigned char bitselect=0; //显示位切换标志位
unsigned char disply[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xal,0x86,0x8e}; //字形数0-9,A-F;
static unsigned char cur_dpy;
cur_dpy=cur_state;
TH0=0xf8; //重装计数初值
TL0=0x30;
if(cur_dpy>=10&&cur_dpy<20)
{
dis_low=1; //关显示
dis_high=1;
cur_dpy-=10;
disdata=disply[cur_dpy]; //从p0口输出字形数
dis_low=0;
}
else
{
switch(bitselect)
{
case 0:
{
if(cur_dpy>=20&&cur_dpy<30)
{
dis_low=1;
cur_dpy-=20;
disdata=disply[cur_dpy];
dis_low=0;
}
else if(cur_dpy>=30&&cur_dpy<40)
{
dis_low=1;
cur_dpy-=30;
disdata=disply[cur_dpy];
dis_low=0;
}
else
{
dis_low=1;
disdata=disply[14];
dis_low=0;
}
}
break;
case 1:
{
if(cur_dpy>=20&&cur_dpy<30)
{
dis_high=1;
disdata=disply[1];
dis_high=0;
}
else if(cur_dpy>=30&&cur_dpy<40)
{
dis_high=1;
disdata=disply[2];
dis_high=0;
}
else
{
dis_high=1;
disdata=disply[14];
dis_high=0;
}
}
break;
default:break;
}
bitselect=~bitselect;
}
}
void dis_ale() //禁止ale,允许内部扩展1024byteRAM
{
AUXR = 0x01;
}
void enable_in_ram() //允许内部1024RAM,允许ALE.默认是允许的
{
AUXR = 0x00;
}
//键盘扫描
void delay_kb(unsigned char time)
{
unsigned char i,j;
for(i=0;i<time;i++)
for(j=0;j<200;j++);
}
unsigned char kbscan(void)
{
unsigned char i,j,temp;
unsigned char vertical=0x01;
unsigned char row=0x10;
do{
P2=0xf0;
}while(P2&0xf0==0xf0);
delay_kb(10);
P2=0xf0;
if(P2&0xf0!=0xf0)
{
for(i=0;i<4;i++)
{
P2=~vertical;
temp=P2&0xf0;
for(j=0;j<4;j++)
{
if(temp&row==0x00)
return(j*8+i);
temp=temp>>1;
}
}
vertical<<=1;
}
else return 20;
}
//ISD4004录放音
void isd_spi(unsigned char cmd) //ISD4004写控制字
{
unsigned char m,i,j;
ss=1;
sclk=0;
ss=0;
m=cmd;
for(i=0;i<8;i++)
{
m=_cror_(m,1); //unsigned char _cror_(unsigned char x,unsigned char y);
//将X值向右旋Y次,即X值的bit0右旋至bit7.返回X值右旋Y次后的数值
j=m<<1;
mosi=CY;
sclk=0;
sclk=1;
}
ss=1;
}
unsigned char chk_ovf(void) //检测OVF,溢出返回1,否则返回0
{
isd_spi(rint);
ss=0;
sclk=0;
sclk=1;
if(miso==1)
{
return 1;
}
else
{
return 0;
}
}
void isd_rec(void) //录音 address--录音地址 0---2400
{
unsigned char i,m,j;
unsigned int datasoute=0,address=0;
static unsigned char addr=0; //初始化isd_addr[]下标
static unsigned int PR_addr=0; //初始化行数(指示录放地址)
isd_spi(powerup);
delay_isd(5118); //上电延时
isd_spi(powerup);
delay_isd(5118); //上电延时
delay_isd(5118); //上电延时
if(init_R_addr==1) //需要初始化录音地址
{
ss=1;
sclk=0;
m=setrec;
ss=0;
for(i=0;i<16;i++)
{
address=_iror_(address,1); //unsigned int _iror_(unsigned int x,unsigned char y);
//将整数类型的X值右旋Y次,即X值的bit0右旋至bit15.返回X值右旋Y次后的16bit数值
datasoute=address<<1;
mosi=CY;
sclk=0;
sclk=1;
}
for(i=0;i<8;i++)
{
m=_cror_(m,1);
j=m<<1;
mosi=CY;
sclk=0;
sclk=1;
}
ss=1; //初始化录放起始地址address=0,PR--PLAY or REC
}
rec_led=0; //开录音指示灯
isd_spi(rec); //从当前地址开始录音
P0=(P0|0xfc);
while(int0==1) //等待OEM或OVF产生中断
{
if(rac) //记录本次录音所占的行数(也就是本次录音有多大)
{
delay_isd(20000);
PR_addr++;
}
if(rec_ctrl==1) //录音键断开,停止录音
{
delay_kb(10); //延时,消抖
if(rec_ctrl==1)
{
rec_led=1; //关录音指示灯
isd_spi(stop);
}
}
} //while end
isd_addr[addr]=PR_addr; //将语音地址依次存入数组
addr++;
if(chk_ovf()); //判断是否溢出,若溢出,停止当前ISD工作
{
rec_led=1; //关录音指示灯
isd_spi(stoppwrdn);
}
}
void isd_play(unsigned int playaddr[]) //放音程序
{
unsigned char i,m,j,n;
unsigned int datasoute=0,address=0;
n=cur_state;
address=playaddr[n];
isd_spi(powerup);
ss=1;
sclk=0;
m=setplay;
ss=0;
for(i=0;i<16;i++)
{
address=_iror_(address,1); //unsigned int _iror_(unsigned int x,unsigned char y);
//将整数类型的X值右旋Y次,即X值的bit0右旋至bit15.返回X值右旋Y次后的16bit数值
datasoute=address<<1;
mosi=CY;
sclk=0;
sclk=1;
}
for(i=0;i<8;i++)
{
m=_cror_(m,1);
j=m<<1;
mosi=CY;
sclk=0;
sclk=1;
}
ss=1;
isd_spi(play);
P0=(P0|0xfc);
while(int0==1)
{
} //while end;
}
void delay_isd(unsigned int i) //延时程序
{
while(i--);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -