写一12864驱动

2020-01-30 13:55发布

#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);//等待按键释放
   }

0条回答

一周热门 更多>