前面讲过两个常用的串口,UART和SPI,这次这次讲解一下另一个常用的串口:IIC(I2C)通信

科普IIC:一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。

通信过程:
主模式时,IIC接口启动数据传输并产生时钟信号。串行数据传输总是以起始条件开始并以停止条件结束。起始条件和停止条件都是在主模式下由软件控制产生。
从模式时,IIC接口能识别它自己的地址(7位或10位)和广播呼叫地址。软件能够控制开启或禁止广播呼叫地址的识别。
数据和地址按8位/字节进行传输,高位在前。跟在起始条件后的1或2个字节是地址(7位模式为1个字节,10位模式为2个字节)。地址只在主模式发送。
在一个字节传输的8个时钟后的第9个时钟期间,接收器必须回送一个应答位(ACK)给发送器。参考下图。

详细协议可以参考:http://blog.csdn.net/subkiller/article/details/6854910

和SPI差不多,使用IIC无非就一个初始化,一个数据发送,一个数据接收,三大功能。

初始化分初始化为主机、从机,不过一般和外部芯片通信单片机都是作为主机。

 

void IIC_Master_Init(void)

{

CLK_PCKENR1 |= 0x01; //使能IIC外设时钟

PB_DDR &= 0xcf;

PB_CR1 &= 0xcf;

PB_CR2 &= 0xcf;

I2C_CR1 = 0x00; //允许时钟延展,禁止广播呼叫,禁止iic

I2C_FREQR = 0x01; //输入时钟频率8MHz(应该是1MHZ才对,可能是原创者之笔误)

I2C_OARH = 0x40; //七位地址模式

I2C_OARL = 0xa0; //自身地址0xa0

I2C_CCRL = 0xff; //

I2C_CCRH = 0x00; //标准模式

I2C_TRISER = 0x02;

I2C_CR1 |= 0x01; //使能iic外设

}

这里使用的是STM8S105片上的IIC引脚PB4、PB5。另外就是需要使能IIC的时钟。

发送和接收数据这里只给出一个最简单的例子,因为不同的外部芯片的通信方式不一样,不过一般都是:

读操作:开始  -> 发送外设地址 -> 开始  ->发送需要读取的寄存器地址 -> 读一个字节  -> (可能再读一个字节)  ->。。。  -> 结束
写操作:开始  -> 发送外设地址 -> 发送需要写入的寄存器地址 -> 写一个字节  -> (可能再写一个字节)  ->。。。  -> 结束

 

void IIC_Write_Byte(u8 DeviceAddress, u8 Address, u8 Data)

{

vu8 temp = 0;

while((I2C_SR3 & 0x02) != 0); //等待IIC总线空闲

IIC_Start();

while((I2C_SR1 & 0x01) == 0); //EV5,起始信号已经发送

I2C_DR = (DeviceAddress & 0xfe); // 发送iic从器件物理地址,最低位0,写操作

while((I2C_SR1 & 0x02) == 0); //地址已经被发送

temp = I2C_SR1; //清除ADDR标志位

temp = I2C_SR3;

while((I2C_SR1 & 0x80) == 0); //等待发送寄存器为空

I2C_DR = Address; //发送要写入的寄存器地址

while((I2C_SR1 & 0x04) == 0); //等待发送完成

while((I2C_SR1 & 0x80) == 0); //等待发送寄存器为空

I2C_DR = Data; //发送要写入的数据

while((I2C_SR1 & 0x04) == 0); //等待发送完成

temp = I2C_SR1; //清零BTF标志位

temp = I2C_DR;

IIC_Stop(); //发送停止信号

}

unsigned char IIC_Read_Byte(u8 DeviceAddress, u8 Address)

{

vu8 temp = 0;

short read_data = 0;

while((I2C_SR3 & 0x02) != 0); //等待IIC总线空闲

I2C_CR2 |= 0x04; //使能ACK

IIC_Start();

while((I2C_SR1 & 0x01) == 0); //EV5,起始信号已经发送

I2C_DR = (DeviceAddress & 0xfe); // 发送iic从器件物理地址,最低位0,写操作

while((I2C_SR1 & 0x02) == 0); //地址已经被发送

temp = I2C_SR1; //清除ADDR标志位

temp = I2C_SR3;

while((I2C_SR1 & 0x80) == 0); //等待发送寄存器为空

I2C_DR = Address; // 发送要读取的寄存器地址

while((I2C_SR1 & 0x04) == 0); //等待数据发送完成

IIC_Start();

while((I2C_SR1 & 0x01) == 0); //EV5,起始信号已经发送

I2C_DR = (DeviceAddress | 0x01); // 发送iic从器件物理地址,最低位1,读操作

while((I2C_SR1 & 0x02) == 0); //地址已经被发送

temp = I2C_SR1; //清除ADDR标志位

temp = I2C_SR3;

while((I2C_SR1 & 0x40) == 0); //等待接收数据寄存器非空

read_data = I2C_DR;

I2C_CR2 &= 0xfb; //读取数据下,发送stop必须禁止ack,才能释放从机

temp = I2C_SR1; //清零BTF标志位

temp = I2C_DR;

IIC_Stop();

return read_data;

}

附:频率寄存器详细资料

stm8s开发(八) IIC的使用:IIC主机通信!相关推荐

  1. 开发调试工具:USB转IIC/I2C/SPI/UART适配器模块可编程开发板

    开发调试工具:USB转IIC/I2C/SPI/UART适配器模块可编程开发板 发个方便测试I2C.SPI.1Wire接口的工具模块 总的思路是通过USB或者UART接口发送一些协议字符串,由模块转换成 ...

  2. STM32CUBEMX开发GD32F303(14)----IIC之配置OLED

    STM32CUBEMX开发GD32F303.14----IIC之配置OLED 概述 视频教学 csdn课程 样品申请 生成例程 配置时钟树 IIC配置 OLED 参考程序 HAL_I2C_Mem_Wr ...

  3. SPI、UART、RS232、RS485、IIC 5种嵌入式经典通信总线协议

    文章目录 一.UART 1.通信基础--并行和串行 并行通信 串行通信 2.通信基础--单工和双工 3.通信基础--比特率 4.通讯基础--异步和同步 5.UART硬件连接 6.UART控制器 串口控 ...

  4. STM32 驱动 GY-302 光照传感器 BH1750 模块(软件IIC与硬件IIC驱动)

    1.特别说明 ​ 要是不想看原理和过程,直接下拉找代码吧,都是测试过的,很稳定,有硬件I2C驱动的,也有软件模拟I2C驱动的,基于STM32F103系列和STM32F4系列实现,基于标准库实现,条理清 ...

  5. 模拟IIC与硬件IIC的区别!

    模拟IIC与硬件IIC的区别! 一:模拟IIC与硬件IIC定义? 模拟I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形. 硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所 ...

  6. firefox扩展开发(八) :控件激活

    firefox扩展开发(八) :控件激活 2008-06-11 17:01 当我们用鼠标点击一个控件,或者用TAB键移动到一个控件上时,我们说这个控件被激活 了(focus),离开这个控件时,我们说这 ...

  7. 电脑向linux板卡传文件,ARM 开发板嵌入式linux系统与主机PC通过串口传输文件

    ARM 开发板嵌入式linux系统与主机PC通过串口传输文件 本来以为按以下两篇文章就可以几步轻松搞定这个问题,没想到遇到两个小麻烦: 1,我用的xp虚拟机下redhat9.0做主机,按照下面第一篇文 ...

  8. 模拟IIC——关于模拟IIC的IO口的配置选取推挽输出还是开漏输出,以及是否需要更改IO口输入输出模式和是否需要对IO配置上拉

    在使用模拟IIC的时候,观看别人的程序的时候发现了程序之间的一些不一样的地方 ----------------------------------代码1------------------------ ...

  9. 2021-09-07体脂秤模块用来做什么?开发八电极体脂秤方案

    体脂秤模块用来做什么?可以用做开发八电极体脂秤方案,我们都在大时代的背景上成长,对于健康都有自己的要求,而体脂秤作为测人体分析脂肪率的设备,可以根据不同用户的体脂状态推荐不同的运动模式,用户通过运动来 ...

  10. 搭建PHP开发环境(五)-虚拟主机

    搭建PHP开发环境(五)-虚拟主机 ​ Apache服务器提供虚拟主机的功能,通过虚拟主机,可以在一台服务器上部署多个网站.通常服务器的IP地址是固定的,不同的虚拟主机解析到同一地址.用户使用不同的域 ...

最新文章

  1. cocos2dx 自定义动画
  2. OpenYurt入门-在树莓派上玩转OpenYurt
  3. Spring常见面试题(13个面试题,回答超详细)
  4. HTTPS虐我千百遍,我却待她如初恋!
  5. [剑指offer]面试题第[60]题[JAVA][n个骰子的点数][动态规划][空间优化]
  6. 首屏动画及验证网络状态跳转
  7. 11_python基础—函数(引用、全局、局部变量)
  8. 计算机学科技术前沿:云计算主要平台及特性
  9. 解决SecureCRT连接linux超时后断开
  10. [转载]直接保存Matlab图像到PPT文件
  11. c语言如何在手机上运行程序,各位前辈这两个程序怎么在手机上运行
  12. linux中级之lvs配置(命令)
  13. 阿里云云计算:4 阿里云产品架构
  14. Unity中的几个”近义词”
  15. 电信光猫/烽火HG6543c1光猫超级密码获取改桥接模式( 中国电信浙江公司定制天翼网关3.0)
  16. 管中窥豹IIoT(一):工业物联网价值与解决方案通用模型
  17. 管理员后台页面html代码,HTML5技术实现的管理员后台模板界面
  18. Unity接入心知天气,获取当前城市天气状况
  19. 迅捷pdf在线转换html,迅捷PDF在线转换器在线pdf转换jpg步骤方法分享
  20. playframework 笔记——搭建自己的paly工程

热门文章

  1. Spring Cloud Netflix项目进入维护模式之我见
  2. 【手写系列】纯手写实现一个高可用的RPC
  3. 【手写系列】理解数据库连接池底层原理之手写实现
  4. Spring Boot开启的2种方式
  5. Android --- .gradle文件夹的路径
  6. li变成行内块级元素之后,每一个li之间会有间隙,这是为什么?
  7. Hibernate出现org.hibernate.MappingException: Unknown entity: com.gxuwz.hiberbate.entity.User的解决办法
  8. python 标准错误输出_过程的实时标准输出/错误捕获
  9. 微软如何在3年内将数据中心的用水量削减95%
  10. 报告:2019-2025年,全球数据中心年复合增长率将超过7%