请教STM8L151与MTK手机I2C通信大问题
时间:10-02
整理:3721RD
点击:
各位好,我这段时间弄STM8L151的I2C与MTK处理器的手机的I2C通信(手机I2C的程序是另一个人写的),弄了一个多星期没搞定。不知道是哪里的原因,我用俩个单片机通信,一个作主机,另一个作从
机(从机接收用中断方式),主机可以正常向从机收发数据,当手机作主机时,一个单片机作从机就出问题了,从机地址匹配正确后不断地进入中断。强制在中断中打印中断事件值为0x6D0。手机电平(
1.8V)已经过电平芯片转换成3.3V电平。用示波器量手机I2C时SCL有一个正脉冲,SDA没响应。希望高手可以给我指出问题。我的代码如下:
主机代码(Master)
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler, 29)
{
switch (I2C_GetLastEvent(I2C1))
{
/* EV5 */
case I2C_EVENT_MASTER_MODE_SELECT :
/* Send slave Address for write */ //I2C_Direction_Receiver I2C_Direction_Transmitter
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter);
break;
/* EV6 */
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
break;
/* EV8 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
/* Transmit Data */
I2C_SendData(I2C1,5);
break;
/* EV8_2 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, DISABLE);
break;
default:
break;
}
}
void main()
{
/* I2C clock Enable*/
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
/* system_clock / 1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* Initialize I2C peripheral */
I2C_Init(I2C1, I2C_SPEED, 0xA0,
I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
/* Enable Buffer and Event Interrupt*/
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);
enableInterrupts();
/* TXBuffer initialization */
for (i = 0; i < BUFFERSIZE; i++)
TxBuffer[i] = i;
USART1_INIT();
printf("I2C test!\r\n");
I2C_GenerateSTART(I2C1, ENABLE);
printf("2C_IT = 1;\r\n");
while (1)
{
/***** reception phase ***/
/* Wait while the bus is busy */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave Address for write */
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver);
/* Test on EV6 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Poll on RxNE Flag */
while ((I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET));
/* Read a byte from the Slave */
RxBuffer[0] = I2C_ReceiveData(I2C1);
printf("RxBuffer[0] = 0x%x\r\n",RxBuffer[0]);
}
}
从机代码(Slave):
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler, 29)
{
/* Read SR2 register to get I2C error */
if(I2C_ReadRegister(I2C1, I2C_Register_SR2))
{
/* Clears SR2 register */
I2C1->SR2 = 0;
/* Set LED2 */
}
switch (I2C_GetLastEvent(I2C1))
{
/******* Slave transmitter ******/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
Rx_Idx = 0;
I2C_state[0] = 1;
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
Slave_Buffer_Rx[0] = I2C_ReceiveData(I2C1);
I2C_state[1] = 1;
break;
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
I2C_state[2] = 1;
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
GPIO_ResetBits(GPIOA,GPIO_Pin_6);
/* Transmit data */
I2C_SendData(I2C1, 0x48);
I2C_state[3] = 1;
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
/* write to CR2 to clear STOPF flag */
Rx_Idx = 0;
I2C_state[4] = 1;
I2C_state[5] = 1;
I2C1->CR2 |= I2C_CR2_ACK;
break;
default:
break;
}
}
void main(void)
{
int i=0;
//initialize I2C GPIO PC0-->I2C_SDA PC1-->I2C_SCL
//GPIO_Init(GPIOC, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Fast);
/* system_clock / 1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* I2C clock Enable*/
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
USART1_INIT();
LED_INIT();
I2C_DeInit(I2C1);
I2C_Cmd(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Initialize I2C peripheral */
I2C_Init(I2C1, 100000, SLAVE_ADDRESS,
I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
/* Enable Error Interrupt*///
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR |I2C_IT_EVT |I2C_IT_BUF), ENABLE);
/* Enable general interrupts */
enableInterrupts();
GPIO_SetBits(GPIOA,GPIO_Pin_6);
printf("I2C test!\r\n");
/*Main Loop */
while (1)
{
Delay(0x5000);
GPIO_SetBits(GPIOA,GPIO_Pin_6);
GPIO_SetBits(GPIOA,GPIO_Pin_5);
Delay(0x5000);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
if(I2C_state[5] == 1)
{
if(I2C_state[0] == 1)
{
DEBUG("从机地址匹配正确");
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
}
if(I2C_state[1] == 1)
{
DEBUG("从机接收到数据");
printf("Slave_Buffer_Rx[0] = %d\r\n",Slave_Buffer_Rx[0]);
i++;
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
}
if(I2C_state[2] == 1)
{
DEBUG("发送地址匹配");
}
if(I2C_state[3] == 1)
{
DEBUG("从机发送数据");
}
if(I2C_state[4] == 1)
{
DEBUG("通信结束");
}
if(aaa == 100)
{
aaa=0;
DEBUG(" 56415312");
}
for(i=0;i<6;i++)
{
I2C_state[i] = 0;
}
}
}
}
机(从机接收用中断方式),主机可以正常向从机收发数据,当手机作主机时,一个单片机作从机就出问题了,从机地址匹配正确后不断地进入中断。强制在中断中打印中断事件值为0x6D0。手机电平(
1.8V)已经过电平芯片转换成3.3V电平。用示波器量手机I2C时SCL有一个正脉冲,SDA没响应。希望高手可以给我指出问题。我的代码如下:
主机代码(Master)
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler, 29)
{
switch (I2C_GetLastEvent(I2C1))
{
/* EV5 */
case I2C_EVENT_MASTER_MODE_SELECT :
/* Send slave Address for write */ //I2C_Direction_Receiver I2C_Direction_Transmitter
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter);
break;
/* EV6 */
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
break;
/* EV8 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
/* Transmit Data */
I2C_SendData(I2C1,5);
break;
/* EV8_2 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, DISABLE);
break;
default:
break;
}
}
void main()
{
/* I2C clock Enable*/
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
/* system_clock / 1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* Initialize I2C peripheral */
I2C_Init(I2C1, I2C_SPEED, 0xA0,
I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
/* Enable Buffer and Event Interrupt*/
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);
enableInterrupts();
/* TXBuffer initialization */
for (i = 0; i < BUFFERSIZE; i++)
TxBuffer[i] = i;
USART1_INIT();
printf("I2C test!\r\n");
I2C_GenerateSTART(I2C1, ENABLE);
printf("2C_IT = 1;\r\n");
while (1)
{
/***** reception phase ***/
/* Wait while the bus is busy */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave Address for write */
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver);
/* Test on EV6 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Poll on RxNE Flag */
while ((I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET));
/* Read a byte from the Slave */
RxBuffer[0] = I2C_ReceiveData(I2C1);
printf("RxBuffer[0] = 0x%x\r\n",RxBuffer[0]);
}
}
从机代码(Slave):
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler, 29)
{
/* Read SR2 register to get I2C error */
if(I2C_ReadRegister(I2C1, I2C_Register_SR2))
{
/* Clears SR2 register */
I2C1->SR2 = 0;
/* Set LED2 */
}
switch (I2C_GetLastEvent(I2C1))
{
/******* Slave transmitter ******/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
Rx_Idx = 0;
I2C_state[0] = 1;
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
Slave_Buffer_Rx[0] = I2C_ReceiveData(I2C1);
I2C_state[1] = 1;
break;
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
I2C_state[2] = 1;
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
GPIO_ResetBits(GPIOA,GPIO_Pin_6);
/* Transmit data */
I2C_SendData(I2C1, 0x48);
I2C_state[3] = 1;
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
/* write to CR2 to clear STOPF flag */
Rx_Idx = 0;
I2C_state[4] = 1;
I2C_state[5] = 1;
I2C1->CR2 |= I2C_CR2_ACK;
break;
default:
break;
}
}
void main(void)
{
int i=0;
//initialize I2C GPIO PC0-->I2C_SDA PC1-->I2C_SCL
//GPIO_Init(GPIOC, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Mode_Out_OD_HiZ_Fast);
/* system_clock / 1 */
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
/* I2C clock Enable*/
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
USART1_INIT();
LED_INIT();
I2C_DeInit(I2C1);
I2C_Cmd(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Initialize I2C peripheral */
I2C_Init(I2C1, 100000, SLAVE_ADDRESS,
I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
/* Enable Error Interrupt*///
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR |I2C_IT_EVT |I2C_IT_BUF), ENABLE);
/* Enable general interrupts */
enableInterrupts();
GPIO_SetBits(GPIOA,GPIO_Pin_6);
printf("I2C test!\r\n");
/*Main Loop */
while (1)
{
Delay(0x5000);
GPIO_SetBits(GPIOA,GPIO_Pin_6);
GPIO_SetBits(GPIOA,GPIO_Pin_5);
Delay(0x5000);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
if(I2C_state[5] == 1)
{
if(I2C_state[0] == 1)
{
DEBUG("从机地址匹配正确");
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
}
if(I2C_state[1] == 1)
{
DEBUG("从机接收到数据");
printf("Slave_Buffer_Rx[0] = %d\r\n",Slave_Buffer_Rx[0]);
i++;
//GPIO_ResetBits(GPIOA,GPIO_Pin_6);
}
if(I2C_state[2] == 1)
{
DEBUG("发送地址匹配");
}
if(I2C_state[3] == 1)
{
DEBUG("从机发送数据");
}
if(I2C_state[4] == 1)
{
DEBUG("通信结束");
}
if(aaa == 100)
{
aaa=0;
DEBUG(" 56415312");
}
for(i=0;i<6;i++)
{
I2C_state[i] = 0;
}
}
}
}
不知道,小编搞定没? 用逻辑分析仪,看一下时序。贴图来给坛友看一看。
谢谢。弄得了,手机那边的波特率没设好。
好的,,,
学习学习一下!