关于STM32硬件I2C问题
前面和大家分享了模拟I2C代码,也来谈谈我的硬件I2C。传感器地址为0x1a,这是实际的SCL与SDA波形图
下面这个图纯属测试,测试是否发出的数据正确,发送的数据为0xaa
代码如下,配置文件也检查了好几遍,并没有发现什么问题,可代码在发送了device地址后,就停了。
请牛牛们帮忙分析
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_i2c.h"
#include "user_i2c.h"
/**
* @briefInitializes peripherals used by the I2C Periph driver.
* @paramNone
* @retval None
*/
void I2C_HighLevel_Init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
/*!< I2C Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
/*!< I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/*!< GPIO configuration */
/*!< Configure I2C pins: SCL */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);//高电平到低电平跳变
/*!< Configure I2C pins: SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);//高电平到低电平跳变?
/*!< GPIO configuration */
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);//低电平到高电平跳变?
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);//低电平到高电平跳变?
/*!< I2C configuration */
I2C_InitTypeDefI2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 200000;
/* I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);
/* Apply I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
}
/**
* @brief Transmit start/adress/stop, receive sensors DATA from I2C Periph.
* @paramNone
* @retval None
*/
UV_Ambient_Sensor I2C_Read(uint8_t Device_Addr, uint8_t Reg_Addr,uint8_t NumByteToRead)
{
UV_Ambient_Sensor UV_value;
//UV_Ambient_Sensor uv_amb_sensor;//store sensor value
//while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));//check if i2c is busy
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//wait ack
//I2C_GenerateSTART(I2C1, DISABLE);
I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Transmitter);// write slave address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
//slave ack
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(I2C1, ENABLE);
I2C_SendData(I2C1, Reg_Addr);// write slave register address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack
/*!< Test on EV8 and clear it */
//while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF));//-------debug1
//I2C_GenerateSTOP(I2C1, ENABLE);//uv datasheet need,stand i2c?
//I2C_GenerateSTOP(I2C1, DISABLE);//stop transmit stop signal
I2C_GenerateSTART(I2C1, ENABLE);
//I2C_GenerateSTART(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//
I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Receiver);// Read
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//
//slave ack
/* One Byte Master Reception procedure (POLLING) -----------------------------*/
/* While there is data to be read */
/*
while(NumByteToRead)
{
if(NumByteToRead == 1)//Generate Stop before receive the last byte
{*/
// while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));//-------debug2
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
// }
/* Test on EV7 and clear it */
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))//
{
/* Read a byte from the sensor */
UV_value.Ambient_value = I2C_ReceiveData(I2C1);
/* Point to the next location where the byte read will be saved */
// pBuffer++;
/* Decrement the read bytes counter */
// NumByteToRead--;
}
//}
/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
return UV_value;
}
void I2C_Write(uint8_t Device_Addr, uint8_t Reg_Addr, uint8_t Ctrl_Cmd)
{
//while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));//check if i2c is busy
I2C_GenerateSTART(I2C1, ENABLE);// SCL与SDA均产生下降沿信号
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));//wait ack
I2C_Send7bitAddress(I2C1, Device_Addr, I2C_Direction_Transmitter);// write slave address,
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
//slave ack
I2C_SendData(I2C1, Reg_Addr);// write slave register address
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack
I2C_SendData(I2C1, Ctrl_Cmd);// data to be written
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//
//slave ack
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
/**
* @briefWait for EEPROM Standby state.
*
* @noteThis function allows to wait and check that EEPROM has finished the
* last operation. It is mostly used after Write operation: after receiving
* the buffer to be written, the EEPROM may need additional time to actually
* perform the write operation. During this time, it doesn't answer to
* I2C packets addressed to it. Once the write operation is complete
* the EEPROM responds to its address.
*
* @paramNone
* @retval sEE_OK (0) if operation is correctly performed, else return value
* different from sEE_OK (0) or the timeout user callback.
*/
void I2C_WaitEepromStandbyState(void)
{
__IO uint16_t SR1_Tmp = 0;
/* Keep looping till the slave acknowledge his address or maximum number
of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
in STM324x7I_eval_i2c_ee.h file) */
do
{
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Read I2C1 SR1 register */
SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
/* Send sensor address for write */
I2C_Send7bitAddress(I2C1, 0x1A, I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));
/* Clear AF flag */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
/* STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}
楼主IIC用的那种模式呢?从器件是否应该有响应? 速度慢点,时序 zhang7309 发表于 2015-1-5 15:00
楼主IIC用的那种模式呢?从器件是否应该有响应?
从器件不响应似乎,很奇怪。
标准I2C,STM32主 hlt512 发表于 2015-1-5 15:02
速度慢点,时序
嗯,要标准速率吗,记得我试过100K的,还是不行。
我这个是200K的,一般来说,官方的要多快比较合适呢 这是什么软件啊~ linshifaa 发表于 2015-1-5 15:37
这是什么软件啊~
软件???? 这个软件啊
4GSa/s这采样率,这示波器多少钱啊,测量信号的带宽能达到多少! linshifaa 发表于 2015-1-5 15:42
这个软件啊
额,这个是示波器,图像可以直接抓取保存到U盘上