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

news2024/11/19 9:33:22

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.coloradmin.cn/o/495964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MTK6765安卓智能模组5G核心板联发科MTK方案主板开发板

联发科MTK6765这是一款12纳米八核A53处理器&#xff0c;最高运行速度可达2.3GHz。它使用Android 9.0操作系统&#xff0c;配备2G16G内存&#xff0c;也支持其他选项1G/3G/4G8G/32G/64G。 此外&#xff0c;它支持全球主流频段&#xff0c;包括默认的国内频段以及2G GSM、2G/3G E…

【Android取证篇】ADB端口驱动更新详细步骤

【Android取证篇】ADB端口驱动更新详细步骤 更新ADB端口驱动&#xff0c;解决无法连接设备问题—【蘇小沐】 1、【记录VID】路径&#xff1a;设备管理器->便携设备->属性->&#xff08;记录&#xff09;VID 查看设备的VID 2、添加设备ID&#xff08;VID&#xff09…

Sass 总结

文章目录 Sass 总结概述编译.scss 和 .sass变量数据类型属性值变量属性名变量 嵌套规则基本嵌套& 父选择器标识符嵌套属性 import 导入导入Sass文件私有化导入原生CSS文件 mixin 混合器无参数带参数命名参数关键字参数可变参数content 混入内容 extend 继承media 媒体查询控…

hbase查询报错unable to find region for

某天由于集群资源不足。hbase大面积 region server 负载爆炸卡死&#xff0c;隔天发现部分查询报错 集群中一张表某些查询找不到region 尝试了重启集群和滚动重启集群&#xff0c;考虑滚动重启的过程会把regionserver上的region迁出和迁入。试试能不能修复&#xff0c;果断的…

自定义项目Jar上传到maven中央仓库(一步到位)

中央仓库 Open Source Software Repository Hosting 简称 OSSRH 实现目标&#xff1a;将自定义项目上传至maven中央仓库&#xff0c;其他人只需引入maven坐标即可直接使用 上传步骤&#xff1a;亲测有效 注册账号&#xff08;去它平台&#xff09;提交工单&#xff08;叫它做事…

USB HS-PHY眼图调试

1 USB2 PHY AFE 1.1 USB 2.0 FS PHY github ultraembedded / core_usb_fs_phy NOP USB transceiver for all USB transceiver which are either built-in into USB IP or which are mostly autonomous. 1.2 电阻参数 USB host端&#xff1a;D和D-各接一个15kΩ的下拉电阻&#…

数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)

目录 最大堆的建立 方法1 方法2 思路图解 代码实现 代码解释 PercDown BuildHeap 最大堆的建立 建立最大堆&#xff1a;将已经存在的N个元素按最大堆的要求存放在一个一维数组中。 方法1 通过插入操作&#xff0c;将N个元素一个一个地插入到一个初始为空的堆中去。…

CSA发布|《洞察2022 云上数据安全与重要事项 》

云安全联盟大中华区就云上数据安全和重要事项的洞察和建议等相关问题展开调查并发布《洞察2022 云上数据安全与重要事项 》&#xff08;以下简称《报告》&#xff09;。报告的主要内容是关于云上数据安全和重要事项的洞察和建议。它包括了对云安全现状的分析、云安全风险的评估…

git的学习

文章目录 一、Git 的简介二、Git 工作流程三、Git 工作区、暂存区和版本库总结 一、Git 的简介 Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软…

【c语言】字符串比较 | API仿真

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …

RabbitMQ可靠性消息发送(java实现)

本博客属于 《RabbitMQ基础组件封装—整体结构》的子博客 一、整体架构 step1&#xff1a;消息落库&#xff0c;业务数据存库的同时&#xff0c;也要将消息记录存入数据库&#xff0c;二者要保证原子性&#xff1b; step2&#xff1a;Producer发送消息到MQ Broker&#xff1b…

Formik使用详解

Formik使用详解 1 引言 在现代Web应用程序中&#xff0c;表单是一种不可避免的输入机制&#xff0c;但是处理表单的过程可能会变得非常复杂。Formik是一个React表单库&#xff0c;它的目标是简化表单处理的过程。本文将介绍Formik的主要功能和用途&#xff0c;以及如何使用它来…

怎么成为一名架构师?架构师第一步。基层开发人员逆袭成为架构师真的很难吗?

文章目录 写在前面一、企业需要什么样的架构师1、从招聘软件上了解2、架构师的主要职责与能力 二、成为一名架构师很难吗1、架构师的定义2、当前大部分开发团队的现状3、为什么要有架构师4、技术人员如何自我突破 三、晨钟暮鼓的几句话 写在前面 一个团队中&#xff0c;每个人…

JAVA基础:Scanner类中next(), nextLine(), hasNext(), hasNextLine()

一、next() : 只读缓冲区中空格之前的数据,并且光标指向本行。二、nextLine() : 读取除回车以外的所有符号(整行内容)&#xff0c;光标定位在下一行三、hasNext() &#xff1a;检查下一个标记&#xff08;token&#xff09;&#xff0c;也就是以空格、制表符或换行符为分隔符的…

[JAVA EE]创建Servlet——实现Servlet接口笔记1

创建Servlet的方式之一&#xff1a;实现servlet接口 servlet的生命周期&#xff1a; 1、实例化&#xff1a;创建servlet实例对象 2、初始化&#xff1a;调用init方法完成初始化工作 3、服务&#xff1a;调用service方法来处理用户请求 4、销毁&#xff1a;调用destroy方法…

Java算法比赛常用方法

1. 开方&#xff1a;Math.sqrt(x); 2. x的a方&#xff1a;Math.pow(x,a); 3. 绝对值&#xff1a;Math.abs(x)&#xff1b; 4. BigInteger&#xff1a;大数&#xff08;加&#xff0c;减&#xff0c;乘&#xff0c;除&#xff0c;取余&#xff09; c.add(d) ; c.subtract(d)…

如何用100天彻底学会Python?

Python 是一门功能强大、易于学习且历史悠久的编程语言。如果你希望在短时间内彻底学会 Python&#xff0c;需要制定一个全面的学习计划&#xff0c;并进行刻意的练习和实践。 以下是一份建议的学习计划&#xff0c;帮助你在 100 天内掌握 Python 技能。 第 1-10 天&#xff…

从bootamition出发分析OpenHarmony下Gralloc buffer管理机制

从bootamition出发分析OpenHarmony下Gralloc buffer管理机制 引言 这个文档主要记录从bootamition角度出发&#xff0c;分析OpenHarmony下对gralloc buffer的管理&#xff01;由于OpenHarmony图形子系统过于复杂&#xff0c;且个人由于能力有限&#xff0c;这里我仅从gralloc b…

2023.03青少年机器人技术等级考试理论综合试卷(五级)

2023年3月青少年机器人技术等级考试理论综合试卷&#xff08;五级&#xff09; 一、单选题(共 20 题&#xff0c;共 80 分) 1. 0x35 & 7 的结果是&#xff1f;&#xff08;A &#xff09; A. 5 B. 55 C. 50 D. 54 2.一般状况下&#xff0c;关于主控板的工作电压&#xff0c…

「 Redis 」大key对持久化有什么影响?

「 Redis 」大key对持久化有什么影响&#xff1f; 参考&鸣谢 Redis 大 Key 对持久化有什么影响&#xff1f; XiaoLinCoding 解决了Redis大key问题&#xff0c;同事们都夸他牛皮 大白斯基 快手面试官&#xff1a;Redis变慢了&#xff0c;如何快速排查&#xff1f; Java 那些…