/******************************************************************************** Copyright (C), Sinowealth Electronic. Ltd. Author: Sino Version: V0.0 Date: 2020/04/26 History: V2.0 2020/04/26 Preliminary ********************************************************************************/ #include "Main.h" #ifdef TWI_Hardware_Module U8 code CRC8Table[256]= { //120424-1 CRC Table 0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D, 0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D, 0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD, 0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD, 0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA, 0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A, 0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A, 0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A, 0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4, 0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4, 0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44, 0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34, 0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63, 0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13, 0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83, 0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3 }; /************************************************************************************************* * 函数名: CRC8cal * 参 数: *p:数据指针;counter:所需计算的长度 * 返回值: 无 * 描 述: CRC8就散 *************************************************************************************************/ U8 CRC8cal(U8 *p, U8 counter) //look-up table calculte CRC { U8 crc8 = 0; for( ; counter > 0; counter--) { crc8 = CRC8Table[crc8^*p]; p++; } return(crc8); } /************************************************************************************************* * 函数名: TWICheckStatus * 参 数: Status:当前TWI的状态 * 返回值: 无 * 描 述: 检测TWI的各个状态是否正常 *************************************************************************************************/ BOOL TWICheckStatus(U8 Status) { BOOL Result = 1; U16 timeoutcount = 48000; //硬件IIC时timeoutcount大于100可正常通讯,软件IIC建议保持原值 (标准DEMO板) while((TWICON&0x08)==0) //等待TWI通讯结束 { McuWDTClear(); //清除看门狗 if(timeoutcount) { timeoutcount--; } else { break; } } if((TWISTA&0xf8) != Status) { Result = 0; //Error } return Result; } /************************************************************************************************* * 函数名: TwiWrite * 参 数: SlaveID: Slave ID WrAddr: 写入地址 AddrType:地址长度,0:长度为1Byte;1:长度为2Bytes Length: 数据长度(不含CRC字节) CrcFlg: Twi通讯是否支持CRC校验,0:不支持CRC,1:支持CRC *WrBuf: 写入数据存放地址 * 返回值: 无 * 描 述: Twi写入操作,包括写入AFE(支持CRC)、RTC和EEPROM(地址长度为2Bytes) *************************************************************************************************/ BOOL TwiWrite(U8 SlaveID, U16 WrAddr, U8 AddrType, U8 Length, U8 CrcFlg, U8 xdata *WrBuf) { U8 i; U8 TempBuf[4]; BOOL Result = 1; U16 timeoutcount = 48000; TempBuf[0] = SlaveID; TempBuf[1] = (U8)WrAddr; TempBuf[2] = *WrBuf; TempBuf[3] = CRC8cal(TempBuf, 3); if(Length > 0) { HTimeoutChk(); TWICON = 0x60; //Start if((!TWICheckStatus(0x08))&&(!TWICheckStatus(0x10))) { Result = 0; goto WrErr; } TWIDAT = SlaveID; //Slave地址 TWICON = 0x40; if(!TWICheckStatus(0x18)) { Result = 0; goto WrErr; } if(AddrType == TWI_ADDR_2B) { TWIDAT = (U8)(WrAddr>>8); //写寄存器高字节地址-仅针对外挂EEPROM TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto WrErr; } } TWIDAT = (U8)WrAddr; //写寄存器地址 TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto WrErr; } if(CrcFlg == TWI_CRC_YES) //如果是写AFE寄存器,则固定写一个字节+CRC { TWIDAT = *WrBuf; //Write Data TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto WrErr; } TWIDAT = TempBuf[3]; //Write CRC TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto WrErr; } } else //写EEPROM和RTC { for(i=0; i 0) { HTimeoutChk(); TWICON = 0x60; //Start if((!TWICheckStatus(0x08))&&(!TWICheckStatus(0x10))) { Result = 0; goto RdErr; } TWIDAT = SlaveID; //发送Slave写地址 TWICON = 0x40; if(!TWICheckStatus(0x18)) { Result = 0; goto RdErr; } if(AddrType == TWI_ADDR_2B) //地址为2Bytes { TWIDAT = (U8)(RdAddr>>8); //读寄存器高字节地址-仅针对外挂EEPROM TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto RdErr; } } TWIDAT = (U8)RdAddr; //发送寄存器低字节地址 TWICON = 0x40; if(!TWICheckStatus(0x28)) { Result = 0; goto RdErr; } // if(SlaveID != AFE_ID) // { // TWIDAT = Length; //发送读取数据长度 // TWICON = 0x40; // if(!TWICheckStatus(0x28)) // { // Result = 0; // goto RdErr; // } // } TWICON = 0x60; //发送RStart if((!TWICheckStatus(0x08))&&(!TWICheckStatus(0x10))) { Result = 0; goto RdErr; } TWIDAT = SlaveID|0x01; //发送Slave读地址 TWICON = 0x40; if(!TWICheckStatus(0x40)) { Result = 0; goto RdErr; } for(i=0; i= 10)&&(TWI_FREQ_KHz <= 400)) // { // #if TWIBR1 < 256 // TWIBR = TWIBR1; // TWISTA |= 0x06; // #elif TWIBR2 < 256 // TWIBR = TWIBR2; // TWISTA |= 0x04; // #elif TWIBR3 < 256 // TWIBR = TWIBR3; // TWISTA |= 0x02; // #elif TWIBR4 < 256 // TWIBR = TWIBR4; // TWISTA |= 0x00; // #endif // } // #else // { // #error: "Please enter a number(TWI_FREQ_KHz) from 10 to 400!"; // } // // #endif TWICON = 0x40; //ENTWI ,禁止高电平超时 TWTFREE = 0xff; //最大超时配置 TWIDAT = 0x00; } //void TwiInit(void) //{ // U16 i,k; // U8 j; // TWICR = 0x32; //默认配置:SCL--P0.5;SDA--P0.4 // TWITOUT = 0x00; //外部有上拉电阻,故芯片内部上拉不用使能 // i = (24000/TWI_FREQ_KHz-16)/2; //配置发送波特率,禁止总线超时判断,f=fsys/(16+2*CR*TWIBR)=24MHz/(16+2*16*TWIBR)=**KHz // for(j=1;j<4;j++) // { // k =1<<(2*j-2); // if(i / k <= 255) // { // TWIBR = i / k; // switch (j) // { // case 1: // TWISTA = 0x00; // break; // // case 2: // TWISTA = 0x02; // break; // // case 3: // TWISTA = 0x04; // break; // // case 4: // TWISTA = 0x06; // break; // } // goto loop; // } // } //loop: //// TWISTA = 0x06; //16分频 // TWICON = 0x40; //ENTWI ,禁止高电平超时 // TWTFREE = 0xff; //最大超时配置 // TWIDAT = 0x00; //} #endif