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

📄 time.c

📁 MSP430驱动时钟芯片PCF8583 借口为IIC总线
💻 C
字号:
#include <intrins.h>
#include<reg52.h>
#define Uchar unsigned char
#define Uint  unsigned int
#define SomeNOP(); _nop_();_nop_();_nop_(); 
/*I2C要用到的口线定意*/
sbit SDA = P2^7;
sbit SCL = P2^6;

//LCD的口线
sbit E=P2^2;
sbit RW=P2^1;
sbit RS=P2^0;
sbit LEDLOCK=P3^2;	
//8字LED的连接方法
//P0.7	P.06	P0.5	P0.4	P0.3	P0.2	P0.1	P0.0
// H      G	 F	 E	 D	 C	 B 	 A

unsigned char code ledcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,	
			      0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};	//数码管段码表

Uchar idata led[6];
Uchar ledcount;

/*定义一个接收的数组*/
Uchar idata recdata[8];			//
Uchar idata clockdata[7];		//系统时钟
Uchar pcpointer,timecount,*gettimeip;				//用于设定从PC接收和发的指针
Uchar bdata myflag;
sbit newtimebit = myflag^0;
sbit recpcokbit = myflag^1;
//I2C驱动要用到的一些函数
void Delay_1ms(Uchar time);
void I2CStart(void);	
void I2CStop(void);
void ACK(void);			//Acknowledge信号
void NACK(void);			//没有Acknowledge信号
void AutoACK(void);		//在一定的时间内自动确定ACK的信号//
void GetPCF8563(Uchar idata *Getip);
void SetPCF8563(Uchar idata *Setip);
Uchar ReadPCF8563(Uchar AddrePCF);
void WritePCF8563(Uchar AddrePCF,Uchar PCFdata);

void time0(void);
void rs232(void);

void main(void)
{
	E=0;			//取消LCD对LED的影响
	RW=0;
	RS=1;
	TH0 = 0xf8;					//2ms
	TL0 = 0xce;
	TH1 = 0xfd;					//以9600Baud的速率和PC机通信
	TL1 = 0xfd;	
	TMOD = 0x21;				//Time0为16位,Time1为8位常数自装
	SCON = 0x50;
	IP = 0x10;
	TR0 = 1;
	TR1 = 1;
	ledcount=0x00;
	IE = 0x92;
	led[0]=4;led[1]=5;led[2]=6;led[3]=7;led[4]=8;led[5]=9;
	while(1){}
}


void time0(void) interrupt 1
{
	TH0 = 0xf8;
	TL0 = 0xce;

	timecount--;
	if(timecount==0)
	{	
		timecount = 250;
		gettimeip=&clockdata[0];
		GetPCF8563(gettimeip);
		led[0]=clockdata[0]&0x0f;
		led[1]=(clockdata[0]>>4)&0x0f;
		led[2]=clockdata[1]&0x0f;
		led[3]=(clockdata[1]>>4)&0x0f;
		led[4]=clockdata[2]&0x0f;
		led[5]=(clockdata[2]>>4)&0x0f;
	}

	P1=0xff;
	LEDLOCK=1;LEDLOCK=0;                                        //利用定时器来获得连续扫描
	ledcount++;
	if(ledcount==0x06){ledcount=0x00;}
	P0=ledcode[led[ledcount]];
	switch(ledcount)
	{
		case 0 : P1=0xef;LEDLOCK=1;LEDLOCK=0;break;
		case 1 : P1=0xdf;LEDLOCK=1;LEDLOCK=0;break;
		case 2 : P1=0xf7;LEDLOCK=1;LEDLOCK=0;P0=P0&0x7f;break;
		case 3 : P1=0xfb;LEDLOCK=1;LEDLOCK=0;break;
		case 4 : P1=0xfd;LEDLOCK=1;LEDLOCK=0;P0=P0&0x7f;break;
		case 5 : P1=0xfe;LEDLOCK=1;LEDLOCK=0;break;				
	}
	
}


//以下为串行口中断程序,用于接收串行数据
void rs232(void) interrupt 4
{
	if(RI==1)
	{	
		
//原输入格式为AA 秒,分,时 日,星期,月年
		if (SBUF==0xaa)
		{
			newtimebit=1;
			pcpointer=0;
		}
		RI = 0;
		recdata[pcpointer++]=SBUF;
		if(pcpointer==8)
		{
			pcpointer =0;
			recpcokbit =1;		//指针还原,置收到完整的控制码			
		}
	}
	else
	{
		TI = 0;
	}			
}


/*----------------------I2C要用到的一些子程序---------------------------------*/
/***********************以下为一些用到的子程序*********************************/
/*延时子程序*/
void Delay_1ms(Uchar time)
{
	Uchar j;
	while(time--)
	{
	for(j=163;j!=0;j--);
	}
}

/*I2C的起动程序*/
void I2CStart(void)	
{
	SDA = 1;
	SomeNOP();
	SCL = 1;
	SomeNOP();
	SDA = 0;
	SomeNOP();
	SCL = 0;
	SomeNOP();
}

/*I2C的停止程序*/
void I2CStop(void)
{
	SDA = 0;
	SomeNOP();
	SCL = 1;
	SomeNOP();
	SDA = 1;
	SomeNOP();
}

void ACK(void)			//Acknowledge信号
{
	SDA = 0;
	SomeNOP();
	SCL = 1;
	SomeNOP();
	SCL = 0;
	SomeNOP();
}

void NACK(void)			//没有Acknowledge信号
{
	SDA = 1;
	SomeNOP();
	SCL = 1;
	SomeNOP();
	SCL = 0;
	SomeNOP();
}

void AutoACK(void)		//在一定的时间内自动确定ACK的信号//
{
	Uchar i = 0;
	SCL = 1;
	SomeNOP();
	while((SDA == 1)&&(i<255))i++;
	SCL = 0;
	SomeNOP();
}
/*I2C写数据程序(向数据线上写一个BYTE)*/
void Writex(Uchar j)
{
	Uchar i,temp;
	temp = j;
	for (i=0;i<8;i++)	//串行移位,先送高位,再送低位//
	{
		temp =temp<<1;
		SCL = 0;
		SomeNOP();
		SDA = CY;
		SomeNOP();
		SCL = 1;
		SomeNOP();
	}
	SCL = 0;
	SomeNOP();
	SDA = 1;
	SomeNOP();
}
/*I2C读数据程序(从数据线上读出一个BYTE)返回值为读出的数据(BYTE型)*/
Uchar Readx(void)
{
	Uchar i,j,k=0;
	SCL = 0;
	SomeNOP();
	SDA = 1;
	for (i=0;i<8;i++)	// 串行移位,先读出高位,后读出低位//
	{
		SomeNOP();
		SCL = 1;
		SomeNOP();
		if(SDA ==1) j=1;
		else	j=0;
		k =(k<<1)|j;
		SCL = 0;
	}
	SomeNOP();		
	return(k); 		//返回读出的值//
}

		

//*******************以下为对PCF8383/PCF8563的读写子程序********************//	
//**********时钟片device address的写地址为0A2H,读地址为0A3H******************//
/*对PCF8563的时钟读到内存中,以IDATA指针开始的连续7个BYTE*/
//****读出的内容依次为“秒,分钟,小时,日,星期,月/世纪,年********************//
//PCF8583依次为“秒,分钟,小时,日,星期月
void GetPCF8563(Uchar idata *Getip)
{
	Uchar i;
	I2CStart();
	Writex(0xA2);
	AutoACK();
	Writex(0x02);	//从秒地址开始读//
	AutoACK();
	I2CStart();
	Writex(0xA3);
	AutoACK();
	for(i=0;i<7;i++)
	{
		*Getip = Readx();
		Getip = Getip++;
		ACK();
	}
	*Getip = Readx();
	NACK();
	I2CStop();
	Delay_1ms(0);
}


/*设定8563/8583的时间内容依次为“秒,分钟,小时,日,星期,月/世纪,年*/
//PCF8585依次为“秒,分钟,小时,日,星期月
void SetPCF8563(Uchar idata *Setip)
{
	Uchar i;
	I2CStart();
	Writex(0xA2);
	AutoACK();
	Writex(0x02);
	AutoACK();
	for(i=0;i<7;i++)
	{
		Writex(*Setip++);
		AutoACK();
	}
	I2CStop();
}

Uchar ReadPCF8563(Uchar AddrePCF)
{
	Uchar i;
	I2CStart();
	Writex(0xA2);
	AutoACK();
	Writex(AddrePCF);
	AutoACK();
	I2CStart();
	Writex(0xA3);
	AutoACK();
	i =Readx();
	//ACK();	//注意:这里不能有ACK应答信号//
	I2CStop();
	Delay_1ms(0);
	return(i);
}
void WritePCF8563(Uchar AddrePCF,Uchar PCFdata)
{
	I2CStart();
	Writex(0xA2);
	AutoACK();
	Writex(AddrePCF);
	AutoACK();
	Writex(PCFdata);
	AutoACK();
	I2CStop();
	Delay_1ms(10);
}
	 

⌨️ 快捷键说明

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