STM32F103 I2C DMA模式下读EEPROM数据出错
I2C的DMA查询模式下读取24C32数据,只能读到第一个数据,不用DMA模式读取数据正常255个数字是1~255,用DMA模式来读取数据全是1了。找不到原因
voidI2Cx_EE_Init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
I2C_InitTypeDef I2C_Initstucture;
RCC_APB2PeriphClockCmd(I2Cx_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin=I2Cx_SCL_PIN|I2Cx_SDA_PIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(I2Cx_SCL_PORT, &GPIO_InitStructure);
I2C_Initstucture.I2C_Ack=I2C_Ack_Enable;
I2C_Initstucture.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
I2C_Initstucture.I2C_ClockSpeed=I2Cx_Speed;
I2C_Initstucture.I2C_DutyCycle=I2C_DutyCycle_2;//I2C_DutyCycle_16_9;
I2C_Initstucture.I2C_Mode=I2C_Mode_I2C;
I2C_Initstucture.I2C_OwnAddress1=I2Cx_OWN_ADDRESS7;
I2C_Init(I2Cx_EEPROM, &I2C_Initstucture);
I2C_Cmd(I2Cx_EEPROM, ENABLE);
I2C_DMACmd(I2Cx_EEPROM, ENABLE);/* Enable I2C1 DMA */
I2Cx_AcknowledgeConfig(I2Cx_EEPROM,1);
}
void I2Cx_DMA_RX_init(u8* pBuffer,u32 addr,u16 len)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(I2Cx_DMA_RX_Channel); /* DMA1 channel7I2C1_RX configuration */
DMA_InitStructure.DMA_PeripheralBaseAddr =I2C1->DR;// (uint32_t)addr;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = len;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(I2Cx_DMA_RX_Channel, &DMA_InitStructure);
}
void ee_dma_read(void)
{
I2Cx_HardwareBus_BusyCheck(I2Cx_EEPROM);
I2C_GenerateSTART(I2Cx_EEPROM, ENABLE);/* Send I2C1 START condition */
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_MODE_SELECT)); /* Test on I2C1 EV5 and clear it */
I2C_Send7bitAddress(I2Cx_EEPROM, EEPROM_ADDRESS, I2C_Direction_Transmitter);/* Send I2C2 slave Address for write */
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Test on I2C1 EV6 and clear it */
I2C_SendData(I2Cx_EEPROM, 0x00);
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_BYTE_TRANSMITTING)); /* Test on I2C1 EV8 and clear it */
I2C_SendData(I2Cx_EEPROM, 0x00);
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_BYTE_TRANSMITTING )); /* Test on I2C1 EV8 and clear it */
I2C_GenerateSTART(I2Cx_EEPROM, ENABLE);
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2Cx_EEPROM, EEPROM_ADDRESS, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2Cx_EEPROM, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
I2Cx_DMA_RX_init(buf,I2Cx_EEPROM->DR,255);
I2C_DMALastTransferCmd(I2Cx_EEPROM, ENABLE);
DMA_Cmd(I2Cx_DMA_RX_Channel, ENABLE);/* Enable DMA1 Channel7 */
while(!DMA_GetFlagStatus(DMA1_FLAG_TC7));/* DMA1 Channel7 transfer complete test */
DMA_Cmd(I2Cx_DMA_RX_Channel, DISABLE);/* Enable DMA1 Channel7 */
I2C_GenerateSTOP(I2Cx_EEPROM, ENABLE);/* Send I2C1 STOP Condition */
I2Cx_AcknowledgeConfig(I2Cx_EEPROM,1);
for(u16 i=0; i<256; i++ )
{
printf("0x%02X ", buf);
if(i%16 == 15) printf("\n\r");
}
}
我已经放弃了STM32的硬件IIC了…… 直接用IO模拟吧,好多资料,代码直接复制,很方便 其实,硬件I2C完全可以用。I2C串行通信,本来就慢,根本不需用DMA处理的,可参考拙文;https://www.stmcu.org.cn/module/forum/thread-621248-1-1.html 请问哪里可以下载到IO模拟的I2C Slave代码呢?
页:
[1]