找回密码
 立即注册
查看: 792|回复: 25

I2C卡死在发送起始信号

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-02-14 17:33:56

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 16:14:43 | 显示全部楼层 |阅读模式

#include "stc8h.h"
//#include "ds1307.h"
#include "intrins.h"
#include "I2C.h"

unsigned char IIC_addr = 0x3C ;
//引脚初始化,全部设为上拉
void I2C_pin_init()
{
P1M0 &= ~0x10; //设置P1.4为双向口模式
P1M1 &= ~0x10;

P1M0 &= ~0x20;                                //设置P1.5为双向口模式
P1M1 &= ~0x20;

P1PU |= 0x10 ;					//设置P1.4的上拉电阻
	P1PU |= 0x20 ;					//设置P1.5的上拉电阻

}

//寄存器初始化

void I2C_Init(void)

{

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

//P_SW2 |= 0x80;								//打开扩展寄存器的操作功能

I2CCFG = 0xe0;                              //使能I2C主机模式
I2CMSST = 0x00;							//I2C主机状诚寄存器清0

}

void Wait()
{
while (!(I2CMSST & 0x40));
I2CMSST &= ~0x40;
}

void Start()
{
I2CMSCR = 0x01; //发送START命令
Wait();
}

void SendData(char dat)
{
I2CTXD = dat; //写数据到数据缓冲区
I2CMSCR = 0x02; //发送SEND命令
Wait();
}

void RecvACK()
{
I2CMSCR = 0x03; //发送读ACK命令
Wait();
}

char RecvData()
{
I2CMSCR = 0x04; //发送RECV命令
Wait();
return I2CRXD;
}

void SendACK()
{
I2CMSST = 0x00; //设置ACK信号
I2CMSCR = 0x05; //发送ACK命令
Wait();
}

void SendNAK()
{
I2CMSST = 0x01; //设置NAK信号
I2CMSCR = 0x05; //发送ACK命令
Wait();
}

void Stop()
{
I2CMSCR = 0x06; //发送STOP命令
Wait();
}

//读取连续接收到的数据,读取多个数据
unsigned char I2C_ReceiveData(unsigned char *ptime,unsigned char num)
{
unsigned char i=0;//cnt=0;

			for( i = 0 ; i < num ; i ++ )
			{
				ptime[i] = RecvData() ;                        //读取秒值

				if( i == 6 )
				{
					SendNAK() ;
				}
				else
				{
					SendACK();
				}
			}

return 0;
}
/*
void Delay()
{
int i;

for (i=0; i<3000; i++)
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}

}*/

//读寄存器中的数据
unsigned char I2C_Read_Byte(unsigned char reg, unsigned char *p_data)
{
unsigned int cnt = 0;

        Start();                                //发送起始命令
    SendData(IIC_addr<<1);                         //发送设备地址+写命令
    RecvACK();
    SendData(reg);                         //发送存储地址
    RecvACK();
	    //Stop();                                 //发送停止命令

    Start();                                //发送起始命令
    SendData((IIC_addr<<1)|0x01);                         //发送设备地址+读命令
			//SendACK();
    RecvACK();
	  I2C_ReceiveData(p_data,7);
      //SendNAK() ;
	    Stop();                                 //发送停止命令
	//Delay();
  	return 1;

}

//读单个字节并反回
unsigned char I2cread(unsigned char reg)
{
//unsigned int cnt = 0;
unsigned char p_data = 0 ;
Start(); //发送起始命令
SendData(IIC_addr<<1); //发送设备地址+写命令
RecvACK();
SendData(reg); //发送存储地址
RecvACK();
//Stop(); //发送停止命令

    Start();                                //发送起始命令
    SendData((IIC_addr<<1)|0x01);                         //发送设备地址+读命令
			//SendACK();
    RecvACK();
	  I2C_ReceiveData(&p_data,1);
      //SendNAK() ;
	    Stop();                                 //发送停止命令
	//Delay();
  	return p_data;

}

//向相应的寄存器中写入相应的值
unsigned char I2C_Write_Byte(unsigned char reg,unsigned char dat )
{
unsigned int cnt = 0;

Start();                                    //发送起始命令
SendData(IIC_addr<<1);                             //发送设备地址+写命令
RecvACK();
SendData(reg);                             //发送存储地址
RecvACK();
SendData(dat);                             //设置小时值
RecvACK();
Stop();                                     //发送停止命令

return 0;

}

在写入时会卡在发送起始信号这……while (!(I2CMSST & 0x40));

看到有的评论说IO要设成开漏,但我之前用过,也是设成准双向IO,可以使用,而且说明书中的例程也是设成的双向IO!

***芯片型号为STC8H1K08
捕获.PNG

没有发现结贴模式,问题已解决是硬件问题,两个IIC器件通信时用的软排线,FPC线连接,在焊接座子时有一根线,恰好是GND断开了,不知道是座子变形断开还是别的原因,引脚应该是焊接上的。是怎么发现的呢,是因为测量两块板的对地电压不一致,从机电压偏高,奇怪的是没有连接GND,从机的PW6513也能输出电压!还有一个原因,在测试PW6513时烧过后级芯片,因为输入电容没有直接接到PW6513的VCC脚上,导致烧了几个后级习片,此时也把从机的IO口烧了,所以是好多问题叠加出现了卡在启动信号发送问题这的!


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-12-23 16:30:50 | 显示全部楼层
没看到是不是开了  这个
  1.     P_SW2 |= 0x80;
复制代码


如果没有开的话 你的内部上拉电阻的配置是无效的。。
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-04-30 08:43:23

33

主题

2351

回帖

4860

积分

论坛元老

积分
4860
发表于 2024-12-23 16:32:06 | 显示全部楼层
再者根据你说 准双向模式下,可以使用,,

开漏模式下不行,且要使用内部上拉电阻的操作,我是不是可以猜测你外部没有上拉电阻,,,
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:09:43
已绑定手机

77

主题

4850

回帖

8388

积分

超级版主

DebugLab

积分
8388
发表于 2024-12-23 16:38:19 | 显示全部楼层
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-02-14 17:33:56

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 16:38:40 | 显示全部楼层
_奶*** 发表于 2024-12-23 16:32
再者根据你说 准双向模式下,可以使用,,

开漏模式下不行,且要使用内部上拉电阻的操作,我是不是可以猜 ...

是没有上拉电阻,问题是现在不行了卡死在发起始信号等待中断置位
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:09:43
已绑定手机

77

主题

4850

回帖

8388

积分

超级版主

DebugLab

积分
8388
发表于 2024-12-23 16:42:25 | 显示全部楼层
  1. void I2C_Start(void)
  2. {
  3.         I2C_Busy=1;
  4.         I2CMSCR=0x81;
  5.         while(I2C_Busy);
  6. }
  7. void I2C_SendData(unsigned char dat)
  8. {
  9.         I2CTXD=dat;
  10.         I2C_Busy=1;
  11.         I2CMSCR=0x82;
  12.         while(I2C_Busy);
  13. }
  14. void I2C_RecvACK(void)
  15. {
  16.         I2C_Busy=1;
  17.         I2CMSCR=0x83;
  18.         while(I2C_Busy);
  19. }
  20. unsigned char I2C_RecvData(void)
  21. {
  22.         I2C_Busy=1;
  23.         I2CMSCR=0x84;
  24.         while(I2C_Busy);
  25.         return I2CRXD;
  26. }
  27. void I2C_SendACK(void)
  28. {
  29.         I2CMSST=0x00;
  30.         I2C_Busy=1;
  31.         I2CMSCR=0x85;
  32.         while(I2C_Busy);
  33. }
  34. void I2C_SendNAK(void)
  35. {
  36.         I2CMSST=0x01;
  37.         I2C_Busy=1;
  38.         I2CMSCR=0x85;
  39.         while(I2C_Busy);
  40. }
  41. void I2C_Stop(void)
  42. {
  43.         I2C_Busy=1;
  44.         I2CMSCR=0x86;
  45.         while(I2C_Busy);
  46. }
复制代码
  1. void Init(void)
  2. {
  3.         P_SW2|=EAXFR;
  4.         
  5.         P3M0=0x00;
  6.         P3M1=0x00;
  7.         P5M0=0x00;
  8.         P5M1=0x00;
  9.         P3PU=0x0c;
  10.         
  11.         I2CCFG=0xC6;        //345.6K@11.0592M
  12.         I2CMSCR=EMSI;
  13.         I2CMSST=0x00;
  14.         
  15.         EA=1;                        //启用总中断
  16. }
复制代码

点评

PxMx和PxPU改成和你硬件一致的  详情 回复 发表于 2024-12-23 16:45
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-02-14 17:33:56

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 16:45:04 | 显示全部楼层
_奶*** 发表于 2024-12-23 16:30
没看到是不是开了  这个

开了,在主时钟设置那开了后没关闭,我在外部加上拉试下,之前的模拟I2C是没有加外部上拉,用的内部上拉,可以工作。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:09:43
已绑定手机

77

主题

4850

回帖

8388

积分

超级版主

DebugLab

积分
8388
发表于 2024-12-23 16:45:54 | 显示全部楼层

PxMx和PxPU改成和你硬件一致的
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-02-14 17:33:56

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 16:46:29 | 显示全部楼层
KNW*** 发表于 2024-12-23 16:45
开了,在主时钟设置那开了后没关闭,我在外部加上拉试下,之前的模拟I2C是没有加外部上拉,用的内部上拉 ...

一定要加外部上拉吗?我感觉好多我都是用内部上拉程序也没问题的啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:8
  • 最近打卡:2025-02-14 17:33:56

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 16:46:54 | 显示全部楼层
Debu*** 发表于 2024-12-23 16:45
PxMx和PxPU改成和你硬件一致的

是P14和P15啊

点评

你改一下 内部4K上拉完全可以的  详情 回复 发表于 2024-12-23 16:56
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 12:53 , Processed in 0.125165 second(s), 110 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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