你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 I2C DMA模式下读EEPROM数据出错

[复制链接]
wdshuang09 提问时间:2020-4-23 12:53 /
I2C的DMA查询模式下读取24C32数据,只能读到第一个数据,不用DMA模式读取数据正常255个数字是1~255,用DMA模式来读取数据全是1了。
找不到原因

void  I2Cx_EE_Init(void)
{
        GPIO_InitTypeDef  GPIO_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 channel7  I2C1_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");   
        }
}


读取数据不对

读取数据不对

读取数据正常

读取数据正常
收藏 评论4 发布时间:2020-4-23 12:53

举报

4个回答
STM1024 回答时间:2020-4-23 15:48:37
我已经放弃了STM32的硬件IIC了……
Io云oT 回答时间:2020-4-23 16:08:17
直接用IO模拟吧,好多资料,代码直接复制,很方便
慎微 回答时间:2020-4-23 17:40:03
其实,硬件I2C  完全可以用。I2C串行通信,本来就慢,根本不需用DMA处理的,可参考拙文;https://www.stmcu.org.cn/module/forum/thread-621248-1-1.html

评分

参与人数 1蝴蝶豆 +4 收起 理由
STMCU + 4

查看全部评分

wangwei0722 回答时间:2020-4-25 20:29:29
请问哪里可以下载到IO模拟的I2C Slave代码呢?

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版