I2C1 从机收发数据
1、将PB6 PB7设置为i2c从机,跟android板卡通讯。
2、Android发送
写命令:
0x05 0x02 0x00 0x00 checksum
n32将收到的命令打印出来
读版本命令:
0x01 0x02 0x00 0x00 checksum
n32将app_version返回电视端
3、i2c从机配置,采用中断方式收发数据。
主要代码:
从机配置代码:
/**
* 从模式采用中断
*/
MI_BOOL i2c1_slave_init(void)
{
I2C_InitType i2c1_slave;
GPIO_InitType i2c1_gpio;
NVIC_InitType NVIC_InitStructure;
RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_I2C1);
RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
GPIO_Structure_Initialize(&i2c1_gpio);
/*PB6 -- SCL; PB7 -- SDA*/
i2c1_gpio.Pin = GPIO_PIN_6 | GPIO_PIN_7;
i2c1_gpio.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
i2c1_gpio.GPIO_Mode = GPIO_MODE_AF_OD;
i2c1_gpio.GPIO_Alternate = GPIO_AF2_I2C1;
GPIO_Peripheral_Initialize(GPIOB, &i2c1_gpio);
I2C_Reset(I2C1);
I2C_Initializes_Structure(&i2c1_slave);
i2c1_slave.BusMode = I2C_BUSMODE_I2C;
i2c1_slave.DutyCycle = I2C_SMDUTYCYCLE_1;
i2c1_slave.OwnAddr1 = I2C1_SLAVE_ADDR;
i2c1_slave.AckEnable = I2C_ACKEN;
i2c1_slave.AddrMode = I2C_ADDR_MODE_7BIT;
i2c1_slave.ClkSpeed = 100000; /* 100K */
I2C_Initializes(I2C1, &i2c1_slave);
/* int enable */
I2C_Interrupts_Enable(I2C1, I2C_INT_EVENT | I2C_INT_BUF | I2C_INT_ERR);
NVIC_Priority_Group_Set(NVIC_PER0_SUB4_PRIORITYGROUP);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initializes(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initializes(&NVIC_InitStructure);
I2C_ON(I2C1);
return MI_TRUE;
}
中断处理函数:
void I2C1_EV_IRQHandler(void)
{
uint8_t timeout_flag = 0;
uint32_t last_event = 0;
last_event = I2C_Last_Event_Get(I2C1);
if ((last_event & I2C_ROLE_MASTER) != I2C_ROLE_MASTER) /* MSMODE = 0:I2C slave mode */
{
switch (last_event)
{
case I2C_EVT_SLAVE_RECV_ADDR_MATCHED: /*0x00020002.EV1 Rx addr matched */
/* clear flag,ready to receive data */
rxDataNum = 0;
break;
case I2C_EVT_SLAVE_SEND_ADDR_MATCHED: /*0x00060082.EV1 Tx addr matched */
send_i2c_message(rxData,rxDataNum);
txDataNum = 0;
I2C1->DAT = txData[txDataNum++];/* Send first data */
break;
/* SlaveTransmitter */
case I2C_EVT_SLAVE_DATA_SENDING: /*0x00060080. EV3 Sending data */
//printf("I2C_EVT_SLAVE_DATA_SENDING\r\n");
break;
case I2C_EVT_SLAVE_DATA_SENDED:
I2C1->DAT = txData[txDataNum++];
break;
/* SlaveReceiver */
case I2C_EVT_SLAVE_DATA_RECVD: /*0x00020040.EV2 one byte recved */
rxData[rxDataNum++] = I2C1->DAT;
break;
case I2C_EVT_SLAVE_STOP_RECVD: /* 0x00000010 EV4 */
I2C_ON(I2C1);
handle_i2c_message(rxData,rxDataNum);
break;
default:
I2C_ON(I2C1);
timeout_flag = 1;
break;
}
}
if (timeout_flag)
{
if ((I2CTimeout--) == 0)
{
//CommTimeOut_CallBack(SLAVE_UNKNOW);
}
}
else
{
I2CTimeout = I2CT_LONG_TIMEOUT;
}
}
void I2C1_ER_IRQHandler(void)
{
uint32_t last_event;
last_event = I2C_Last_Event_Get(I2C1);
if(last_event == I2C_EVT_SLAVE_ACK_MISS)
{
I2C_Flag_Status_Clear(I2C1, I2C_FLAG_ACKFAIL);
if(rxDataNum != 0) /*slave send the last data and recv NACK */
{
//flag_slave_send_finish = 1;
}
else /*not the last data recv nack, send fail */
{
}
}
}
接收到数据都放在 send_i2c_message跟handle_i2c_message函数中处理。
MI_BOOL send_i2c_message(MI_U8 *p_buff,MI_U32 len)
{
switch (p_buff[UART_CMD_INDEX])
{
case I2C_GET_SYSTEM_VERSION_CMD/* constant-expression */:
/* 获取系统版本号 */
if (calculate_checksum_and_length(p_buff,len) == MI_TRUE)
{
MI_CHAR version[48] = {0};
system_info_get_app_version(version);
memset(txData,0,I2C_SEND_REC_DATA_LENGTH);
memcpy(txData,version,strlen(version));
printf("get version = %s\r\n",version);
}
break;
default:
break;
}
return MI_TRUE;
}
MI_BOOL handle_i2c_message(MI_U8 *p_buff,MI_U32 len)
{
if(p_buff != 0)
{
for(int i=0;i<len;i++)
{
printf("0x%02x " ,p_buff[i]);
}
printf("\r\n");
}
return MI_TRUE;
}
main.c中增加收发buffer的定义
uint16_t rxDataNum = 0;
uint8_t rxData[I2C_SEND_REC_DATA_LENGTH] = {0};
uint8_t txData[I2C_SEND_REC_DATA_LENGTH] = {0};
uint16_t txDataNum = 0;
main.h
#define I2C_SEND_REC_DATA_LENGTH 256
extern uint16_t rxDataNum;
extern uint8_t rxData[I2C_SEND_REC_DATA_LENGTH];
extern uint8_t txData[I2C_SEND_REC_DATA_LENGTH] ;
extern uint16_t txDataNum ;
4、Android App运行效果图:
5、N32打印接收数据如图: