【STM8S103K3】 I2C
以下为.h文件:
定义了PA1为SDA,PA2为SCL
#ifndef __I2C_H
#define __I2C_H
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "tim1.h"
#include "uart.h"
#include <iostm8s103f3.h>
#include <intrinsics.h>#define SCL PA_ODR_ODR2
#define SDA PA_ODR_ODR1
#define SDAM PA_IDR_IDR1
#define SET_SCL_OUT() {PA_DDR_DDR2=1; PA_CR1_C12 = 1; PA_CR2_C22 = 0;}
#define SET_SDA_OUT() {PA_DDR_DDR1=1; PA_CR1_C11 = 1; PA_CR2_C21 = 0;}
#define SET_SDA_IN() {PA_DDR_DDR1=0; PA_CR1_C11 = 0; PA_CR2_C21 = 0;}void IIC_Init(void);
void Delay_us(u8 z);
void I2C_Start(void);
void I2C_Stop(void);
void IIC_Ack(void);
void IIC_NAck(void);
uint8_t IIC_Wait_Ack(void);
void IIC_Send_Byte(uint8_t txd);
uint8_t IIC_Read_Byte(uint8_t ack);
void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data);
void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num);#endif
以下为.c文件:
#include "I2C.h"
//--------------------------------------------------------------
// Prototype : void I2C_Start(void)
// Calls : Delay_5us()
// Description : Start Singnal
//--------------------------------------------------------------
void IIC_Init(void)
{SET_SCL_OUT();SET_SDA_OUT(); SCL = 1;SDA = 1;
}
//--------------------------------------------------------------
// Prototype : void Delay_5us(void)
// Description : 大约延时5us
//--------------------------------------------------------------
void Delay_us(u8 z)
{//u8 i; //fcpu 8MHz 时//for (i=50; i>0; i--);while(z--){nop();nop();nop();nop();}
}
//--------------------------------------------------------------
// Prototype : void I2C_Start(void)
// Calls : Delay_5us()
// Description : Start Singnal
//--------------------------------------------------------------
void I2C_Start(void)
{// SDA 1->0 while SCL High//SCL高电平期间,SDA出现一个下降沿表示起始信号SET_SDA_OUT();SDA = 1; //数据线先保持为高,起始信号要该口的下降沿 Delay_us(4);SCL = 1; //时钟线保持为高 Delay_us(40); //有一个大概5us的延时具体以器件而定 SDA = 0; //数据线拉低出现下降沿 Delay_us(4); //延时 一小会,保证可靠的下降沿 SCL = 0; //拉低时钟线,保证接下来数据线允许改变
}//--------------------------------------------------------------
// Prototype : void I2C_Stop(void)
// Calls : Delay_5us()
// Description : Stop Singnal
//--------------------------------------------------------------
void I2C_Stop(void)
{// SDA 0->1 while SCL High//SCL高电平期间,SDA产生一个上升沿 表示停止SET_SDA_OUT();SCL = 0;Delay_us(2);SDA = 0; //保证数据线为低电平Delay_us(40);SCL = 1; //先保证时钟线为高电平Delay_us(10); //延时 以得到一个可靠的电平信号 SDA = 1; //数据线出现上升沿 Delay_us(40); //延时 保证一个可靠的高电平
}//应答函数
void IIC_Ack(void)
{//数据线一直保持为低电平,时钟线出现上升沿即为应答SET_SDA_OUT();Delay_us(10);SDA = 0;Delay_us(10);SCL = 0;Delay_us(40);SCL = 1;Delay_us(40);//应答完成后 将时钟线拉低 允许数据修改SCL = 0;
}
//非应答
void IIC_NAck(void)
{//非应答即相反 与应答区别即为数据线保持高电平即可SET_SDA_OUT();Delay_us(10);SDA = 1;Delay_us(10);SCL = 0;Delay_us(40);SCL = 1;Delay_us(40);//最后要将时钟线拉低 允许数据变化SCL = 0;
}
//等待应答
uint8_t IIC_Wait_Ack(void)//0为有应答,1为无应答
{//应答等待计数uint8_t ackTime = 0;//先将数据线要设置成输入模式本程序未体现,有应答则会出现下降沿SCL = 0;SET_SDA_OUT();Delay_us(10); SDA = 1;//Delay_us(30);SET_SDA_IN();//切换为输入模式//时钟线拉高SCL = 1;Delay_us(30);//等待数据线拉低应答while(SDAM){//如果在该时间内仍未拉低ackTime ++;if(ackTime > 250){//认为非应答 停止信号I2C_Stop();return 1;}}SCL = 0;return 0 ;
}void IIC_Send_Byte(uint8_t txd)
{//定义一个计数变量uint8_t i;SET_SDA_OUT();//将时钟线拉低允许数据改变
// SCL = 0;//按位发送数据for(i = 0;i < 8; i ++){Delay_us(2);if((txd&0x80)>>7) //0x80 1000 0000SDA=1;elseSDA=0;txd<<=1; Delay_us(20); SCL=1;Delay_us(20); SCL=0; Delay_us(20); }
}//返回值为收到的数据
//参数为是否应答1应答0不应答
uint8_t IIC_Read_Byte(uint8_t ack)
{//定义计数变量uint8_t i = 0;//定义接收变量uint8_t receive = 0;//此时要把数据线的模式切换为输入模式 本程序中不予体现SET_SDA_IN();//切换为输入模式for(i = 0;i < 8; i ++){Delay_us(50);SCL = 0;Delay_us(50);//时钟线拉高 读数据保证对方数据不改变SCL = 1;//来一个延时保证电平可靠// Delay_us(5);//先左移接收变量,防止循环结束时改变该变量receive<<=1;//判断数据线电平if(SDAM){//高电平的话接收变量自加,低电平不变化只左移,即保证了该位为0receive++;}//延时一小会 保证一个可靠的电平// Delay_us(1);//时钟线拉低,允许下一位数据改变//SCL = 0;}Delay_us(50);SCL = 0;
// if(!ack)
// {//不需要应答 则给出非应答信号,不再继续
// IIC_NAck();
// }
// else
// {//需要应答 则给应答
// IIC_Ack();
// }return receive;
}void Device_WriteData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t Data)
{//起始信号I2C_Start(); //发送器件地址 IIC_Send_Byte(DeciveAddr); //等待应答IIC_Wait_Ack(); //发送数据地址IIC_Send_Byte(DataAddr); //等待应答IIC_Wait_Ack(); //发送数据IIC_Send_Byte(Data); //等待应答IIC_Wait_Ack(); //结束信号I2C_Stop();
}//读数据
//参数一 器件地址
//参数二 数据地址
//参数三 接收数据存储
//参数四 接收长度
//
void Decive_ReadData(uint8_t DeciveAddr,uint8_t DataAddr,uint8_t *ReciveData,uint8_t num)
{//定义计数变量uint8_t i;//起始信号I2C_Start();//发送器件地址IIC_Send_Byte(DeciveAddr);//等待应答IIC_Wait_Ack();//发送数据地址IIC_Send_Byte(DataAddr); //等待应答IIC_Wait_Ack(); //起始信号I2C_Start();//发送器件地址读模式IIC_Send_Byte(DeciveAddr + 1);//等待应答IIC_Wait_Ack();//读数据for(i = 0;i < (num-1);i ++){//前num-1位数据时需要给应答的因为要继续读*ReciveData= IIC_Read_Byte(1);ReciveData++;}//最后一位数据不需要给应答 因为不用读了*ReciveData = IIC_Read_Byte(0);//停止信号I2C_Stop();
}
注:I2C通讯需外接上拉电阻!
【STM8S103K3】 I2C相关推荐
- 【STM32】I2C相关函数和类型
00. 目录 文章目录 00. 目录 01. I2C简介 02. 相关类型 03. 相关函数 04. 结构体封装 05. 预留 06. 附录 07. 声明 01. I2C简介 I2C(内部集成电路)总 ...
- 【STM32】I2C详解
00. 目录 文章目录 00. 目录 01. I2C简介 02. I2C主要特性 03. I2C功能说明 04. I2C中断 05. I2C相关寄存器 5.1 I2C 控制寄存器 1 (I2C_CR1 ...
- Linux clock子系统【3】-i2c控制器打开时钟的流程分析(devm_clk_get)(consumer侧)
文章目录 前言 一.硬件流程图 二.晶振设备树描述 三. I2CX时钟设备树描述 四.驱动中获得/使能时钟 4.1 流程源码分析 4.1.1 devm_clk_get(struct device *d ...
- 【转】 i2c驱动调试经验
原文网址:http://blog.csdn.net/cmm20071020/article/details/7179958 把一个i2c驱动从2.6.21升级到2.6.39 上网查到一篇帖子,讲了驱动 ...
- 【InterFace】I2C 总线详述
背景 昨天出去了一趟,人问:你熟悉什么?答:软硬件.结果,好尴尬. 硬件一般都做什么内容? 答:电源设计. 能说下升压.降压电路是怎么实现的吗? 答:不能.(Ps:后续增加 电源设计原理) 通讯都用到 ...
- 【RTT】I2C总线设备:分析
I2C总线设备 概要 一.I2C硬件资源初始化 二.软件I2C的注册函数 三.I2C总线设备的注册 四.I2C总线设备的初始化 五.I2C的数据 六.I2C总线设备的使用 1. 查找I2C总线设备 2 ...
- 【sylixos】i2c设备驱动创建和使用
前提是需要已实现过i2c总线驱动 步骤 步骤分为几步: 创建设备 API_I2cAdapterCreate 传输消息 API_I2cDeviceTransfer 发送消息 API_I2cDeviceM ...
- 【Arduino】I2C Master 实现
#背景 前几天,有个海外的客户在使用 Arduino 连接产品(I2C接口)的时候,发现有异常.为了方便,我自己写了个 Arduino 的例程.使用 Arduino 例程的时候发现,官方的描述不太详细 ...
- 【单片机】I2C通信详解介绍(初学,浅显易懂,基本知识)
介绍:I2C通讯协议(Inter-Integrated Circuit)引脚少,硬件实现简单,可扩展性强,不需要USART.CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC) ...
- 【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪
I2C练习 MPU6050简介 寄存器查询表格 STM32CubeMx配置 代码文件 mpu6050.h文件 mpu6050.c文件 main.c文件 总结 MPU6050简介 MPU-6000(60 ...
最新文章
- AI如何帮助我们理解意识——麻省理工最新大脑研究
- 发觉好像视力户籍变差么。。
- Unity中实现Hololens的三维空间映射Spatial mapping
- bartender外部表不是预期格式_三张表轻松搞定项目计划
- MPEG-LA发布VVC专利池
- Pythton3实例
- js获取对象数组中指定属性值对象_3分钟学会操作JavaScript内置对象,快来试试吧...
- centos 7 修改ip
- HDU 6051 If the starlight never fade(原根+推式子)
- 图解ZooKeeper的典型应用场景(转载)
- java8新特性有哪些
- 清华郝景芳:中国教育还欠缺什么?如何弥补当下教育的不足? (公号回复“郝景芳”下载PDF典藏版)
- 同济版《工程数学:线性代数》60条笔记全整理
- 元宇宙,风口还是扯淡?
- python爬虫获取维基百科词条
- 冬天洗衣不动手,这几款智慧洗衣机可以帮到你
- 被误解的明朝——中国的文艺复兴(转)
- 科学动画制作工具——Blender
- 联想禁止 win10 更新 v2.11 免费版
- arcgis区位图的制作——以武汉市为例