📄 smbus.c
字号:
/* * Purpose: M-Bus Subrouting * */ #include "..\NUCLEUS\mcf5307.h"#include "main.h"#define IMMaddr 0x10000000#define SDRAMaddr 0x00000000#define SDRAMsize 0x00800000 // 8M#define SRAMaddr 0x00800000#define SRAMsize (4 * 1024) // 4K#define EXT_SRAMaddr 0xFE400000 #define EXT_SRAMsize (128 * 1024) // 128K#define Read 0x00#define Write 0x01#define bool unsigned char//Global Pointerextern MCF5307_IMM *imm;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;struct time Time;bool TestOver(void); void InitMbus(void);bool ReadB(void);bool WriteB(void);bool SetRTC(void);bool ReadRTC(void);void TestHang(void);void IicDelay(void);void TestMbus(void);void TestMbus(void){// imm= (MCF5307_IMM *)0x10000000;// InitMbus(); MTxData[0]=0xa0; //write demo MTxData[1]=0x00; MRxData[0]=0x51; MRxData[1]=0x52; MRxData[2]=0x53; MRxData[3]=0x54; MRxData[4]=0x55; MRxData[5]=0x56; MRxData[6]=0x57; MRxData[7]=0x58; AddressNumber=2; DataNumber=8; PtrAddress=MTxData; PtrData=MRxData; WriteB(); while(1) { MTxData[0]=0xa0; //dummy write to rewind pointor MTxData[1]=0x00; MRxData[0]=0x55; AddressNumber=2; DataNumber=0; PtrAddress=MTxData; PtrData=MRxData; WriteB(); MTxData[0]=0xa1; //to read data MTxData[1]=0x00; MRxData[0]=0x41; MRxData[1]=0x42; MRxData[2]=0x43; MRxData[3]=0x44; MRxData[4]=0x45; MRxData[5]=0x46; MRxData[6]=0x47; MRxData[7]=0x48; AddressNumber=1; DataNumber=8; PtrAddress=MTxData; PtrData=MRxData; ReadB(); } MTxData[0]=0xde; // wel MTxData[1]=0x00; MTxData[2]=0x3f; MRxData[0]=0x02; AddressNumber=3; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; WriteB(); MTxData[0]=0xde; // wel & rwel MTxData[1]=0x00; MTxData[2]=0x3f; MRxData[0]=0x06; AddressNumber=3; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; WriteB(); MTxData[0]=0xde; //write second to start the clock ,32.768k wave should appear on pin2 MTxData[1]=0x00; MTxData[2]=0x30; MRxData[0]=0x00; AddressNumber=3; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; WriteB(); while(1) { MTxData[0]=0xde; //dummy write to rewind pointor to second MTxData[1]=0x00; MTxData[2]=0x30; MRxData[0]=0x55; AddressNumber=3; DataNumber=0; PtrAddress=MTxData; PtrData=MRxData; WriteB(); MTxData[0]=0xdf; //to read data second address=0x30; MTxData[1]=0x00; MRxData[0]=0x41; MRxData[1]=0x42; MRxData[2]=0x43; MRxData[3]=0x44; MRxData[4]=0x45; MRxData[5]=0x46; MRxData[6]=0x47; MRxData[7]=0x48; AddressNumber=1; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; ReadB(); Second=MRxData[0]; } }//to Init. M-busvoid InitMbus(void){ unsigned char Status; TestHang(); imm->mbus.MBCR=0x00; //disenable the mbus ,disenable the int. imm->mbus.MFDR=0x3a; //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 // changed to demo.c // imm->sim.IMR=0x0003f7fe; //enable the mbus int. // asm(" move.w #0x2000,SR "); //enable interrupt}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++; // asm(" move.w #0x2000,SR "); //enable interrupt 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++; // asm(" move.w #0x2000,SR "); //enable interrupt 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 //imm->mbus.MBCR=Status; // Status=imm->mbus.MBCR; 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 //imm->mbus.MBCR=Status; //Status=imm->mbus.MBCR; 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 SetRTC(void){ MTxData[0]=0xde; // wel MTxData[1]=0x00; MTxData[2]=0x3f; MRxData[0]=0x02; AddressNumber=3; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xde; // wel & rwel MTxData[1]=0x00; MTxData[2]=0x3f; MRxData[0]=0x06; AddressNumber=3; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xde; //write second to start the clock ,32.768k wave should appear on pin2 MTxData[1]=0x00; MTxData[2]=0x30; MRxData[0]=Time.Second; MRxData[1]=Time.Minute; MRxData[2]=Time.Hour; MRxData[3]=Time.Date; MRxData[4]=Time.Month; MRxData[5]=Time.Year; MRxData[6]=0x01; MRxData[7]=0x20; AddressNumber=3; DataNumber=8; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; return 0x01; }bool SetRTC1337(void){ MTxData[0]=0xd0; // write command MTxData[1]=0x0e; // write control reg MRxData[0]=0x80; //stop rtc, 1Hz, enable all out. AddressNumber=2; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xd0; //write second to start the clock ,32.768k wave should appear on pin2 MTxData[1]=0x00; MRxData[0]=Time.Second; MRxData[1]=Time.Minute; MRxData[2]=Time.Hour; MRxData[3]=0x01; //day MRxData[4]=Time.Date; MRxData[5]=Time.Month; MRxData[6]=Time.Year; AddressNumber=2; DataNumber=7; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xd0; // write command MTxData[1]=0x0e; // write control reg MRxData[0]=0x00; //start rtc, 1Hz, enable all out. AddressNumber=2; DataNumber=1; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; return 0x01; }bool ReadRTC(void){ MTxData[0]=0xde; //dummy write to rewind pointor to second MTxData[1]=0x00; MTxData[2]=0x30; MRxData[0]=0x55; AddressNumber=3; DataNumber=0; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xdf; //to read data second address=0x30; MTxData[1]=0x00; MRxData[0]=0x55; MRxData[1]=0x55; MRxData[2]=0x55; MRxData[3]=0x55; MRxData[4]=0x55; MRxData[5]=0x55; MRxData[6]=0x55; MRxData[7]=0x55; AddressNumber=1; DataNumber=2; PtrAddress=MTxData; PtrData=MRxData; if(ReadB()==0x00) return 0x00; Time.Second=MRxData[0]; Time.Minute=MRxData[1]; Time.Hour=MRxData[2]; Time.Date=MRxData[3]; Time.Month=MRxData[4]; Time.Year=MRxData[5]; return 0x01;}bool ReadRTC1337(void){ MTxData[0]=0xd0; //dummy write to rewind pointor to second MTxData[1]=0x00; AddressNumber=2; DataNumber=0; PtrAddress=MTxData; PtrData=MRxData; if(WriteB()==0x00) return 0x00; MTxData[0]=0xd1; //to read data second address=0x30; MRxData[0]=0x55; MRxData[1]=0x55; MRxData[2]=0x55; MRxData[3]=0x55; MRxData[4]=0x55; MRxData[5]=0x55; MRxData[6]=0x55; MRxData[7]=0x55; AddressNumber=1; DataNumber=7; PtrAddress=MTxData; PtrData=MRxData; if(ReadB()==0x00) return 0x00; Time.Second=MRxData[0]; Time.Minute=MRxData[1]; Time.Hour=MRxData[2]; Time.Date=MRxData[4]; //no day Time.Month=MRxData[5]; Time.Year=MRxData[6]; 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 + -