跟着野火的课程做到I2C实验,在I2C写入EEPROM实验起始信号sb无响应,反复发送起始信号也无反应,但是用课程的例子是可以的
i2c头文件
#ifndef __BSP_I2C_H
#define __BSP_I2C_H
#include "stm32f10x.h"
#include <stdio.h>
//EEPROM 设备地址 10100000
#define EERPOM_ADDR 0xa0
// IIC EERPOM的引脚定义
//PB6 I2C1_SCL
//PB7 I2C1_SDA
#define STM32_I2C_OWN_ADDR 0x5f//101111
//IIC1
#define EEPROM_I2C I2C1
#define EEPROM_I2C_CLK RCC_APB1Periph_I2C1
#define EEPROM_I2C_APBxClkCmd RCC_APB1PeriphClockCmd
#define EEPROM_I2C_BAUDRATE 400000
// IIC GPIO 引脚宏定义
#define EEPROM_I2C_SCL_GPIO_CLK (RCC_APB2Periph_GPIOB)
#define EEPROM_I2C_SDA_GPIO_CLK (RCC_APB2Periph_GPIOB)
#define EEPROM_I2C_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define EEPROM_I2C_SCL_GPIO_PORT GPIOB
#define EEPROM_I2C_SCL_GPIO_PIN GPIO_Pin_6
#define EEPROM_I2C_SDA_GPIO_PORT GPIOB
#define EEPROM_I2C_SDA_GPIO_PIN GPIO_Pin_7
void I2C_EE_Config(void);
void EEPROM_Byte_Write(uint8_t addr,uint8_t data);
void EEPROM_Read(uint8_t addr,uint8_t *data,uint8_t numByteToRead);
void EEPROM_WaitForWriteEnd(void);
#endif /* __BSP_I2C_H */
i2c c文件(部分)
#include "bsp_i2c.h"
void I2C_EE_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 打开I2C GPIO的时钟
EEPROM_I2C_GPIO_APBxClkCmd(EEPROM_I2C_SCL_GPIO_CLK|EEPROM_I2C_SDA_GPIO_CLK, ENABLE);
// 打开I2C 外设的时钟
EEPROM_I2C_APBxClkCmd(EEPROM_I2C_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_GPIO_PIN;
GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
// 配置I2C的工作参数
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//使能应答
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//使用7位地址模式
I2C_InitStructure.I2C_ClockSpeed = EEPROM_I2C_BAUDRATE;//配置SCL时钟频率
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//占空比 高:低 = 1:2
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = STM32_I2C_OWN_ADDR;//这是STM32 IIC自身设备地址,只要总线上唯一即可
I2C_Init(EEPROM_I2C,&I2C_InitStructure);
// 使能串口
I2C_Cmd(EEPROM_I2C, ENABLE);
}
//向EEPROM写入一个字节
void EEPROM_Byte_Write(uint8_t addr,uint8_t data)
{
do
{
//发送起始信号
I2C_GenerateSTART(EEPROM_I2C,ENABLE);
//等待EV5 开始信号SB应答
}while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT));
//EV5事件被检测到后发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,EERPOM_ADDR,I2C_Direction_Transmitter);
//等待EV6 地址发送信号应答
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR);
//传送要操作的单元地址
I2C_SendData(EEPROM_I2C,addr);
//等待EV8 TXE
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTING) == ERROR);
//发送要存储的字节
I2C_SendData(EEPROM_I2C,data);
//等待EV8_2
while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED) == ERROR);
//数据传输完成
//发送结束信号
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
}
一直在发送sb信号和检查sb信号响应循环,即检查不到sb响应信号,附上图片