OpenEdv-开源电子网

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

为什么51的I2C要软件模拟而32可以不要??

[复制链接]

24

主题

77

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-10-30
在线时间
34 小时
发表于 2016-11-16 11:04:40 | 显示全部楼层 |阅读模式
3金钱
RT

最佳答案

查看完整内容[请看2#楼]

谁说32不要的。。。大家的程序基本都是模拟IIC。 如果芯片本身有硬件IIC可以直接使用,但是32的据说常常自己挂掉,时序错乱了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-11-16 11:04:41 | 显示全部楼层
谁说32不要的。。。大家的程序基本都是模拟IIC。
如果芯片本身有硬件IIC可以直接使用,但是32的据说常常自己挂掉,时序错乱了。
自在随心
回复

使用道具 举报

24

主题

77

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2016-10-30
在线时间
34 小时
 楼主| 发表于 2016-11-16 11:27:02 | 显示全部楼层
yuzeyuan1 发表于 2016-11-16 11:22
谁说32不要的。。。大家的程序基本都是模拟IIC。
如果芯片本身有硬件IIC可以直接使用,但是32的据说常常自 ...

哈哈原来这样哦 可能是我记错了!!
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-11-16 11:29:22 | 显示全部楼层
托马斯拉丁 发表于 2016-11-16 11:27
哈哈原来这样哦 可能是我记错了!!

话说玩单片机两年,不知51为何物,所以不知道51那边是啥情况。。。
自在随心
回复

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2015-8-17
在线时间
8 小时
发表于 2016-11-16 12:12:16 | 显示全部楼层
用32硬件I2C的路过
回复

使用道具 举报

4

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2016-8-4
在线时间
192 小时
发表于 2016-11-16 12:32:39 | 显示全部楼层
颠疯 发表于 2016-11-16 12:12
用32硬件I2C的路过

硬件I2C稳定吗?
回复

使用道具 举报

10

主题

254

帖子

0

精华

高级会员

Rank: 4

积分
594
金钱
594
注册时间
2015-10-17
在线时间
145 小时
发表于 2016-11-16 12:36:15 | 显示全部楼层
stm32的硬件IIC优势有的,但是我感觉32硬件IIC 比软件模拟的还要复杂.
开着单片机翱翔在天空
回复

使用道具 举报

2

主题

61

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
410
金钱
410
注册时间
2016-5-6
在线时间
110 小时
发表于 2016-11-16 12:55:34 | 显示全部楼层
主要是看你使用的51,是否有提供iic硬件接口,旧一点的就没有
没有就只能用模拟的,stm32是有提供硬件iic接口,貌似大部分人
都说不稳定。
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2016-11-16 13:00:14 | 显示全部楼层
stm32模拟的I2C时序可以比硬件的更加快,省时间。
回复

使用道具 举报

1

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1183
金钱
1183
注册时间
2015-5-28
在线时间
149 小时
发表于 2016-11-17 10:37:28 | 显示全部楼层
题主问的是为什么~所以我想说下这个为什么~这个跟芯片的设计有很大的关系。我们平时讲到的8051,ARM,MIPS等等针对的是一个芯片内核IP core。芯片设计公司一般会直接购买IP core,这个IP core是一个没有任何扩展的处理器核心(没有GPIO,没有UART,没有SPI,没有IIC等等),芯片厂家会拿到IP Core后进行外设扩展的设计,已适应不同的客户需求,加入需要的各种外设模块,所以51不是没有硬件IIC,增强型的51是有硬件IIC的,也可以不用模拟,题主使用的51是应该是最基础的51,芯片厂家并没有设计硬件IIC到芯片里面去,所以就只能通过软件来模拟时序了~
回复

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2015-8-17
在线时间
8 小时
发表于 2016-11-18 13:54:08 | 显示全部楼层
小施 发表于 2016-11-16 12:32
硬件I2C稳定吗?

设备跑了几个月,没挂掉。
回复

使用道具 举报

8

主题

47

帖子

1

精华

高级会员

Rank: 4

积分
675
金钱
675
注册时间
2014-9-17
在线时间
89 小时
发表于 2016-11-20 15:44:26 来自手机 | 显示全部楼层
我们公司就用STM32硬件I2C接口,很稳定,只要把I2C中断优先级提至最高。
回复

使用道具 举报

106

主题

418

帖子

0

精华

高级会员

Rank: 4

积分
764
金钱
764
注册时间
2016-7-26
在线时间
123 小时
发表于 2016-11-21 21:17:29 | 显示全部楼层
颠疯 发表于 2016-11-16 12:12
用32硬件I2C的路过

能分享一下程序吗???
回复

使用道具 举报

106

主题

418

帖子

0

精华

高级会员

Rank: 4

积分
764
金钱
764
注册时间
2016-7-26
在线时间
123 小时
发表于 2016-11-21 21:19:37 | 显示全部楼层
火透 发表于 2016-11-20 15:44
我们公司就用STM32硬件I2C接口,很稳定,只要把I2C中断优先级提至最高。

请问能够分享一下时序吗??我的不知道为什么ADDR位再没读SR1,SR2就自动的清零了???
回复

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-11-21 22:38:14 | 显示全部楼层
F0,F4的好像比较稳定,F1的好像不行
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-11-22 13:44:00 | 显示全部楼层
F4一樣一值busy阿....
回复

使用道具 举报

8

主题

47

帖子

1

精华

高级会员

Rank: 4

积分
675
金钱
675
注册时间
2014-9-17
在线时间
89 小时
发表于 2016-11-23 15:56:27 | 显示全部楼层
u8 I2C_ReadMultiBytes(I2C_TypeDef* I2Cx,u8 I2C_Addr, u8 addr,u8 *buf,u16 num)
{
    if (0 == num)
        return 0;
       
    if (0 == I2C_PARAM.idle)
        return 0;

        I2C_PARAM.idle       = 0;//busy
        I2C_PARAM.id         = I2C_Addr;
        I2C_PARAM.addr       = addr;
        I2C_PARAM.index      = 0;
        I2C_PARAM.r_w        = 1;   //read
        I2C_PARAM.bufLen     = num;
        I2C_PARAM.pBuff      = buf;
        I2C_PARAM.FunCallBack = (void (*)(I2C_TypeDef*, void *))_I2cTxIRQ;       
    I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    /* Send I2C START condition */
    I2C_GenerateSTART(I2Cx, ENABLE);
    return num;
}

u8 I2C_WriteMultiBytes(I2C_TypeDef* I2Cx,u8 I2C_Addr, u8 addr,u8 *buf,u16 num)
{
    if (0 == num)
        return 0;
       
    if (0 == I2C_PARAM.idle)
        return 0;

        I2C_PARAM.idle       = 0;//busy
        I2C_PARAM.id         = I2C_Addr;
        I2C_PARAM.addr       = addr;
        I2C_PARAM.index      = 0;
        I2C_PARAM.r_w        = 0;   //write
        I2C_PARAM.bufLen     = num;
        I2C_PARAM.pBuff      = buf;
        I2C_PARAM.FunCallBack = (void (*)(I2C_TypeDef*, void *))_I2cTxIRQ;       
    I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    /* Send I2C START condition */
    I2C_GenerateSTART(I2Cx, ENABLE);
    return num;
}


/*******************************************************************************
* Function Name : u8 I2C_IdleState(void)
* Description   : 查询是否总线空闲 如果为空闲则读取参数
* Output        :   return:     0)忙碌     1)空闲
*******************************************************************************/
u8 I2C_IdleState(I2C_TypeDef* I2Cx)
{
        return (I2C_PARAM.idle && (!I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)));
}


/*******************************************************************************
* Function Name : static void _I2cTxIRQ(I2C_TypeDef* I2Cx, I2C_PARAM_TYPE *pParam)
* Description   : 发送数据中断函数,I2C事件中断函数中回调
*******************************************************************************/
static void _I2cTxIRQ(I2C_TypeDef* I2Cx, I2C_PARAM_TYPE *pParam)
{
    switch (I2C_GetLastEvent(I2Cx))
    {
    /* Test on I2Cx EV5 and clear it */
    case I2C_EVENT_MASTER_MODE_SELECT:
        I2C_Send7bitAddress(I2Cx, pParam->id, I2C_Direction_Transmitter);
        break;

    /* Test on I2Cx EV6 and first EV8 and clear them */
    case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
        /* Send the first data */
        I2C_SendData(I2Cx, pParam->addr);  /* EV8 just after EV6 */
        break;

    case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
        if((pParam->index < pParam->bufLen) && (pParam->r_w == 0))
        {
            /* Transmit buffer data */
            I2C_SendData(I2Cx, pParam->pBuff[pParam->index++]);
        }
        else
        {   
            I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE);
        }
        break;

    /* Test on I2Cx EV8 and clear it */
    case I2C_EVENT_MASTER_BYTE_TRANSMITTED:     
        if (pParam->r_w != 0)
        {
            pParam->FunCallBack = (void (*)(I2C_TypeDef*, void *))_I2cRxIRQ;            
            I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);
            I2C_GenerateSTART(I2Cx, ENABLE);
        }
        else
        {
            I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
            I2C_AcknowledgeConfig(I2Cx, DISABLE);
            I2C_GenerateSTOP(I2Cx, ENABLE);            
            pParam->idle = 1;            //接收结束标志
        }
        break;
    }
}

/*******************************************************************************
* Function Name : static void _I2cRxIRQ(I2C_TypeDef* I2Cx, I2C_PARAM_TYPE *pParam)
* Description   : 接收数据中断函数,I2C事件中断函数中回调
*******************************************************************************/
static void _I2cRxIRQ(I2C_TypeDef* I2Cx, I2C_PARAM_TYPE *pParam)
{
    switch (I2C_GetLastEvent(I2Cx))
    {
    /* Test on I2Cx EV5 and clear it */
    case I2C_EVENT_MASTER_MODE_SELECT:  
        /* Send I2Cx slave Address for write */
        I2C_Send7bitAddress(I2Cx, pParam->id, I2C_Direction_Receiver);
        break;

    /* Test on I2Cx EV6 and first EV8 and clear them */
    case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
        if (pParam->index == (pParam->bufLen - 1))
        {
            I2C_AcknowledgeConfig(I2Cx, DISABLE);
            I2C_GenerateSTOP(I2Cx, ENABLE);
        }
        break;

    /* Test on I2Cx EV2 and clear it */
    case I2C_EVENT_MASTER_BYTE_RECEIVED:
        pParam->pBuff[pParam->index++] = I2C_ReceiveData(I2Cx);
            
        if (pParam->index == (pParam->bufLen - 1))
        {
            I2C_AcknowledgeConfig(I2Cx, DISABLE);
            I2C_GenerateSTOP(I2Cx, ENABLE);
        }
        else if (pParam->index >= pParam->bufLen)
        {
                  pParam->FunCallBack = (void (*)(I2C_TypeDef*, void *))_I2cTxIRQ;    //默认进接收中断      
            I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
            pParam->idle = 1;   //空闲         
        }
        break;
    }
}
当你的才华还撑不起你的野心时你就应该静下心来学习。当你的经济还撑不起你的梦想时,你就应该踏实的去工作。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 10:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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