小学生
最后登录1970-1-1
在线时间 小时
注册时间2023-10-5
|
指南者硬件IIC发送起始信号没有响应,一直卡死在EV5事件,在EV5加上超时等待之后,又卡死在下一个标志位,估计EEPROM无法应答,求解
#include"i2c.h"
//配置I2C的GPIO
//配置I2C的工作模式
//编写write byte函数
//编写RANDOM read函数
//校验函数
//编写以及校验page write以及pag read函数
uint32_t T=10000;
void I2C_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 打开IIC外设的时钟
DEBUG_I2C_APBxClkCmd(DEBUG_I2C_CLK, ENABLE);
// 打开SCL与SDA的时钟
DEBUG_I2C_GPIO_APBxClkCmd(DEBUG_I2C_GPIO_SCL_CLK|DEBUG_I2C_GPIO_SDA_CLK, ENABLE);
// 将I2C_SCL的GPIO配置为复用开漏模式
GPIO_InitStructure.GPIO_Pin = DEBUG_I2C_GPIO_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_I2C_GPIO_SCL_PORT, &GPIO_InitStructure);
// 将I2C_SDA的GPIO配置为复用开漏模式
GPIO_InitStructure.GPIO_Pin = DEBUG_I2C_GPIO_SDA_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(DEBUG_I2C_GPIO_SCL_PORT, &GPIO_InitStructure);
// 配置I2C的工作参数
// 使能应答
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
// 配置数据帧
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
// 配置波特率
I2C_InitStructure.I2C_ClockSpeed = DEBUG_I2C_BAUDRATE ;
// 配置占空比
I2C_InitStructure.I2C_DutyCycle= I2C_DutyCycle_2;
//配置工作模式
I2C_InitStructure.I2C_Mode= I2C_Mode_I2C ;
//配置STM32自身地址
I2C_InitStructure.I2C_OwnAddress1=I2C_STM32_OwnAddress1;
;
// 完成I2C的初始化配置
I2C_Init(I2C1, &I2C_InitStructure);
// 使能I2C
I2C_Cmd(I2C1, ENABLE);
}
void I2C_sendbyte(uint8_t addr,uint8_t data)
{
//发送起始信号
I2C_GenerateSTART (DEBUG_I2C_EEPROM,ENABLE);
//检测ev5事件
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_MODE_SELECT)==ERROR)
{
if(T==0)
{
break;
}
T--;
}
//发送要写入的EEPROM地址
I2C_Send7bitAddress(DEBUG_I2C_EEPROM,I2C_EEPROM_Address,I2C_Direction_Transmitter);
//检测ev6
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
//发送的数据要写在什么地方
I2C_SendData (DEBUG_I2C_EEPROM,addr);
//检测ev8事件
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);
//发送数据
I2C_SendData (DEBUG_I2C_EEPROM,data);
//检测ev8(形参应用完成时)
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
//发送停止信号
I2C_GenerateSTOP(DEBUG_I2C_EEPROM,ENABLE);
}
//由函数传出数据应采用传址,若传值则在函数生存周期结束后传取出的数据自动销毁
void I2C_Random_read(uint8_t addr,uint8_t *data,uint8_t num)
{
//发送起始信号
I2C_GenerateSTART (DEBUG_I2C_EEPROM,ENABLE);
//检测ev5事件
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
//发送要写入的EEPROM地址
I2C_Send7bitAddress(DEBUG_I2C_EEPROM,I2C_EEPROM_Address,I2C_Direction_Transmitter);
//检测ev6
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
//第二次起始信号
I2C_GenerateSTART (DEBUG_I2C_EEPROM,ENABLE);
////检测ev5事件
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
//发送要读取的EEPROM地址
I2C_Send7bitAddress(DEBUG_I2C_EEPROM,I2C_EEPROM_Address,I2C_Direction_Receiver);
//检测ev6,从机把数据发送给主机,产生ev7事件
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)==ERROR);
while(num)
{
if(num==1)
//最后一个数据,产生no ack信号
I2C_AcknowledgeConfig(DEBUG_I2C_EEPROM,ENABLE);
else
//检测ev7,若ev7有效,stm32数据寄存器有有效数据
while(I2C_CheckEvent(DEBUG_I2C_EEPROM,I2C_EVENT_MASTER_BYTE_RECEIVED)==ERROR);
//将数据寄存器的值传入变量
*data=I2C_ReceiveData(DEBUG_I2C_EEPROM);
//存储下一个数据
data++;
num--;
}
//数据传输完成,发送停止信号
I2C_GenerateSTOP (DEBUG_I2C_EEPROM,ENABLE);
//使能ack,方便下次通讯
I2C_AcknowledgeConfig(DEBUG_I2C_EEPROM,ENABLE);
}
void I2C_WaitforEEPROM_Write(void)
{
do
{
//发送起始信号
I2C_GenerateSTART (DEBUG_I2C_EEPROM,ENABLE);
//检测起始位
while(I2C_GetFlagStatus (DEBUG_I2C_EEPROM,I2C_FLAG_SB)==RESET);
//发送要写入的EEPROM地址
I2C_Send7bitAddress(DEBUG_I2C_EEPROM,I2C_EEPROM_Address,I2C_Direction_Transmitter);
//检测ev6
}
while(I2C_GetFlagStatus(DEBUG_I2C_EEPROM,I2C_FLAG_ADDR)==RESET);
//EEPORM内部时序完成,发送停止信号,结束这段通讯
I2C_GenerateSTOP (DEBUG_I2C_EEPROM,ENABLE);
}
|
|