#include<REG51.H>
#include<intrins.h> //包含_nop_()函数以及左移定义的头文件
#define uchar unsigned char
#define uint unsigned int
#define lcddata P0
#define ISDPOWERUP 0X20 //ISD4004上电
#define ISDSTOP 0X10 //ISD4004下电
#define OPERSTOP 0X30 //ISD4004停止当前操作
#define PLAYSET 0XE0 //ISD4004从指定地址开始放音
#define PLAYCUR 0XF0 //ISD4004从当前地址开始放音
#define RECSET 0XA0 //ISD4004从指定地址开始录音
#define RECCUR 0XB0 //ISD4004从当前地址开始录音
sbit SS=P1^5; //LOW IS ACTIVELY
sbit MOSI=P1^1;
sbit MISO=P1^7;
sbit SCLK=P1^4;
sbit K1=P3^2;
sbit K2=P3^3;
sbit K3=P3^4;
sbit K4=P3^5;
sbit fmq=P3^6;
sbit rs= P2^0;
sbit rw= P2^1;
sbit e = P2^2;
sbit busy=P0^7; //lcd busy bit
signed char num=0;//站号
int reccout=0; //录音变量
int recbit=0; //定义变量录音位
void delay1ms(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<115;j++) //1ms基准延时程序
{
;
}
}
}
////////////////////////////////////
void delayms(uchar ms)
// 延时子程序
{
uchar j;
while(ms--)
{
for(j = 0; j < 120; j++);
}
}
////////////////////////////////
void delay500us()
{
unsigned char j;
for(j=0;j<57;j++) //500us基准延时程序
{
;
}
}
void mdelay(uint delay)
{ uint i;
for(;delay>0;delay--)
{for(i=0;i<80;i++) //1ms延时.
{;}
}
}
void beep() //产生1KHZ频率声音的函数
{
fmq=0;
delay500us();
fmq=1;
delay500us();
}
////////////////放音部分子程序,放音地址由ADDR决定////
void play(uint addr)
{ uint y;
SS=0;
MOSI=0;//发送开始
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0x20>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}//发送结束
SS=1;//上电结束
delayms(50);
SS=0;
MOSI=0;//发送地址
SCLK=0;
for(y=0;y<16;y++)
{
SCLK=0;
if((addr>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}//发送地址结束
MOSI=0;//放音
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0xe0>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SS=1;
/* SS=0;
MOSI=0;//放音
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0xf0>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SS=1; */
}
//////////////////////////录音部分子程序,地址由ADDR决定/////////////////////////
void rec(uint addr)
{ uint y;
SS=0;
MOSI=0;//发送开始
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0x20>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}//发送结束
SS=1;//上电结束
delayms(50);
SS=0;
MOSI=0;//发送开始
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0x20>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}//发送结束
SS=1;//上电结束
delayms(50);
delayms(50);
SS=0;
MOSI=0;//发送地址
SCLK=0;
for(y=0;y<16;y++)
{
SCLK=0;
if((addr>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}//发送地址结束
MOSI=0;
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0xa0>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SS=1;
/* SS=0;
MOSI=0;
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0xb0>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SS=1; */
}
////////////////////////////////////
////////////////////////////////
void stop()
{
uchar y;
SS=1;
SS=0;
MOSI=0;//放音
SCLK=0;
for(y=0;y<8;y++)
{
SCLK=0;
if((0x30>>y)&0x01)MOSI=1;
else MOSI=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SS=1;
}
////////////////////////////////////
void recsound() ///录音子函数
{
if(recbit)
{recbit=0;
switch(reccout)
{case 1:{rec(0x50);}break;
case 2:{rec(0x100);}break;
case 3:{rec(0x150);}break;
case 4:{rec(0x200);}break;
}
}
}
////////////////////////////////////
void playsound() ///放音子函数
{
switch(num)
{case 0:{play(0x50);}break; //此处第一个站名的开始地址为0X00,到0X100地址结束,约为51秒。
case 1:{play(0x100);}break;
case 2:{play(0x150);}break;
case 3:{play(0x200);}break;
}
}
////////////////////////////////////
void keyscan() //直控键盘扫描子程序。
{
uchar t;
if((K3&K4)==0)
{
delay1ms(15); //判断是该站还是上一站并且对键盘去抖动
if((K3&K4)==0)
{
for(t=0;t<100;t++)
{beep();}
if(K3==0)
{
recbit=1;
if(reccout>4)
{reccout=0;}
reccout++;
}
else if(K4==0)
{
stop();
}
}
while(!(K3&K4));//等待按键释放
}
}
////////////////////////////////////////////////
//************************************************
void show(); //液晶显示程序
//****************************************
//12864液晶显示部分子程序模块
//****************************************
void wr_d_lcd(uchar content);
void wr_i_lcd(uchar content);
void clrram_lcd (void);
void init_lcd(void);
void busy_lcd(void);
void rev_row_lcd(uchar row);
void rev_co_lcd(uchar row,uchar col,uchar mode);
void clr_lcd(void);
void wr_co_lcd(uchar row,uchar col,uchar lcddata1,uchar lcddtta2);
void wr_row_lcd(uchar row,char *p);
//**********************************
//液晶初始化
//**********************************
void init_lcd(void)
{
wr_i_lcd(0x06); /*光标的移动方向*/
wr_i_lcd(0x0c); /*开显示,关游标*/
}
//***********************************
//填充液晶DDRAM全为空格
//**********************************
void clrram_lcd (void)
{
wr_i_lcd(0x30);
wr_i_lcd(0x01);
}
//***********************************
//对液晶写数据
//content为要写入的数据
//***********************************
void wr_d_lcd(uchar content)
{
busy_lcd();
rs=1;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//对液晶写指令
//content为要写入的指令代码
//*****************************
void wr_i_lcd(uchar content)
{
busy_lcd();
rs=0;
rw=0;
lcddata=content;
e=1;
;
e=0;
}
//********************************
//液晶检测忙状态
//在写入之前必须执行
//********************************
void busy_lcd(void)
{
lcddata=0xff;
rs=0;
rw=1;
e =1;
while(busy==1);
e =0;
}
//********************************
//指定要显示字符的坐标
//*******************************
void gotoxy(unsigned char y, unsigned char x)
{
if(y==1)
wr_i_lcd(0x80|x);
if(y==2)
wr_i_lcd(0x90|x);
if(y==3)
wr_i_lcd((0x80|x)+8);
if(y==4)
wr_i_lcd((0x90|x)+8);
}
//**********************************
//液晶显示字符串程序
//**********************************
void print(uchar *str)
{
while(*str!=' ')
{
wr_d_lcd(*str);
str++;
}
}
//***************************************
//液晶显示主程序模块
//***************************************
void show()
{ init_lcd();
clrram_lcd();
gotoxy(1,0);
print("最佳魅力城市");
gotoxy(2,0);
print("烟台欢迎您");
mdelay(10000);
init_lcd();
clrram_lcd();
gotoxy(1,0);
print("山东工商学院坐落");
gotoxy(2,0);
print("在渤海之滨,凤凰");
gotoxy(3,0);
print("山下");
mdelay(10000);
init_lcd();
clrram_lcd();
gotoxy(1,0);
print("四年留下了很多");
gotoxy(2,0);
print("祝大家:");
gotoxy(3,0);
print("心想事成,幸福快乐");
mdelay(10000);
}
void show1(num)
{ if(num==0)
{
gotoxy(1,0);
print("下一站");
gotoxy(2,0);
print("黄海明珠");
}
else if(num==1)
{
gotoxy(1,0);
print("下一站");
gotoxy(2,0);
print("山东工商学院");
}
else if(num==2)
{
gotoxy(1,0);
print("下一站");
gotoxy(2,0);
print("烟台大学");
}
else if(num==3)
{
gotoxy(1,0);
print("下一站");
gotoxy(2,0);
print("滨州医学院");
}
}
/*******************************************
函数功能:主函数
******************************************/
void main()
{
EA=1; //开放总中断
EX0=1; //允许使用外中断0
EX1=1; //允许使用外中断1
IT0=1; //选择负跳变来触发外中断0
IT1=1; //选择负跳变来触发外中断1
P1=0xff;
P2=0Xff;
P3=0Xff;
while(1)
{
keyscan();
recsound();
//show(); //液晶显示数据
}
}
/**************************************************************
函数功能:外中断0的中断服务程序
**************************************************************/
void int0(void) interrupt 0//外中断0的中断编号为0
{
uchar t;
if(K1==0)
{
delay1ms(15); //判断是该站还是上一站并且对键盘去抖动
if(K1==0)
{
for(t=0;t<100;t++)
{beep();}
playsound();
init_lcd();
clrram_lcd();
show1(num);
delay1ms(200);
num=num+1; //判断是该站时站号加一
if(num>=3)
{num=3;}
}
while(!K1);//等待按键释放
}
}
/**************************************************************
函数功能:外中断T1的中断服务程序
**************************************************************/
void int1(void) interrupt 2//外中断1的中断编号为1
{
uchar t;
if(K2==0)
{
delay1ms(15); //判断是该站还是上一站并且对键盘去抖动
if(K2==0)
{
for(t=0;t<100;t++)
{beep();}
playsound();
init_lcd();
clrram_lcd();
show1(num);
delay1ms(200);
num=num-1; //判断是该站时站号加一
if(num<=0)
{num=0;}
}
}
while(!K2);//等待按键释放
}
一周热门 更多>