历史上的今天
今天是:2025年04月01日(星期二)
2019年04月01日 | STM32的硬件I2C实现及问题
2019-04-01 来源:eefocus
虽然软件可实现I2C读取三轴传感器数据,但I2C作为一种重要的通信协议是一定要搞清楚问题所在的,SO继续研究之前的问题。(网上传言STM32硬件I2C有问题,但仍然有人实现出来)
再次启动程序,依旧是停在原来的位置

等待EV6,网上搜索相关问题好多人都停在了等待EV5上。分析EV5等待问题,主机发送起始信号,没能接受从设备发送的应答,
或者可能都没有发送。此问题应该是接线或IIC初始化代码的问题。
而我此时停在等待EV6,说明已检测到该设备。换句话说从设备已经知道了主设备的存在。却在主设备发送设备地址之后,接受不到从设备的应答信号,自己分析有两种可能,一是设备地址错误,从设备接受到不是自身的设备而地址自然不会应答。二是从设备已应答,而并接受到。在设备地址正确的前提下(前面已经通过例程验证过,前面的文章),思索第二种问题。
网上类似问题网友回应也是繁多,如RCC时钟初始化的问题,检查代码RCC_APB1Periph_I2C1,RCC_APB2Periph_GPIOB均已使能。又如可能i2c1默认引脚被复用,或该引脚没接上拉电阻,而不能开漏输出。将默认PIN6.PIN7重映射后依旧老样子排除该问题。
(重映射函数
GPIO_PinRemapConfig(u32 GPIO_Remap, FunctionalState NewState)
)
再一次想到时钟问题,将IIC初始化结构体中的速率该低
![]()
原来是400000,也不行
直到在某论坛看到据说可以直接用的程序,打开发现代码并无差别,唯一不同的是,RCC初始化,其代码在主函数开始就初始化了所有的需要用到的时钟包括
![]()
,只是初始化位置不同。。。。
终于豁然开朗。
数据读取准确无误。
之后又将初始化程序恢复到原位置发现,程序仍可正确运行,不知何解。
尝试恢复速率发现,恢复成400000后不能读取,程序停滞在等待EV6
2000000等待EV5,1000000等待EV5
只能还设为100000,可以正常工作。
至此可确定STM32硬件I2C真的有问题!!!!
程序只能在10000输出,仅供参考
.h
#ifndef __I2C_H__
#define __I2C_H__
#include "stm32f10x.h"
void I2C_GPIO_Config(void);
void I2C1_Init(void);
void I2C1_Write(u8 addr, u8 data);
u8 I2C1_Read(u8 nAddr);
#endif
.c
#include "tb_delay.h"
#include "i2c.h"
void I2C_GPIO_Config()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
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);
}
void I2C1_Init()
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x77;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 10000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
void I2C1_Write(u8 addr, u8 data)
{
I2C_AcknowledgeConfig(I2C1,ENABLE);
I2C_GenerateSTART(I2C1,ENABLE);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;}//EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;} //EV6
I2C_SendData(I2C1,addr);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //EV8
I2C_SendData(I2C1,data);
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;}
I2C_GenerateSTOP(I2C1,ENABLE);
}
u8 I2C1_Read(u8 nAddr)
{
I2C_AcknowledgeConfig(I2C1,ENABLE); //????
I2C_GenerateSTART(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //??EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Transmitter); //????????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){;}//??EV6
I2C_SendData(I2C1,nAddr);//?????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){;} //??EV8
I2C_GenerateSTART(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)){;} //??EV5
I2C_Send7bitAddress(I2C1,0x3a,I2C_Direction_Receiver); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){;} //??EV6
I2C_AcknowledgeConfig(I2C1,DISABLE); //??????
I2C_GenerateSTOP(I2C1,ENABLE); //???????
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){;} //??EV7
return I2C_ReceiveData(I2C1); //???????
}
史海拾趣
|
求助:CodeWarrior for ADS 1.2中编译出错 工程中,用ADS编译,出现了Errors: Could not find or load the file 襐IC.a?for target 褼ebugRel?for project 襱est1.mcp? Could not find or load the file 褻omm.a?for target 褼ebugRel?for project 襱est1.mcp? The following access p ...… 查看全部问答> |
|
请登陆淘宝进行详细的细节查询 淘宝地址: http://auction1.taobao.com/auction/0/item_detail-0db2-a975eaf6e989403d6987eeb2fde3c9d9.jhtml 欢迎购买. … 查看全部问答> |
|
小弟刚入道,就遇到棘手的问题,希望大家帮忙啊,谢谢! 问题如下 在Wince下 我在Form1中添加了一个PictureBox1,想在上面画个点,或者圆 结果发现连Paint()函数都没 ,郁闷;还有 CreatGraphic函数也没,该怎么办啊? 使用VB.net2005 谁能发个 ...… 查看全部问答> |
|
1.第一忌 自己不动脑筋,一遇到问题就问别人有句话说的好“吃别人咀嚼过的馍不香”。对于新手来说,做每一件事都是一次学习的好机会。有时候,探索的过程比最终的结果更重要。当你经过自己的努力,解决问题时,成就感和自信心会随之逐渐建立。如果 ...… 查看全部问答> |
|
今早用altium designer6.9画原理图时突然出现了这么一个问题··不得其解啊 就是我放置导线时··本来把我想要连接上的两个引脚端连上就可以了··可是呢··导线的终点却与多个引脚连到一起了··自动产生了很多我不想要连接上的节点··这是怎么回事呢?之前放导线的时候貌似没出现这情况··… 查看全部问答> |




