Hi,大家好
我在调试CC3200的I2C Slave,使用的是lauchpad GCC + Eclipse开发,之前测试了一下CC3200 I2Cmaster模式,工作正常, 现在改为Slave模式发现无法进入中断,通过逻辑分析仪分析,我发现CC3200有被寻址到,也回复了应答信号,但是这些东西并不是我的中断程序做的。
下面是我的代码:
void main(void)
{
…
// Configure PIN_05 for I2C0 I2C_SCL
PinTypeI2C(PIN_05, PIN_MODE_5);
// Configure PIN_06 for I2C0 I2C_SDA
PinTypeI2C(PIN_06, PIN_MODE_5);
MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK);
MAP_PRCMPeripheralReset(PRCM_I2CA0);
I2CSlaveInit(I2CA0_BASE, 127);
I2CSlaveFIFODisable(I2CA0_BASE);
MAP_I2CIntRegister(PRCM_I2CA0, I2C0_IRQHandler);
I2CSlaveIntEnableEx(I2CA0_BASE,
I2C_SLAVE_INT_START |
I2C_SLAVE_INT_STOP |
I2C_SLAVE_INT_DATA);
while(1) { }
}
void I2C0_IRQHandler(void)
{
unsigned char rx_data;
GPIOPinWrite(GPIOA3_BASE, 0x01, 1);
MAP_UtilsDelay(1);
GPIOPinWrite(GPIOA3_BASE, 0x01, 0);
Message("I2C0 Inte! \r\n");
if(I2C0_SCSR & I2C_SCSR_DA) //Check RREQ = 1?
{
/* I2C Master Write */
//Receive data from data register
rx_data = I2C0_SDR;
//Send ACK signal
I2CSlaveACKValueSet(I2CA0_BASE, 1);
}
else if(I2C0_SCSR & I2C_SCSR_TREQ) //Check RREQ = 1?
{
I2C0_SDR = 0x37;
}
else
{
return;
}
}
谢谢.
joanne xiao:
你好,我最近也在做i2c slave 中断,但是对初始化不大清晰,想问下Eugene这方面调通了吗?帮忙指点下,拜托
Eugene You:
回复 joanne xiao:
调通了,如果有需要可以给我发邮件 yuting0501@gmail.com
Yonghua Pan:
回复 Eugene You:
如果可以,能否把你的工程附件在这里,本着分享的精神, 🙂
Eugene You:
回复 Yonghua Pan:
配置没有问题,是之前的SDK没有支持GCC,中断向量表没有重映射,导致无法进入中断。
calvin chen:
回复 Eugene You:
您好!
我也遇到一样的问题。代码和您给出的差不多,I2C Slave地址0x24,用 PIN01 和 PIN02,LaunchPad 的 J2 J3 已经取下。
CC2541作为 I2C Master,用 123k 或 256k 时钟都试过(CC2541 I2C 不支持100k或400k时钟,不知道问题是否出在这里)。CC2541 的 I2C 处理程序已经在其它地方验证过,没有问题。
现象:
1. CC3200 作为 I2C Slave 没有进入中断处理;
2. CC2541 作为 I2C Master 没有收到 Addr ACK,无法发送数据。
3. 使用 IAR,Debug 发现 Memory I2CA0 在初始化过程中没有任何变化,不解。
您能否将调试通过的代码发给我:378648860@qq.com,非常感谢!
calvin chen:
回复 calvin chen:
补充一下我的测试代码:
void main(){ long lRetVal = -1;
// Initialize Board configurations BoardInit();
// Pinmux for UART PinMuxConfig();
// Configuring UART InitTerm();
// Initialize I2C as salve i2cs_Init(); UART_PRINT("\r\n**I2C intialized as slave, ready to receive data…\r\n"); while(1) { } }
void i2cs_Init(void){ //Enable I2C Peripheral MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK); MAP_PRCMPeripheralReset(PRCM_I2CA0);
//Init Slave Mode, Set Slave Address I2CSlaveInit(I2CA0_BASE, I2C_SLAVE_ADDR);
I2CSlaveFIFODisable(I2CA0_BASE);
//Enable Slave Interrupt I2CSlaveIntEnableEx(I2CA0_BASE, I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP|I2C_SLAVE_INT_DATA);
//Register I2C Interrupt I2CIntRegister(I2CA0_BASE, i2cs_IrqIntHandler); I2CSlaveDataGet(I2CA0_BASE);
//Enable Processor IntEnable(INT_I2CA0);}
void i2cs_IrqIntHandler(void){ uint32_t uiStatus; uint32_t data; //char str[10]; UART_PRINT("I2C IRQ: "); uiStatus = I2CSlaveStatus(I2CA0_BASE); I2CSlaveIntClearEx(I2CA0_BASE, I2C_SLAVE_INT_DATA); if(uiStatus & I2C_SCSR_DA) { data = I2CSlaveDataGet(I2CA0_BASE); //memcpy(str, &data, 4); UART_PRINT("0x%X ", data); } else if(uiStatus & I2C_SLAVE_ACT_TREQ) { I2CSlaveDataPut(I2CA0_BASE, 0x01); } }
void PinMuxConfig(void){ // Enable Peripheral Clocks MAP_PRCMPeripheralClkEnable(PRCM_UARTA0, PRCM_RUN_MODE_CLK); MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK);
// Configure PIN_55 for UART0 UART0_TX MAP_PinTypeUART(PIN_55, PIN_MODE_3);
// Configure PIN_57 for UART0 UART0_RX MAP_PinTypeUART(PIN_57, PIN_MODE_3);
// Configure PIN_03 for I2C0 I2C_SCL MAP_PinTypeI2C(PIN_01, PIN_MODE_0);
// Configure PIN_04 for I2C0 I2C_SDA MAP_PinTypeI2C(PIN_02, PIN_MODE_0); }
Eugene You:
回复 calvin chen:
Hi calvin,
和I2C相关的代码我已经都发到我的问题中。CC3200的中断向量表是需要重映射的,你是否定义了IAR编译器的宏?你可以试着打印一下中断向量表,观察一下I2C中断的函数地址,是否和其他默认的中断函数地址相同,如果相同则说明你未重映射中断向量表。
calvin chen:
回复 Eugene You:
谢谢您的飞速回复!您说的中断向量表设置是不是这一段,工程定义了 ewarm 编译选项,并且执行了 MAP_IntVTableBaseSet
void BoardInit(void){/* In case of TI-RTOS vector table is initialize by OS itself */#ifndef USE_TIRTOS // Set vector table base #if defined(ccs) MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]); #endif #if defined(ewarm) MAP_IntVTableBaseSet((unsigned long)&__vector_table); #endif#endif // Enable Processor MAP_IntMasterEnable(); MAP_IntEnable(FAULT_SYSTICK);
PRCMCC3200MCUInit();}
calvin chen:
回复 Eugene You:
我明白您说的意思了,IAR 的中断向量表定义在 startup_ewarm.c 中,其中 I2C0 的入口还是 IntDefaultHandler,所以工作不正常。
我马上改了试试
calvin chen:
回复 Eugene You:
我遇到的问题和您遇到的不一样,我的 vector table 是正确初始化了的,在 IntRegister() 也正确地将中断处理函数写到了 vector table。
我的程序已经调通,问题有两个:
1. PIN_01 和 PIN_02 配置错了,应该是 PIN_MODE_1,我写成 PIN_MODE_0 了。该问题导致引脚配置成通用 GPIO;
2. 开发板的 J2 和 J3 不应该取下,取下后导致 SCL 和 SDA 没有上拉,数据传输不稳定,很容易断开。
希望对后面的童鞋们有帮助。