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

📄 main.c

📁 pcf8563实时时钟芯片与spec061单片机接口的测试程序,并使用了LCD显示,测试通过.
💻 C
字号:
//*****************************************************//
//*********工程名称:pcf8563.spj************************//
//*******编译器软件:u'nSP IDE,凌阳公司*****************//
//**功能:使用pcf8563实现时钟,并通过LCD显示出来********//
//**硬件连接:IOA口的高八位接液晶显示器,IOB口接pcf8563*//
//****2006年8月3号调试成功,愿与大家共勉***************//
//*****************************************************//

#include	"SPCE061V004.H"
unsigned int data_out;
int g8563_Store[7];                           /*时间交换区,全局变量声明*/
int c8563_Store[7]={0x00,0x18,0x10,0x21,0x01,0x08,0x06};     /*写入时间初值*/
char r1[16]={"    年  月  日  "};
char r2[16]={"      星期      "};
char r3[16]={"    时  分  秒  "};
char week[7][2]={"日","一","二","三","四","五","六"};
//******IOB初始化*******     以B0口为数据位  B1为时钟位 
int IOB_Ini()
{
  *P_IOB_Dir=0x0003;          //B0 SDA      B1 SCL
  *P_IOB_Attrib=0x0003;
  *P_IOB_Data=0x0000; 
}

/********************************************
内部函数,延时1
********************************************/
void Delay(int i)
{                                         /*根据晶振频率制定延时时间*/
   while(i--)     
   	*P_Watchdog_Clear = 1;                          
}

/********************************************
内部函数,I2C开始
********************************************/
void Start()
{ 
  *P_IOB_Dir=0x0003;          //B0 SDA      B1 SCL
  *P_IOB_Attrib=0x0003;
  *P_IOB_Data=0x03;
  Delay(2);
  *P_IOB_Data=0x02;
  Delay(2);
  *P_IOB_Data=0x00;
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop()
{  *P_IOB_Dir=0x0003;          //B0 SDA      B1 SCL
   *P_IOB_Attrib=0x0003;
   *P_IOB_Data=0x00;
   Delay(2);
   *P_IOB_Data=0x02;
   Delay(2);
  *P_IOB_Data=0x03;
   Delay(31);
}
/********************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
********************************************/
void WriteACK(int ack)
{*P_IOB_Dir=0x0003;          //B0 SDA      B1 SCL
*P_IOB_Attrib=0x0003;
   *P_IOB_Data|=ack;
   Delay(2);
   *P_IOB_Data|=0x02;
   Delay(2);
  *P_IOB_Data&=0xfffd;
}
/********************************************
内部函数,等待ACK
********************************************/
void WaitACK()
{ int errtime=20;
  *P_IOB_Dir=0x0002;          //B0 SDA      B1 SCL
  *P_IOB_Attrib=0x0003;
	
   *P_IOB_Data|=0x01;
   Delay(2);                  /*读ACK*/
   *P_IOB_Data=0x03;
   Delay(2);
   while(*P_IOB_Data&0x0001)
   {  errtime--;
      if(!errtime) 
      Stop();
   }
   *P_IOB_Data&=0xfffd;
   Delay(5);
}
/********************************************
内部函数.输出数据字节
入口:B=数据
********************************************/
void writebyte(int wdata)
{  int i;
*P_IOB_Dir=0x0003;         
  *P_IOB_Attrib=0x0003;

  
   for(i=0;i<8;i++)
   {
       if(wdata&0x80) *P_IOB_Data=0x01;
       else *P_IOB_Data=0x00;
       wdata<<=1;
       *P_IOB_Data|=0x02;
       Delay(2);
       *P_IOB_Data&=0xfd;
   }
   WaitACK();          //I2C器件或通讯出错,将会退出I2C通讯
}
/********************************************
内部函数.输入数据
出口:B
********************************************/
int Readbyte()                                  
{ 

   int i,bytedata;
   *P_IOB_Dir=0x0002;           //输入
   *P_IOB_Attrib=0x0002;
   *P_IOB_Data=0x01;
   for(i=0;i<8;i++)
   {
      *P_IOB_Data|=0x0002;                     
      bytedata<<=1;             
      bytedata|=(*P_IOB_Data&0x0001);            
      *P_IOB_Data&=0xfffd;
      Delay(2);
   }
   return(bytedata);
}
/********************************************
输出数据->pcf8563
********************************************/
void writeData(int address,int mdata)
{
   Start();
   writebyte(0xa2);           /*写命令*/
   writebyte(address);        /*写地址*/
   writebyte(mdata);          /*写数据*/
   Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
int ReadData(int address) /*单字节*/
{  int rdata;
   Start();
   writebyte(0xa2);            /*写命令*/
   writebyte(address);         /*写地址*/
   Start();
   writebyte(0xa3);            /*读命令*/
   rdata=Readbyte();
   WriteACK(1);
   Stop();
   return(rdata);
}
void ReadData1(int address,int count,int * buff) /*多字节*/
{  int i;
   Start();
   writebyte(0xa2);              /*写命令*/
   writebyte(address);           /*写地址*/
   Start();
   writebyte(0xa3);              /*读命令*/
   for(i=0;i<count;i++)
   {
        buff[i]=Readbyte();
        if(i<count-1) WriteACK(0);
   }
  WriteACK(1);
   Stop();
}
/********************************************
内部函数,读入时间到内部缓冲区
********************************************/
void P8563_Read()
{int time[7];
    time[0]=ReadData(0x02);
    time[1]=ReadData(0x03);
    time[2]=ReadData(0x04);
    time[3]=ReadData(0x05);
    time[4]=ReadData(0x06);
    time[5]=ReadData(0x07);
    time[6]=ReadData(0x08);
    g8563_Store[0]=time[0]&0x7f;     //秒
    g8563_Store[1]=time[1]&0x7f;     //分
    g8563_Store[2]=time[2]&0x3f;     //小时
    g8563_Store[3]=time[3]&0x3f;     //日
    g8563_Store[4]=time[4]&0x07;     //星期
    g8563_Store[5]=time[5]&0x1f;     //月
    g8563_Store[6]=time[6]&0xff;     //年
}

/********************************************
读入时间到内部缓冲区----外部调用 
********************************************/
void P8563_gettime()
{
    P8563_Read();
    if(g8563_Store[0]==0)
      P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
}

/********************************************
写时间修改值
********************************************/
void P8563_settime()
{
     int i;
     for(i=2;i<=8;i++) { writeData(i,g8563_Store[i-2]); }
    // writeData(6,g8563_Store[3]);
}

/*****************************************
P8563的初始化-----外部调用
******************************************/
void P8563_init()
{
    int i;
    if((ReadData(0xa)&0x3f)!=0x8) /*检查是否第一次启动,是则初始化时间*/
    {
        for(i=0;i<=6;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
        P8563_settime();
        writeData(0x0,0x00);
       // writeData(0xa,0x8); /*8:00报警*/
      //  writeData(0x1,0x12); /*报警有效*/
        writeData(0xd,0x00);
    }
}

//***************换算*********************//
int transform()
{	int w;
	r3[11]=(g8563_Store[0]&0x000f)+'0';
	r3[10]=((g8563_Store[0]&0x0070)>>4)+'0';
	r3[7]=(g8563_Store[1]&0x000f)+'0';
	r3[6]=((g8563_Store[1]&0x0070)>>4)+'0';
    r3[3]=(g8563_Store[2]&0x000f)+'0';
    r3[2]=((g8563_Store[2]&0x0030)>>4)+'0';
      w=g8563_Store[4]&0x0007;
    r2[10]=week[w][0];r2[11]=week[w][1];
    r1[11]=(g8563_Store[3]&0x000f)+'0';
    r1[10]=((g8563_Store[3]&0x0030)>>4)+'0';
    r1[7]=(g8563_Store[5]&0x000f)+'0';
 	r1[6]=((g8563_Store[5]&0x0010)>>4)+'0';   
    r1[3]=(g8563_Store[6]&0x000f)+'0';
    r1[2]=((g8563_Store[6]&0x00f0)>>4)+'0';
} 
  
///********************************************
//*****************液晶显示********************
void send_data(unsigned int data)     //高8位为待送数据
{	int i=8,j,data1;
	data=data>>6;       //IO9为数据输入端,右移4位与IO11对齐
 	while (i--)
	{
	data1=data&0x0200;
	 if (data1)
	  {data_out|=data1;
	  *P_IOA_Data=data_out;}
	 else
	   {data_out&=0xfdff;
	   *P_IOA_Data=data_out;}
	   
	data_out|=0x0400;     //set sclk to high  IO10
	*P_IOA_Data=data_out;
	
	data_out&=0xfbff;     //set sclk to low   IO10
	*P_IOA_Data=data_out;
	data=data<<1;
	}
	
}
void write_data(data)                        //低八位是待写入数据
unsigned int data;
{	unsigned int data1=0xfa00,data2,data3;   //data2中存放高4位数据,data3中存放低4位数据
	data_out=data_out|0x0100;                 //cs set to high
	*P_IOA_Data=data_out;
	data2=data&0x00f0;						//取高4位数据
	data2=data2<<8;
	data3=data&0x000f;						//取低4位数据
	data3=data3<<12;
	send_data(data1);
	send_data(data2);
	send_data(data3);
	data_out=data_out&0xfeff;
	*P_IOA_Data=data_out;                    //cs set to low
}
void write_comm(data)			          	//低八位是待写入数据
unsigned int data;
{	unsigned int data1=0xf800,data2,data3;
	data_out=data_out|0x0100;                 //cs set to high
	*P_IOA_Data=data_out;
	data2=data&0x00f0;						//取高4位数据
	data2=data2<<8;
	data3=data&0x000f;						//取低4位数据
	data3=data3<<12;
	send_data(data1);
	send_data(data2);
	send_data(data3);
	data_out=data_out&0xfeff;
	*P_IOA_Data=data_out;                    //cs set to low
}
	
void init_io(void)
{
	*P_IOA_Data=0x00ff;
	*P_IOA_Dir=0xef00;
	*P_IOA_Attrib=0xffff;
	 data_out=0x0000;				//初始化A口数据
}

void screen(data)
char data[65];
{		unsigned int i,j;
		for (i=0;i<64;i++)
			{write_data(data[i]);
			if (i==15)
			write_comm(0x0090);    //设定DDRAM第二行,第一列
			if (i==31)
			write_comm(0x0088);    //设定DDRAM第三行,第一列
			if (i==47)
			write_comm(0x0098);    //设定DDRAM第四行,第一列
			if (i==63)
			write_comm(0x0080);    //设定DDRAM第四行,第一列
			}
}


unsigned int addr=0x0800; 

void steprow(int r,char *p)
{
 int i=0;
 switch(r) 
 {
  case 1:addr=0x0080; write_comm(addr);
        for(i=0;i<16;i++)                                                                          
          write_data(p[i]); break;
  case 2:addr=0x0090; write_comm(addr);
        for(i=0;i<16;i++)                                                                          
          write_data(p[i]); break; 
  case 3:addr=0x0088; write_comm(addr);
        for(i=0;i<16;i++)                                                                          
          write_data(p[i]); break; 
  case 4:addr=0x0098; write_comm(addr);
        for(i=0;i<16;i++)                                                                          
          write_data(p[i]); break;       
 }

}
main()
{   init_io();
	IOB_Ini();
		write_comm(0x0030);			//基本指令集
		write_comm(0x0001);			//清除显示屏幕,把DDRAM位址计数器调整为"00H"
		write_comm(0x0003);			//把DDRAM位址计数器调整为"00H",游标回原点,该功能不影响显示DDRAM
		write_comm(0x0006);			//光标右移
		write_comm(0x000e);	       
	P8563_init();
  while(1)
  {	steprow(1,r1);
  	steprow(2,r2);
  	steprow(3,r3);
 	
    P8563_gettime();
    transform();
  
    *P_Watchdog_Clear = 1;
  }
}

⌨️ 快捷键说明

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