×
单片机 > 单片机程序设计 > 详情

C8051F040按键程序

发布时间:2020-06-08 发布时间:
|

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

uchar xdata virt_port; 
bit SPI_BUSY; 

unsigned char xdata tab1[8]={0x53,0x31,0x53,0x32,0x53,0x33,0x53,0x34}; 


sbit key1=P2^0; 
sbit key2=P2^1; 
sbit key3=P2^2; 
sbit key4=P2^3; 
sbit LCDCs=P2^5; 
void os_init(); 
void port_init(); 
void spi_init(); 
void writecode(uchar ins); 
void writEDAta(uchar d); 
void lcdchar (uchar da); 
void lcdinit(); 
void writelcd(uchar spi_data); 
void delay(uint d); 
void main() 
{   
    WDTCN = 0xDE;                                           // 关闭看门狗 
    WDTCN = 0xAD; 
    os_init(); 
    port_init(); 
    spi_init(); 
      SFRPAGE   = CONFIG_PAGE; 
     EIE1      = 0x01; 
     EA=1; 
   while(1) 
   { 
   if(key1==0) 
   {  
   delay(2000);  
   lcdinit(); 
   lcdchar(6); 
       } 
    if(key2==0) 
    { delay(2000);  
      lcdinit(); 
      lcdchar(4); 
   } 
  if(key3==0) 
    { delay(2000);  
      lcdinit(); 
      lcdchar(2); 
   } 
   if(key4==0) 
    { delay(2000);  
      lcdinit(); 
      lcdchar(0); 
   } 
   
   } 


void os_init() 

    int i = 0; 
    SFRPAGE   = CONFIG_PAGE; 
    OSCXCN    = 0x67;                                    //外部22.1184M晶振 
    for (i = 0; i     while ((OSCXCN & 0x80) == 0); 
    CLKSEL    = 0x01;                                    //系统时钟不分频 

void port_init() 

    SFRPAGE   = CONFIG_PAGE; 
       P0MDOUT=0xff; 
    XBR0      = 0x06; 
    XBR2      = 0x40; 
    P2MDOUT=0xff; 


void spi_init() 

      SFRPAGE   = SPI0_PAGE; 
      SPI0CFG   = 0x40; 
      SPI0CN    = 0x01; 
      SPI0CKR   = 0x6D; 




 void delay(uint d) 
 {uint i,j; 
  for(i=0;i    { 
    for(j=10;j>0;j--); 
    } 

 } 
 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 (uchar da) 
     { 
     uint xdata i,j,k; 
     for(j=0;j<5000;j++);                  //数据读、写操作,画面不动 
     for(k=0;k<5000;k++); 
   
     for(i=da;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++); 
      
      } 
                                         
   
      
  
    
    
     } 


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; 
        } 

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址