yinci325 发表于 2013-4-2 14:57:42

写一12864驱动

#include<REG51.H>
#include<intrins.h>//包含_nop_()函数以及左移定义的头文件
#define uchar unsigned char
#define uintunsigned 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!='\0')
        {
                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);//等待按键释放
   }

页: [1]
查看完整版本: 写一12864驱动