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

菜鸟新手求关注,STM32F103CBT6,I2C通信报错

[复制链接]
wuyankun 提问时间:2014-11-6 17:12 /
公司最近打算采用ST的单片机,其他单片机工程师比较忙,好吧,我只是个打杂的,于是被抓壮丁来处理,目标是使用I2C总线和一外设通信,想想也没啥难度。      于是,我参考网上的教程,配置了Keil的开发环境,参照了Keil给的I2C例子,写了个I2C通信代码,可是无法通信,非常着急,希望xdjm路过给打个赏,给找找虫子,非常感谢!
     简单的说是这样的,使用I2C2和外设相连,(I2C2连端口复用都没得)

     /* Includes ------------------------------------------------------------------*/#include "stm32f10x_lib.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define I2C2_SLAVE_ADDRESS7           0x00                //I2C2的地址,7位寻址
#define ADV7611_SLAVE_ADDRESS7        0x98                 //ADV7611的地址,7位寻址
#define BufferSize             2          //u16
#define ClockSpeed             400000         //2MHz
u8 I2C2_Buffer_Tx[BufferSize]={0,0};
u8 I2C2_Buffer_Rx[BufferSize]={0,0};
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
I2C_InitTypeDef  I2C_InitStructure;       
EXTI_InitTypeDef EXTI_InitStructure;
ErrorStatus HSEStartUpStatus;   
//自定义的配置功能函数
/* Private functions ---------------------------------------------------------*/
void RCC_Configuration(void);         //时钟,使用某功能前必须先激活该模块的时钟
void GPIO_Configuration(void);         //GPIO配置信息,使用哪种端口,输入,输出,和初始值
void NVIC_Configuration(void);         //中断配置信息
void ADV7611_Write(u8* pBuffer, u16 WriteAddrOffset, u16 NumByteToWrite);  //写ADV7611一段数据,字节对齐
void ADV7611_Read(u8* pBuffer, u16 ReadAddrOffset, u16 NumByteToRead);          //读ADV7611一段数据,字节对齐
void delay_ms(u16 time);//非精确的延时函数


int main(void)//主过程函数
{

  /* System clocks configuration ---------------------------------------------*/
  RCC_Configuration();
  /* NVIC configuration ------------------------------------------------------*/
  NVIC_Configuration();
  /* GPIO configuration ------------------------------------------------------*/
  GPIO_Configuration();


  //reset ADV7611 chips frist
  GPIO_ResetBits(GPIOA,GPIO_Pin_9);
  delay_ms(5);
  GPIO_SetBits(GPIOA,GPIO_Pin_9);
  delay_ms(5);


  /* I2C configuration ------------------------------------------------------*/
  I2C_Configuration();

        I2C2_Buffer_Tx[0]=0x00;         I2C2_Buffer_Tx[1]=0x00;
        ADV7611_Write(I2C2_Buffer_Tx, 0x400, 2);

  while (1)                                  
  {
  }
}


void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }

  /* Enable peripheral clocks --------------------------------------------------*/
  /* GPIOB Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);       
  /* GPIOA Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* AFIO clock enable */
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);       
  /* I2C1 and I2C2 Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 | RCC_APB1Periph_I2C2, ENABLE);
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configures the different GPIO ports.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GPIO_Configuration(void) //配置GPIO的管脚功能
{
  GPIO_InitTypeDef GPIO_InitStructure;        //初始化的结构

  /* Configure I2C1 pins: SCL and SDA ----------------------------------------*/
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Configure I2C2 pins: SCL and SDA ----------------------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */  
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif
}


void I2C_Configuration(void) //配置GPIO的管脚功能
{

  //配置I2C1的初始化参数
  /* I2C1 configuration ------------------------------------------------------*/
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//激活ACK
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7bit的地址模式
  I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;//设置I2C的时钟频率
  /* Enable I2C1 and I2C2 ----------------------------------------------------*/
  I2C_Cmd(I2C1, ENABLE);
  I2C_Init(I2C1, &I2C_InitStructure); //初始化I2C1

  /* I2C2 configuration ------------------------------------------------------*/
  I2C_InitStructure.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;//设置I2C2的地址信息,其他的配置信息和I2C1相同
  I2C_Cmd(I2C2, ENABLE);
  I2C_Init(I2C2, &I2C_InitStructure);//初始化I2C2

}

void ADV7611_Write(u8* pBuffer, u16 WriteAddrOffset, u16 NumByteToWrite)
{
  u8 Offset_MSB = 0; u8 Offset_LSB = 0;

  /*wait I2C idle statues */
  while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));
  /* Send I2C2 START condition */
  I2C_GenerateSTART(I2C2, ENABLE);        //I2C2产生开始信号(S),进入主发送模式
  /* Test on I2C2 EV5 and clear it */
  while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); //产生开始信息后,需要检测是否有EV5事件通知

  /* Send MDIN380 slave Address for write */
  I2C_Send7bitAddress(I2C2, ADV7611_SLAVE_ADDRESS7        , I2C_Direction_Transmitter);//发送从设备的地址,和传输方向(R?W?)

  /* Test on EV6 and clear it */
  while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  //I2C_Cmd(I2C2, ENABLE);

  /*with 16bit BUS Mode,then MSB(A10...A8),LSB(A7...A0)*/
  Offset_MSB = (u8) ((WriteAddrOffset>>8)&0x0F);
  Offset_LSB = (u8) (WriteAddrOffset&0x00FF);

  /* Send the ADV7611's internal address (MSB) to write to */   
  I2C_SendData(I2C2, Offset_MSB);  

  /* Test on EV8 and clear it */
  while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* Send the ADV7611's internal address (LSB) to write to */   
  I2C_SendData(I2C2, Offset_LSB);  

  /* Test on EV8 and clear it */
  while(! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  /* While there is data to be written */
  while(NumByteToWrite--)  
  {
    /* Send the current byte */
    I2C_SendData(I2C2, *pBuffer);

    /* Point to the next byte to be written */
    pBuffer++;

    /* Test on EV8 and clear it */
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  }

  /* Send STOP condition */
  I2C_GenerateSTOP(I2C2, ENABLE);

}

void delay_ms(u16 time)
{
  u16 i=0;
  while(time--)
  {       
                  i=12000;
                   while(i--);       
  }       
}



<
收藏 评论12 发布时间:2014-11-6 17:12

举报

12个回答
goswa 回答时间:2014-11-6 18:02:45
STM32F103 IIC硬件有BUG,建议采用IO模拟IIC通讯。
回答时间:2014-11-7 15:43:28
楼上说的正确,我们都是用的IO模拟I2C通信。
wuyankun 回答时间:2014-11-9 20:20:23
goswa 发表于 2014-11-6 18:02
STM32F103 IIC硬件有BUG,建议采用IO模拟IIC通讯。

谢谢回复,可否提高一份参考代码给小弟,wuyankun1986@126.com,再次感谢
wuyankun 回答时间:2014-11-9 20:21:11
安 发表于 2014-11-7 15:43
楼上说的正确,我们都是用的IO模拟I2C通信。

谢谢,不知可否提供参考代码,方便的话,wuyankun1986@126.com
wuyankun 回答时间:2014-11-11 12:25:42
安 发表于 2014-11-10 09:23
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=94048&highlight=I2C
http://www.stmcu. ...

谢谢,目前使用模拟器抓取波形,使用的模拟io的I2C方式,非常感谢
liwei5126 回答时间:2014-11-11 15:22:42
我是用IO模拟的I2C,你可以试试。
quillan-148562 回答时间:2014-11-13 17:16:09
你好 能否把你的adv7611代码参考一下?我最近想做adv7611的开发。 我的邮箱quillan2006@126.com
wuyankun 回答时间:2014-11-17 16:01:09
quillan-148562 发表于 2014-11-13 17:16
你好 能否把你的adv7611代码参考一下?我最近想做adv7611的开发。 我的邮箱

ADV7611有个论坛,上面有人贴出了完整代码,可以参考,我们这边项目还需要用MDIN380显示输出,所以没有办法验证正确性,我把代码转给你,是参考的
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版