单片机GD32F303RCT6 (Macos环境)开发 (十七)—— i2c1从机中断接收发送数据

news2024/10/7 15:27:29

i2c1从机中断接收发送数据

1、将i2c1设置为从机模式,与树莓派连接。树莓派发送或者读取数据,gd32中断触发,从而接收数据或者向主机发送数据。
2、关于代码的宏定义配置
Application目录的Makefile中 ENABLE_I2C_TEST = yes才会编译I2C1的相关代码。
同时修改i2c.h文件,定义I2C1_MODE为I2C1_MODE_SLAVE,编译烧录后,i2c1即为从机模式。

#define I2C1_MODE                   I2C1_MODE_SLAVE

3、i2c1从机设置代码,i2c.c中

void i2c1_slave_config(void)
{
    /* enable GPIOB clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* enable I2C1 clock */
    rcu_periph_clock_enable(RCU_I2C1);
    /* connect PB10 to I2C1_SCL */
    /* connect PB11 to I2C2_SDA */
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//配置PB10,PB11为复用功能

    /* configure I2C clock */
    i2c_clock_config(I2C1, I2C1_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_OWN_ADDRESS7);
    /* enable I2C1 */
    i2c_enable(I2C1);
    /* enable acknowledge */
    i2c_ack_config(I2C1, I2C_ACK_ENABLE);

    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(I2C1_EV_IRQn, 0, 2);
    nvic_irq_enable(I2C1_ER_IRQn, 0, 1);
    /* enable the I2C1 interrupt */
    i2c_interrupt_enable(I2C1, I2C_INT_ERR);
    i2c_interrupt_enable(I2C1, I2C_INT_BUF);
    i2c_interrupt_enable(I2C1, I2C_INT_EV);

}

4、中断处理函数,gd32f30x_it.c中修改

#if I2C1_MODE == I2C1_MODE_SLAVE
/*!
    \brief      I2C1 event handle function
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_EV_IRQHandler(void)
{
    I2C1_EventIRQ_Handler();
}

/*!
    \brief      I2C1 error handle function
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_ER_IRQHandler(void)
{
    I2C1_ErrorIRQ_Handler();
}
#endif

5、 I2C1_EventIRQ_Handler()、I2C1_ErrorIRQ_Handler() 在i2c.c定义

volatile uint8_t        i2c_txbuffer[4] = {0x98,0x78,0x67,0xff};
volatile uint8_t        i2c_rxbuffer[128];
volatile uint16_t       i2c_rx_num;
volatile uint16_t       i2c_tx_num;
static   uint8_t        isfirst = 0;

static void send_i2c_data(uint8_t *p_buff,uint16_t len)
{

    printf("get read command ");
    print_register_value(p_buff,len);

}


/*!
    \brief      handle I2C1 event interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_EventIRQ_Handler(void)
{
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) {
        /* clear the ADDSEND bit */
        if (isfirst == 0)
        {
            isfirst = 1;
            i2c_rx_num = 0; 
        }
        else
        {
            isfirst = 0;
            i2c_tx_num = 0;
            send_i2c_data(i2c_rxbuffer,i2c_rx_num);
        }
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND);
    } else if((i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TBE)) && (!i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR))) {
        
        /* send a data byte */ 
        //printf("now send data  %d: \r\n",i2c_tx_num);
        i2c_data_transmit(I2C1, i2c_txbuffer[i2c_tx_num++]);
    } else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)) {
        /* if reception data register is not empty ,I2C1 will read a data from I2C_DATA */
        i2c_rxbuffer[i2c_rx_num] = i2c_data_receive(I2C1);
        i2c_rx_num++;

    } else if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_STPDET)) {

        //printf("get num == %d\r\n",i2c_rx_num);
        print_register_value(i2c_rxbuffer,i2c_rx_num);
        /* clear the STPDET bit */
        i2c_enable(I2C1);
        i2c_rx_num = 0;
        i2c_tx_num = 0;
        isfirst = 0;
    }
}


/*!
    \brief      handle I2C1 error interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void I2C1_ErrorIRQ_Handler(void)
{
    /* no acknowledge received */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_AERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_AERR);
    }

    /* SMBus alert */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT);
    }

    /* bus timeout in SMBus mode */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBTO)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBTO);
    }

    /* over-run or under-run when SCL stretch is disabled */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR);
    }

    /* arbitration lost */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB);
    }

    /* bus error */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR);
    }

    /* CRC value doesn't match */
    if(i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)) {
        i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR);
    }
    // /* disable the I2C1 interrupt */
    // i2c_interrupt_disable(I2C1, I2C_INT_ERR);
    // i2c_interrupt_disable(I2C1, I2C_INT_BUF);
    // i2c_interrupt_disable(I2C1, I2C_INT_EV);
}

6、现象,
树莓派发送数据:i2ctransfer -f -y 1 w4@0x18 0x08 0x09 0xA0 0xA3
gd32打印
在这里插入图片描述
树莓派读取数据:
i2ctransfer -y -f 1 w3@0x30 0x18 0x19 0x56 r3
发送三个数据读取三个,gd32打印如下:
在这里插入图片描述
树莓派读取的数据:
在这里插入图片描述
0x98 0x78 0x67是我们定义的数据
volatile uint8_t i2c_txbuffer[4] = {0x98,0x78,0x67,0xff};
7、代码路径:https://gitee.com/xiaoguo-tec_0/gd32-iap-code.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512519.html

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

相关文章

为啥马斯克一边反对Open AI,一边又自己另搞AI

这事我过去就说过,我现在再老生常谈一次。 (1) 我过去说过一个事:汽车自己智能其实还不能做到真正的智能,必须车路人都智能了,智能汽车才能真正智能。 因为车路人智能,这本质是数字世界和数字世…

开源之夏 2023 | 与 Databend 一同探索云数仓的魅力

活动概览 开源之夏是由中科院软件所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动,旨在鼓励在校学生积极参与开源软件的开发维护,培养和发掘更多优秀的开发者,促进优秀开源软件社区的蓬勃发展,助力开源软件供应链…

基于AT89C52单片机的交通信号灯设计

点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87772657 源码获取 主要内容: 本次设计所提出的一种基于单片机技术的简易计算器的方案,能更好的解决计算机计算的问题,随着数字生活的到来&…

eSIM-GSMA-1-EID规则定义

规范 SGP.02-v4.0.pdf Official Document SGP.02 - Remote Provisioning Architecture for Embedded UICC Technical Specification eid管理规则-SGP.29-1.0 EID Principles 国家编号机构发布 ICCID 的现有机制,以及后续的用户识别不受影响 EID 的核心目的是唯…

知识管理协同工具:助力企业综合信息规整化发展

随着信息化时代的来临,企业面临的信息越来越庞杂,如何管理和利用这些信息成为了企业发展的关键。知识管理作为一种新型的管理思想和方法,已经被广泛应用于企业管理中。知识管理工具是知识管理的重要手段之一,它可以帮助企业实现信…

STM32的功耗模式

按功耗由高到低排列, STM32 具有运行、睡眠、停止和待机四种工作模式。 低功耗各模式下芯片工作情况: 睡眠模式:仅关闭了内核时钟,内核停止运行,但其片上外设, CM4 核心的外设全都还照常 运行。有两种方式…

一款开源免费、非常好用的的SSH/SFTP客户端Electerm

electerm是一款基于electron开发的SSH/SFTP客户端,同时支持Linux、MAC、Windows操作系统,免费开源。 下载地址 Releases electerm/electerm (github.com) 点击下图箭头所指,下载windwos版本 安装 双击安装,等待安装完成 使用…

Melis4.0[D1s]:8.显示测试:图片格式和透明度

文章目录 1.准备素材图片1.1 测试图片像素格式的软件RawViewer.exe1.1.1 使用方法 1.2 自己生成测试图片 2.D1s显示引擎介绍(不保证正确)2.1 D1s 可以有2个独立的display device输出(可以同时接2个显示器)2.2 D1s 的 DISP0 有2个通…

普罗米修斯-docker安装

prometheus 监控原理 1、prometheus :虽然说是监控平台,但是实际上是一套数据库 2、mysql_exporter: 可以理解成程序或者软件,他是工作在我们要监控的目标服务器上,主要是用于监控mysql的数据。 3、node_exporter: 他的作用主要是…

Java 3种IO模型,一次搞懂

大家好,我是老三,上一节我们讨论了Linux的五种IO模型,接下来,我们从Java语言层面,来看看对IO的实现。 在Java中,一共有三种IO模型,分别是阻塞IO(BIO)、非阻塞IO(NIO)和异步IO(AIO)。 Java BIO …

IDEA “Cannot resolve symbol” 解决办法

系列文章目录 文章目录 系列文章目录前言一、Cannot resolve symbol是什么问题?二、第一步:检查Maven配置三、第二步:检查target四、 第三步:检查 project五、第四步:lombok 问题总结 前言 请耐心读完,也许…

FE_Vue框架的重要属性讲解【ref props mixin】

1 ref属性 对于传统的HTML而言,id 和 ref确实没有什么差别,但是对于组件来说就不一样了。给组件加id,打印出获取的结果为组件所对应的完整DOM结构。给组件加ref,打印出获取的结果就是VueComponent实例。 被用来给元素或子组件注册…

【SpringCloud微服务实践】注册与发现(Eureka)

注册与发现(Eureka) 注册与发现初实践,注册中心采用SpringCloud全家桶中的Eureka,并配合RestTemplate从Euraka调用微服务。 在前置章节的电影票-用户服务组的基础上升级,摒弃硬编码微服务地址的方案,使用eureka实现微服务的动态…

计算机毕业论文选题推荐|软件工程|系列三

文章目录 导文题目导文 计算机毕业论文选题推荐|软件工程 (***语言)==使用其他任何编程语言 例如:基于(***语言)门窗账务管理系统的设计与实现 得到:基于JAVA门窗账务管理系统的设计与实现 基于vue门窗账务管理系统的设计与实现 等等 题目 基于(***语言) 一体化智慧停车…

86.qt qml-多种粒子特效按钮实现

截图如下所示: 动图如下所示: 支持黑白模式: 1.实现原理 配合之前我们学习的: 82.qt qml-2D粒子系统、粒子方向、粒子项(一)_诺谦的博客-CSDN博客 83.qt qml-初步学习2D粒子影响器(二)_诺谦的博客-CSDN博客 即可实现出来。 以按钮特效3按钮为例:

Google I/O 2023 - Flutter 3.10 发布,快来看看有什么更新吧

核心部分原文链接:https://medium.com/flutter/whats-new-in-flutter-3-10-b21db2c38c73 虽然本次 I/O 的核心 keynote 主要是 AI ,但是按照惯例依然发布了新的 Flutter 稳定版,不过并非大家猜测的 4.0,而是 3.10 ,Flu…

PING命令的高级用法

对于Windows下ping命令相信大家已经再熟悉不过了,但是能把ping的功能发挥到最大的人却并不是很多,当然我也并不是说我可以让ping发挥最大的功能,我也只不过经常用ping这个工具,也总结了一些小经验,现在和大家分享一下。…

studioone6离线下载电脑版

随着技术的不断进步,音乐家不再将作曲编曲局限在手绘和实体乐器演奏上,各类编曲软件和插件在模拟乐器中无限接近实质,大大简化了编曲作曲的工作。 Studio One6就是其中的佼佼者之一,它不仅支持用户对音频进行剪切编辑混音等后期处…

#VERDI# 关于Verdi如何使用reverse调试

前言 今天我们 一起学习Verdi的一种回退仿真机制。也即:reverse 为了使用verdi reverse debug 机制,以下注意事项必须满足: (1)Reverse Debug page 必须设置为交互模式:tools-》preferences->Intera…

修改图片大小尺寸如何操作?修改图片大小尺寸的作用

图片在不同场合下需要具备适当的尺寸和分辨率,如果不满足要求,就会影响到其质量和效果。因此,修改图片大小尺寸是一种常见的处理方法,可以让图片更好地适应不同的需求和场景。 修改图片的大小和尺寸可以带来以下几个好处&#xf…