利用开漏输出模式模拟IIC

/************************************************************
利用IO口模拟IIC时序,需要使用2个IO口(SDA和SCL)

    SCL时钟线只能由主器件进行控制,所以SCL引脚必须为输出模式
SDA数据线,在主器件发送数据时,SDA引脚为输出模式
SDA数据线,在主器件接收数据时,SDA引脚为输入模式

************************************************************/

//配置SCL——》PB6,PB7的引脚设置
#define  SDA_SET(n)  (n)?(GPIO_SetBits(GPIOB,GPIO_Pin_7)):(GPIO_ResetBits(GPIOB,GPIO_Pin_7)) 
#define  SCL_SET(n)  (n)?(GPIO_SetBits(GPIOB,GPIO_Pin_6)) : (GPIO_ResetBits(GPIOB,GPIO_Pin_6)) 
#define  SDA_READ    GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
void IIC_SCLConfig(void)
{
//打开GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure = {0};//定义结构体GPIO外设结构体变量

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //配置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推挽模式
GPIO_Init(GPIOB, &GPIO_InitStructure);

//配置IIC_Config初始化
void IIC_Config(void)
{
IIC_SCLConfig();

    //开始期间SDA 与SCL都空闲状态是高电平
SDA_SET(1);
SCL_SET(1);
Delay_nus(5);
}

//IIC的开始信号
void IIC_Start(void)
{
//2.确保SDA与SCL空闲处于高电平
SDA_SET(1);
SCL_SET(1);
Delay_nus(5);
//3.SDA电平拉低
SDA_SET(0);
Delay_nus(5);
//4.把SCL引脚电平拉底此时,此时准备数据
SCL_SET(0);
Delay_nus(5);
}

//IIC的发送字节  
//由于:开始-->发送字节-->等待应答-->发送字节所以第一步不能少
void IIC_SendByte(uint8_t Byte)
{
//2.把SCL引脚电平拉底此时,此时准备数据
SCL_SET(0);
Delay_nus(5);
//3.此时准备数据
for(uint8_t i = 0;i < 8;i++)
{
//4.判断最高位是0或者是1
if(Byte & 0x80)
{
SDA_SET(1);
}
else
{
SDA_SET(0);
}
Byte <<= 1;
Delay_nus(5);
//5.此时SCL引脚电平拉高,从机接收数据
SCL_SET(1);
Delay_nus(5);
//6.把SCL引脚电平拉底此时,此时准备数据
SCL_SET(0);
Delay_nus(5);
}
}
//判断是否从机应答
uint8_t IIC_SlaveACK(void)
{
uint8_t data = 0;
SDA_SET(1);//主机释放SDA,让从机对SDA进行控制
//2.把SCL引脚电平拉低,此时第九个脉冲的低电平,此时从机准备Bit
SCL_SET(0);
Delay_nus(5);
//3.把SCL引脚电平拉高,此时第九个脉冲高电平到来
SCL_SET(1);
Delay_nus(5);
//4.主机读取状态 1:表示未应答   0:表示已应答
if(SDA_READ)
{
data = 1;
}
else
{
data = 0;
}
//5.把SCL引脚电平拉低,此时第九个脉冲的结束
SCL_SET(0);
Delay_nus(5);
return data;
}
//IIC读取数据
uint8_t IIC_ReadData(void)
{
uint8_t data = 0; 
SCL_SET(0);
//主机释放SDA,让从机对SDA进行控制
SDA_SET(1);
//3.主机循环八次读取数据
for(uint8_t i = 0;i < 8;i++)
{
//2.把SCL引脚拉低,此时从机准备数据
SCL_SET(0);
Delay_nus(5);
//4.把SCL电平拉高8bit,此时主机读取bit
SCL_SET(1);
Delay_nus(5);
//5.主机读取bit
data <<= 1;
data |= SDA_READ;
//Delay_nus(5);

}
//    //6.把SCL引脚电平拉低,此时准备数据
//    SCL_SET(0);
//    Delay_nus(5);
return data;
}

//主机应答  ACK = 1 表示不应答   ACK = 0表示应答
void IIC_MasterACK(uint8_t Ack)
{

    //2.把SCL引脚电平拉低,此时主机准备应答
SCL_SET(0);
Delay_nus(5);
//3.判断主机是否应答 1:表示未应答   0:表示已应答
if(Ack)
{
SDA_SET(1);
}
else
{
SDA_SET(0);
}

    //4.把SCL引脚电平拉高,从机读取应答
SCL_SET(1);
Delay_nus(5);
//5.把SCL引脚电平拉低
SCL_SET(0);
Delay_nus(5);

}
//停止位

void IIC_Stop(void)
{
//1.SDA配置为输出模式
//    IIC_SDAConfig(GPIO_Mode_Out_OD);
//2.确保SDA与SCL都为低电平
SDA_SET(0);
SCL_SET(0);
Delay_nus(5);
//3.SCL电平拉高
SCL_SET(1);
Delay_nus(5);
//4.SDA电平拉高
SDA_SET(1);
Delay_nus(5);
}

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

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

相关文章

闸机控制系统从设计到实现全解析:第 5 篇:RabbitMQ 消息队列与闸机通信设计

第 5 篇&#xff1a;RabbitMQ 消息队列与闸机通信设计RabbitMQ 是一款开源的消息队列中间件&#xff08;Message Queue&#xff0c;MQ&#xff09;&#xff0c;基于 Erlang 语言开发&#xff0c;遵循 AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队…

Linux 常用命令大全:覆盖日常 99% 操作需求

1、基本命令 pwd&#xff1a;显示当前工作目录的绝对路径&#xff0c;例如在复杂目录结构中快速确认位置&#xff0c;执行后会输出类似/home/user/documents的结果。 cd&#xff1a;切换目录&#xff0c;cd 目录路径可进入指定目录&#xff0c;cd ~回到当前用户的家目录&…

普通电脑与云电脑的区别有哪些?全面科普

近年来&#xff0c;越来越多的人不再购置升级自己的电脑&#xff0c;转而选择云电脑&#xff0c;云端产品正在变得越来越普及易用。那么它究竟跟我们的普通本地设备有什么区别呐&#xff1f;或许很多人并不知悉&#xff0c;对此&#xff0c;本篇内容小编就为大家简要科普一下普…

【Python】支持向量机SVM

示例代码&#xff1a;import numpy as np import matplotlib.pyplot as plt from sklearn import svm from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report# 设…

当AI学会“抄近路”:残差网络如何突破深度学习的极限

**——解读《Deep Residual Learning for Image Recognition》**今天我想带大家回到2015年&#xff0c;见证人工智能领域的一场“捷径革命”——由何恺明等人提出的**深度残差学习框架&#xff08;ResNet&#xff09;**。这篇论文解决了困扰AI界多年的“深度诅咒”&#xff0c;…

HCIP--BGP综合实验

目录 BGP综合实验报告 一、实验拓扑 二、实验要求 三、实验思路 &#xff08;一&#xff09;IP地址规划 &#xff08;二&#xff09;整体思路 四、实验步骤 &#xff08;一&#xff09; IP地址配置 &#xff08;二&#xff09; AS2内部配置OSPF协议 &#xff08;三&a…

Java 基础编程案例:从输入交互到逻辑处理

在Java编程学习中&#xff0c;输入输出、循环控制和逻辑判断是核心基础。本文整理了10个经典案例&#xff0c;涵盖Scanner输入处理、斐波那契数列、成绩统计、登录验证等场景&#xff0c;帮助初学者掌握编程逻辑与实用技巧。 一、Scanner输入交互&#xff1a;获取用户输入并处理…

LeetCode 面试经典 150_数组/字符串_整数转罗马数字(18_12_C++_中等)(模拟)(对各位进行拆解)

LeetCode 面试经典 150_数组/字符串_整数转罗马数字&#xff08;18_12_C_中等&#xff09;题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;模拟&#xff09;&#xff1a;思路二&#xff08;对各位进行拆解&#xff09;&a…

计算机网络摘星题库800题笔记 第6章 应用层

第6章 应用层 6.1 网络应用的架构 考点 1 CS 架构 题组闯关 1.DNS 是基于 ( ) 模式的分布式系统。 A. C/S B. B/S C. P2P D. 以上均不正确 1.【参考答案】A 【解析】本题考查网络应用模型。 DNS 作为分布式应用&#xff0c;是一种典型的 C/S 模式&#xff0c;是随着 Internet 技…

BLUCK电路的输入电容应该怎么选取

借用TI的BULK芯片讨论一下输入电容怎么选取的问题&#xff0c;BULK电源是我们常用的电源&#xff0c;它的原理请看之前的文章&#xff1a; 高压差为何不用LDO&#xff1f;DCDC效率更高&#xff01;-CSDN博客 本文我们探讨一下输入电容&#xff0c;输入电容是控制纹波的关键&a…

CAN仲裁机制的原理

我们来详细讲 CAN 仲裁机制 的原理和工作方式,这是 CAN 总线最核心的特性之一。 1️⃣ 基本概念 CAN 总线是 多主机、多节点的串行总线,所有节点共享一根差分信号线(CAN_H / CAN_L)。 每个节点都可以随时发送消息(多主机机制) 总线只能同时有一个节点成功发送 仲裁 用…

【GPT入门】第46课 vllm安装、部署与使用

【GPT入门】第46课 vllm安装、部署与使用 1.准备服务器 2. 安装 conda环境,隔离base环境 3. vllm使用 3.1 在线推理, openai兼容服务器 3.2 模型离线调用 4. 没有使用GPU问题分析 1.准备服务器 cuda 版本选12.1 vllm官网介绍: https://vllm.hyper.ai/docs/getting-started/…

【从网络基础到实战】理解TCP/IP协议体系的核心要点(包含ARP协议等其他协议介绍)

前言&#xff1a; 学习计算机网络不仅是软件开发的基础功&#xff0c;更是成为一名合格后端工程师、网络工程师的重要门槛。本文将基于 TCP/IP 协议体系&#xff0c;系统梳理网络层、数据链路层、以及相关协议的核心知识&#xff0c;并结合实际案例与代码示例帮助理解。一、网络…

Python 元类基础:从理解到应用的深度解析

在 Python 的高级编程中&#xff0c;元类&#xff08;metaclass&#xff09; 无疑是最神秘又最强大的特性之一。它不仅是构建类的“工厂”&#xff0c;更是 Python 灵活对象模型的体现。本文将带你从基础概念入手&#xff0c;深入理解元类的本质、工作机制以及实际应用&#xf…

Nginx 配置代理服务器的详细方法

一、什么是代理服务器&#xff1f; 类型说明正向代理客户端通过代理访问目标服务器&#xff08;隐藏客户端身份&#xff09;反向代理客户端访问代理服务器&#xff0c;由代理服务器请求后端服务器&#xff08;隐藏后端服务器&#xff09; 二、Nginx 反向代理配置方法&#xff…

Lombok插件介绍及安装(Eclipse)

一、Lombok 的用途 Lombok是一个 Java 库&#xff0c;通过注解的方式简化 Java 代码的编写。它能够自动生成常见的代码&#xff0c;如getter、setter、toString、equals、hashCode等方法&#xff0c;从而减少样板代码&#xff0c;使代码更加简洁、易读。 Lombok 通过添加**Dat…

硬核操作!Go 语言生成 “会爬墙的清洁机器人”,玻璃外墙自己擦

本文聚焦于利用 Go 语言开发 “会爬墙的清洁机器人” 这一硬核技术&#xff0c;围绕该机器人如何实现玻璃外墙自主清洁展开。首先介绍开发背景与需求&#xff0c;接着阐述 Go 语言在其中的优势&#xff0c;详细讲解机器人的核心技术&#xff0c;包括吸附系统、运动控制、清洁机…

Qt——实现”Hello World“、认识对象树与Qt坐标系

在创建项目时&#xff0c;使用的基类Base Class为QWidget 1. 使用图形化界面的方式实现“Hello World” 双击文件&#xff1a;widget.ui&#xff0c;进入designer模式&#xff1a;在“控件盒子”的“Display Widgets”中找到“Label”&#xff0c;并拖放到白板中双击刚刚拖放到…

智能合约开发全流程实战指南

目录 灵感探索与概念验证合约开发常见问题 Hardhat 初始化项目问题合约编译错误处理智能合约设计缺陷 合约测试最佳实践 单元测试环境配置测试用例编写技巧测试覆盖率和策略常见测试失败原因 合约部署实战指南 部署到不同网络部署前准备事项部署后验证方法部署费用和Gas优化 合…

IPA1299至为芯替代TI ADS1299的脑机接口芯片

在脑机接口、神经科学研究和医疗电子设备领域&#xff0c;脑电信号采集芯片是连接生物电信号与数字世界的重要组件。目前&#xff0c;TI等国际厂商凭借技术优势占据市场主要份额&#xff0c;国内厂商在成本控制、供货周期和技术自主性方面面临挑战。英集芯推出的IPA1299低噪声多…