⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 340_lcd.c

📁 与320*240相连的DS1302时钟程序
💻 C
字号:
/******************************************************************************
由于LV595芯片片选引脚与以太网控制芯片CP2200中断引脚复用因些在此例程中加入了将
CP2200芯片中断关闭的代码。还要在建立工程文件时将CP220X_REG.C文件包含到工程中.
******************************************************************************/


#include "C8051F340.h"
#include "INTRINS.H"
#include "cp220x_reg.h"

#define  uchar unsigned char
#define  uint  unsigned int
#define  BASE_ADDRESS   0x10
#define EMIF_TIMING	0x9E 


sbit LcdCs=P0^3;
sbit led=P2^4;
bit SPI_BUSY;
//***************DS1302*******************************
//**************************************************
#define  NOP  _nop_()
#define  uchar   unsigned char

sbit    IO=P3^1;
sbit    SCLK=P3^2;
sbit    RSTB=P3^3;


uchar xdata virt_port;
uchar xdata discode;//开关显示、光标、闪烁的命令字暂存单元
uint Count1ms;


//signed char xdata tab1[16]={0x20,0x20,0x42,0x54,0x20,0x46,0x33,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}; 
//void delay(uint timer);
void writelcd(uchar spi_data);
void writecode(uchar ins);
void writedata(uchar d);
void lcdinit();
void lcdchar (void);
void lcdaddr(uchar DDRAM);
void cursoropen(uchar position);//开光标,关闪烁
void displayopen(void);			//开显示,光标、闪烁不变
void ether_reset_low();
void ether_reset_high (void);
void Delay1ms(uint T);
void EMIF_Init (void);

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


   
   void  delay(uchar i)
    { 
     while (--i);
	}

//*****************************RESET  FUNCTION///////////////
   void reset()
   {
	    RSTB=0;
	    SCLK=0;
	    delay(100);
	    RSTB=1;
		delay(100);
   }
//***************************BYTE  WRITE************//
void  wbyte(uchar w_byte)
{
	uchar i;
	for(i=0;i<8;++i)
	{ 
		IO=0;
		if(w_byte&0x01) IO=1;		//w_byte最低位是否为1,若为1,IO=1,否则不改变IO值
		SCLK=0;						// 产生上升沿脉冲
		delay(20);					 
		SCLK=1;
		delay(20);
		w_byte>>=1;
	
	}
}
//***********************	 BYTE READ******************//
uchar rbyte()
{
	uchar i;
	uchar R_BYTE;
	uchar TMPBYTE;
	R_BYTE=0X00;
	IO=1;
	for(i=0;i<8;++i)
	{
	   
		SCLK=1;
		delay(20);
	    SCLK=0;
		TMPBYTE=(uchar)IO;
		TMPBYTE<<=7;
		R_BYTE>>=1;
		R_BYTE|=TMPBYTE;
		delay(20);
	}
	return(R_BYTE);
}

uchar time_data[8]={0,0,1,1,1,1,1,1};//sec,min,hrs,dte,mon,day,yr
uchar time_diplay[14]={0x31,0x35,0x38,0x32,0x39,0x33,0x34,0x33,0x32,0x37,0x31};

//*********************时间初始校准与初始化**************************************//
void time_int_DS1302()      //24小时模式
{	
	uchar time[8]={0,0,0x12,1,1,1,0,0};//sec,min,hrs,dte,mon,day,yr
//	uchar i;
	reset();
	wbyte(0x8e);//写保护控制寄存器
	wbyte(0);//允许写入
	reset();
	wbyte(0x90); //涓流充电控制寄存器
	wbyte(0);    //禁止充电
	reset();
	wbyte(0x80);  //秒         //2000年1月1日12点0分13秒 星期一
	wbyte(0x13);
	reset(); 
    wbyte(0x82);  //分
    wbyte(0x00);
	reset(); 
	wbyte(0x84);  //HR
    wbyte(0x12);
	reset(); 
	wbyte(0x86);  //DATA
    wbyte(0x00);
	reset(); 
	wbyte(0x88);  //MOUTH
    wbyte(0x00);
	reset(); 
	wbyte(0x8A);  //DAY
    wbyte(0x00);
    reset(); 
	wbyte(0x8C);  //YEAR
    wbyte(0x20);
    reset(); 
//	for(i=0;i<8;i++) 
//	wbyte(time[i]);    
//	reset();
}
//****************************************************************************
//****************DS1302显示数据	 ASCII码数字转化	   ***********************/
//******************************************************************************

/*void  display_xlat()
{ 	
	uchar i,j=0,num1,num2;
	for(i=0;i<7;i++)
	{  
		num1=time_data[i]&0x0F;
		num2=time_data[i];
		num2>>=4;
		time_diplay[j]=num1+0x30;
		time_diplay[j+1]=num2+0x30;
		j+=2;
	}
}
   */uchar time_sec=0;				 定义秒	//定义秒,且初始化为0
//**********************时间显示***************************************
void  time_display_DS1302()
{  
    
	reset();
	wbyte(0x81);          	
	time_sec=rbyte();    
	reset();
	time_data[0]=(time_sec>>4)+0x30;				//将秒的个位与十位分离,且转化为acsII码在,LCD1602上显示
	time_data[1]=(time_sec&0x0f)+0x30;

}

void SPI_Init()										//1602采用SPI方式传送数据,对SPI方式初始化
{
    SPI0CFG   = 0x70;
    SPI0CN    = 0x01;
    SPI0CKR   = 0x3B;
  

} 

void writelcd(uchar spi_data)	   //向LV595写数据以SPI方式
{

 	uint xdata i,j;
 	for(i=0;i<3;i++)
	LcdCs=0;
	SPI_BUSY=1;
	delay1us();
	SPI0DAT=spi_data;
     for(j=0;j<500;j++)
		{
	   if(!SPI_BUSY)break;
		} 
	delay1us();
	LcdCs=1;
	delay1us();
 	delay1us();
	delay1us();
	delay1us();
	delay1us();
	delay1us();
	delay1us();
//	for(j=0;j<5000;j++);

}

 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<2;i++)
	{
		writedata(time_data[i]);
		for(j=0;j<5000;j++);                  //数据读、写操作,画面不动
    	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 port_init()
{
     P0MDOUT=0xff;
     XBR0      = 0x02;
     XBR1      = 0x40;
     P1MDOUT|= 0xDf;                    // /WR and /RD are push-pull
     P2MDOUT|= 0xFF;
     P3MDOUT  =0xFD;
     P4MDOUT |= 0xFF;


}

void main(void)
{
   uint j;

   PCA0MD &= ~0x40;     //关闭看门狗定时器
   OSCICN |= 0x03;      //内部高频振荡器12M晶振做为系统时钟
   port_init();		   //端口初始化
   EMIF_Init ();
   ether_reset_low();
   for(j=0;j<5000;j++);
   ether_reset_high ();
   INT0EN = 0x00;                         
   INT1EN = 0x00;
   SPI_Init();
   time_int_DS1302();
   IE = 0x40;
   EA=1;	
   	lcdinit();
 //while(1) {
	  
   		   //液晶初始化
 while(1)
 { //
  EA=0;
  time_display_DS1302();
  EA=1;
  lcdchar();
  delay(60000);		 
  delay(60000);
  delay(60000);
  delay(60000);
  delay(60000);

  //time_display_DS1302();
  }
 
 }

//}

void spi_isr(void) interrupt 6 
{
	if(SPIF)		
		{
		SPIF=0;
		SPI_BUSY=0;
		}
		

	if(WCOL)
		{
		WCOL=0;
		}
}

 
void ether_reset_low()
{
   P1 &= ~0x01;               // Pull reset low
}
void ether_reset_high (void)
{
   P1 |= 0x01;               // Allow /RST to rise
   while(!(P1 & 0x01));      // Wait for /RST to go high

}
 
void EMIF_Init (void)
{
   EMI0CF = 0x1B;             // non-muxed mode; split mode
                              // with bank select
   EMI0TC = EMIF_TIMING;      // This constant may be modified
                              // according to SYSCLK to meet the
                              // timing requirements for the CP2200
   EMI0CN = BASE_ADDRESS;     // Page of XRAM accessed by EMIF
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -