GD32VF103 I2C从机模板 – TaterLi 个人博客

作为I2C从机程序,关键变量aReceiveBuffer以及关键常量I2C0_SLAVE_ADDRESS7,第一个是I2C设备寄存器内容,第二个是I2C地址.

当上位机读写寄存器时候,实际上读写的是aReceiveBuffer的内容,除了0x00这个之外,其他全部可以读写.算是比较方便实现某些功能.

编译器:toolchain-gd32v 9.2.0 [GCC]

#include "gd32vf103.h"

#include "systick.h"

#include <stdio.h>

#include <stdint.h>

/* 这里指定的地址是0x41. */

#define I2C0_SLAVE_ADDRESS7 0x82

uint8_t ubRegIndex = 0;

uint8_t aReceiveBuffer[255];

/* GD32VF103 I2C 事件处理模块 */

void I2C0_EV_IRQHandler(void)

{

    /* 收到地址请求 */

    if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND))

    {

        i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);

        /* 收到主机写入有2个可能,写地址/写数据. */

    }

    else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE))

    {

        if (ubRegIndex == 0)

        {

            ubRegIndex = i2c_data_receive(I2C0);

        }

        else

        {

            aReceiveBuffer[ubRegIndex++] = i2c_data_receive(I2C0);

        }

        /* 收到主机读取就应该把读取内容送上 */

    }

    else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE))

    {

        i2c_data_transmit(I2C0, aReceiveBuffer[ubRegIndex++]);

        /* 如果收到主机停,那应该停. */

    }

    else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET))

    {

        i2c_stop_on_bus(I2C0);

        ubRegIndex = 0;

        /* 如果收到的是NACK,也代表主机不想再发数据了. */

    }

    else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))

    {

        ubRegIndex = 0;

    }

}

void I2C0_ER_IRQHandler(void)

{

}

int main(void)

{

    /* 时钟初始化 */

    rcu_periph_clock_enable(RCU_GPIOB);

    rcu_periph_clock_enable(RCU_I2C0);

    /* I2C GPIO 初始化 : PB6 => I2C0_SCL,PB7 => I2C0_SDA */

    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);

    /* 复位I2C外设 */

    i2c_software_reset_config(I2C0, I2C_SRESET_SET);

    i2c_software_reset_config(I2C0, I2C_SRESET_RESET);

    /* I2C时钟配置,作为从机,这个不重要. */

    i2c_clock_config(I2C0, 100000, I2C_DTCY_2);

    /* I2C地址配置 */

    i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_SLAVE_ADDRESS7);

    /* 使能I2C */

    i2c_enable(I2C0);

    /* 允许ACK */

    i2c_ack_config(I2C0, I2C_ACK_ENABLE);

    /* 开启中断事务处理 */

    i2c_interrupt_enable(I2C0, I2C_INT_ERR);

    i2c_interrupt_enable(I2C0, I2C_INT_EV);

    i2c_interrupt_enable(I2C0, I2C_INT_BUF);

    eclic_global_interrupt_enable();

    eclic_irq_enable(I2C0_EV_IRQn, 1, 0);

    while (1)

    {

    }

}

效果演示.

为了可读性,就没必要脱裤子放屁写寄存器版本了,我相信编译器能把这点差距抹平,就这么用吧.

(0)

相关推荐

  • 【博文连载】ARM GIC(二)中断术语

    ARM在GIC中,对于中断,定义了如下的一些术语. 一.中断状态 对于每一个中断而言,有以下4个状态: inactive:中断处于无效状态 pending:中断处于有效状态,但是cpu没有响应该中断 ...

  • 最通俗理解SAI接口 – TaterLi 个人博客

    STM32的新片子的音频外设叫SAI了,S就是Serial,A就是Audio,I就是Interface,还是挺好记的.究竟新在哪里,就是支持音频各种了,但是实际上用到的,还不是I2S.为了不要让大家蒙 ...

  • 诗歌:九张机 | 雪韵 朗诵 | 奇博

    长风文化传媒集团 风起金源,长歌当酒 九张机 雪韵 轻烟斜雨剪残辉, 乱绪乡愁侵秀眉. 弹指屏前痴语寄, 半笺世缘九张机. 一张机,光阴似箭笑人痴. 红尘一度犹当戏. 青丝渐少,银丝两鬓,俗事总皈依. ...

  • VMware虚机模板(如何导出和导入OVF文件)

    工具 VMware worktation Pro 15.0 centos7.6 一.导出OVF文件 1.点击"开始"-"VMware"-"VMware ...

  • 粉丝查到​PGOne参加音乐节的航班准备接机?工作人员发博辟谣

    嗨,这里是背挎包会下腰不吃辣椒的你大猫~~~ 在中文说唱圈,一直存在着这么三大未解之谜,分别是三棒子当年为什么要揍TT.JD到底*没*以及PG One到底能不能复出?而这其中,又以最后一个问题尤为受大 ...

  • 古韵新风|九张机 文/张红博

    站在岚山之巅,举目四望,湘江古镇与龙光宝塔尽收眼底,三水六桥,步云飞虹历历在目,远山崎岖连绵直奔八闽百粤,湘水绵水在山下汇为贡江蜿蜒九曲,飘然西去,车水马龙田园村舍,风景如画使人心醉神迷,宠辱皆忘,禁 ...

  • 极萃口服液机的博客

    谈及养生,我们很快就会想起被传承几千年的中药文化,几千年来,熬.煮.炖,已经成为了家用养生的关键,而现在,我却要告诉你,这些方法非但药效不佳,还会偷偷让你败惨了家! 你是不是也有这样的感觉,明明

  • 【精品博文】为什么I2C从机地址要左移一位?

    对许多刚开始接触I2C的新手来说,最开始比较疑惑,当MCU做主机与一些I2C接口的从机(比如一些数字传感器,大多数仍为I2C接口)通信时,无论是用IO模拟I2C协议还是使用I2C模块,在发送从机地址时 ...

  • 聊聊五行的奥秘(二)——火(曲炜原创)_曲炜周易_新浪博客

    (2010-10-08 14:24:55) 火主夏令,夏季火旺.火特性,炎上,扩散.有扩散性,向外爆发.这是火的运行特性.有的书上说,火,无毒.很多人不懂这是什么意思.其实只要了解火的特性就明白其中的 ...

  • 聊聊五行的奥秘(四)——水(曲炜原创)_曲炜周易_新浪博客

    聊聊五行的奥秘(四)--水(曲炜原创) (2010-10-14 08:21:40) 转载▼标签: 曲炜聊聊五行五行五行秘密阴阳分类: 曲炜谈易--周易技巧点窍 水,五行旺于冬季,主要原因是因为冬季的特 ...