OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3471|回复: 1

STM8S105K4硬件IIC卡死在发送起始信号,怎么破?

[复制链接]

0

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2019-6-29
在线时间
9 小时
发表于 2019-10-4 18:18:53 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 nj786c 于 2019-10-4 18:23 编辑

硬件IIC调试SHT30的
一开始卡在等待总线空闲,后查贴,①设置了option byte AFR6 ②在初始化里加了复位I2C->CR2 |= 0x80;等待总线空闲问题解决。
紧接着发送起始信号,通过串口打印信息发现 等待发送完成卡住了。没有发送启动信号,难道是硬件bug?还是有什么没设置到位的地方?
关键位置已用红字标识。求解救!
void I2C_Init(void)
{
   CLK->CKENR1|=0x01;//使能IIC时钟
  I2C->CR1=0;   
  I2C->FREQR=16;//设置时钟为16m
  I2C->CCRL=0x50;//100khz的IIC速度
  I2C->CCRH=0x00;
  I2C->TRISER=0x11;//250ns上升时间
  /* Enable I2C */
  I2C->CR1 |= I2C_CR1_PE;  
  I2C->CR2 |= 0x80;//复位一下 用于去除busy
}
void Driver_I2CSend(u8 Address,u8 *DataBuff,u16 DataLen)
{         
  volatile u8 temp;//防止被优化而产生警告
  u16 time;  

  while(I2C->SR3&0x02)//等待总线空闲        
  printf("n1-------------!\n");//调试一开始卡在这,在初始化里加了   I2C->CR2 |= 0x80;这个位置就过了。  


  I2C->CR2 |= 0x01;//发送起始信号

  while((I2C->SR1&0x01)==0)//等待起始信号发送完毕,现在就卡在这了,卡了两天了求大神解救!
  printf("n2-----hhhh---------\n");  

  ............以下程序先省略了
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
141
金钱
141
注册时间
2012-8-31
在线时间
20 小时
发表于 2019-12-6 16:50:52 | 显示全部楼层
#define I2C_Over_Time 0xFA //超时处理时间需要根据实际调整

void I2C_init(void)
{
  //I2C_FREQR和I2C_CCRL,CCRH ,I2C_TRISER要对应fMASTER频率计算。。
  //但测试的效果来看好像又没什么影响。
  I2C_FREQR |= 0x10; //输入外设时钟频率为16MHz
  I2C_CR1    = 0x00; //禁止I2C外设
  I2C_TRISER = 0x0c;
  I2C_CCRL   = 0x37;
  I2C_CCRH   = 0x00;
  I2C_CR1   |= 0x01; //开启I2C外设
  I2C_CR2   |= 0x04; //应答使能
  I2C_OARL   = 0xfe;  //自身地址
  I2C_OARH   = 0x40;
}

//读IIC器件,
//参数:返回的字节缓冲,器件地址,开始地址,要读的字节数。
void Read_I2C_Dev(u8 *pBuffer,u8 ID_addr,u8 address,u8 Number)
{
  u8 cnt=0;
  while(I2C_SR3 & 0x02) //等待总线空闲
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_CR2 |= 0x01; //产生起始位
  while(!(I2C_SR1 & 0x01)) //等待START发送完
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_DR =ID_addr; //发24c02器件地址
  while(!(I2C_SR1 & 0x02)) //等特7位器件地址发送完
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_SR1;
  I2C_SR3;
  I2C_DR = address;
  while(!(I2C_SR1 & 0x84))
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_CR2 |= 0x01; //产生重复起始位
  while(!(I2C_SR1 & 0x01)) //等待START发送完
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_DR =ID_addr+1; //读
  while(!(I2C_SR1 & 0x02)) //等特7位器件地址发送完
  {
    if(++cnt>I2C_Over_Time) //超时退出
    {
      I2C_CR2|=0x02;
      return;
    }
  }
  cnt=0;
  I2C_SR1;
  I2C_SR3;
  while(Number) //要读几个字节
  {
    if(Number== 1)
    {
     I2C_CR2 &= ~0x04; //不返回应答
     I2C_CR2 |= 0x02; //产生停止位
    }
    if(I2C_SR1 & 0x40)
    {
     I2C_SR1;
     *pBuffer = I2C_DR;
     pBuffer++;
     Number--;
    }
  }
  I2C_CR2 |= 0x04;
  I2C_CR2 &= ~0x08;
}
力拔山河兮盖世,时不利兮追不逝
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 03:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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