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

📄 13.3(8583).c

📁 数字信号处理器 原理、结构及应用基础-TMS320F28x所附光盘源程序C-C++ 刘和平等编著
💻 C
字号:
/****************************************************************
** 功能描述:该程序实现对I2C总线日历时钟芯片PCF8583的读写操作**
****************************************************************/ 
//GPIOF1 SCL ,GPIOF3 SDA
#include "DSP28_Device.h"
#define 	TDATA_H	   0x0002		//FLOATS DATA LINE (IOPF1=1)  
#define	TSHIFTNUM		5
#define 	TNUMBER       6		    //读写PCF8583的参数字个数
unsigned int 	time[4]; //time[0]年(XXXX XXXX XXXX XXXX) 
                   //time[1]月(XXXX XXXX)日(XXXX XXXX)、
		           //time[2]星期(0000 XXXX)时(XXXX XXXX)
                   //time[3]分(XXXX XXXX)秒(XXXX XXXX)
unsigned int   year_base=0x2004;   //PCF8583的年份时基
unsigned int 	chtime[4];          //写日历时钟
unsigned int	pcf_data[6],flag;

/*****************************************************************
** 函数名:prom_transmit()
** 功能描述:I2C发送一字节子程序
****************************************************************/ 
void prom_transmit(unsigned int promdata)  
{	
	unsigned long int i = 0;
    unsigned int k = 0;
    EALLOW;                      /*SDA output*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
	EDIS;	
		
	for(k=0;k<8;k++)  
	{
		GpioDataRegs.GPFDAT.bit.GPIOF1=0;			/*SCL=0*/
	  	for (i=0;i<100;i++){}			
	  	if(promdata&0x0080)
	  		GpioDataRegs.GPFDAT.bit.GPIOF3=1;		/*SDA=1*/
	 	else
	  		GpioDataRegs.GPFDAT.bit.GPIOF3=0;		/*SDA=0*/
	  	for (i=0;i<100;i++){};					
	  	GpioDataRegs.GPFDAT.bit.GPIOF1=1;			/*SCL=1*/
	  	for (i=0;i<200;i++){};
	  	promdata=promdata<<1;
	}
}
		  
/*****************************************************************
** 函数名:prom_receive()
** 功能描述:I2C接收一字节子程序
****************************************************************/ 	       	
unsigned int prom_receive() 
{	
    unsigned long int i = 0;
    unsigned int k = 0 ;
	unsigned int promdata=0x0000;
	EALLOW;                      /*SDA input*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=0;
	EDIS;		
	
	for(k=0;k<8;k++) 
	{
		promdata=promdata<<1;
		GpioDataRegs.GPFDAT.bit.GPIOF1=0;	    	/*SCL=0*/
		for (i=0;i<200;i++){};
		GpioDataRegs.GPFDAT.bit.GPIOF1=1;			/*SCL=1*/
		for (i=0;i<100;i++){};
	  	if(GpioDataRegs.GPFDAT.bit.GPIOF3==0)
	  		promdata=promdata&0xFFFE; /*如果数据位为0,则R_DATA最低位清零*/
		else  
 			promdata=promdata|0x0001;
 		for (i=0;i<100;i++){};	
	}
	return(promdata);	
}

/*****************************************************************
** 函数名:prom_start()
** 功能描述:I2C 启动子程序
****************************************************************/ 
void prom_start() 
{	
 	unsigned long int i = 0;
 	EALLOW;                      /*SDA output*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
	EDIS;
	
 	GpioDataRegs.GPFDAT.bit.GPIOF1=0;		//SCL=0
 	for (i=0;i<100;i++){}
 	GpioDataRegs.GPFDAT.bit.GPIOF3=1;		//SDA=1
 	for (i=0;i<100;i++){};
	GpioDataRegs.GPFDAT.bit.GPIOF1=1;		//SCL=1
	for (i=0;i<100;i++){};	
 	GpioDataRegs.GPFDAT.bit.GPIOF3=0;		//SDA=0
 	for (i=0;i<100;i++){};	
}	
/*****************************************************************
** 函数名:prom_stop()
** 功能描述:I2C 结束子程序
****************************************************************/  	
void prom_stop() 
{
 	unsigned long int i = 0;
 	EALLOW;                      /*SDA output*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
	EDIS;
		
 	GpioDataRegs.GPFDAT.bit.GPIOF1=0;			//SCL=0
 	for (i=0;i<100;i++){}
 	GpioDataRegs.GPFDAT.bit.GPIOF3=0;			//SDA=0
 	for (i=0;i<100;i++){}		
 	GpioDataRegs.GPFDAT.bit.GPIOF1=1;			//SCL=1	
 	for (i=0;i<100;i++){}	
 	GpioDataRegs.GPFDAT.bit.GPIOF3=1;			//SDA=1
 	for (i=0;i<100;i++){}
}
/*****************************************************************
** 函数名:prom_slave_ack()
** 功能描述:I2C 从机应答子程序
****************************************************************/ 
unsigned int prom_slave_ack()  
{	
	unsigned long int i = 0;
    unsigned int k = 0 ;                       
 	EALLOW;                      		   /*SDA input*/
   	GpioMuxRegs.GPFDIR.bit.GPIOF3=0;
	EDIS;
	GpioDataRegs.GPFDAT.bit.GPIOF1=0;	   /*SCL=0*/
 	for (i=0;i<200;i++){};
 	GpioDataRegs.GPFDAT.bit.GPIOF1=1;	   /*SCL=1*/	
 	for (i=0;i<100;i++){};
 	if(GpioDataRegs.GPFDAT.bit.GPIOF3==0)
 		k=0;					
 	else
 		k=1;                  //失败
 	for (i=0;i<100;i++){};
   	return(k);     
}
/*****************************************************************
** 函数名:prom_no_ack()
** 功能描述:I2C 主机不发应答子程序
****************************************************************/ 
void prom_no_ack() 
{
	unsigned long int i = 0;
	EALLOW;                            /*SDA output*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
	EDIS;
	
	GpioDataRegs.GPFDAT.bit.GPIOF1=0;		//SCL=0
	GpioDataRegs.GPFDAT.bit.GPIOF3=1;		//SDA=1
 	for (i=0;i<200;i++){}		
 	GpioDataRegs.GPFDAT.bit.GPIOF1=1;		//SCL=1
	for (i=0;i<200;i++){}		
} 
/*****************************************************************
** 函数名:prom_master_ack()
** 功能描述:I2C 主机应答子程序
****************************************************************/ 
void prom_master_ack()  
{
	unsigned long int i = 0;
	EALLOW;                            /*SDA output*/
    GpioMuxRegs.GPFDIR.bit.GPIOF3=1;
	EDIS;
	
	GpioDataRegs.GPFDAT.bit.GPIOF1=0;		//SCL=0
	GpioDataRegs.GPFDAT.bit.GPIOF3=0;		//SDA=0
	for (i=0;i<200;i++){}
	GpioDataRegs.GPFDAT.bit.GPIOF1=1;		//SCL=1
	for (i=0;i<200;i++){}		
}
/*****************************************************************
** 函数名:write()
** 功能描述:写数据子程序(单字节)
****************************************************************/
int write(unsigned int *array,unsigned int num)
 {
 	unsigned int j = 0;
    unsigned int k = 0 ;
 	for(j=0;j<num;j++)  
		{	
	  		prom_transmit(*array&0xff);	        //送低8位
	  		k=prom_slave_ack();
	  		if(k==1)break;
	  		array++;
		}
	return(k);
}
/*****************************************************************
** 函数名:read()
** 功能描述:读数据子程序(单字节)
****************************************************************/
Uint16 read(unsigned int *array,unsigned int num)
{
    unsigned int j = 0;
    unsigned int k = 0;
    Uint16 temp=0x00;
	prom_start();
	prom_transmit(0x00a3);
	k=prom_slave_ack();
    if(k==0)	
	{	
		for(j=0;j<(num-1);j++) 
		{
	  		temp=prom_receive();
	  		prom_master_ack();
	  		*array=temp&0x00ff;
	  		array++;
	  	}
	  	temp=prom_receive();
	  	prom_no_ack();
	  	*array=temp&0x00ff;
	  	prom_stop();
	  	k=0;
	}
	return(k);   
} 
/*****************************************************************
** 函数名:prom_wr()
** 功能描述:连续页读写子程序
**入口:要写数据的数组首址ARRAY,要写的起始地址ADDR,读写控制字,
		要写的字数num
**出口:返回0或1。为0表示操作成功;为1表示操作失败
****************************************************************/ 		
unsigned int prom_wr(unsigned int *array,unsigned int addr,Uint16 control,unsigned int num) 
{   
    unsigned long int i = 0;
    unsigned int k = 0 ;
    unsigned int addr_l; //addr_h,addr_l;  
	//addr_h=(addr>>8)&0x00ff;
	addr_l=addr&0x00ff;
	prom_start();
   	k=control&0xFFFE;               //清除控制字节第0位
	        prom_transmit(k);		//送写控制字
	        k=prom_slave_ack();	
	if(k==0)
	   	{	
	   		prom_transmit(addr_l);  //送地址低位
	        k=prom_slave_ack();
	     }
    if(k==0)
        {
        	i=control&0x0001;
        	if(i==0x0000)
        		k=write(array,num);
        	else 	
        		k=read(array,num);
		}		
	prom_stop();
	return(k);   
}  

void time_write()
{	
    //year_base=0x2004;			//PCF8583的年份时基
	chtime[0]=0x0001;			//2005年			
	chtime[1]=0x0522;			//05月22日
	chtime[2]=0x0017;			//星期0 17点
	chtime[3]=0x1030;			//10分30秒
	pcf_data[0]=0x0;					
	pcf_data[1]=chtime[3]&0x00ff;			//second
	pcf_data[2]=(chtime[3]&0xff00)>>8;		//minute
	pcf_data[3]=chtime[2]&0x00ff;			//hour;
	pcf_data[4]=((chtime[0]&0x03)<<6)|(chtime[1]&0x003f);	//year/date
	pcf_data[5]=((chtime[2]&0x0700)>>3)|((chtime[1]&0x1f00)>>8);//week/month
	prom_wr(&pcf_data[0],0x0001,0xa2,TNUMBER);
} 

void IOinit()
{
	//定义GPIOF1,F3为一般I/O口,	GPIOF1为输出
	EALLOW;	
	GpioMuxRegs.GPFMUX.bit.SPISOMIA_GPIOF1=0;
	GpioMuxRegs.GPFMUX.bit.SPISTEA_GPIOF3=0;
	GpioMuxRegs.GPFDIR.bit.GPIOF1=1;
	EDIS;
}

main(void) 
{
   	unsigned long int i = 0;
   	InitSysCtrl();  // 系统初始化程序,该子程序在DSP28_sysctrl.c中
 	DINT;           // 关闭总中断
	IER = 0x0000;   // 关闭外围中断
	IFR = 0x0000;   // 请中断标志	
	IOinit();	    // I/O初始化子程序
	time_write();   // 写PCF8583的参数 
	for (i=0;i<1000000;i++){};
	
	//读PCF8583的参数 
	while (1)
	{
		flag=prom_wr(&pcf_data[0],0x0001,0xa3,TNUMBER); //flag=0x00;则读数成功
		if (flag==0)
		{
			time[0]=year_base+(pcf_data[4]>>6);//year
			time[1]=((pcf_data[5]&0x001f)<<8)|(pcf_data[4]&0x003f);	//month,date
			time[2]=((pcf_data[5]&0x00e0)<<3)|(pcf_data[3]);	//week.hour
			time[3]=(pcf_data[2]<<8)|pcf_data[1];		//minute,second
			for (i=0;i<1000000;i++){};
		}
	}
}

⌨️ 快捷键说明

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