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

I2C主机接收--从机发送问题,谢过大神啦

[复制链接]
woshilee 提问时间:2014-11-26 09:51 /
本帖最后由 woshilee 于 2014-11-26 16:26 编辑

我用STM32F103的I2C1作为主接收器,I2C2作为从发送器,程序如下,程序总是会卡在判断ADDR位那里,就是红色部分,小弟菜鸟,不知道对I2C的理解哪里不对,就是无法运行,很捉急,谢谢大神帮忙了
#include <stm32f10x.h>
#include <stdio.h>
u8 Getbyte=0;
u8 i=0;
u8 flag1=0,flag2=0,sendflag=0;
/*****************************************************
函数: void Delay(vu32 nCount)
参数: vu32 nCount 延时时间
描述: 延时指定时间
返回: 无
******************************************************/
void Delay(vu32 nCount)
{
    for(; nCount != 0; nCount--);
}

/********************USART1配置函数************************/
void USART1_Config(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;              //串口的波特率,例如115200 最高达4.5Mbits/s
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据字长度(8位或9位)
USART_InitStructure.USART_StopBits = USART_StopBits_1;      //可配置的停止位-支持1或2个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;         //无奇偶校验  
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //双工模式,使能发送和接收  
USART_Init(USART1, &USART_InitStructure);  // 调用STM32的USART初始化底层函数
USART_Cmd(USART1,ENABLE);
}


void I2C_Config(void)
{        
        I2C_InitTypeDef  I2C_InitStructure;
  /* I2C configuration */
        I2C_DeInit(I2C1);
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0xA1;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 400000;
  I2C_Cmd(I2C1, ENABLE);
  I2C_Init(I2C1, &I2C_InitStructure);
        I2C_AcknowledgeConfig(I2C1, ENABLE);        

        
        I2C_DeInit(I2C2);
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0xA2;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 400000;
  I2C_Init(I2C2, &I2C_InitStructure);
        I2C_Cmd(I2C2, ENABLE);
        /*允许1字节1应答模式*/
        I2C_AcknowledgeConfig(I2C2, ENABLE);        
        
}

/********************GPIO配置函数************************/
void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;//定义 GPIO_InitTypeDef类型结构体GPIO_InitStructure

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_10|GPIO_Pin_11; //PB.6,PB.7
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;        //复用开漏输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);
        
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);
        
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/********************时钟配置函数************************/
void RCC_Config(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);  //使能GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2, ENABLE);  //使能usart1时钟
}
/********************printf函数支持函数************************/
int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */
    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
    {}

    /* e.g. write a character to the USART */
    USART_SendData(USART1, (uint8_t) ch);

    return ch;
}
int fgetc(FILE *fp)
{
        int ch = 0;
        
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
    {
    }

    ch = (int)USART1->DR & 0xFF;
        
    putchar(ch); //回显        
        return ch;
}


/********************主函数************************/
int main(void)
        {
                RCC_Config();
                GPIO_Config();         
                USART1_Config();
                I2C_Config();

               
                while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
                I2C_GenerateSTART(I2C1, ENABLE);// 在BUSY=0时发送起发送起始条件,进入主模式
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));// 发生以后读SR1并写DR,((uint32_t)0x00030001)  /* BUSY总线忙, MSL主模式 and SB起始条件已发送 flag */  
                I2C_Send7bitAddress(I2C1, 0xA2, I2C_Direction_Receiver);//发送地址,最后一位为1写,最后一位为0读
                while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


               
                while(I2C_GetFlagStatus(I2C2, I2C_FLAG_ADDR) == RESET);
                I2C_SendData(I2C2, 0xff);
                while(I2C_GetFlagStatus(I2C1,I2C_FLAG_RXNE) == RESET);
                Getbyte=I2C_ReceiveData(I2C1);
               
                I2C_AcknowledgeConfig(I2C1, DISABLE);        
                I2C_AcknowledgeConfig(I2C2, DISABLE);                        
                I2C_GenerateSTOP(I2C1, ENABLE);                 
                printf("\r\n%d\r\n",Getbyte);
               
                while(1);

        }










I2C_Slave_Send.rar

下载

3.91 MB, 下载次数: 207, 下载积分: ST金币 -1

收藏 2 评论17 发布时间:2014-11-26 09:51

举报

17个回答
海鱼 回答时间:2017-1-12 17:19:09
zbber 发表于 2017-1-1 14:36
103的I2C听说是挺难搞,硬件上有问题,030和F4上的倒是用过,配置是比较麻烦,但是调好了还是挺 ...

想请教一下 F030 如何配置成i2c的从机啊 就是ping同了从机地址之后 从机就发送一组数据~~
我现在用DMA模式 只能发送一次 之后就 主机读I2c  就会出现I2c总线超时了~
STM32F051 回答时间:2016-12-13 23:47:55
我只是过来看看热闹,当年用STM8的时候,就是被IIC弄死的;后来ST新出品的器件,把IIC的部分重新设计过了,听说是有BUG,当时有人甚至还仔细分析过BUG;如果只是读写24CXX,应该是可以的;但双机通讯用它,难,改成模拟IIC后,没问题了。
这次过来看,就是想知道,ST改进后的IIC核还有没有问题。主要是STM32F0系列;
那片清茶 回答时间:2014-11-26 11:50:19
很多人问题出在这个地方 ,最好你换成模拟的IIC方式,这样稳定。
chinahuangyong 回答时间:2014-11-28 15:41:40
不知道你的地址设置对了没,比如你的地址是0x50,你输入进去的应该是(0x50<<2)
woshilee 回答时间:2014-12-1 08:58:11
chinahuangyong 发表于 2014-11-28 15:41
不知道你的地址设置对了没,比如你的地址是0x50,你输入进去的应该是(0x50 ...

左移两位?这个手册上有提到吗?
yvonn 回答时间:2014-12-10 22:02:39
103的I2C听说是挺难搞,硬件上有问题,030和F4上的倒是用过,配置是比较麻烦,但是调好了还是挺好用的,建议你参考103的官方历程,注意一些细节问题。我就发现F4的GPIO初始化的时候就是不能放在一起,新出的030就可以放到一起初始化,证明ST已经在改进,所以103的更要注意细节。希望对你有帮助。
woshilee 回答时间:2014-12-11 08:48:56
yvonn 发表于 2014-12-10 22:02
103的I2C听说是挺难搞,硬件上有问题,030和F4上的倒是用过,配置是比较麻烦,但是调好了还是挺好用的,建 ...

初始化不能放在一起ishi库有问题吧?总不至于是硬件问题
chinahuangyong 回答时间:2014-12-19 21:08:20
woshilee 发表于 2014-12-1 08:58
左移两位?这个手册上有提到吗?

说错了 ,左移一位,不好意思哈
wamcncn 回答时间:2014-12-19 21:18:22
本帖最后由 wambob 于 2014-12-19 21:19 编辑

多参考几个程序看看,有写错的地方没 ,红色的地方是 I2C库函数 ,头文件包了吗
woshilee 回答时间:2014-12-20 13:20:06
chinahuangyong 发表于 2014-12-19 21:08
说错了 ,左移一位,不好意思哈

是ST的参考手册上说的吗?
chinahuangyong 回答时间:2014-12-21 20:43:07
woshilee 发表于 2014-12-20 13:20
是ST的参考手册上说的吗?

7位地址+1位读写,手册上没有直接,要你自己做的时候理解,看官网的历程,不过直接用查询的IIC不好用,建议用终端或者DMA
haha2012 回答时间:2016-8-4 19:13:37
了解下,看看
不再犹豫c 回答时间:2016-11-18 10:45:38
楼主问题现在解决了吗
诗歌 回答时间:2016-11-28 20:06:33
感觉没错,看不出来
五哥1 回答时间:2016-12-31 02:09:03
楼主后续问题解决了吗?
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版