首 页文档资料下载资料维修视频包年699元
请登录  |  免费注册
当前位置:精通维修下载 > 文档资料 > 家电技术 > 单元电路介绍 > 其它电路
c8051F040单片机驱动74HC595程序
来源:本站整理  作者:佚名  2011-08-04 10:13:57



#include "C8051F040.h"
#define uchar unsigned char
#define uint unsigned int

uchar xdata virt_port;
bit SPI_BUSY;
unsigned char xdata tab1[16]={0x20,0x20,0x42,0x54,0x20,0x46,0x30,0x34,0x30,0x20,0x56,0x31,0x2e,0x30
                            ,0x20,0x20};
unsigned char xdata Netdata[16]={0x77,0x77,0x77,0x2e,0x78,0x68,0x6c,0x2e,0x63,0x6f,
                                0x6d,0x2e,0x63,0x6e,0x20,0x20}; 
sbit LCDCs=P2^5;
void os_init();
void port_init();
void spi_init();
void writecode(uchar ins);
void writedata(uchar d);
void lcdchar (void);
void lcdinit();
void writelcd(uchar spi_data);
void main()
{  
    WDTCN = 0xDE;                                           // 关闭看门狗
    WDTCN = 0xAD;
    os_init();
    port_init();
    spi_init();
      SFRPAGE   = CONFIG_PAGE;
     EIE1      = 0x01;
     EA=1;
   while(1)
   {
 
   
   lcdinit();
   lcdchar();
   }

}
void os_init()
{
    int i = 0;
    SFRPAGE   = CONFIG_PAGE;
    OSCXCN    = 0x67;                                    //外部22.1184M晶振
    for (i = 0; i < 3000; i++);                         //等待外部晶振稳定 
    while ((OSCXCN & 0x80) == 0);
    CLKSEL    = 0x01;                                    //系统时钟不分频
}
void port_init()
{
    SFRPAGE   = CONFIG_PAGE;
       P0MDOUT=0xff;
    XBR0      = 0x06;
    XBR2      = 0x40;

}
void spi_init()
{
      SFRPAGE   = SPI0_PAGE;
      SPI0CFG   = 0x40;
      SPI0CN    = 0x01;
      SPI0CKR   = 0x6D;


}



 void delay1us(void)
    {
    uchar xdata i;
    for(i=10;i>0;i--);
    } 

void writelcd(uchar spi_data)       //向LV595写数据以SPI方式
{
  uint xdata i,j,k;
     for(i=0;i<9;i++);
    LcdCs=0;
    delay1us();    
    SPI_BUSY=1;
    SFRPAGE   = SPI0_PAGE;
    SPI0DAT=spi_data;
    for(j=0;j<500;j++)
        {
       if(!SPI_BUSY)break;
        } 
    delay1us();
    
    LcdCs=1;
    delay1us();
    delay1us();
    delay1us();
    delay1us();
    delay1us();
    delay1us();
    for(k=0;k<5000;k++);
    
/* **************************************************************************
 // 以下这段代码,是用IO口模拟SPI传输的程序
   LcdCs=0;
  for(i=0;i<8;i++)
  { SPICLK=0;
    if(spi_data&0x80)
       spi_mosi=1;
    else 
       spi_mosi=0;
    spi_data<<=1;
    SPICLK=1;
     for(j=0;j<10;j++)
     {_nop_();}
    SPICLK=0;
   }
   LcdCs=1;
/***************************************************************************/
}
void writecode(uchar ins)                    //向液晶控制模块写命令
     {
      uchar xdata t;
      uint xdata j;
    
      for(j=0;j<500;j++);    
      virt_port|=ins&0xf0;                    //取高字节向1602写数据 
      writelcd(virt_port);                    //先写高4位后再写低4位 这是在选择四个数据线的时候
     
      virt_port|=0x08;                          
      writelcd(virt_port);                    //使能E脚为高电平
      virt_port&=~0x08;                    
      writelcd(virt_port);                    //使能E脚为低电平

      t=ins<<4;             
      virt_port|=t&0xf0;                      //取低字节向1602写数据
      writelcd(virt_port);
      virt_port|=0x08;                        //使能E脚为高电平
      writelcd(virt_port);
      virt_port&=~0x08;                        //使能E脚为低电平
      writelcd(virt_port);
      virt_port=0;
      writelcd(virt_port);
     }

void writedata(uchar d)                       //写数据到1602
     {
      uchar xdata i,t;
      uint xdata j;
      
      for(j=0;j<500;j++);        
      virt_port|=0x02;                       //光标返回指令
      writelcd(virt_port);
      virt_port|=d&0xf0;                   //取高字节数据给数据寄存器
      writelcd(virt_port);
      virt_port|=0x08;                     //使能E脚为高电平
      writelcd(virt_port);
      virt_port&=0xf7;                     //使能E脚为低电平
      writelcd(virt_port);
      virt_port&=0x07;                       //设置光标右移,文字也右移
      writelcd(virt_port);
           
      t=d&0x0f;
      virt_port|=t<<4;                       //取低字节数据给数据寄存器
      writelcd(virt_port);

      virt_port|=0x08;                     //使能E脚为高电平
      writelcd(virt_port);
      for(i=3;i>0;i--); 
      virt_port&=0xf7;                     //使能E脚为低电平
      writelcd(virt_port);
      virt_port=0;                           //数据清零
      writelcd(virt_port);
    }

 void lcdchar (void)
     {
     uint xdata i,j,k;
     for(j=0;j<5000;j++);                  //数据读、写操作,画面不动
     for(k=0;k<5000;k++);
  
     for(i=0;i<16;i++)
     {
       writedata(tab1[i]);
       for(j=0;j<1000;j++);
       for(k=0;k<1000;k++);
       for(k=0;k<5000;k++);
       for(k=0;k<1000;k++);
       for(k=0;k<5000;k++);
       for(k=0;k<5000;k++);
       for(k=0;k<5000;k++);
     
      }
                                        
  
      writecode(0xb0);                       // 换行                   
      for(j=0;j<5000;j++);                                        
      for(k=0;k<5000;k++);
 
     for(i=0;i<16;i++)
     {
       writedata(Netdata[i]);
       for(j=0;j<5000;j++)    delay1us();
       for(k=0;k<5000;k++);
       for(k=0;k<5000;k++);
       for(k=0;k<5000;k++);
       for(k=0;k<5000;k++);
       
               
      };
   
     }


void lcdinit()
{
     uint xdata i;
    
      virt_port=0x00;
      writelcd(virt_port);         //RS脚为零写指令寄存器     RW为低电平
      virt_port|=0x08;              //使能脚E=1
      writelcd(virt_port);
       virt_port&=0xf7;             //使E=0使能脚发生跳变高--低
      writelcd(virt_port);
      for(i=1000;i>0;i--);         //3次延时,重要!
      for(i=8000;i>0;i--);         //用延时代替查询      

    
      virt_port=0;                 //写入20码,设置为4位总线方式,非常重要!!!!!
      writelcd(virt_port);
      virt_port|=0x20;             //只写高字节
      writelcd(virt_port);
      virt_port|=0x08;           //E=1
      writelcd(virt_port);
      for(i=20;i>0;i--);         //使命令执行
      virt_port&=0xf7;           //E=0
      writelcd(virt_port);
      for(i=10;i>0;i--);
      virt_port=0;
      writelcd(virt_port);
     
     

      writecode(0x38);            //设两行显示,4线方式5*10字符显示
      for(i=50;i>0;i--);
        writecode(0x06);            //光标右移
      for(i=50;i>0;i--);
     
      
      writecode(0x0c);            //开显示指令
      for(i=50;i>0;i--);
      
     
      writecode(0x02);            //光标返回指令
      for(i=50;i>0;i--);
       
    
     
      writecode(0x01);            //清屏指令
      for(i=50;i>0;i--);
}

void spi_srs  () interrupt 6
{
    if(SPIF)        
        {
      SFRPAGE   = SPI0_PAGE;
      SPIF=0;

        SPI_BUSY=0;
        }
        

    if(WCOL)
        {
       SFRPAGE   = SPI0_PAGE;
        WCOL=0;
        }

}

关键词:

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分)
Copyright © 2007-2017 down.gzweix.Com. All Rights Reserved .
页面执行时间:13,484.38000 毫秒