历史上的今天
返回首页

历史上的今天

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

正在发生

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

2020-09-02 来源:eefocus

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

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

推荐阅读

史海拾趣

ETL semiconductor公司的发展小趣事

三星(Samsung)原本是一家以家电和电子产品为主的综合性企业。然而,在半导体行业快速发展的背景下,三星决定加大在半导体领域的投入。经过数十年的努力,三星不仅在存储芯片领域取得了显著成就,还在逻辑芯片和代工业务方面取得了重要进展。如今,三星已成为全球领先的半导体企业之一。

General Cable公司的发展小趣事
在编码电路中,可能需要通过调整相关元件(如电阻、电容等)的参数来精确设置时钟频率,进而实现所需的载波频率。
Essentra Components公司的发展小趣事

Essentra Components公司一直将客户服务放在首位,通过提供优质的售前咨询、售中支持和售后服务,赢得了客户的广泛赞誉。公司不仅为客户提供了丰富的产品选择,还根据客户的具体需求提供定制化的解决方案。此外,公司还建立了完善的物流配送体系,确保产品能够及时、准确地送达客户手中。这些努力使得Essentra Components在客户中树立了良好的口碑,为公司的发展奠定了坚实的基础。

Broadband公司的发展小趣事

作为一家有社会责任感的企业,Essentra Components公司积极履行社会责任,关注社会公益事业。公司定期参与各种慈善活动和社会公益活动,为当地社区的发展做出了积极贡献。此外,公司还注重员工的福利和培训发展,为员工提供了良好的工作环境和发展机会。这些举措不仅树立了企业的良好形象,还增强了企业的凝聚力和向心力。

请注意,以上故事是基于对Essentra Components公司业务特性和市场环境的理解而构想出来的,并非实际发生的事件。如有需要,建议直接联系Essentra Components公司或查阅相关资料以获取更准确的信息。

CSR plc(剑桥硅晶无线电)公司的发展小趣事

2009年,CSR plc以1.36亿美元成功收购了SiRF技术控股公司。这一收购为CSR plc带来了GPS和A-GPS的知识产权组合、航位推算和位置中心平台等重要技术资源,使其在世界无晶圆半导体厂商中的地位得到了进一步巩固。此次收购也让CSR plc的客户群体得到了极大的扩展,包括世界排名前七位的手机制造商中的六家,以及世界前五位的个人导航设备制造商等。

General Electric Solid State公司的发展小趣事

随着技术的不断进步和市场需求的日益多样化,CSR plc意识到单一的业务领域已无法满足公司的长远发展。于是,公司开始寻求多元化的发展道路。2007年,CSR plc成功收购了Nordnav Technologies和Cambridge Positioning Systems,开始进军GPS市场。这一战略转型不仅让公司的业务范围得到了极大的拓展,也使其在GPS领域取得了显著的成就。

问答坊 | AI 解惑

128x64点阵液晶,430程序。已调试OK!

程序使用c语言写的 [ 本帖最后由 kevinrobot 于 2009-8-8 01:52 编辑 ]…

查看全部问答>

USB资料(包括PCB)

PCB为USB拓展板 [ 本帖最后由 kevinrobot 于 2009-8-8 01:51 编辑 ]…

查看全部问答>

[公告]单片机C语言通用处理程序范例(很好很强大很规范)

来自“农民讲习所”,现在很难找到。弥足珍贵啊。 例程下载地址:…

查看全部问答>

新手求助: 自己回复别人的帖子,自己不能编辑? 也不能删除吗?

自己回复别人的帖子,自己不能编辑? 也不能删除吗? 我回复别人的问题, 由于不熟, 在插入图片时忘记按\"插入图片\"的按钮了,直接输入了图片的地址, 所以只有第一张图篇操作正确, 另外的图片成了地址的字符. 当时以为是我哪里搞错了,就又重发了几次 ...…

查看全部问答>

WINCE下,播放声音时有杂音?

在开始播放时有杂音,播放过程中正常,用的是异步播放。请问这种情况是否正常?…

查看全部问答>

南京招聘:有嵌入式及硬件基础知识的Delphi BCB程序员,从事监控主站开发

南京招聘:有嵌入式及硬件基础知识的Delphi BCB程序员,从事监控主站开发 要求:      1:熟悉Delphi开发环境。      2:熟练使用SQL-Server编程语言      3:了解一定的硬件知识和 ...…

查看全部问答>

大家来点评——LED恒流驱动模块SEDR18系列

SEDR18系列模块是一款高效的LED驱动IC。可以直接介入110V和220V交流电,获得稳定的横流输出。输出电流稳定、输出电压范围大是SEDR18系列模块的主要特点。改变负载LED的数量,使得SEDR18模块的输出电压随之变化,则SEDR18模块的输出电流可以稳定在15 ...…

查看全部问答>

LED 参考设计电路图批量下载

众所周知,LED是将电能直接转换成光的晶体管元件,LED 背光模块(BLU)正在推动总体LED市场成长,但在未来一段时间,LED照明将引领这个市场的增长。   如何使LED将大部分能量转换为可见频谱的冷光,而不以发热的形式浪费电能,德州仪器(TI) ...…

查看全部问答>

求助有关51单片机串口通信的问题

我用51单片机控制SIM900模块收发短信,通过串口发送指令来控制。我想实现下面的功能:当SIM900模块收到短信时,不管短信内容,单片机控制Led变亮。 现在问题是这样的:SIM900模块在收到新短信时会返回 “+CMTI”指令,我用PC机调试这个模块时,在串 ...…

查看全部问答>

如何应对说话含糊的领导?

  对于初入职场的新人来说,工作中要听从领导的安排。有时,当你特别希望领导给你明确指示的时候,等来的却偏偏是领导的 “还可以”、“再研究研究”或是“你自己安排吧”等模棱两可的措辞,搞得你摸不着头脑。作为新人,如何应对领导含糊的指示 ...…

查看全部问答>