关于BF51x TWI的应用的问题:
TWI用作EEPROM的驱动(IIC)
/**************************************************************************** * 名称 : Reset_TWI * 功能 : 复位 TWI接口 * 入口参数 :无 * 返回值 :无 ****************************************************************************/ void Reset_TWI(void) { //RESET_TWI CONTROLLER *pTWI_CONTROL = RESET_TWI; ssync();
//CLEAR ALL ERRONOUS CONDITIONS BEFORE ENABLING TWI *pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK; ssync();
//CLEAR ALL INTERRUPTS BEFORE ENABLING TWI *pTWI_INT_STAT = SINIT | SCOMP | SERR | SOVF | MCOMP | MERR | XMTSERV | RCVSERV; ssync();
//FLUSH THE FIFOs - BOTH TX AND RX. *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH; ssync(); }
/**************************************************************************** * 名称 : TWI_MasterMode_Write * 功能 : TWI接口写数据 * 入口参数 :无 * 返回值 :无 ****************************************************************************/ void TWI_MasterMode_Write(unsigned short DeviceAddr, unsigned short *TWI_Data_Pointer, unsigned short TX_Count, unsigned short TWI_TX_Length) { int i, j; //FLUSH THE FIFOs - BOTH TX AND RX. *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH; ssync();
*pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK; ssync();
*pTWI_FIFO_CTL = 0; // Clear the bit manually *pTWI_CONTROL = TWI_ENA | PRESCALE_VALUE; // PRESCALE = fsclk/10MHz *pTWI_CLKDIV = ((CLKDIV_HI) << 8) | (CLKDIV_LO); // For 100KHz SCL speed: CLKDIV = (1/100KHz)/(1/10MHz) = 100 -> SCL symetric: CLKHI = 50, CLKLOW = 50 *pTWI_MASTER_ADDR = DeviceAddr; // Target address (7-bits plus the read/write bit the TWI controls for (i = 0; i < TX_Count; i++) { delay(); // # of configurations to send to the sensor *pTWI_XMT_DATA8 = *TWI_Data_Pointer++; // Pointer to an array and load a value where a list of data is located *pTWI_MASTER_CTL = (TWI_TX_Length<<6) | MEN;// | FAST; // Start transmission for (j = 0; j < (TWI_TX_Length-1); j++) { // # of transfers before stop condition while (*pTWI_FIFO_STAT == XMTSTAT) // wait to load the next sample into the TX FIFO ssync();
*pTWI_XMT_DATA8 = *TWI_Data_Pointer++; // Load the next sample into the TX FIFO. Pointer to an array where a list of data is located ssync(); } while ((*pTWI_INT_STAT & MCOMP) == 0) // Wait until transmission complete and MCOMP is set ssync(); *pTWI_INT_STAT = XMTSERV | MCOMP; // service TWI for next transmission delay(); } asm("nop;"); asm("nop;"); asm("nop;");
}
这个是我在论坛里看到的TWI的驱动。有几点不太明白:
1:TWI_TX_Length是发送的数据长度,是否包括从机的地址?
2:按照IIC协议第一个字节应该是从机的地址+读/写位;那么TWI_Data_Pointer第一个字节是否是从机的地址+读/写位?
如果我想向从地址为0x01发送0x02,0x03,0x04三个数据TWI_TX_Length是多少?TWI_Data_Pointer指向的数据是怎样的?
主机发送过程中,运行完 *pTWI_MASTER_CTL = (TWI_TX_Length<<6) | MEN;// | FAST; // Start transmission
TWI_MASTER_STAT(Master Mode Status Register)就会出现BUFRDERR (Buffer Read Error);TWI_INT_STAT(TWI Interrupt Status Register) 就会出现 MERR (Master Transfer Error)。同时TWI_INT_STAT 还有MCOMP (Master Transfer Complete)就是发送完成的标志,这是问什么。请求高手 帮忙解决
答:
1. 不包括,你看下 TWI_MasterMode_Write 函数,
*pTWI_MASTER_ADDR = DeviceAddr; // Target address (7-bits plus the read/write bit the TWI controls 这里是送设备地址,送完后才进入循环传数据。 2.不是,TWI_MasterMode_Write 函数变量中,已经有一个设备地址的参数传进去了。这个地址不包括读写位,采用7bit的地址。
TWI_TX_Length 是3,TX_Count为1,TWI_Data_Pointer是你数据所在的指针地址或者数组名称。
出现错误可能是没有哦得到设备的握手ACK信号。
给你一个简单例子看看。
问:
在主机的写操作中: // # of configurations to send to the sensor *pTWI_XMT_DATA8 = *TWI_Data_Pointer++; // Pointer to an array and load a value where a list of data is located *pTWI_MASTER_CTL = (TWI_TX_Length<<6) | MEN;// | FAST; // Start transmission
为什么要先写*pTWI_XMT_DATA8 再使能*pTWI_MASTER_CTL;按照芯片手册上的操作是应该先写使能*pTWI_MASTER_CTL;从机地址 发送完成之后再写*pTWI_XMT_DATA8。如果按照手册上的这种操作就会出现 TWI_MASTER_STAT(Master Mode Status Register)就会出现BUFRDERR (Buffer Read Error);TWI_INT_STAT(TWI Interrupt Status Register) 就会出现 MERR (Master Transfer Error)。同时TWI_INT_STAT 还有MCOMP (Master Transfer Complete)就是发送完成的标志。 请教斑竹有没有遇到同样问题。
答:WI_XMT_DATA8 是向TWI数据寄存器送需要传输的数据,然后使能传输,ADI官方的代码一直是这么写的,没有仔细看过他的接口资料。按官方的代码来吧。 感觉TWitter接口做的不是很好,有的时候传输会出错,我在官方的代码中,曾经看到有一个TWI程序,采用的循环传输的方式,就是传输数据后接收设备应答,设备不应答就连续传输。所以我认为官方也应该遇到了TWI传输失败的事情。 感觉TWI还不如直接用IO写个IIC模式的稳定。经常遇到得不到响应信号死掉或者超时的情况。 |