C文件:

-------------------------------------------------------------------------------------

#include"Si2c.h"

//Bus driver implementation
Si2c_device         Si2c_device_nu[MY_SI2C_DEVICE_NU];

enum Si2c_err MY_Si2c_err;

void Si2c_delay( unsigned int dy ) {
    unsigned int        i     = 0;
    for( i = 0; i < dy; i++ )
        ;
}
//
void My_Si2c_GPIO_init( void ) {
    rcu_periph_clock_enable( RCU_GPIOB );
    gpio_init( GPIOB, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_12 ); //scl
    gpio_init( GPIOB, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_13 ); //sda
    gpio_bit_write( GPIOB, GPIO_PIN_13, SET );
    gpio_bit_write( GPIOB, GPIO_PIN_12, SET );
    Si2c_delay( MY_SI2C_DELAY );
    Si2c_delay( MY_SI2C_DELAY );
}

//
//1
void My_Si2c_SDA_set( void ) {
    gpio_bit_write( GPIOB, GPIO_PIN_13, SET );
}

//
//0
void My_Si2c_SDA_reset( void ) {
    gpio_bit_write( GPIOB, GPIO_PIN_13, RESET );
}

//
//1
void My_Si2c_SCL_set( void ) {
    gpio_bit_write( GPIOB, GPIO_PIN_12, SET );
}

//
//0
void My_Si2c_SCL_reset( void ) {
    gpio_bit_write( GPIOB, GPIO_PIN_12, RESET );
}

//if STM32
//In open drain mode, read access to the input data register yields I/O status
//if LPCxxx
//The software can read the state of all GPIO pins except those selected as analog input or output in the I/O configuration logic
//Outside. To read the state of a pin, it is not necessary to select GPIO in the I/O configuration.
//if STC of 51
//Open-drain, internal pull-up resistance is disconnected
//Open leakage mode can read the external state and output (high level or low current)
//Flat). If you want to read the external state correctly or need to output high level, you need external
//Add pull resistance, otherwise can not read the external state, also can not output high level.
unsigned char My_Si2c_SCL_read( void ) {
    return gpio_input_bit_get( GPIOB, GPIO_PIN_12 );
}

unsigned char My_Si2c_SDA_read( void ) {
    return gpio_input_bit_get( GPIOB, GPIO_PIN_13 );
}

//Check the reply
unsigned char MY_Si2c_check_reply( unsigned char nu ) {
    //SCL  ____---____
    //SDA  ????ACK????
    unsigned char     tmp;
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SDA_set();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SCL_set();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    if( 0 == Si2c_device_nu[nu].Si2c_SDA_read() ) {
        tmp                                 = S_OK;
    } else {
        tmp                                 = bus_noack;
    }
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SCL_reset();
    return tmp;
}

//Start signal
unsigned char MY_Si2c_start( unsigned char nu ) {
    //SCL     --------------------------_________
    //SDA     --------------------_______________
    if( 1 == Si2c_device_nu[nu].Si2c_SCL_read() && 1 == Si2c_device_nu[nu].Si2c_SDA_read() ) {
        Si2c_device_nu[nu].Si2c_SDA_reset();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_reset();
        Si2c_delay( MY_SI2C_DELAY / 2 );
    } else {
        return bus_err;
    }
    return S_OK;
}

//Send reply signal
void MY_Si2c_send_ack( unsigned char nu ) {
    //SCL ____
    //SDA ----
    Si2c_device_nu[nu].Si2c_SDA_reset();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SCL_set();
    Si2c_delay( MY_SI2C_DELAY );
    Si2c_device_nu[nu].Si2c_SCL_reset();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SDA_set();
    //SCL ____
    //SDA ----
}

void MY_Si2c_stop( unsigned char nu ) {
    //SCL  ______-----------------
    //SDA  ???______________------
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SDA_reset();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SCL_set();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SDA_set();
    Si2c_delay( MY_SI2C_DELAY );
    //SCL  --------
    //SDA  --------
}

void MY_Si2c_send_nack( unsigned char nu ) {
    //SCL ____
    //SDA ----
    Si2c_device_nu[nu].Si2c_SDA_set();
    Si2c_delay( MY_SI2C_DELAY / 2 );
    Si2c_device_nu[nu].Si2c_SCL_set();
    Si2c_delay( MY_SI2C_DELAY );
    Si2c_device_nu[nu].Si2c_SCL_reset();
    Si2c_delay( MY_SI2C_DELAY / 2 );
}

unsigned char MY_Si2c_addressing( unsigned char nu, unsigned char addr,
                                  unsigned char rw ) {
    //SCL  __---___---
    //SDA  C-----C-------
    unsigned char     i     = 0;
    unsigned char     tmp = ( addr << 1 ) | rw;
    for( i = 0; i < 8; i++ ) {
        if( tmp & 0x80 ) {
            Si2c_device_nu[nu].Si2c_SDA_set();
        } else {
            Si2c_device_nu[nu].Si2c_SDA_reset();
        }
        tmp <<= 1;
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_set();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_reset();
    }
    //SCL  ____
    //SDA  ????
    if( S_OK == MY_Si2c_check_reply( nu ) ) {
        return S_OK;
    } else {
        return bus_noack;
    }
    //SCL ____
    //SDA ????
}

void MY_Si2c_send_char( unsigned char nu, unsigned char tmp ) {
    unsigned char     i     = 0;
    for( i = 0; i < 8; i++ ) {
        if( tmp & 0x80 ) {
            Si2c_device_nu[nu].Si2c_SDA_set();
        } else {
            Si2c_device_nu[nu].Si2c_SDA_reset();
        }
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_set();
        Si2c_delay( MY_SI2C_DELAY );
        Si2c_device_nu[nu].Si2c_SCL_reset();
        if( i == 7 ) {
            Si2c_device_nu[nu].Si2c_SDA_set();
        }
        tmp <<= 1;
    }
}

void MY_Si2c_read_char( unsigned char nu, unsigned char* data ) {
    //SCL ____
    //SDA ????
    unsigned char     i     = 0;
    Si2c_delay( MY_SI2C_DELAY / 2 );
    for( i = 0; i < 8; i++ ) {
        *data <<= 1;
        Si2c_device_nu[nu].Si2c_SCL_set();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        if( 1 == Si2c_device_nu[nu].Si2c_SDA_read() ) {
            ( *data ) |= 1;
        }
        Si2c_device_nu[nu].Si2c_SCL_reset();
        Si2c_delay( MY_SI2C_DELAY / 2 );
    }
}

unsigned char MY_Si2c_Multibyte_sending( unsigned char nu, unsigned char addr,
        unsigned char* buffer, unsigned char len ) {
    unsigned char     i     = 0;
    MY_Si2c_start( nu );
    if( S_OK == MY_Si2c_addressing( nu, addr, MY_SI2C_WRITE ) ) {
        //SCL ____
        //SDA ????
        for( i = 0; i < len; i++ ) {
            MY_Si2c_send_char( nu, buffer[i] );
            if( S_OK != MY_Si2c_check_reply( nu ) ) {
                Si2c_device_nu[nu].Si2c_SCL_set();
                return bus_noack;
            }
        }
    } else {
        Si2c_device_nu[nu].Si2c_SCL_set();
        return bus_noack;
    }
    MY_Si2c_stop( nu );
    return S_OK;
}

unsigned char MY_Si2c_Multibyte_reading( unsigned char nu, unsigned char addr,
        unsigned char* buffer, unsigned char len ) {
    unsigned char     i     = 0;
    MY_Si2c_start( nu );
    if( S_OK == MY_Si2c_addressing( nu, addr, MY_SI2C_READ ) ) {
        //SCL ____
        //SDA ????
        for( i = 0; i < len; i++ ) {
            MY_Si2c_read_char( nu, &buffer[i] );
            //SCL ____
            //SDA ????
            if( i == ( len - 1 ) )
                MY_Si2c_send_nack( nu );
            else
                MY_Si2c_send_ack( nu );
            //SCL ____
            //SDA ----
        }
    } else {
        return bus_noack;
    }
    MY_Si2c_stop( nu );
    return S_OK;
}

unsigned char MY_Si2c_writeandread( unsigned char nu, unsigned char addr, unsigned char* mregister,
                                    unsigned char rsize, unsigned char* buff, unsigned char bsize ) {
    unsigned char     i     = 0;
    MY_Si2c_start( nu );
    if( S_OK == MY_Si2c_addressing( nu, addr, MY_SI2C_WRITE ) ) {
        //SCL ____
        //SDA ????
        for( i = 0; i < rsize; i++ ) {
            MY_Si2c_send_char( nu, mregister[i] );
            if( S_OK != MY_Si2c_check_reply( nu ) ) {
                return bus_noack;
            }
        }
        //SCL ____
        //SDA ----
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_set();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SDA_reset();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        Si2c_device_nu[nu].Si2c_SCL_reset();
        Si2c_delay( MY_SI2C_DELAY / 2 );
        if( S_OK != MY_Si2c_addressing( nu, addr, MY_SI2C_READ ) )
            return bus_noack;
        for( i = 0; i < bsize; i++ ) {
            MY_Si2c_read_char( nu, &buff[i] );
            if( i == ( bsize - 1 ) )
                MY_Si2c_send_nack( nu );
            else
                MY_Si2c_send_ack( nu );
        }
    } else {
        return bus_noack;
    }
    MY_Si2c_stop( nu );
    return S_OK;
}

void MY_Si2c_unlockbus( unsigned char nu ) {
    unsigned char i = 0;
    Si2c_device_nu[nu].Si2c_SDA_set();

Si2c_delay( MY_SI2C_DELAY * 2 );
    for( i = 0; i < 9; i++ ) {
        Si2c_device_nu[nu].Si2c_SCL_set();
        Si2c_delay( MY_SI2C_DELAY * 2 );
        Si2c_device_nu[nu].Si2c_SCL_reset();
        Si2c_delay( MY_SI2C_DELAY * 2 );
    }
    Si2c_device_nu[nu].Si2c_SCL_set();
    Si2c_delay( MY_SI2C_DELAY * 4 );
}

void My_Si2c_Querying_secondary_Devices( unsigned char nu, unsigned char* myaddrs ) {
//7F
    unsigned char i = 0;
    unsigned char tmp = 0;
    unsigned char j = 0;
    for( i = 0; i < ( 0x7F + 1 ); i++ ) {
        MY_Si2c_start( nu );
        tmp = MY_Si2c_addressing( nu, i, MY_SI2C_READ );
        MY_Si2c_stop( nu );
        if( S_OK == tmp ) {
            myaddrs[j++] = i;
        }
        Si2c_delay( MY_SI2C_DELAY );
    }
}

void Si2c_initial( void ) {
    Si2c_device_nu[0].Si2c_GPIO_init = My_Si2c_GPIO_init;
    Si2c_device_nu[0].Si2c_SDA_set = My_Si2c_SDA_set;
    Si2c_device_nu[0].Si2c_SDA_reset = My_Si2c_SDA_reset;
    Si2c_device_nu[0].Si2c_SDA_read = My_Si2c_SDA_read;
    Si2c_device_nu[0].Si2c_SCL_set = My_Si2c_SCL_set;
    Si2c_device_nu[0].Si2c_SCL_reset = My_Si2c_SCL_reset;
    Si2c_device_nu[0].Si2c_SCL_read = My_Si2c_SCL_read;
    Si2c_device_nu[0].Si2c_GPIO_init();
}

H文件

----------------------------------------------------------------------------------

#ifndef __MY_SI2C__
#define __MY_SI2C__

#include "gd32f30x_gpio.h"
#include "gd32f30x_rcu.h"

#define MY_SI2C_DEVICE_NU 2  //The bus number
#define MY_SI2C_READ 1
#define MY_SI2C_WRITE 0

#define MY_SI2C_ADDR1 (0x68)    //Device address

#define MY_SI2C_DELAY 150 //The bus delay

#define Si2c_LOG

//Bus error type
enum Si2c_err {
    S_OK = 0,
    bus_err,
    bus_busy,
    bus_noack,
};

extern enum Si2c_err MY_Si2c_err;

//Bus driver implementation
typedef struct {
    void ( *Si2c_GPIO_init )( void );
    void ( *Si2c_SDA_set )( void );
    void ( *Si2c_SDA_reset )( void );
    void ( *Si2c_SCL_set )( void );
    void ( *Si2c_SCL_reset )( void );
    unsigned char ( *Si2c_SCL_read )( void );
    unsigned char ( *Si2c_SDA_read )( void );
} Si2c_device;

//Bus driver implementation
extern Si2c_device Si2c_device_nu[MY_SI2C_DEVICE_NU];

void Si2c_delay( unsigned int dy );
void My_Si2c_GPIO_init( void );
void My_Si2c_SDA_set( void );
void My_Si2c_SDA_reset( void );
void My_Si2c_SCL_set( void );
void My_Si2c_SCL_reset( void );
unsigned char My_Si2c_SCL_read( void );
unsigned char My_Si2c_SDA_read( void );

//Check the reply
unsigned char MY_Si2c_check_reply( unsigned char nu );

//Start signal
unsigned char MY_Si2c_start( unsigned char nu );

//Send reply signal
void MY_Si2c_send_ack( unsigned char nu );
void MY_Si2c_stop( unsigned char nu );
void MY_Si2c_send_nack( unsigned char nu );
unsigned char MY_Si2c_addressing( unsigned char nu, unsigned char addr, unsigned char rw );
void MY_Si2c_send_char( unsigned char nu, unsigned char tmp );
void MY_Si2c_read_char( unsigned char nu, unsigned char* data );
unsigned char MY_Si2c_Multibyte_sending( unsigned char nu, unsigned char addr, unsigned char* buffer, unsigned char len );
unsigned char MY_Si2c_Multibyte_reading( unsigned char nu, unsigned char addr, unsigned char* buffer, unsigned char len );
unsigned char MY_Si2c_writeandread( unsigned char nu, unsigned char addr, unsigned char* mregister, unsigned char rsize, unsigned char* buff, unsigned char bsize );
void My_Si2c_Querying_secondary_Devices( unsigned char nu, unsigned char* myaddrs );
void Si2c_initial( void );
void MY_Si2c_unlockbus( unsigned char nu );

#endif

修复之前写的模拟I2C程序,增加多总线,时序更精确操作相关推荐

  1. GPIO模拟I2C程序实现

    GPIO模拟I2C程序实现. I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个 ...

  2. 51单片机模拟I2C程序

    IIC即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦公司研发出来的.是一种两线式串行总线,两条线可以挂多个参与通信的器件,即多机模式.一般由控制器作为主机. ...

  3. 【STM32】GPIO模拟I2C程序示例

    00. 目录 文章目录 00. 目录 01. IIC简介 02. 功能描述 03. 硬件模块 04. 软件设计 05. 结果验证 06. 附录 07. 声明 01. IIC简介 IIC(Inter-I ...

  4. STM32模拟I2C程序

    修改自cleanflight /*******************************************************************************测试平台: ...

  5. STM8S 模拟I2C程序

    STM8S的硬件I2C还是存在问题,不敢贸然使用. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM PE_IDR_IDR2 # ...

  6. SGP30传感器示例程序(基于51单片机、IO模拟I2C)

    SGP30传感器示例程序(基于51单片机.IO模拟I2C) SGP30传感器I2C地址:0x58 说明:这里采用使用IO模拟的方式来实现I2C 点击这里下载SGP30测试源码及数据手册 /*SGP30 ...

  7. python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例

    Python 超简单的聊天程序 客户端: import socket, sys host = '10.248.27.23' # host = raw_input("Plz imput des ...

  8. 单片机GPIO软件模拟I2C通讯程序

    文章原始地址:http://feotech.com/?p=98 本程序主要用于使用可编程芯片自身的IO管脚,模拟I2C通信的协议,实现I2C总线数据的传输. /******************** ...

  9. 能不能用python开发qq_用Python写一个模拟qq聊天小程序的代码实例

    用Python写一个模拟qq聊天小程序的代码实例 发布时间:2020-09-09 07:49:29

最新文章

  1. 气象各种资料汇总(持续更新ing)
  2. POI LastRowNum and PhysicalNumberOfRows
  3. LeetCode MySQL 197. 上升的温度
  4. Python | Pyplot标签
  5. Windows Server 2008 R2 域控DOS命令
  6. latex中括号大小控制 [转]
  7. java微信发文字乱码_获取微信用户信息出现乱码
  8. 完全卸载go语言编译器
  9. App设计之路——WebApp浅谈
  10. Hibernate组件作为Map索引(四)
  11. 微信小程序|基于小程序实现人脸识别对比
  12. PostgreSQL下载和安装教程
  13. lof基金溢价率php源码,一文读懂LOF基金套利策略 LOF是球友们很喜欢的一类基金,这类基金不仅可以在场内进行高效买卖,而且还可以进行折溢价套利。不过这里面牵扯到很多细节,... - 雪球...
  14. windows无法格式化u盘_Windows系统提示U盘无法完成格式化的解决方法
  15. 千岛湖2日团建旅行!游览天下第一秀水,感受湖岛遍布的磅礴气势!_团建拓展_嗨牛团建_杭州站...
  16. NLP入门概览(9) ——句法分析c:局部句法分析、依存关系分析
  17. 数据分析课设(SPSS,EVIEWS,R)【理论】
  18. 彻底删除VM虚拟机手把手详细教学
  19. 洛谷:P2172 [国家集训队]部落战争
  20. 线性模型和非线性模型的区别,以及激活函数的作用

热门文章

  1. 华为鸿蒙os用时间长了会卡吗,外媒再放狠话!华为鸿蒙OS系统和安卓没区别:同样也会越用越卡顿...
  2. js前端可视化 | 单位平面向量旋转的数学原理与计算
  3. Java进位制转换小技巧
  4. 百度Apollo自动驾驶学习笔记
  5. 年纪轻轻竟脱发?头发到底该如何挽回?
  6. Serverless实践系列(四):网站监控脚本的实现
  7. 前台传入数据,在后台servelet中接收的,强硬解决乱码格式
  8. 桥牌坐庄训练bm2000 level3闯关记录——A6
  9. 202012-5 星际旅行 C++暴力80分
  10. 万卷书 - 欧洲的门户 [The Gates of Europe]