📄 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 "..\nucleus\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);void TestMbus(void);void TestMbus(void){ bool Status; Time.Second=0x01; Time.Minute=0x01; Time.Hour=0x01; Time.Date=0x01; Time.Day=0x01; Time.Month=0x01; Time.Year=0x04; Status=InitRTC8563(); Status=SetRTC8563(&Time); while(1) { Status=GetRTC8563(&Time); } }//to Init. M-busvoid InitMbus(void){ unsigned char Status; TestHang(); imm->mbus.MBCR=0x00; //disenable the mbus ,disenable the int. imm->mbus.MFDR=0x32; //45M/224=200K / 45M / 896 =50K imm->mbus.MADR=0x11; //slave address ,may no use imm->sim.ICR3=0x8c; //100 011 00: autovector and level 3, prority 0 Status=imm->mbus.MBCR; //generate a stop Status&=0xdf; imm->mbus.MBCR=Status; // to stop the bus imm->mbus.MBCR=0xc0; //enable the int ,as slave 1100-0000}bool ReadB(void){ unsigned char Status; // TestHang(); IicDelay(); IicDelay(); MbusOver=0; MbusCompleted=0x00; //0xff means data OK! MbusMode=Read; MbusBytesTransmitted=0; Status=imm->mbus.MBSR; Status=imm->mbus.MBSR; Status&=0xfd; //to clear MIF 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 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++; 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; // TestHang(); 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 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; //if( (Status&0x20)==0x20 ) // { 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 + -