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

📄 smbus.c

📁 mcf5307开发板上进行iic接口实验
💻 C
字号:
/*  * Purpose:		M-Bus Subrouting *  */#define IMMaddr	0x10000000#define SDRAMaddr 0x00000000#define SDRAMsize 0x00800000		//8M#define SRAMaddr 0x00800000#define SRAMsize (4 * 1024)		//4K#define Read       0x00#define Write      0x01#define bool unsigned char#include "mcf5307.h" #include "time.h"//Global Pointerextern MCF5307_IMM *imm;struct time Time;  unsigned int AddressNumber;unsigned int DataNumber;unsigned int MbusBytesTransmitted;unsigned char  MbusMode;unsigned char  MbusCompleted;unsigned char  MTxData[10];unsigned char  MRxData[10];unsigned char *PtrAddress;unsigned char *PtrData;unsigned char Second;unsigned long int MbusOver;bool TestOver(void);   void InitMbus(void);bool ReadB(void);bool WriteB(void);void TestHang(void);void IicDelay(void);bool SetRTC8563(struct time *Time);bool GetRTC8563(struct time *Time);bool InitRTC8563(void);//to Init. M-busvoid InitMbus(void){	unsigned char Status;   	TestHang();   	imm->mbus.MBCR=0x00;       //disenable the I2cbus ,disenable the I2c int, select slave mode.   	imm->mbus.MFDR=0x32;       //the frequncy of I2c is 45M/224=200K  / 45M  / 896  =50K   	imm->mbus.MADR=0x11;       //slave address ,may no use      	imm->sim.ICR3=0x8c;        //100 011 00: autovector, level 3 and prority 0; the source of    	                           // the int is inside mode int        	Status=imm->mbus.MBCR;     //generate a stop   	Status&=0xdf;              //to clear the MSTA of the MBCR   	imm->mbus.MBCR=Status;     // to stop the bus(d5 of the MBCR is from 1 to 0) 	   	imm->mbus.MBCR=0xc0;	   //enable the I2c and I2c int ,as slave  1100-0000}bool ReadB(void){   	unsigned char Status;   	IicDelay();   	IicDelay();   	MbusOver=0;   	MbusCompleted=0x00;                //0xff means  data OK!   	MbusMode=Read;   	MbusBytesTransmitted=0;      	Status=imm->mbus.MBSR;             // get the I2c status from the I2c status register     	Status=imm->mbus.MBSR;		   // ?????? can it be canceled???????   	Status&=0xfd;                      //to clear MIF, clear mbus int   	imm->mbus.MBSR=Status;      	Status=imm->mbus.MBSR;   	while( (Status&0x20)==0x20 )   	{    		Status=imm->mbus.MBSR;            //if  busy ,then wait   MBB    		if(TestOver()==0x00)     		return 0x00;   	}   	MbusOver=0x00;   	   	Status=imm->mbus.MBCR;   	Status|=0x10;                      //switch to transmit mode by setting the MTX   	imm->mbus.MBCR=Status;      	Status=imm->mbus.MBCR;   	Status|=0x20;                      //generate the "start" I2c (MSTA from 0 to 1 )   	imm->mbus.MBCR=Status;      	imm->mbus.MBDR=*PtrAddress;        //load the first byte (Address) to MBDR   	PtrAddress++;   	Status=imm->mbus.MBSR;   	while( (Status&0x20)!=0x20 )   	{    		Status=imm->mbus.MBSR;            //if  not busy ,then wait   MBB    		if(TestOver()==0x00)     		return 0x00;   	}         	MbusOver=0x00;      	while(MbusCompleted==0x00)   	{    		if(TestOver()==0x00)     		return 0x00;   	}   	return 0x01;}bool WriteB(void){   	unsigned char Status;   	IicDelay();   	IicDelay();   	MbusCompleted=0x00;                //0xff means  data OK!   	MbusMode=Write;   	MbusBytesTransmitted=0;      	Status=imm->mbus.MBSR;    	Status=imm->mbus.MBSR;   	Status&=0xfd;                      //to clear MIF, clear mbus int   	imm->mbus.MBSR=Status;    	MbusOver=0x00;        	Status=imm->mbus.MBSR;   	while( (Status&0x20)==0x20 )   	{    		Status=imm->mbus.MBSR;            //if  busy ,then wait   MBB    		if(TestOver()==0x00)     		return 0x00;   	}      	Status=imm->mbus.MBCR;   	Status|=0x10;                      //switch to transmit mode   MTX   	imm->mbus.MBCR=Status;      	Status=imm->mbus.MBCR;   	Status|=0x20;                      //generate the "start"   MSTA   	imm->mbus.MBCR=Status;      	imm->mbus.MBDR=*PtrAddress;        //load the first byte (Address) to MBDR   	PtrAddress++;   	MbusOver=0x00;    	Status=imm->mbus.MBSR;   	while( (Status&0x20)!=0x20 )   	{    		Status=imm->mbus.MBSR;            //if  not busy ,then wait   MBB    		if(TestOver()==0x00)     		return 0x00;   	}        	MbusOver=0x00;       	while(MbusCompleted==0x00)   	{     	if(TestOver()==0x00)      		return 0x00;   	}      	return 0x01;}void Interrupt_mbus(){ 	unsigned char Status;	Status=imm->mbus.MBSR;      	if (2 != (Status&2) )     return;   	Status&=0xfd;                      //to clear MIF   	imm->mbus.MBSR=Status;	   	MbusBytesTransmitted++;	    	if( (MbusMode==Read)&(MbusCompleted!=0xff)) 	{ 		if(MbusBytesTransmitted==1)        //means trans address ok!  		{   			Status=imm->mbus.MBSR;   			if((Status&0x01)==0x01)                           		return;                   //no ack ,then error       			if( (AddressNumber) >1)           //if Address Number >1 continue to trans    			{      				imm->mbus.MBDR=*PtrAddress;    //load the next byte      				PtrAddress++;	    	      				return;    			}   			else    			{      				Status=imm->mbus.MBCR;          //only one address ,then switch to rx mode      				Status&=0xef;             	    //switch to receive mode   MTX      				if(DataNumber==1)               //if only one data ,then no ack        				Status|=0x08;                //change TXAK  bit     				else        				Status&=0xf7;        				imm->mbus.MBCR=Status;     				Status=imm->mbus.MBDR;          //dummy  read  to generarate clock        				return;     			}	  	  		}  		else if(MbusBytesTransmitted<AddressNumber)  		{     			imm->mbus.MBDR=*PtrAddress;     //load the next address byte     			PtrAddress++;   	     			return;   		}  		else if(MbusBytesTransmitted==AddressNumber)  		{  	    		if(DataNumber!=0)    			{	     				Status=imm->mbus.MBCR;          //     				Status&=0xef;                  //switch to receive mode   MTX     				if(DataNumber==1)               //if only one data ,then no ack        				Status|=0x08;                //change TXAK  bit     				else        				Status&=0xf7;        				imm->mbus.MBCR=Status;          			Status=imm->mbus.MBDR;          //dummy  read  to generarate clock             	     				return;    			}   			else   			{     				Status=imm->mbus.MBCR;        //    DataNumber?=0  ,it's funny     				Status&=0xdf;     				imm->mbus.MBCR=Status;        // to stop the bus 	 	     				MbusCompleted=0xff;	     				return;   			}     		}      		else if(MbusBytesTransmitted==(AddressNumber+DataNumber-1))  		{   	     			Status=imm->mbus.MBCR;     			Status|=0x08;     			imm->mbus.MBCR=Status;         		     			*PtrData=imm->mbus.MBDR;       //this is the 2nd last data ,so next data(Last data) no ack     			PtrData++;     			return;     		}  		else if( MbusBytesTransmitted==(AddressNumber+DataNumber) )  		{     			Status=imm->mbus.MBSR;	     			Status=imm->mbus.MBCR;     			Status&=0xdf;     			imm->mbus.MBCR=Status;        // to stop the bus 		     			*PtrData=imm->mbus.MBDR;      //read the last data     			MbusCompleted=0xff;      			imm->mbus.MBCR=Status;        // to stop the bus      			Status=imm->mbus.MBSR;     			return;  		}  		else  		{       			Status=imm->mbus.MBCR;     			Status&=0xf7;     			imm->mbus.MBCR=Status;		     			*PtrData=imm->mbus.MBDR;       //this is not the 2nd last data nor the last one,so next data(Last data) need ack     			PtrData++;		     			return;  		}  	}        //this is the end of ReadBytes  	if( (MbusMode==Write)&(MbusCompleted!=0xff)) 	{ 		if(MbusBytesTransmitted==1)        //means trans address ok!  		{   			Status=imm->mbus.MBSR;   			if((Status&0x01)==0x01)                           		return;           //no ack ,then error       			imm->mbus.MBDR=*PtrAddress;       //load the next address byte    			PtrAddress++;	    			return;		}  		else if(MbusBytesTransmitted<AddressNumber)  		{     			imm->mbus.MBDR=*PtrAddress;     //load the next address byte     			PtrAddress++;   	     			return;   		}  		else if(MbusBytesTransmitted==AddressNumber)  		{     			if(DataNumber==0)     			{      				Status=imm->mbus.MBCR;          //no data      				Status&=0xdf;      				imm->mbus.MBCR=Status;         // to stop the bus 		      				MbusCompleted=0xff;	      			}     			else     			{ 	     				//change to DataPointor      				imm->mbus.MBDR=*PtrData;        //load the next data byte      				PtrData++;   	              	      				return;     			}   		}        	else if( (MbusBytesTransmitted>AddressNumber)&&(MbusBytesTransmitted<(AddressNumber+DataNumber)) )  		{   	     			imm->mbus.MBDR=*PtrData;        //load the next data byte     			PtrData++;     			return;     		}  		else if(MbusBytesTransmitted==(AddressNumber+DataNumber) )  		{     			Status=imm->mbus.MBCR;     			Status&=0xdf;     			imm->mbus.MBCR=Status;         // to stop the bus 		     			MbusCompleted=0xff;     			return;  		}  		else  		{      			return;  		}  	}        }bool InitRTC8563(void){   	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x00;         //  write control reg no. 1 and 2     	MRxData[0]=0x40;         //   	MRxData[1]=0x00;	   	      	AddressNumber=2;   	DataNumber=2;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)    		return 0x00;	      	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x09;         //  	     	MRxData[0]=0x80;         //  minute alarm    	MRxData[1]=0x80;	    //  hour alarm   	MRxData[2]=0x80;	    //  date alarm	   	MRxData[3]=0x80;         //  day  alarm    	MRxData[4]=0x80;	    //  clkout at 32.768KHz   	MRxData[5]=0x00;	    //  disenable countor  	   	AddressNumber=2;   	DataNumber=6;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)    		return 0x00;     	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x00;         //  write control reg no. 1 and 2     	MRxData[0]=0x00;         //   	MRxData[1]=0x00;	   	      	AddressNumber=2;   	DataNumber=2;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)    		return 0x00;	      	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x09;         //       	MRxData[0]=0x80;         //  minute alarm    	MRxData[1]=0x80;	    //  hour alarm   	MRxData[2]=0x80;	    //  date alarm	   	MRxData[3]=0x80;         //  day  alarm    	MRxData[4]=0x80;	    //  clkout at 32.768KHz   	MRxData[5]=0x00;	    //  disenable countor  	   	AddressNumber=2;   	DataNumber=6;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)    		return 0x00;}bool SetRTC8563(struct time *Time){   	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x02;         //  write control reg no. 1 and 2     	MRxData[0]=Time->Second;         //   	MRxData[1]=Time->Minute;   	MRxData[2]=Time->Hour;   	MRxData[3]=Time->Date;   	MRxData[4]=Time->Day;   	MRxData[5]=Time->Month;   	MRxData[6]=Time->Year;	   	      	AddressNumber=2;   	DataNumber=7;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)    		return 0x00;   	   	return 0x01;		    }bool GetRTC8563(struct time *Time){   	MTxData[0]=0xa2;         //  write command   	MTxData[1]=0x02;         //  write control reg no. 1 and 2     	MRxData[0]=Time->Second;         //   	MRxData[1]=Time->Minute;   	MRxData[2]=Time->Hour;   	MRxData[3]=Time->Date;   	MRxData[4]=Time->Day;   	MRxData[5]=Time->Month;   	MRxData[6]=Time->Year;	   	      	AddressNumber=2;   	DataNumber=0;   	PtrAddress=MTxData;   	PtrData=MRxData;      	if(WriteB()==0x00)   	//dummy write   		return 0x00;   	   	MTxData[0]=0xa3;             // to read at 02   	MTxData[1]=0x00;     	MRxData[0]=0x55;   	MRxData[1]=0x55;   	MRxData[2]=0x55;   	MRxData[3]=0x55;   	MRxData[4]=0x55;   	MRxData[5]=0x55;   	MRxData[6]=0x55;    	AddressNumber=1;   	DataNumber=7;   	PtrAddress=MTxData;   	PtrData=MRxData;   	if(ReadB()==0x00)    		return 0x00;   	   	Time->Second=(MRxData[0]&0x7f);   	Time->Minute=(MRxData[1]&0x7f);   	Time->Hour=  (MRxData[2]&0x3f);   	Time->Date=  (MRxData[3]&0x3f);   	Time->Day=   (MRxData[4]&0x03);   	Time->Month= (MRxData[5]&0x1f);   	Time->Year=  (MRxData[6]&0x7f);      	return 0x01; 		    }void TestHang(void){ 	unsigned char Status; 	Status= imm->mbus.MBSR;      	imm->mbus.MBCR=0x00;   	imm->mbus.MBCR=0xa0;   	Status= imm->mbus.MBDR;     	IicDelay();   	IicDelay();   	imm->mbus.MBSR=0x00;   	imm->mbus.MBCR=0x00;  }void IicDelay(void){ 	int i; 	for(i=0;i<1000;i++) 	{  		;	 	}		}bool TestOver(void){ 	MbusOver++; 	if(MbusOver>100000)     		return 0x00;	else    		return 0x01;   	}

⌨️ 快捷键说明

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