找回密码
 立即注册
楼主: KNW123

I2C卡死在发送起始信号

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:463
  • 最近打卡:2025-06-17 17:53:48

33

主题

2448

回帖

5174

积分

论坛元老

积分
5174
发表于 2024-12-23 16:48:20 | 显示全部楼层
KNW*** 发表于 2024-12-23 16:46
一定要加外部上拉吗?我感觉好多我都是用内部上拉程序也没问题的啊

理论上只要有上拉就行,用内部还是外部 就看外部电路是什么样的了,


要是还是不行的话,,,上示波器看看怎么回事吧
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复 支持 反对

使用道具 举报 送花

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

6

主题

28

回帖

164

积分

注册会员

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

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

#include "reg51.h"
#include "intrins.h"

sfr     P_SW2   =   0xba;

#define I2CCFG      (*(unsigned char volatile xdata *)0xfe80)
#define I2CMSCR     (*(unsigned char volatile xdata *)0xfe81)
#define I2CMSST     (*(unsigned char volatile xdata *)0xfe82)
#define I2CSLCR     (*(unsigned char volatile xdata *)0xfe83)
#define I2CSLST     (*(unsigned char volatile xdata *)0xfe84)
#define I2CSLADR    (*(unsigned char volatile xdata *)0xfe85)
#define I2CTXD      (*(unsigned char volatile xdata *)0xfe86)
#define I2CRXD      (*(unsigned char volatile xdata *)0xfe87)

sfr     P0M1    =   0x93;
sfr     P0M0    =   0x94;
sfr     P1M1    =   0x91;
sfr     P1M0    =   0x92;
sfr     P2M1    =   0x95;
sfr     P2M0    =   0x96;
sfr     P3M1    =   0xb1;
sfr     P3M0    =   0xb2;
sfr     P4M1    =   0xb3;
sfr     P4M0    =   0xb4;
sfr     P5M1    =   0xc9;
sfr     P5M0    =   0xca;

sbit    SDA     =   P1^4;
sbit    SCL     =   P1^5;

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();
}

void Delay()
{
    int i;

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

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    P_SW2 = 0x80;

    I2CCFG = 0xe0;                              //使能I2C主机模式
    I2CMSST = 0x00;

    Start();                                    //发送起始命令
    SendData(0xa2);                             //发送设备地址+写命令
    RecvACK();
    SendData(0x02);                             //发送存储地址
    RecvACK();
    SendData(0x00);                             //设置秒值
    RecvACK();
    SendData(0x00);                             //设置分钟值
    RecvACK();
    SendData(0x12);                             //设置小时值
    RecvACK();
    Stop();                                     //发送停止命令

    while (1)
    {
        Start();                                //发送起始命令
        SendData(0xa2);                         //发送设备地址+写命令
        RecvACK();
        SendData(0x02);                         //发送存储地址
        RecvACK();
        Start();                                //发送起始命令
        SendData(0xa3);                         //发送设备地址+读命令
        RecvACK();
        P0 = RecvData();                        //读取秒值
        SendACK();
        P2 = RecvData();                        //读取分钟值
        SendACK();
        P3 = RecvData();                        //读取小时值
        SendNAK();
        Stop();                                 //发送停止命令

        Delay();
    }
}


这个SDA被设置成双向IO,SCL被 设置成开漏
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:469
  • 最近打卡:2025-06-17 09:09:48
已绑定手机

79

主题

5137

回帖

9134

积分

超级版主

DebugLab

积分
9134
发表于 2024-12-23 16:56:04 | 显示全部楼层

你改一下
内部4K上拉完全可以的
DebugLab
回复 支持 反对

使用道具 举报 送花

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

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 17:15:11 | 显示全部楼层
Debu*** 发表于 2024-12-23 16:56
你改一下
内部4K上拉完全可以的

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

现在卡在while() 这

点评

这应该在中断里的 你抄一下我的程序好吗 https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=13173&pid=133651  详情 回复 发表于 2024-12-23 17:37
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:469
  • 最近打卡:2025-06-17 09:09:48
已绑定手机

79

主题

5137

回帖

9134

积分

超级版主

DebugLab

积分
9134
发表于 2024-12-23 17:35:42 | 显示全部楼层
KNW*** 发表于 2024-12-23 17:15
void Wait()
{
    while (!(I2CMSST & 0x40));
  1. void I2C_Isr(void) interrupt 24
  2. {
  3.         _push_(P_SW2);
  4.         P_SW2|=EAXFR;
  5.         if(I2CMSST&MSIF)
  6.         {
  7.                 I2CMSST&=~MSIF;
  8.                 I2C_Busy=0;
  9.         }
  10.         _pop_(P_SW2);
  11. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:469
  • 最近打卡:2025-06-17 09:09:48
已绑定手机

79

主题

5137

回帖

9134

积分

超级版主

DebugLab

积分
9134
发表于 2024-12-23 17:37:53 | 显示全部楼层
KNW*** 发表于 2024-12-23 17:15
void Wait()
{
    while (!(I2CMSST & 0x40));

这应该在中断里的
你抄一下我的程序好吗
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=13173&pid=133651

DebugLab
回复 支持 反对

使用道具 举报 送花

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

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 17:45:06 | 显示全部楼层
Debu*** 发表于 2024-12-23 17:37
这应该在中断里的
你抄一下我的程序好吗
https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpos ...

STC的例程就是这样的啊,我准备加上拉电阻试下

点评

用中断还是查询 如果用中断,必须有中断函数,否则跑飞 如果用查询,不能开I2C中断  详情 回复 发表于 2024-12-23 18:13
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:469
  • 最近打卡:2025-06-17 09:09:48
已绑定手机

79

主题

5137

回帖

9134

积分

超级版主

DebugLab

积分
9134
发表于 2024-12-23 18:13:02 | 显示全部楼层
KNW*** 发表于 2024-12-23 17:45
STC的例程就是这样的啊,我准备加上拉电阻试下

用中断还是查询
如果用中断,必须有中断函数,否则跑飞
如果用查询,不能开I2C中断
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:395
  • 最近打卡:2025-06-18 06:00:50

7

主题

286

回帖

1403

积分

金牌会员

积分
1403
发表于 2024-12-23 18:13:17 | 显示全部楼层
搞定了吗?学习一下
回复 支持 反对

使用道具 举报 送花

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

6

主题

28

回帖

164

积分

注册会员

积分
164
发表于 2024-12-23 20:02:25 | 显示全部楼层
men*** 发表于 2024-12-23 18:13
搞定了吗?学习一下

没啊,你也有这个疑问?准备加两个外部上拉电阻
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-6-18 07:46 , Processed in 0.167775 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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