修复之前写的模拟I2C程序,增加多总线,时序更精确操作
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程序,增加多总线,时序更精确操作相关推荐
- GPIO模拟I2C程序实现
GPIO模拟I2C程序实现. I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个 ...
- 51单片机模拟I2C程序
IIC即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦公司研发出来的.是一种两线式串行总线,两条线可以挂多个参与通信的器件,即多机模式.一般由控制器作为主机. ...
- 【STM32】GPIO模拟I2C程序示例
00. 目录 文章目录 00. 目录 01. IIC简介 02. 功能描述 03. 硬件模块 04. 软件设计 05. 结果验证 06. 附录 07. 声明 01. IIC简介 IIC(Inter-I ...
- STM32模拟I2C程序
修改自cleanflight /*******************************************************************************测试平台: ...
- STM8S 模拟I2C程序
STM8S的硬件I2C还是存在问题,不敢贸然使用. #define SCL PE_ODR_ODR1 #define SDA PE_ODR_ODR2 #define SDAM PE_IDR_IDR2 # ...
- SGP30传感器示例程序(基于51单片机、IO模拟I2C)
SGP30传感器示例程序(基于51单片机.IO模拟I2C) SGP30传感器I2C地址:0x58 说明:这里采用使用IO模拟的方式来实现I2C 点击这里下载SGP30测试源码及数据手册 /*SGP30 ...
- python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例
Python 超简单的聊天程序 客户端: import socket, sys host = '10.248.27.23' # host = raw_input("Plz imput des ...
- 单片机GPIO软件模拟I2C通讯程序
文章原始地址:http://feotech.com/?p=98 本程序主要用于使用可编程芯片自身的IO管脚,模拟I2C通信的协议,实现I2C总线数据的传输. /******************** ...
- 能不能用python开发qq_用Python写一个模拟qq聊天小程序的代码实例
用Python写一个模拟qq聊天小程序的代码实例 发布时间:2020-09-09 07:49:29
最新文章
- Spring注入方法
- Angular Schematics 学习笔记
- 极光IM初始化SDK出错
- 巧用Dictionary实现日志数据批量插入
- .net core 中通过 PostConfigure 验证 Options 参数
- 覆盖所有面试知识点,赶紧收藏!
- 理解JS的6种继承方式
- Geatpy自定义初始种群
- 单链表删除指定节点c语言,在单链表删除指定节点之后的节点
- 集合点(掌握)-并发
- 3.1. 一元、多元逻辑回归、tensorflow2实现——python实战
- java学生成绩管理系统(集合与泛型、文件读写)
- 疲劳检测方法总结_计算机视觉
- Automate your Android app testing
- java更改文件编码方式_java 更改文件编码
- CSS效率---常用CSS框架
- Unity代码生成实例物体
- 《麦田里的守望者》 经典摘录
- 【软考】2020下半年软件设计师 易错知识点(1)
- word中如何去掉文档右侧带格式的批注框
热门文章
- (二)、Apache doris编译
- 百度飞桨蜜度文本智能较对大赛经验分享(17/685)
- 厦门感恩回馈一线职工 为其开启“新年旅程”
- 2008世界旅游大使中国赛区总决赛在正定华丽落幕
- 爬虫利器 xpath 实践案例
- CH340驱动问题,由于 Windows 无法加载这个设备所需的驱动程序,导致这个设备工作异常。 (代码 31)
- 【智能门禁系统设计】——项目需求分析(门禁终端软件)
- 虚拟化系统到VMware虚拟机
- 猪八戒网冲刺港交所上市:2021年GMV达84亿元,朱明跃持股28%
- 常用的40引脚的RGB屏介绍