OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 10731|回复: 32

stm8 调试硬件I2C心得(原创)

[复制链接]

  离线 

9

主题

21

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
227
金钱
227
注册时间
2013-1-5
在线时间
0 小时
发表于 2014-2-28 11:17:26 | 显示全部楼层 |阅读模式
            

stm8 调试硬件I2C心得

 

  这次调试stm8的硬件真是艰辛,没有想到这样恼火!整整搞啦 我5天的时间,参考网上很多例子和风驰的stm8讲解!和自己的实践,终于搞通啦!特将自己在调试过程中一些心得希望的大家分享。由于本人水平有限也希望大家指出不足和错误的地方!

 

  Stm8不需要专门配置GPIO口,执行初始化就可以啦!有些stm8需要打开EEPROM设置I2C(看官方文档)

 

  Stm8主要靠SR1SR3状态寄存器判断I2C的情况(while(!XXXXX)就是出自这里),多半大家调不通!就是卡在这里(需要注意的是 寄存器有些位,只要读寄存器就可以清除,在仿真的时候,最好不要打开寄存器页面)。这里分软故障和硬故障:

 

  首先是硬故障一般是stm8芯片IO口坏啦,有些时候stm8能够写程序而且IO别的功能都是好的,单单是I2C用不起!还有就是IO上拉电压不够!我就遇到这样的问题,我IO 加上逻辑分析仪后就可以调通,不加就通不了。这个也搞啦我很久。

 

  软故障一般主要是设置CR1CR2问题,只要按照我的参考程序设置就可以!

 

  我详细的讲讲,寄存器I2c_CR2 应答使能位(位2ack。首先是理解:官方文档上面说的是ack应答使能,对是使能!很多人包括我自己 开始都认为是发送ack,导致每次stm8收到数据后,我们都手动在每次收到字节后加I2C_AcknowledgeConfig(I2C_ACK_CURR)无任何意义,因为在接收模式下,收到完整字节后,自动发送ack(提前是CR2 ack位使能,不需要专门CR2 ack位置1)   ,都是软件虚拟I2C用多啦!想当然啦!

还有就是使用这个ack!设置ACK都必须在接收字节前,也就是说为个在收到最后一个字节后产生一个NACK 脉冲,在读倒数第二个数据字节之后,必须清除ack(ack=0)!设置ack同理! 还有需要 主要的地方 如果设置 ack=0; 下次需要重新产生ack的时候!需要手动置位ack!记住在开始接收之前!如果你只有一个字节正确,后面全部是0xFF...可能就是这个问题(切记!切记!很多例子都没有加上这句,包括风驰 的例子!! 不过 他没有加循环如果他再循环一次就会出现问题。)

 

  随便说说仿真调试!在调试过程中,最好不要打开I2C寄存器看!因为对寄存器的读,也会造成寄存器有些位重置!直接按Go,然后暂停。进去程序看卡在那里啦。

 

  操作库和寄存器编写程序,其实没有分别!不过为啦更好的理解,我在这里是操作寄存器!网上有人说加入中断会对I2C产生影响,我这里没有加中断。希望有后来人补全!反正我这几天运行没有发现问题!

 

附录主要I2C程序

MLX90615(stm8硬驱动I2C程序完整版).zip

1.31 MB, 下载次数: 3771

stm8调试硬件I2C心得.pdf

169.74 KB, 下载次数: 2594

回复

使用道具 举报

  离线 

9

主题

21

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
227
金钱
227
注册时间
2013-1-5
在线时间
0 小时
 楼主| 发表于 2014-2-28 11:18:02 | 显示全部楼层

/*******************************************************************************
 * 名称: Read_8816
 * 功能: 读取温度数据
 * 形参: *pBuffer 返回读取数据指针
         index 温度寄存器地址
         NumByteToRead 需要读取字节数


 * 返回: 无
 * 说明: 该函数直接操作stm8寄存器!
         寄存器I2c_CR2 应答使能位(位2)ack=1,当stm8接受到数据后,自动发送ACK.不需要手动ack

         为个在收到最后一个字节后产生一个NACK 脉冲,在读倒数第二个数据字节之后,必须清除ack位(ack=0)

         当接收到最后一个字节,需要重新使能ack=1.(如果不设置ack=1,循环开始后,收到第一个字节stm8不会发送ack,造成除每次循环第一个字节正常外,后面收到
         的数据都是0xFF....stm8一直不给ack)
          
         需要注意的是 寄存器有些位,只要读寄存器就可以清除(不需要专门写入寄存器,在仿真的时候,最好不要打开寄存器页面),
 ******************************************************************************/


void Read_8816(u8 *pBuffer, u8 index, u8 NumByteToRead)


 
  while(I2C->SR3 & 0x02);  //等待总线空闲   检测i2c-SR3 busy位 
 
 
  //以下见stm8s中文数据手册P251(图96主设备发送模式发送序列图)
 
  //S 起始条件
  I2C->CR2 |= 0x01;  //产生起始位            CR2 start位      

  //EV5:SB=1,读SR1 然后将地址写入DR寄存器将清除该标志。
  while(!(I2C->SR1 & 0x01));  //等待START发送完 E5

 
  //ADDRESS (发送模式)
  I2C->DR = 0x00;  //发送MLX90615器件地址(最后一位是0,表示发送)
 
 
  while(!(I2C->SR1 & 0x02));  //等特7位器件地址发送完并且收到ack,ADDR置1
 
 //EV6:ADDR 在软件读取SR1后,对SR3寄存器读操作 将清除改位
 I2C->SR1; //见P251 读SR1 (实验证明可以不要)
 I2C->SR3; //然后读SR3 清  ADDR(等于库函数I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED))
 
 
  //DATA 发送寄存器地址
  I2C->DR = (u8)(index);
 
  //EV8_2 TxE=1 ,BTF=1,产生停止条件时由硬件清除。
  while(!(I2C->SR1 & 0x84));  //检测SR1 TXE1 BTF位置(只有当stm8收到ack,TxE才会置1,其实这句相当于判断收到ack没有?)
 
 
 
  //在发送地址和清除ADDR 之后,I2C接口进入主设备接收模式。以下见stm8s中文数据手册P252(图97主设备接收模式接收序列图)
 
  //S 重复起始条件
  I2C->CR2 |= 0x01;  //产生重复起始位

  //EV5:SB=1,读SR1 然后将地址写入DR寄存器将清除该标志。
  while(!(I2C->SR1 & 0x01));  //等待START发送完
 
  //ADDRESS (接收)
  I2C->DR = 0x01;  //发送MLX90615器件地址(最后一位是1,表示接收),发送完后自动发送ack(提前是CR2 ack位使能)
 
 
  //EV6:ADDR 在软件读取SR1后,对SR3寄存器读操作 将清除改位
  while(!(I2C->SR1 & 0x02));  //等特7位器件地址发送完并且收到ack,ADDR置1

 I2C->SR1; //见P251 读SR1 (实验证明可以不要)
 I2C->SR3; //然后读SR3 清  ADDR(等于库函数I2C_ClearFlag(I2C_FLAG_ADDRESSSENTMATCHED))

 
 //循环读取数据
  while(NumByteToRead) 
  {
      //EV7_1 :RxNE=1 ,读DR寄存器清除该标志。设置ACK=0和STOP 请求。(在接收最后一个字节前)
        if(NumByteToRead == 1) //实验证明在最后一个字节前后都一样

    {
      I2C->CR2 &= ~0x04; //ack使能
     
      I2C->CR2 |= 0x02;  //停止位产生stop
   

    }
     
   
      ///测试EV7 RxNE=1(收到一个字节后RxNE置1) ,判断DR寄存器有数据
    if(I2C->SR1 & 0x40)
    {   
   

     
       *pBuffer=I2C->DR;//在接收模式下,收到完整字节后,自动发送ack(提前是CR2 ack位使能,不需要专门CR2 ack位置1)
              //在风驰里面例子,在每次收到字节后加I2C_AcknowledgeConfig(I2C_ACK_CURR)无任何意义,
       pBuffer++; 
       NumByteToRead--;
          
             
         
 
     
    }

     
  }
  
 I2C->CR2 |= 0x04;//为一下循环开始 设置 ack使能,上面 EV7_1设置ack=0发送stop后;需要手动设置ack=1使能,必要在接收数据之前
 
 //切记!切记!很多例子都没有加上这句,包括风驰 的例子!! 不过 他没有加循环! 如果他在循环一次就会出现问题。CR2 ack位其实就是使能的意思!!很多人都理解成需要手动设置!
 // 都是软件模拟I2C 搞太多!! 想当然啦!没有仔细看官方的文档!

}

 

 

 

回复 支持 反对

使用道具 举报

  离线 

1

主题

25

帖子

0

精华

新手上路

积分
49
金钱
49
注册时间
2014-2-25
在线时间
0 小时
发表于 2014-2-28 14:58:23 | 显示全部楼层
呵呵,调多了就好了
回复 支持 反对

使用道具 举报

  离线 

516

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
134643
金钱
134643
注册时间
2010-12-1
在线时间
1313 小时
发表于 2014-2-28 15:10:20 | 显示全部楼层
不错,cool
回复 支持 反对

使用道具 举报

  离线 

9

主题

21

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
227
金钱
227
注册时间
2013-1-5
在线时间
0 小时
 楼主| 发表于 2014-2-28 16:32:34 | 显示全部楼层
回复【3楼】LWM1368:

呵呵,调多了就好了

---------------------------------
我写这个帖子的原因 ,就是  让后来人少走弯路!!! 有些东西,要是不明白!! 坑死!!!
回复 支持 反对

使用道具 举报

  离线 

17

主题

472

帖子

1

精华

高级会员

Rank: 4

积分
718
金钱
718
注册时间
2013-11-23
在线时间
0 小时
发表于 2014-2-28 19:09:19 | 显示全部楼层
顶,赞一个
回复 支持 反对

使用道具 举报

  离线 

516

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
134643
金钱
134643
注册时间
2010-12-1
在线时间
1313 小时
发表于 2014-2-28 21:45:05 | 显示全部楼层
回复【5楼】bigwudan:
---------------------------------
谢谢分享。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

头像被屏蔽

  离线 

6168

主题

7041

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19700
金钱
19700
注册时间
2012-12-27
在线时间
23 小时
发表于 2014-3-10 20:34:03 | 显示全部楼层
感谢分享,版区有你更精彩!
回复 支持 反对

使用道具 举报

  离线 

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2013-10-7
在线时间
2 小时
发表于 2014-9-1 09:24:15 | 显示全部楼层
此处只有五个字。
回复 支持 反对

使用道具 举报

  离线 

18

主题

453

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1451
金钱
1451
注册时间
2014-2-25
在线时间
175 小时
发表于 2014-9-2 19:26:32 | 显示全部楼层
mark一下
回复 支持 反对

使用道具 举报

  离线 

2

主题

9

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2014-7-19
在线时间
2 小时
发表于 2014-9-5 10:25:13 | 显示全部楼层
牛人,听说这IIC很不好调
回复 支持 反对

使用道具 举报

  离线 

0

主题

4

帖子

0

精华

新手入门

积分
24
金钱
24
注册时间
2014-7-30
在线时间
0 小时
发表于 2014-9-12 12:58:34 | 显示全部楼层
谢谢分享。牛人,
回复 支持 反对

使用道具 举报

  离线 

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2014-7-29
在线时间
2 小时
发表于 2014-9-15 11:38:23 | 显示全部楼层
最近在做这个方面 十分感谢
回复 支持 反对

使用道具 举报

  离线 

180

主题

310

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2012-8-26
在线时间
50 小时
发表于 2014-9-19 07:51:09 | 显示全部楼层
非常感谢。·
为了雅典娜?为了爱与正义
回复 支持 反对

使用道具 举报

  离线 

1

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2013-7-21
在线时间
3 小时
发表于 2014-9-25 17:51:11 | 显示全部楼层
不错,学习了~
回复 支持 反对

使用道具 举报

  离线 

27

主题

309

帖子

1

精华

高级会员

Rank: 4

积分
773
金钱
773
注册时间
2012-6-19
在线时间
19 小时
发表于 2014-12-10 15:51:08 | 显示全部楼层
谢谢分享!!
回复 支持 反对

使用道具 举报

  离线 

0

主题

4

帖子

0

精华

新手入门

积分
24
金钱
24
注册时间
2014-12-11
在线时间
0 小时
发表于 2014-12-22 20:29:41 | 显示全部楼层
最近被i2c困了很久,STM8提供的 eprom 高階語言程式庫,因為不完全(還是我不了解)一值無法應用,經常發生 溢位的問題...
回复 支持 反对

使用道具 举报

  离线 

5

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-20
在线时间
0 小时
发表于 2015-1-7 14:43:21 | 显示全部楼层
请问我用stm8做从机与上位机用IIC通信,stm8单片机接收上位机的命令后,再返回数据给上位机,stm8单片机的设备地址要怎样去设置,我在datasheet里面没有找到单片机IIC通信时的设备地址。
回复 支持 反对

使用道具 举报

  离线 

6

主题

63

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2011-2-12
在线时间
28 小时
发表于 2015-2-6 17:08:36 | 显示全部楼层
感谢楼主的分享,刚好要用到I2C,谢谢
回复 支持 反对

使用道具 举报

  离线 

7

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2014-6-14
在线时间
1 小时
发表于 2016-1-21 11:04:06 | 显示全部楼层
留个印以备后面用
回复 支持 反对

使用道具 举报

  离线 

0

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2013-8-16
在线时间
18 小时
发表于 2016-3-7 20:57:05 | 显示全部楼层
谢谢分享。。。。
回复 支持 反对

使用道具 举报

  离线 

16

主题

36

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
320
金钱
320
注册时间
2015-11-25
在线时间
63 小时
发表于 2016-3-16 11:06:00 | 显示全部楼层
谢谢!学习了!我正想用I2C做单片机间通信了!
不积跬步无以至千里!
回复 支持 反对

使用道具 举报

  离线 

3

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2015-11-8
在线时间
15 小时
发表于 2016-4-7 16:27:46 | 显示全部楼层
mark mark
回复 支持 反对

使用道具 举报

  离线 

2

主题

4

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2013-4-22
在线时间
4 小时
发表于 2016-4-28 09:42:14 | 显示全部楼层
已经放弃STM8S105K6T6的硬件I2C调试
回复 支持 反对

使用道具 举报

  离线 

32

主题

1596

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3795
金钱
3795
注册时间
2016-5-29
在线时间
578 小时
发表于 2016-5-29 13:14:17 | 显示全部楼层
个人意见: 从来不使用硬件I2C,没有使用硬件I2C的理由.硬件I2C并不减少CPU的负载.也没有减少程序的复杂度.倒是要多学习一下他的寄存器 .
回复 支持 反对

使用道具 举报

  离线 

0

主题

39

帖子

0

精华

高级会员

Rank: 4

积分
915
金钱
915
注册时间
2015-1-4
在线时间
80 小时
发表于 2016-6-24 17:13:39 | 显示全部楼层
Just study it, thanks.
回复 支持 反对

使用道具 举报

  离线 

14

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
225
金钱
225
注册时间
2012-10-11
在线时间
65 小时
发表于 2016-6-26 10:29:36 | 显示全部楼层
谢楼主的分享!
回复 支持 反对

使用道具 举报

  离线 

0

主题

0

帖子

0

精华

新手入门

积分
20
金钱
20
注册时间
2015-7-20
在线时间
0 小时
发表于 2016-7-5 11:06:41 | 显示全部楼层
很有帮助,,谢谢
回复 支持 反对

使用道具 举报

  离线 

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2016-7-9
在线时间
8 小时
发表于 2016-8-1 15:54:13 | 显示全部楼层
顶一个,之前也是弄硬件I2C主从机弄得心碎
回复 支持 反对

使用道具 举报

  离线 

0

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2016-1-31
在线时间
11 小时
发表于 2016-8-12 14:10:23 | 显示全部楼层
赞下楼主,论坛有你更精彩。
回复 支持 反对

使用道具 举报

  离线 

2

主题

8

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2015-12-9
在线时间
3 小时
发表于 2016-8-15 14:18:51 | 显示全部楼层
你好,楼主,我也在调试STM8s105k6的I2C slave设备,但是SR3上一直是busy状态,option byte已经通过STVD烧录成了i2cdata和clk管脚,但是还是同样效果。。这个程序是之前网络上STM8S105的例程,在STM8s103K3上已经试验成功,没什么问题
回复 支持 反对

使用道具 举报

  离线 

2

主题

8

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2015-12-9
在线时间
3 小时
发表于 2016-8-21 01:48:09 | 显示全部楼层
IANZHANG3431 发表于 2016-8-1 15:54
顶一个,之前也是弄硬件I2C主从机弄得心碎

你好,硬件I2C主从机弄出来了吗?我的还有问题,能不能给我一点帮助?
回复 支持 反对

使用道具 举报

  离线 

0

主题

2

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2018-7-28
在线时间
1 小时
发表于 2018-10-18 17:24:27 | 显示全部楼层
留个爪
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




关闭

正点原子双11大促销上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-11-13 15:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */