历史上的今天

今天是:2024年09月02日(星期一)

正在发生

2020年09月02日 | stm8s开发(八) IIC的使用:IIC主机通信!

发布者:Serene123 来源: eefocus关键字:stm8s  IIC  主机通信! 手机看文章 扫描二维码
随时随地手机看文章

  前面讲过两个常用的串口,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

  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在IAR环境下的项目工程,包括了SPI、IIC、PWM、AWU、USART、EEPROM等片上硬件的初始化代码。


  http://download.csdn.NET/detail/devintt/9454188

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

关键字:stm8s  IIC  主机通信! 引用地址:stm8s开发(八) IIC的使用:IIC主机通信!

上一篇:stm8s开发(七) SPI的使用:SPI主机通信!
下一篇:stm8s开发(六) EXIT的使用:做一个外部中断的按钮

推荐阅读

1、CAN只具有CAN_High和CAN_Low两条信号线,CAN是以差分信号的形式进行通信的; 2、CAN通信有两种网络:一种是遵循ISO11898标准的高速短距离闭环网络,它的总线最大长度为40m,通信速度最高位1Mbit/s;另外一种是遵循ISO11519-2标准的低速远距离开环网络,最大传输距离为1km,最高通信速率为125kbit/s。 3、CAN的通信节点由一个CAN控制器、一个CAN接收器组...
近日,国内第三代半导体行业领军企业——深圳基本半导体宣布了一则重磅消息:一辆搭载了基本半导体碳化硅MOSFET和碳化硅肖特基二极管的新能源汽车,至今已累计无故障行驶120天、运行里程超过1万公里!基本半导体正不断提速车规级碳化硅功率器件的研发和测试,在国内第三代半导体企业中脱颖而出,将引领碳化硅器件技术创新,推动功率器件国产替代进程。百亿...
把LED闪烁程序通过pic18f的boot程序烧入PIC18F66K80单片机pic18f66k80_boot 的hex文件:接收串口:D0 F2 09 20 00 34 35 36 37 38 ,该指令将跳转到0x2058地址处运行代码:0400000065EF03F0B5:10001C00730E416E1F0E426E82EC01F0F26AFC6AA6:10002C008A0E0F01016F600E026F080E056F010E34:10003C00066F550E076F6ECF4FF0E00E4F1603E1B3:10004C000087...
在前面的视频里我们举了一个例子,母亲看书被声音打断,远处的声音来源有多种多样,声音传入耳朵,再由耳朵传入大脑,整个过程涉及声音来源耳朵大脑,为了确保这个母亲看书的过程能够被声音打断,我们必须保证声音来源可以发出声音,耳朵没有聋,脑袋没有傻。中断处理流程1、中断初始化:①我们需要设置中断源,让它能够发出中断②设置中断控制器,让它能...

史海拾趣

问答坊 | AI 解惑

进口电容的标识

<1>单位:基本单位为P,辅助单位有G,M,N。换算关系为:<1G=1000UF><1M=1UF=1000PF> <2>标注法:通常不是小数点,而是用单位整数,将小数部分隔开。例如:6G8=6.8G=6800UF;2P2=2.2PF;M33=0.33UF;68n=0。068UF有的电容器用 ...…

查看全部问答∨

求助!中英文对照论文

求助一篇关于MSP430用于交通灯控制的,有中英文对照的论文,5000字,谢谢了!…

查看全部问答∨

关于余数的问题

老师,假如被除数放在R1R0中,我用被除数除以一万得到被除数的万位,那么我在用得到的余数除以一千得到千位,依次类推我可以得到被除数的百,十,个位,这样就可以把放在R1R0中的数在数码管上显示出来了。 但我有一点不怎么理解呢? 比如:我用被 ...…

查看全部问答∨

明年开始全球手机统一充电器?

每次换手机,都附送新充电器,不同品牌又有不同款式充电器,结果旧的扔掉,超级不环保。   全球10大手机商,终于同意明年开始,向用户提供统一标准的充电器,预料充电器将在全球步入一统时代。     现在随机送充电器十分浪费,欧洲 ...…

查看全部问答∨

帮我看看这个电路的功能

帮我看看这个电路的功能和原理,谢谢大家了,这个是从PI控制后输入,输出的信号是频率和脉宽都变化的波形。…

查看全部问答∨

请教个小问题,关于802.11的物理层的FHSS。

这几天在看802.11的物理层的FHSS(Frequency Hopping Spread Spectrum , 调频扩频),工作在2.4GHz,使用了79个信道,每个信道的带宽为1MHZ,这里的带宽是这什么意思? 谢谢!…

查看全部问答∨

雷达测距传感器在这种环境下可以应用吗?

这是一个孔深在50米的一个封闭孔,孔的直径大约在60毫米,我想用雷达测距在孔口发射和接收来测孔深不知道可不可行,希望大家给提点建议,看看雷达测距是否可行,或者还有没有别的测距方式能测到孔底,激光测距好像不太可行,因为空不一定是很直的。 ...…

查看全部问答∨

现在用有protel99 和 ad6.9 用哪个好些?

开始学习硬件 电脑只能带的起这两个软件  用哪个呢…

查看全部问答∨

zigbee主从设备的切换,求各位大虾相助~~!

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我想实现这样一个功能,在zigbee组建的网络里面,有一个主设备,一个备份主设备,其他是从设备,当主设备出现故障后,网络自动切换到从设备上工作(即从备份主设备变成主设备,原来的主设备转为 ...…

查看全部问答∨

PWM可不可以出1-10HZ的方波

请教各位大神:怎么出1-10Hz的方波啊???…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved