STM32——IIC通信

IIC协议代码:

/*-------------------------------------------------*/
/*                                                 */
/*            实现IIc总线功能的源文件              */
/*                                                 */
/*-------------------------------------------------*/

#include "stm32f10x.h"  //包含需要的头文件
#include "delay.h"      //包含需要的头文件
#include "iic.h"        //包含需要的头文件

/*-------------------------------------------------*/
/*函数名:初始化IIC接口                            */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Init(void)
{			
	GPIO_InitTypeDef  GPIO_InitStructure;                      //定义一个设置IO的变量

	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );    //使能GPIOB时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;    //准备设置PB6 PB7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           //推免输出方式  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //IO速率50M
	GPIO_Init(GPIOB, &GPIO_InitStructure);                     //设置PB6 PB7
	
	IIC_SCL_H;   //SCL拉高
	IIC_SDA_H;   //SDA拉高
}
/*-------------------------------------------------*/
/*函数名:IIC起始信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Start(void)
{
	SDA_OUT();     //SDA线输出模式
    IIC_SDA_H;	   //SDA拉高  
	IIC_SCL_H;     //SCL拉高	  
	Delay_Us(4);   //延时
 	IIC_SDA_L;     //SCL高电平的时候,SDA由高到低,起始信号
}
/*-------------------------------------------------*/
/*函数名:IIC停止信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Stop(void)
{
	SDA_OUT();     //SDA线输出模式
	IIC_SDA_L;     //SDA拉低
	IIC_SCL_H;     //SCL拉高
 	Delay_Us(4);   //延时
	IIC_SDA_H;     //SCL高电平的时候,SDA由低到高,发出停止信号					   	
}
/*-------------------------------------------------*/
/*函数名:等待应答                                 */
/*参  数:无                                       */
/*返回值:0:成功  1:失败                         */
/*-------------------------------------------------*/
char IIC_Wait_Ack(void)
{
	unsigned char timeout=0; //定义一个变量,用于计算超时时间
	
	IIC_SDA_H;	             //SDA拉高
	SDA_IN();                //SDA线输入模式 
	IIC_SCL_H;	             //SCL拉高
	 
	while(READ_SDA){         //等待SDA变低电平,表示应答到来,不然一直while循环,直到超时	
		timeout++;           //超时计数+1
		if(timeout>250){     //如果大于250	
			IIC_Stop();      //发送停止信号
			return 1;        //返回1,表示失败
		}
		Delay_Us(2);         //延时
	}
	IIC_SCL_L;               //SCL拉低
	Delay_Us(20);            //延时	
	return 0;                //返回0,表示成功
} 	
/*-------------------------------------------------*/
/*函数名:发送一个字节                             */
/*参  数:txd:发送的字节                          */
/*返回值:无                                       */
/*-------------------------------------------------*/ 			  
void IIC_Send_Byte(unsigned char txd)
{                        
    unsigned char t;                   //定义一个变量用于for循环 
	
	SDA_OUT(); 	                       //SDA线输出模式 
    IIC_SCL_L;                         //SCL拉低,开始数据传输
    for(t=0;t<8;t++){                  //for循环,一位一位的发送,从最高位 位7开始                 
        IIC_SDA_OUT(((txd&0x80)>>7));  //给SDA数据线
        txd<<=1; 	                   //左移一位,准备下一次发送
		Delay_Us(2);                   //延时
		IIC_SCL_H;                     //SCL拉高
		Delay_Us(2);                   //延时
		IIC_SCL_L;	                   //SCL拉低
    }	 
} 	    
/*-------------------------------------------------*/
/*函数名:读取一个字节                             */
/*参  数:ack:是否发送应答 1:发 0:不发           */
/*返回值:读取的数据                               */
/*-------------------------------------------------*/   
unsigned char IIC_Read_Byte(unsigned char ack)
{
	unsigned char i;           //定义一个变量用于for循环 
	unsigned char receive;     //定义一个变量用于保存接收到的数据
		
	receive = 0;               //清除receive,准备接收数据
	SDA_IN();                  //SDA设置为输入
    IIC_SCL_L;                 //SCL拉低
    Delay_Us(20);               //延时	
	for(i=0;i<8;i++){          //for循环,一位一位的读取	 
		IIC_SCL_H;             //SCL拉高 
		Delay_Us(20);           //延时
        receive<<=1;           //左移一位,准备下次的读取
        if(READ_SDA)receive++; //读取数据
		Delay_Us(20);           //延时
		IIC_SCL_L;             //SCL拉低  
		Delay_Us(20);           //延时 		
    }					 
    if(!ack){        //不需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_H;   //时钟脉冲的高电平期间保持稳定的高电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低 
	}else{           //需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_L;   //时钟脉冲的高电平期间保持稳定的低电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低
		IIC_SDA_H;   //SDA拉高
	}
    return receive;
}

24C02利用IIC进行存储代码:

/*-------------------------------------------------*/
/*                                                 */
/*             实现24c02功能的源文件               */
/*                                                 */
/*-------------------------------------------------*/

#include "stm32f10x.h"  //包含需要的头文件
#include "24c02.h"      //包含需要的头文件
#include "delay.h" 	    //包含需要的头文件			 
#include "iic.h"        //包含需要的头文件

/*-------------------------------------------------*/
/*函数名:从24c02指定的地址读一字节数据            */
/*参  数:ReadAddr:需要读数据的地址                */
/*返回值:读到的数据                               */
/*-------------------------------------------------*/
unsigned char AT24C02_ReadOneByte(unsigned char ReadAddr)
{				  
	unsigned char receive;         //定义一个变量用于保存接收到的数据
		
	receive = 0;                   //清除receive,准备接收数据
	IIC_Start();                   //IIC开始信号
	IIC_Send_Byte(AT24C02_WADDR);  //发送24c02器件地址+写操作	   	
	IIC_Wait_Ack();                //等待应答
    IIC_Send_Byte(ReadAddr);       //发送需要读数据的地址 
	IIC_Wait_Ack();	               //等待应答 
	IIC_Start();  	 	           //IIC开始信号
	IIC_Send_Byte(AT24C02_RADDR);  //发送24c02器件地址+读操作				   
	IIC_Wait_Ack();	               //等待应答
    receive=IIC_Read_Byte(0);	   //读一字节数据,保存在receive变量中   
    IIC_Stop();                    //停止信号
	Delay_Ms(5);                   //延迟
	return receive;                //返回读取的数据
}

/*-------------------------------------------------*/
/*函数名:指定地址写入一个数据                     */
/*参  数:WriteAddr  :写入数据的目的地址           */
/*参  数:DataToWrite:要写入的数据                 */
/*返回值:无                                       */
/*-------------------------------------------------*/
void AT24C02_WriteOneByte(unsigned char WriteAddr,unsigned char DataToWrite)
{				   	  	    																 
    IIC_Start();                    //开始信号
	IIC_Send_Byte(AT24C02_WADDR);   //发送器件地址+写操作	 
	IIC_Wait_Ack();	                //等待应答
    IIC_Send_Byte(WriteAddr);       //发送写入数据的目的地址
	IIC_Wait_Ack(); 	 	        //等待应答									  		   
	IIC_Send_Byte(DataToWrite);     //发送要写入的数据							   
	IIC_Wait_Ack();  		        //等待应答	   
    IIC_Stop();                     //停止信号  
	Delay_Ms(5);                    //延迟
}

/*-------------------------------------------------*/
/*函数名:指定地址写入一页数据(8字节)            */
/*参  数:WriteAddr  :写入数据的起始地址           */
/*参  数:DataToWrite:要写入的数据(8个字节)      */
/*返回值:无                                       */
/*-------------------------------------------------*/
void AT24C02_WritePage(unsigned char WriteAddr,unsigned char *DataToWrite)
{				   	  	    																 
	unsigned char i;                   //定义一个变量用于for循环   
 
	IIC_Start();                       //开始信号
	IIC_Send_Byte(AT24C02_WADDR);      //发送器件地址+写操作	 
	IIC_Wait_Ack();	                   //等待应答
    IIC_Send_Byte(WriteAddr);          //发送写入数据的目的地址
	IIC_Wait_Ack(); 	 	           //等待应答	
			Delay_Us(20);
	for(i=0;i<8;i++){                  //24c02一页8个字节,循环写入
		IIC_Send_Byte(DataToWrite[i]); //发送要写入的数据							   
		IIC_Wait_Ack();  		       //等待应答

	}	
    IIC_Stop();                        //停止信号 
	Delay_Ms(5);                       //延迟	
}
/*-------------------------------------------------*/
/*函数名:从指定的地址读一页数据(8字节)            */
/*参  数:ReadAddr:需要读数据的地址                */
/*参  数:Redata:保存接收到的数据                  */
/*返回值:读到的数据                               */
/*-------------------------------------------------*/
void AT24C02_ReadPage(unsigned char ReadAddr, unsigned char *Redata)
{				  		
	unsigned char i;               //定义一个变量用于for循环   
	
	IIC_Start();                   //IIC开始信号
	IIC_Send_Byte(AT24C02_WADDR);  //发送器件地址+写操作	   	
	IIC_Wait_Ack();                //等待应答
    IIC_Send_Byte(ReadAddr);       //发送需要读数据的地址 
	IIC_Wait_Ack();	               //等待应答 
	IIC_Start();  	 	           //IIC开始信号
	IIC_Send_Byte(AT24C02_RADDR);  //发送器件地址+读操作				   
	IIC_Wait_Ack();	               //等待应答
	for(i=0;i<7;i++){              //24c02一页8个字节,循环读取前7个字节	
		Redata[i]=IIC_Read_Byte(1);//读一字节数据,发送ACK信号 
    }	
	Redata[7]=IIC_Read_Byte(0);    //读最后一字节数据,不发送ACK信号 
    IIC_Stop();                    //停止信号
	Delay_Ms(5);                   //延迟
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jmeter 入门指南:从零开始学习

JMeter 是一个非常流行的开源工具&#xff0c;用于进行负载测试。它支持多种网络协议&#xff0c;包括 HTTP、FTP、SMTP、JMS、SOAP、JDBC 等&#xff0c;使其成为在多种应用环境中检测性能瓶颈的理想选择。本文将详细介绍如何利用 JMeter 进行高效的接口自动化测试。 创建和执…

01 Docker 概述

目录 1.Docker简介 2.传统虚拟机 vs 容器 3.Docker运行速度快的原因 4.Docker基本组成三要素 5.Docker 平台架构 入门版 架构版 1.Docker简介 Docker是基于Go语言实现的云开源项目。 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere&#xff0c…

python3中的pdb使用

目录 1 介绍 1 介绍 有脚本文件main.py&#xff0c;其内容如下&#xff0c; import os import sys if __name__ "__main__":n 10for i in range(n):j i 10j j * j if j % 2 0:print("j is even!")else:print("j is odd.")n 20s 0 fo…

和鲸“101”计划领航!和鲸科技携手北中医,共话医学+AI 实验室建设及创新人才培养

为进一步加强医学院校大数据管理与应用、信息管理与信息系统&#xff0c;医学信息工程等专业建设&#xff0c;交流实验室建设、专业发展与人才培养经验&#xff0c;6 月 22 日&#xff0c;由北京中医药大学&#xff08;简称“北中医”&#xff09;主办&#xff0c;上海和今信息…

windows远程连接无法复制文件

windows远程桌面无法复制文件 解决方案 打开任务管理器管理器,在详细信息界面,找到rdpclip.exe进程&#xff0c;选中并点击结束任务&#xff0c;杀死该进程。 快捷键 win r 打开运行界面&#xff0c;输入 rdpclip.exe &#xff0c;点击确定运行。即可解决无法复制文件问题。…

QStringListModel 绑定到QListView

1.QStringListModel 绑定到listView&#xff0c;从而实现MV模型视图 2.通过QStringListModel的新增、删除、插入、上下移动&#xff0c;listView来展示出来 3.下移动一行&#xff0c;传入curRow2 的个人理解 布局 .h声明 private:QStringList m_strList;QStringListModel *m_m…

单向链表结构

链表结构简介 链表结构是一种用比较特殊的数据结构类型&#xff0c;它也是线性数据结构中的一种&#xff0c;但是与栈结构等线性数据结构不同&#xff0c;它的内部结构并不是一个简单的存储空间&#xff0c;而是一个带有指向性质的单元。要理解链表结构要弄清楚两个问题&#x…

仰邦BX.K协议对接

背景 使用BX 6K控制卡控制诱导屏显示剩余车位数&#xff0c;由于控制卡和服务端不在一个局域网内&#xff0c;所以不能使用官网提供的案例&#xff0c;官网提供的案例为控制卡为TCP Server&#xff0c;服务端为TCP Client&#xff0c;因此需要开发此程序&#xff0c;服务端左右…

Python爬虫实战案例——王者荣耀皮肤抓取

大家好&#xff0c;我是你们的老朋友——南枫&#xff0c;今天我们一起来学习一下该如何抓取大家经常玩的游戏——王者荣耀里面的所有英雄的皮肤。 老规矩&#xff0c;直接上代码&#xff1a; 导入我们需要使用到的&#xff0c;也是唯一用到的库&#xff1a; 我们要抓取皮肤其…

【Linux】TCP协议【下二】{流量控制/滑动窗口/延迟应答/捎带应答/拥塞控制}

文章目录 1.流量控制--利用“窗口大小”字段协商数据量大小1. 1第一次的时候&#xff0c;怎么保证发送数据量是合理的1.2第三次握手ack的时候&#xff0c;可以携带数据&#xff01;1.3流量控制&#xff0c;属于可靠性还是属于效率&#xff1f; 2.滑动窗口--利用滑动窗口解决批量…

UE5 动画蓝图

文章目录 一、State Machines二、Blend Spaces三、Aim Offset四、Montage 初步介绍 Unreal Engine 5 Tutorial - Animation Blueprint Part 1: State Machines (youtube.com) Unreal Engine 5 Tutorial - Animation Blueprint Part 2: Blend Spaces (youtube.com) Unreal Engi…

读人工智能全传01图灵的电子大脑

1. 人工智能 1.1. 人类对人工智能的梦想&#xff0c;可以追溯到很久很久以前 1.1.1. 从古希腊开始&#xff0c;铁匠之神赫菲斯托斯(Hephaestus)拥有赋予金属物品生命的能力 1.1.2. 从16世纪的布拉格开始&#xff0c;传说中伟大的拉比在那里用黏土制作了一个傀儡魔像&#xf…

使用patch-package自动修改node_modules中的内容/打补丁

背景 在使用VuePress搭建个人博客的过程中&#xff0c;我需要使用到一个用来复制代码块的插件uepress-plugin-nuggets-style-copy。 问题&#xff1a;插件可以正常安装&#xff0c;但是启动会报错。通过查看错误信息&#xff0c;定位是插件中的copy.vue文件出现错误&#xff0c…

【实战场景】记一次UAT jvm故障排查经历

【实战场景】记一次UAT jvm故障排查经历 开篇词&#xff1a;干货篇&#xff1a;1.查看系统资源使用情况2.将十进制进程号转成十六进制3.使用jstack工具监视进程的垃圾回收情况4.输出指定线程的堆内存信息5.观察日志6.本地环境复现 总结篇&#xff1a;我是杰叔叔&#xff0c;一名…

仿论坛项目--初识Spring Boot

1. 技术准备 技术架构 • Spring Boot • Spring、Spring MVC、MyBatis • Redis、Kafka、Elasticsearch • Spring Security、Spring Actuator 开发环境 • 构建工具&#xff1a;Apache Maven • 集成开发工具&#xff1a;IntelliJ IDEA • 数据库&#xff1a;MySQL、Redi…

Docker拉取失败,利用 Git将 Docker镜像重新打 Tag 推送到阿里云等其他公有云镜像仓库里

目录 一、开通阿里云容器镜像服务 二、Git配置 三、去DockerHub找镜像 四、编写images.txt文件 ​五、演示 六、其他注意事项 最近一段时间 Docker 镜像一直是 Pull 不下来的状态&#xff0c;想直连 DockerHub 是几乎不可能的。更糟糕的是&#xff0c;很多原本可靠的国内…

Vue+ElementUi实现录音播放上传及处理getUserMedia报错问题

1.Vue安装插件 npm install --registryhttps://registry.npmmirror.com 2.Vue页面使用 <template><div class"app-container"><!-- header --><el-header class"procedureHeader" style"height: 20px;"><el-divid…

密码学及其应用 —— 密码学的经典问题

1. 古典密码学问题 1.1 问题1&#xff1a;破解凯撒密码 1.1.1 问题 凯撒密码是最简单的单字母替换加密方案。这是一种通过将字母表中的字母固定向右移动几位来实现的加密方法。解密下面的文本&#xff0c;该文本通过对一个去除了空格的法语文本应用凯撒密码获得&#xff1a; …

layui-按钮

1.用法 使用 用button标签 type"button" class"layui-button" 效果&#xff1a; 2.主题设置 前面都要加上layui-bin 3.尺寸设置 可以叠加使用&#xff01; 4.圆角设置 加一个layui-bin-radius 5.按钮图标设置 里面加一个i标签 加class"layui-…

借教室(题解)

P1083 [NOIP2012 提高组] 借教室 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路&#xff1a;二分前缀和 我们将和质检员那题差不多&#xff0c;只需要将候选人二分即可 #include<bits/stdc.h> using namespace std; #define int long long int n,m; int r[100000…