搜索
bottom↓
回复: 60

STM32 I2C 源代码,应用STM32的标准库,非中断方式,已测试,通信稳定,给初学STM32 I2C的朋友

[复制链接]

出0入0汤圆

发表于 2009-10-13 22:51:55 | 显示全部楼层 |阅读模式
最近刚买了块金牛的开发板,用的STM32F107VC的MPU,在网上搜了半天找了些资料,但测试过程中发现通信不太稳定,在自己的板子上调试了几天,修改了几个地方,现在通过i2c读写,24CL02正常,且稳定。
下面整理些在开发中需要注意的问题,供初学者参考,并附上软件包。供大家研究。 代码是参照网上一位朋友的,在细节部分做了修改,在此表示感谢。

STM32 I2C开发注意问题,非中断方式
1.GPIO端口配置阶段,需要首先使能I2C时钟,然后再配置端口工作方式,否则无效,配置SDA、SCL端口为开漏输出模式,注意与ARM不同的是即使使能IO的特殊功能,仍然需要手动设置GPIO的工作方式;
2.对于I2C器件的读写,由于时序的原因,有的时候读写状态寄存器时会有问题,不像51那样可以自己控制时序与数据,操作起来比较方便,在查询和清除状态寄存器时同样要注意时序问题,否则可能不能正确捕捉到。比如在查询i2c总线是否被占用时,发送完地址数据需要延时一点时间,否则不能捕捉到ADDR置位信号。具体参看程序代码;
3.模拟I2C读写时,如果一次读取多个字节,总是传输不稳定,经过反复测试,将多字节操作全部由单字节操作实现,经实践发现通信比较稳定;
4.STM的数据手册写得确实不怎么样,对于在i2c通信过程中,产生的状态信息说明很不清楚,不要按照数据手册上的去研究通信过程中各个状态寄存器的单个或组合值,直接看它提供的库文件,它已经把各个状态时的状态寄存器组合值定义好了,拿过来直接用吧。
5.切记,在通信过程中,不是每一个状态仅置位一个状态位,而是多个状态位,否则你怎么搞都搞不通的。

以上是我在开发过程中的一点心得,希望对大家有帮助,也希望有心的人可以对驱动加以改进,大家共同研究。

另外说明:
代码中除了i2c,还有lcd的代码,lcd的代码是开发板带的,如果不用直接注释掉就可以了。
用stm32f107最好用mdk3.8以上的版本,另外如果要用到这个芯片的一些外围接口,最好安装RL-ARM库,因为现在对stm32的支持比较少,开发板上的例程很多都是用的stm的RL-ARM中的库文件。
STM32 的I2C应用-非中断方式ourdev_491300.rar(文件大小:398K) (原文件名:I2C.rar)

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2009-10-13 22:52:29 | 显示全部楼层
站位

出0入0汤圆

 楼主| 发表于 2009-10-13 22:53:28 | 显示全部楼层
站位

出0入0汤圆

 楼主| 发表于 2009-10-13 22:53:38 | 显示全部楼层
站位

出0入0汤圆

发表于 2009-10-13 22:54:16 | 显示全部楼层
好东西啊 , 搞得定这个不容易啊 呵呵

出0入0汤圆

发表于 2009-10-13 23:10:10 | 显示全部楼层
一次只能读写一个字节?差了点儿巴!

出0入0汤圆

 楼主| 发表于 2009-10-13 23:18:11 | 显示全部楼层
楼上的误解了,一次可以读写多个字节,但是底层驱动是以单次读写实现的,这样比较稳定。
另外需要说明的是
24lc02,写只能单字节写,或者页写,就算是页写,也只能一次写8个字节;
读可以顺序读,理论上好像没有什么限制,但是我不能保证稳定,如果哪位朋友有顺序读写稳定的代码,还望指点一二。

出0入0汤圆

发表于 2009-10-13 23:48:54 | 显示全部楼层
今天也写了个模拟的。。。。发现连续读写也是不稳定。。

出0入0汤圆

发表于 2009-10-14 00:02:25 | 显示全部楼层
STM32的IIC还真怪异。。还没时间玩STM32。板子放在一边。。

出0入0汤圆

发表于 2009-10-14 19:46:50 | 显示全部楼层
风闻IIC库函数有问题,大家谈谈具体哪里有问题?

出0入0汤圆

发表于 2009-10-17 14:51:26 | 显示全部楼层
好帖,总是在单字节读上出错,正好借鉴一下。

出0入0汤圆

 楼主| 发表于 2009-10-31 10:49:01 | 显示全部楼层
怎么都沉了。

出0入0汤圆

发表于 2010-3-1 14:22:38 | 显示全部楼层
看过这帖子.我自己亲自试了一下.

ST的库和例程都是好的.

如果说您没有成功.我相信是下面这个宏没有改.

#if defined (EE_M24C08)
#define I2C_FLASH_PAGESIZE    8        //        16

原来是16.改成8.

其他的.我什么都没有动.我测试的也是24c02.

祝后来者好运.

出0入0汤圆

发表于 2010-3-5 16:51:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-3-5 17:53:11 | 显示全部楼层
下载并收藏,楼主辛苦了,多谢!

出0入0汤圆

发表于 2010-8-26 10:03:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-10 00:52:27 | 显示全部楼层
我的II2C也有问题,回复【12楼】wisebaby 明君
看过这帖子.我自己亲自试了一下.
st的库和例程都是好的.
如果说您没有成功.我相信是下面这个宏没有改.
#if defined (ee_m24c08)
#define i2c_flash_pagesize    8 // 16
原来是16.改成8.
其他的.我什么都没有动.我测试的也是24c02.
祝后来者好运.
-----------------------------------------------------------------------

我的II2C也有问题,我得把那个16改为8 试试看

出0入0汤圆

发表于 2010-9-21 11:25:34 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-1-25 22:27:36 | 显示全部楼层
谢谢,明天测试一下。。。

出0入0汤圆

发表于 2011-2-9 23:35:00 | 显示全部楼层
我也刚写一个,过来学习一下。

出0入0汤圆

发表于 2011-2-10 11:48:35 | 显示全部楼层
俺们一直都是用中断方式的,51下是这样,转来ARM7还是这样,不过这次不用调试飞了好大的劲!
感觉还是中断方式的好,!
多主,多从,都是主发!很好用的!

出0入0汤圆

发表于 2011-2-13 13:48:30 | 显示全部楼层
还是用模拟的好,硬件的IIC不大有把握

出0入0汤圆

发表于 2011-2-17 12:22:54 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-2-17 12:37:19 | 显示全部楼层
有空试试i2c

出0入0汤圆

发表于 2011-2-17 13:37:38 | 显示全部楼层
好东西啊

出0入0汤圆

发表于 2011-3-13 11:38:16 | 显示全部楼层
一直听说STM32的I2C有问题,没想到楼主竟然能测试成功,我也来试试,验证一下

出0入0汤圆

发表于 2011-6-19 00:06:38 | 显示全部楼层
楼主研究的很细致,尤其是第二条里面查询总线busy状态后要延时的问题,
但这个问题也很危险,我试了不加延时的话会和Delay_Init()函数(源自Alientek开发板的,无中断)冲突导致i2c无法工作,如果延时个2us,又太长,还是无法查询到正确的状态。
很好奇楼主是怎么定下这个时间的。

出0入0汤圆

发表于 2011-6-28 09:55:36 | 显示全部楼层
移到24C64上:

/************************************************************************************
**函 数 名: unsigned char I2C_ReadOneByte(I2C_TypeDef *I2Cx,unsigned char I2C_Addr,unsigned char addr)
**功    能: 通过指定I2C接口读取一个字节数据
**入口参数: I2C_TypeDef *I2Cx,STM32 的I2C 寄存器基址,从器件地址,addr 预读取字节存储位置
**         
**出口参数: 读取到的数值
************************************************************************************/
static unsigned char I2C_ReadOneByte(I2C_TypeDef *I2Cx,unsigned char I2C_Addr,unsigned short int addr)
{
        unsigned char res=0;
        I2C_AcknowledgePolling(I2Cx,I2C_Addr);
       
        I2C_GenerateSTART(I2Cx, ENABLE);       
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
       
        I2C_Send7bitAddress(I2Cx,I2C_Addr,I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        I2C_SendData(I2Cx,(unsigned char)((addr & 0x1F00) >> 8));  //设置高起始地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        I2C_SendData(I2Cx,(unsigned char)(addr & 0x00FF));         //设置低起始地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        I2C_GenerateSTART(I2Cx,ENABLE);
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
       
        I2C_Send7bitAddress(I2Cx,I2C_Addr,I2C_Direction_Receiver);
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
       
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_RECEIVED));
        res=I2Cx->DR;

        I2C_GenerateSTOP(I2Cx,ENABLE);
        return res;
               
}

/************************************************************************************
**函 数 名: static unsigned char I2C_WriteOneByte(I2C_TypeDef *I2Cx,unsigned char I2C_Addr,unsigned char addr,unsigned char value)
**功    能: 通过指定I2C接口写入一个字节数据
**入口参数: I2C_TypeDef *I2Cx,STM32 的I2C 寄存器基址,从器件地址,addr 预写入字节地址,value 写入数据
**         
**出口参数: 成功返回0
************************************************************************************/
static unsigned char I2C_WriteOneByte(I2C_TypeDef *I2Cx,unsigned char I2C_Addr,unsigned short int addr,unsigned char value)
{
       
        I2C_AcknowledgePolling(I2Cx,I2C_Addr);
       
        I2C_GenerateSTART(I2Cx, ENABLE);       
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));
       
        I2C_Send7bitAddress(I2Cx,I2C_Addr,I2C_Direction_Transmitter);
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

        I2C_SendData(I2Cx,(unsigned char)((addr & 0x1F00) >> 8));         //设置高起始地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));

        I2C_SendData(I2Cx,(unsigned char)(addr & 0x00FF));                         //设置低起始地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
       
        I2C_SendData(I2Cx,value);
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));       
       
        I2C_GenerateSTOP(I2Cx,ENABLE);
        return 0;
}

出0入0汤圆

发表于 2011-7-30 10:49:33 | 显示全部楼层
大虾...让我琢磨了一天的I2C终于成功了...膜拜中...

出0入0汤圆

发表于 2011-10-10 13:33:29 | 显示全部楼层
mark。参考中......

出0入0汤圆

发表于 2011-10-10 14:26:56 | 显示全部楼层
问题1:读操作时,停止位不是应该在最后一位字节接受之前给出的吗?
    2:在用到fsmc时钟时会干扰到i2c通讯,不知道这个问题怎么解决?

出0入30汤圆

发表于 2012-2-3 15:30:32 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-2-3 19:05:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-5 21:51:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-8 11:36:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-9 14:57:11 | 显示全部楼层
mark一下

出0入30汤圆

发表于 2012-2-22 16:52:57 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-2-23 13:00:52 | 显示全部楼层
顶一个

出0入0汤圆

发表于 2012-2-26 16:31:48 | 显示全部楼层
回复【12楼】wisebaby 明君
看过这帖子.我自己亲自试了一下.
st的库和例程都是好的.
如果说您没有成功.我相信是下面这个宏没有改.
#if defined (ee_m24c08)
#define i2c_flash_pagesize    8 // 16
原来是16.改成8.
其他的.我什么都没有动.我测试的也是24c02.
祝后来者好运.
-----------------------------------------------------------------------

去试一下

出0入0汤圆

发表于 2012-4-18 00:21:16 | 显示全部楼层
mark!!正好学习这个

出0入0汤圆

发表于 2012-4-18 20:35:10 | 显示全部楼层
嗯 毕设用STM32  I2C也会用到 这段时间开始调I2C了  STM32 的I2C太高级了  楼主的建议很有用 多谢分享……

出0入0汤圆

发表于 2012-4-23 20:27:16 | 显示全部楼层
我的ARM板子上有I2C EEPROM 的例子  我现在做的是 实现两块stm32间的I2C通信 可怜 一直通不起来 ……  程序在公司 明天贴上  大家帮我修改修改好不 拜托拜托

出0入0汤圆

发表于 2012-4-23 21:12:49 | 显示全部楼层
留个名先.

出0入0汤圆

发表于 2012-4-23 22:55:59 | 显示全部楼层
作为参考

出0入0汤圆

发表于 2012-4-24 10:46:33 | 显示全部楼层
你好,能否抽空帮我看下这个程序,我在两块STM32板子间做I2C通信,主发从收,因为没有两个主机两个仿真器 ,我就是先将主机的程序固化到主机中,然后在从机上调试运行,结果是跑了N多次,只有两次收到数据,都是正确的。其他时候就一直停在
1. while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));  //Bus busy flag 0x00020000 -- SR2 BUSY位
或者停在  /*接收地址*/
2. I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Receiver);  //从机地址 传输方向
     while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED));/*EV1 ADDR*/

你能否帮我看下,到底是哪里出错了。。。俺琢磨了好久,都是按照STM32手册写的,怎么就错了呢。。。。。。


////////////////////////////////////主STM32板  设置地址为0x90////////////////////////////////
#define N 8

int main(void)
{
  I2C_Configuration();
  I2C_Master_Send();
}

void I2C_Configuration(void)
{
        I2C_InitTypeDef  I2C_InitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);          //I2C时钟
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  //I2C对应GPIO管脚时钟
   

        /* PB6,7 I2C1 PB10.11 I2C2  SCL and SDA */
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //设置管脚为复用功能开漏输出
        GPIO_Init(GPIOB, &GPIO_InitStructure);          //I2C接口使用的GPIO管脚初始化
       
            I2C_DeInit(I2C1); //0x40005400恢复到默认值
            I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;         //设置I2C接口模式
            I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C接口的高低电平周期
            I2C_InitStructure.I2C_OwnAddress1 = 0x90;          //设置I2C接口的主机地址
            I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;        //设置是否开启ACK响应         
            I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
            I2C_InitStructure.I2C_ClockSpeed = 100000;        //100K速度
   
        I2C_Cmd(I2C1, ENABLE);                            //使能I2C接口
        I2C_Init(I2C1, &I2C_InitStructure);               //I2C接口初始化
        /*允许1字节1应答模式*/
        I2C_AcknowledgeConfig(I2C1, ENABLE);              //使能I2C接口响应--应答功能

}

void I2C_Master_Send(void)
{
        u8 i,data_send[N],data_receive[N];
        for(i=0;i<N;i++)
        {
                data_send[i] = i+9;
                data_receive[i] = 0;       
        }

        while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));         //Bus busy flag 0x00020000        -- SR2 BUSY位
                                                               
        /*起始位*/
        I2C_GenerateSTART(I2C1, ENABLE);                           //CR1_START_Set 0x0100 -- CR1 START
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  /* EV5 0x00030001 BUSY, MSL and SB flag */

        /*写器件地址*/
        I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Transmitter);  //从机地址 传输方向
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* EV6.8 BUSY, MSL, ADDR, TXE and TRA flags */

        /*写地址值*/
//        I2C_SendData(I2C1, 0);
//        while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* TRA, BUSY, MSL, TXE and BTF flags */

        for(i=0;i<N;i++)  
        {
          I2C_SendData(I2C1,data_send[i]);
          while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));        /* EV8 TRA, BUSY, MSL, TXE and BTF flags */
        }
       
        /*停止位*/
        I2C_GenerateSTOP(I2C1, ENABLE);
}

////////////////////////////////////从STM32板  设置地址为0x60////////////////////////////////
#define N 8

int main(void)
{
  I2C_Configuration();
  I2C_Slave_Receive();
}


void I2C_Configuration(void)
{
        I2C_InitTypeDef  I2C_InitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);          //I2C时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  //I2C对应GPIO管脚时钟
   

        /* PB6,7 I2C1 PB10.11 I2C2  SCL and SDA */
        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //设置管脚为复用功能开漏输出
        GPIO_Init(GPIOB, &GPIO_InitStructure);          //I2C接口使用的GPIO管脚初始化
       
        I2C_DeInit(I2C1); //0x40005400恢复到默认值
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;         //设置I2C接口模式
            I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C接口的高低电平周期
            I2C_InitStructure.I2C_OwnAddress1 = 0x60;          //设置I2C接口的主机地址
            I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;        //设置是否开启ACK响应         
            I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
            I2C_InitStructure.I2C_ClockSpeed = 100000;        //100K速度
   
        I2C_Cmd(I2C1, ENABLE);                            //使能I2C接口
        I2C_Init(I2C1, &I2C_InitStructure);               //I2C接口初始化
        /*允许1字节1应答模式*/
        I2C_AcknowledgeConfig(I2C1, ENABLE);              //使能I2C接口响应--应答功能

}

void I2C_Slave_Receive(void)
{
        u8 i,data_receive[N];
        for(i=0;i<N;i++)
        {
                data_receive[i] = 0;       
        }

        while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));         //Bus busy flag 0x00020000        -- SR2 BUSY位

        /*允许1字节1应答模式*/
        I2C_AcknowledgeConfig(I2C1, ENABLE);   //CR1_ACK_Set 0x0400 -- CR1 ACK位

        /* 发送起始位 */
            I2C_GenerateSTART(I2C1, ENABLE); //CR1_START_Set 0x0100 -- CR1 START

        /*接收地址*/
        I2C_Send7bitAddress(I2C1,0x60,I2C_Direction_Receiver);  //从机地址 传输方向
            while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED));/*EV1 ADDR*/

            for(i=0;i<N;i++)
            {
                if(7==i)
                {
                             I2C_AcknowledgeConfig(I2C1, DISABLE);        //最后一位后要关闭应答的
                            I2C_GenerateSTOP(I2C1, ENABLE);                        //发送停止位
                }
            
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED)); /* EV2 */
                    data_receive[i] = I2C_ReceiveData(I2C1);
            }
        //再次允许应答模式
        I2C_AcknowledgeConfig(I2C1, ENABLE);
}

出0入0汤圆

发表于 2012-4-26 14:07:06 | 显示全部楼层
咋木有人来看看涅…… 大侠……求解啊啊

出0入0汤圆

发表于 2012-5-5 11:06:41 | 显示全部楼层
我现在写的一个linux+C嵌入式程序,
主要用于TCPIP通讯
程序流程:
PC---网络---开发板----串口---设备
PC机每次连接开发板时,都重新下发连接请求,连接成功后
PC机下发指令到开发板,开发板对PC机指令进行分析,再通过串口转发一串指令到设备
设备返回一系列数据,开发板再向PC返回

现在有几个问题
1.看门狗程序:
看门狗程序应该如何写??
是与原程序单独分开,还是写在一个执行程序里
while(1)
{
  看门狗程序
   while(1)
   {
     接收PC机指令
   
   }


}
谁能帮我解答下,感谢

出0入0汤圆

发表于 2012-5-7 17:42:41 | 显示全部楼层
我的还没搞好

出0入0汤圆

发表于 2012-5-22 22:14:45 | 显示全部楼层
学习  谢谢楼主

出0入0汤圆

发表于 2012-11-7 20:28:26 | 显示全部楼层
make

出0入0汤圆

发表于 2012-11-27 17:30:55 | 显示全部楼层
stm32的I2C,留记备用

出0入0汤圆

发表于 2013-3-1 21:36:10 | 显示全部楼层
Thanks for sharing!

出0入0汤圆

发表于 2013-4-1 14:37:56 | 显示全部楼层
谢谢楼主分享,收下了!!!!!!

出0入0汤圆

发表于 2013-4-22 08:59:58 | 显示全部楼层
学习一下,正弄呢。

出0入0汤圆

发表于 2013-9-28 16:49:25 | 显示全部楼层
想问下stm32硬件iic稳定么,貌似网上一搜问题很多呀!

出0入0汤圆

发表于 2013-10-14 15:49:25 | 显示全部楼层
mark                 

出30入8汤圆

发表于 2017-3-15 23:14:39 | 显示全部楼层
強帖留名!

出0入0汤圆

发表于 2017-5-17 11:03:21 | 显示全部楼层
先收着,感谢。

出0入0汤圆

发表于 2017-5-19 15:45:28 | 显示全部楼层
这种方法比硬件i2c好用多了,但是以前大量过夜测试还是有遇到过通信失败,死在while状态里,后来出货还是用的模拟i2c

出0入0汤圆

发表于 2019-4-14 08:01:21 | 显示全部楼层
不知道现在STM32的标准库I2C的BUG有没有被修复呢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 23:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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