若是AVR的TWI,要注意每次通信都要先 DDRC &= ~((1 << SCL) | (1 << SDA));//SCL、SDA 引脚内部上拉电阻 TWCR &= ~(1 << TWEN); PORTC |= (1 << SCL) | (1 << SDA);//SCL、SDA 引脚内部上拉电阻 再在TWStart()内TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
我反复做过实验...把我害苦了...助好友TestCode成功!!!
哈哈...以下程序在ouravr那里都没舍得发...(非常好用)
inline void TwiObj::WorkExec(void) { static unsigned char Count = 0; unsigned char worknum; DDRC &= ~((1 << SCL) | (1 << SDA));//SCL、SDA 引脚内部上拉电阻 TWCR &= ~(1 << TWEN); PORTC |= (1 << SCL) | (1 << SDA);//SCL、SDA 引脚内部上拉电阻 if (Busy) {//主机忙 TWStop(); } else { MainCount = 0;//发送0个数据 SubComm = 0;//不允许发送数据 SubCount = 4;//接收4个数据 Count &= 0x0f;//16个为一轮 if ((Count & 1) == 0) {//偶数为1通道 worknum = 0; SubAddr = UsiSlaveAddrRd1;//从机地址 } else {//奇数为2通道 worknum = 1; SubAddr = UsiSlaveAddrRd2;//从机地址 } //..................
inline void TwiObj::TWStart(void) { Busy = true; Status = 0;//主机准备发送启始位 Count = 0;//发送数据个数 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE); }
inline void TwiObj::TWREStart(void) { Busy = true; Status = 0x55;//主机准备发送启始位 Count = 0;//接收数据个数 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE); }
inline void TwiObj::TWStop(void) { Busy = false; // Status = 0xaa;//pwy Count = 0; TWCR = (1 << TWINT) | (1 << TWSTO);//关闭TWIE//pwy }
//inline(不敢加) void TwiObj::Exec(void) { // TW_Error = TW_STATUS; // if (!Busy) TWStop();//pwy // else { switch(TW_STATUS) { case TW_START://主机收到自己发送的开始信号 if (Status == 0) {//本次中断应该接收TW_START信号//pwy TWDR = SubAddr & 0xfe;//发送子机地址(写) Status = 1;//Status下次主发为1,主收为2 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去 //::Uart.puts("TW_START"); //::Uart.putstr("Status="); //::Uart.puthex(Status); //::Uart.puts(""); } else TWStop(); break; case TW_REP_START://主机收到自己发送的重新开始信号 if ((Status == 0x55) && (SubAddr & 0xfe)) {//本次中断应该接收TW_START信号//pwy TWDR = SubAddr;//发送子机地址(读) Status = 2;//Status下次主发为1,主收为2 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去 } else TWStop(); break; case TW_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令 if (Status == 1) {//本次中断应该接收TW_MT_SLA_ACK信号 Status = 3;//Status下次应该收TW_MT_DATA_ACK TWDR = SubComm;//发送子机命令 /*----------------------------------------------------------------------------- 以后可以复杂些 -----------------------------------------------------------------------------*/ TxBuffer[0] = SubComm;//简单命令校验 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去 //::Uart.puts("TW_MT_SLA_ACK"); //::Uart.putstr("Status="); //::Uart.puthex(Status); //::Uart.puts(""); } else TWStop(); break; case TW_MR_SLA_ACK://主收机接收到从机的地址应答信号 if (SubCount && (Status == 2)) {//本次中断应该接收TW_MR_SLA_ACK信号 Status = 4;//Status下次应该收TW_MR_DATA_ACK TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);//主机转入接收状态 //::Uart.puts("TW_MT_SLA_ACK"); //::Uart.putstr("Status="); //::Uart.puthex(Status); //::Uart.puts(""); } else TWStop(); break; case TW_MT_DATA_ACK: if ((Count < MainCount) && (Status == 3) && ((SubAddr & 1) == 0)) {//本次中断应该接收TW_MT_DATA_ACK信号 TWDR = TxBuffer[Count ++];//发送子机数据 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//发送出去 } else if ((Count == MainCount) && (Status == 3) && (SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号 TWREStart();// } // else if ((Count == MainCount) && (Status == 3) && ((SubAddr & 1) == 0)) { // TW_Error = 0xfe;//数据发送成功 // TWStop(); // } else TWStop(); break; // case TW_MT_DATA_NACK://数据发送结束 // if ((Count == MainCount) && (Status == 4)) { // TW_Error = 0xf0;//数据发送失败 // } // TWStop(); // break; case TW_MR_DATA_ACK: if ((Count < SubCount) && (Status == 4)) { RxBuffer[Count ++] = TWDR;//接收子机数据 if (Count < SubCount) TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE) | (1 << TWEA);//主机转入接收状态 else TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWIE);//主机转入接收状态 } else TWStop(); break; case TW_MR_DATA_NACK://数据接收结束 //::Uart.puts("TWI_GOOD"); if ((Count == SubCount) && (Status == 4)) { if (((RxBuffer[0] ^ RxBuffer[2]) == 0xff) && ((RxBuffer[1] ^ RxBuffer[3]) == 0xff)) { if ((RxBuffer[0] & 0xf0) == (SubComm & 0xf0)){ SetTwiDataBuff(); //Uart.puts("TWI_GOOD"); } } //::Uart.puts("TWI_GOOD"); // TW_Error = 0xff;//数据接收成功 } // TWStop(); // break; default: TWStop(); //::Uart.puts("TWI_BAD"); //::Uart.putstr("TW_STATUS="); //::Uart.puthex((unsigned int)TW_STATUS); //::Uart.puts(""); break; } // } }
|
文章评论(0条评论)
登录后参与讨论