当前位置: 首页 > article >正文

国民技术N32G430开发笔记(18)- I2C1 从机收发数据

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打印接收数据如图:
在这里插入图片描述


http://www.kler.cn/a/17260.html

相关文章:

  • 轻松上手:使用Docker部署Java服务
  • 6.2 对角化矩阵(2)
  • RoseTTAFold MSA_emb类解读
  • 运行WHTools批量启动游戏房间工具提示要安装.Net Framework3.5解决
  • 通用项目工程的过程视图概览
  • 综合案例铁锅炖(CSS项目大杂烩)
  • 【react全家桶学习】react组件中的ref属性(详)
  • K8S之HPA自动扩缩容机制
  • 【五一创作】QML、Qt Quick /Qt中绘制圆形
  • 第四章 数据关联分析方法
  • C/C++每日一练(20230504)
  • [Leetcode] 0697.数组的度
  • api 和 implementation 区别
  • 最大和+翻硬币(蓝桥杯JAVA解法)
  • 【python】创建python包
  • 浅谈MySQL索引以及执行计划
  • 自定义类型:结构体
  • Windeployqt 打包,缺少DLL 的原因分析,解决方法
  • 【网络】网络基础入门
  • Bean的作用域和生命周期
  • Splunk 转移数据之collect 命令
  • 功能齐全的 DIY ESP32 智能手表设计之PCB介绍
  • 一篇带你快速入门DDD领域驱动设计
  • 【JavaEE初阶】简单了解wait和notify方法~
  • MySQL 精选 35 道面试题大厂稳了(含答案)
  • 真无线耳机哪款性价比高?高性价比无线耳机排行榜