MSP430FR5738 I2C DMA 模式调试时碰到了一个问题,貌似是430单片机的bug,问题描述如下
1、P1.6/1.7配置成I2C Slave 通信模式,I2C Slave RX 和Slave TX配置成DMA模式,配置代码如下
由于I2C 接受数据时,事先并不知道接收长度,在DMA接收时,当STOP信号到来时,表示一帧数据的结束。
当STOP信号到来时,结束当前DMA传输
1. I2C Config
void I2C_Slave_Init(unsigned char address)
{
UCB0CTLW0 |= UCSWRST; //reset I2C Module
UCB0CTLW0 |= UCMODE_3 + UCSYNC; //I2C Slave
UCB0CTLW1 &= ~USCI_I2C_UCCLTOIFG;
UCB0CTLW1 |= (0x01 << 6);
UCB0I2COA0 = address + UCOAEN; //I2C ADDRESS
//Set P1.6 & P1.7 on I2C MODE
P1SEL1 |= BIT6 + BIT7;
P1SEL0 &= ~BIT6;
P1SEL0 &= ~BIT7;
UCB0CTLW0 &= ~UCSWRST; //release reset I2C Module
UCB0IE__I2C |= UCSTPIE;//Enable I2C INTERRUPT
}
2、I2C Slave RX DMA config
void I2C_Slave_RX_DMA_Config()
{
DMA0CTL =
(0x00 << 12) //Single Transfer
|(0x03 << 10) //Dest Inc
|(0x00 << 8) //Src Unchange
|(0x01 << 7)
|(0x01 << 6);
DMA0SA = (unsigned int)&UCB0RXBUF;
DMA0DA = (unsigned int)buf;
DMA0SZ = 40;
DMACTL0 |= 18;//MSP430FR5738 I2C Slave RX Trigger
DMA0CTL |= DMAIE;
DMA0CTL |= DMAEN;
}
3、中断
switch(__even_in_range(UCB0IV,0x1E))
{
case 0x08:
if(UCB0CTLW0_bit.UCTR == 0) //Receive
{
DMA I2C Slave RX ReConfig
}
else //Transmitter
{
DMA I2C Slave TX ReConfig
}
UCB0IFG = 0;
break;
default:
break;
}
main()
{
.....
I2C_Slave_Init();
I2C_Slave_RX_DMA_Config();
_EINT();
while(1)
{
...
....
//P2DIR_bit.P2DIR2 = 1;
}
}
问题
如果在while(1)的循环里涉及到单片机IO寄存器的配置,操作,则 I2C Slave RX DMA接收就会出问题,表现目前监测到两种情况,一种就是没有识别STOP信号,无中断产生,另一种是中断IFG标志已产生,但没有进中断服务程序,如果此时在仿真器中暂停一次,再全速运行,则可以进中断服务程序
如果while(1)里没有对IO端口的操作,则整个I2C Slave RX DMA 没有任何问题
对IO端口寄存器配置操作,不会影响I2C Slave TX DMA