[STM32F0] STM32F030K6

[复制链接]
 楼主| smartdog_1 发表于 2014-7-3 14:36 | 显示全部楼层 |阅读模式
本帖最后由 smartdog_1 于 2014-7-3 14:51 编辑

各位好:
      
         小弟用STM32F030K6 做I2C从机,利用TI 的SOC做主机,设定好从机地址之后,挂在驱动。
         
         在Keil中抓到了I2C中断,寄存器中的地址也是正确的。但是I2C总线的SCL被一直托低,同时SDA是高,导致SOC这边出现异常。MCU也没有正确给出ACK。
         使能了自动ACK。

         我用了CPAL I2C库,找了一大圈也没找到问题在哪儿。

         哪位知道的给个参考

mmuuss586 发表于 2014-7-3 15:10 | 显示全部楼层
先模拟吧,模拟成功了再改成硬件IIC的,ST的IIC弄起来比较麻烦的;
 楼主| smartdog_1 发表于 2014-7-3 16:30 | 显示全部楼层
mmuuss586 发表于 2014-7-3 15:10
先模拟吧,模拟成功了再改成硬件IIC的,ST的IIC弄起来比较麻烦的;

不会吧,模拟有点单疼哦
香水城 发表于 2014-7-3 16:30 | 显示全部楼层
首先,可以在SCK线上传一个电阻,根据低电平的幅值来判断是主机、还是从机拉低了这条时钟线。

第二,F0的I2C有个很强大的“clock stretch”功能,但是这个功能,在F0作为I2C从设备时,需要在主机支持"clock stretch"时可以使能。最后把示波器上的波形贴个图,从起始位开始哦。
香水城 发表于 2014-7-3 16:46 | 显示全部楼层
本帖最后由 香水城 于 2014-7-3 16:47 编辑

F0的I2C作为从机时的【时钟延展特性】

F0 I2C从设备的时钟延展特性.png
cailantu 发表于 2014-7-3 16:58 | 显示全部楼层
学习了,感谢香水
 楼主| smartdog_1 发表于 2014-7-3 17:32 | 显示全部楼层
香水城 发表于 2014-7-3 16:30
首先,可以在SCK线上传一个电阻,根据低电平的幅值来判断是主机、还是从机拉低了这条时钟线。

第二,F0的I ...

可以确认是MCU拉低了SCL。将MCU的地址随便改成其他的之后,数据线不会被拉低。

CPAL中有这样的代码:
    /* If NACK Slave Own Address option bit selected */
    if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0)
    {
      /* Disable Acknowledgement of own Address */
      __CPAL_I2C_HAL_DISABLE_DEV(pDevInitStruct->CPAL_Dev);

      CPAL_LOG("\n\rLOG : I2C Device NACK Own Address Mode Enabled");
    }

#define __CPAL_I2C_HAL_DISABLE_DEV(device)              CPAL_I2C_DEVICE[(device)]->CR1 &= ~I2C_CR1_PE

很不能理解,明明是关闭自动ACK,为什么是Disable DEV 呢 ?

我将这一句换成
    /* If NACK Slave Own Address option bit selected */
    if ((pDevInitStruct->wCPAL_Options & CPAL_OPT_I2C_NACK_ADD) != 0)
    {
      /* Disable Acknowledgement of own Address */
      __CPAL_I2C_HAL_ENABLE_NACK(pDevInitStruct->CPAL_Dev);
      CPAL_LOG("\n\rLOG : I2C Device NACK Own Address Mode Enabled");
    }
    else
    {
        /* Enable Acknowledgement of own Address */
        __CPAL_I2C_HAL_ENABLE_ACK(pDevInitStruct->CPAL_Dev);
        CPAL_LOG("\n\rLOG : I2C Device ACK Own Address Mode Enabled");
    }
#define __CPAL_I2C_HAL_ENABLE_NACK(device)              CPAL_I2C_DEVICE[(device)]->CR2 |= I2C_CR2_NACK

#define __CPAL_I2C_HAL_DISABLE_NACK(device)             CPAL_I2C_DEVICE[(device)]->CR2 &= ~I2C_CR2_NACK

就会出现SCL被拉低,无ACK   SDA正常。

如果不替换,会出现SCL SDA 在ACK之后都被拉低。

波形暂时没附上,代会抓一个
 楼主| smartdog_1 发表于 2014-7-3 20:49 | 显示全部楼层
本帖最后由 smartdog_1 于 2014-7-3 21:12 编辑

scope_1.png scope_0.png 目前的代码如下:

  1. #defined  CPAL_I2C_DMA_PROGMODEL

  2.    //初始化I2C 数据结构
  3.     CPAL_I2C_DeInit(I2C_DevStructures[0]);
  4.     CPAL_I2C_StructInit(I2C_DevStructures[0]);

  5. #ifdef CPAL_I2C_DMA_PROGMODEL
  6.     I2C_DevStructures[0]->wCPAL_Options = CPAL_OPT_I2C_NACK_ADD | CPAL_OPT_I2C_WAKEUP_STOP | CPAL_OPT_DMARX_TCIT;
  7.     I2C_DevStructures[0]->CPAL_ProgModel = CPAL_PROGMODEL_DMA;
  8. #elif defined (CPAL_I2C_IT_PROGMODEL)
  9.     SLAVESTRUCTURE.wCPAL_Options =  CPAL_OPT_I2C_NACK_ADD | CPAL_OPT_I2C_WAKEUP_STOP;
  10.     SLAVESTRUCTURE.CPAL_ProgModel = CPAL_PROGMODEL_INTERRUPT;
  11. #else
  12. #error "Please select one of the programming model (in main.h)"
  13. #endif

  14.     /* Configure Own address 1 */
  15.     I2C_DevStructures[0]->pCPAL_I2C_Struct->I2C_OwnAddress1 = OWNADDRESS;

  16.     /* Set I2C Speed */
  17.     I2C_DevStructures[0]->pCPAL_I2C_Struct->I2C_Timing = SLAVE_I2C_TIMING;

  18.     /* Select Slave Mode */
  19.     I2C_DevStructures[0]->CPAL_Mode = CPAL_MODE_SLAVE;

  20.     /* Initialize I2Cx Device*/
  21.     CPAL_I2C_Init(I2C_DevStructures[0]);

  22.     /* Infinite loop */
  23.     while (1)
  24.     {
  25.         /* Reset BufferRX value */
  26.         memset(BufferRX, 0, (uint16_t)BufferSize);

  27.         /* Initialize Transfer parameters */
  28.         I2C_DevStructures[0]->pCPAL_TransferRx = &sRxStructure;
  29.         sRxStructure.wNumData = BufferSize;
  30.         sRxStructure.pbBuffer = (uint8_t*)BufferRX;
  31.         delay(10);

  32.         /* Read operation */
  33.         CPAL_I2C_Read(I2C_DevStructures[0]);

  34.         /* Enter Stop Mode and wait for interrupt to wake up */
  35.         //PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
  36.                 __WFI();

  37.         /* Wait until communication finishes */
  38.         while ((I2C_DevStructures[0]->CPAL_State != CPAL_STATE_READY)
  39.                         && (I2C_DevStructures[0]->CPAL_State != CPAL_STATE_ERROR));

  40.         /* Configure SystemClock*/        
  41.         Restore_Configuration();

  42.         /* Configure and enable the systick timer to generate an interrupt each 1 ms */
  43.         SysTick_Config((SystemCoreClock / 1000));

  44.         /* If are received correctly */
  45.         if (Compare_bBuffer((uint8_t*)BufferTX, BufferRX, BufferSize) == PASSED )
  46.         {
  47.             /* Update LCD Display */
  48.             //LCD_DisplayStringLine(Line9, MESSAGE6);
  49.         }
  50.         else
  51.         {
  52.             /* Update LCD Display */
  53.             //LCD_DisplayStringLine(Line9, MESSAGE10);
  54.         }
  55.         delay(50);
  56.     }

在第九个时钟周期之后,SCL SDA都被托低,即使关闭了NOSTRETCH 也是一样。

 楼主| smartdog_1 发表于 2014-7-4 12:46 | 显示全部楼层
等了很久。。。哪位大哥给指点一下
香水城 发表于 2014-7-4 17:06 | 显示全部楼层
从波形看到,主设备对从地址为0x6c的设备,即STM32F030寻址,并且是读操作的企图(方向位为1)。然后SCK和SDA两根线就都处于地电平了。

首先,还是那句话,串个电阻,通过看低电平的幅值才是说明谁把SCK拉低的最直接证据。仅仅主设备换了对另外一个地址的从设备的寻址就没有问题,不是直接证据。

第二,根据5楼的信息,从设备在地址匹配事件后(ADDR标志置位),如果F030的I2C ISR没有软件清零ADDRCF;或者ADDR标志清零了,但是从设备要发送的数据还没有写进TXDR,都会发生以上波形看到的时钟延展

 楼主| smartdog_1 发表于 2014-7-10 16:06 | 显示全部楼层
Sorry,这几天在弄CUPS部分,MCU这块一直没有回复。

MCU目前是这样的:移除了CPAL库,直接使用ST 提供的API,使能了 slave byte control之后,MCU能够正确给出ACK。但是这块得先放一下,过段时间把CUPS搞定之后再来将详细的解决方法贴出来。

帖子就暂时不结了。
 楼主| smartdog_1 发表于 2014-7-16 09:00 | 显示全部楼层
目前关于应答的问题已经搞定了,从新加入CPAL库,实现从机接收数据。
CPAL的代码使用如下,给需要的人一个参考
  1.         /* Start CPAL communication configuration ***********************************/
  2.     /* Initialize local Reception structures */
  3.     sRxStructure.wNumData = 2;               /* Maximum Number of data to be received */
  4.     sRxStructure.pbBuffer = RxBuffer;   /* Common Rx buffer for all received data */
  5.     sRxStructure.wAddr1 = 0;            /* Not needed */
  6.     sRxStructure.wAddr2 = 0;            /* Not needed */

  7.     /* Initialize local Transmission structures */
  8.     sTxStructure.wNumData = 4;               /* Maximum Number of data to be transmission */
  9.     sTxStructure.pbBuffer = TxBuffer;   /* Common Rx buffer for all received data */
  10.     sTxStructure.wAddr1 = OWN_ADDRESS;  /* The own board address */
  11.     sTxStructure.wAddr2 = 0;            /* Not needed */

  12.     /* Set SYSCLK as I2C clock source */
  13.     RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);

  14.     /* Configure the device structure */
  15.     CPAL_I2C_StructInit(&I2C1_DevStructure);      /* Set all fields to default values */
  16.     I2C1_DevStructure.CPAL_Mode = CPAL_MODE_SLAVE;

  17.     I2C1_DevStructure.wCPAL_Options =  CPAL_OPT_NO_MEM_ADDR | CPAL_OPT_DMATX_TCIT |
  18.                                        CPAL_OPT_DMARX_TCIT | CPAL_OPT_I2C_WAKEUP_STOP;
  19.     I2C1_DevStructure.CPAL_ProgModel = CPAL_PROGMODEL_DMA;

  20.     I2C1_DevStructure.pCPAL_I2C_Struct->I2C_Timing = I2C_TIMING;
  21.     I2C1_DevStructure.pCPAL_I2C_Struct->I2C_OwnAddress1 = OWN_ADDRESS;
  22.     I2C1_DevStructure.pCPAL_TransferRx = &sRxStructure;
  23.     I2C1_DevStructure.pCPAL_TransferTx = &sTxStructure;

  24.     /* Initialize CPAL device with the selected parameters */
  25.     CPAL_I2C_Init(&I2C1_DevStructure);
但是目前还有一个问题没有解决:主机读MCU时,MCU如何应答数据,在CPAL库中暂时没找到适合应答的地方,如果哪位前辈做过这块,麻烦给个指点.小弟不胜感激
 楼主| smartdog_1 发表于 2014-7-17 18:03 | 显示全部楼层
本帖最后由 smartdog_1 于 2014-7-17 18:37 编辑

IIC的问题基本解决了,分享一下心得,虽然这个帖子已经没人关注了。。。。。
1、CPAL中并没有完善对SLAVE模式时,应答机制。Master读时,需要自行添加相关的状态标志,然后在主循环中将数据发送出去
2、Slaver 响应完 Master的一次读操作之后,需要重新初始化IIC控制器。(具体需要重置哪个寄存器,没去深究,直接重新初始化了,简单方便)
3、利用CPAL作为从机时,Master写支持的还OK
4、CPAL在读取OAR1 OAR2时,存在很明显的Bug,在代码中显而易见,有哪位使用的可以自行修改
5、CPAL对于 STM32F030K6 器件不支持,需要手动修改一些地方,还算比较简单,就不最赘述了

最后不得不说,新器件 + CPAL 真是个坑,如果不是想偷懒,自己写寄存器,就不会那么麻烦了。。。。。

说明:本人使用的CPAL版本是 1.1.0 / 16-January-2014 ,以后的版本可能会修正这些问题
chindis 发表于 2015-1-19 23:02 | 显示全部楼层
我很需要
睿翼1992 发表于 2015-3-17 15:36 | 显示全部楼层
xktesla 发表于 2015-8-5 23:27 | 显示全部楼层
smartdog_1 发表于 2014-7-17 18:03
IIC的问题基本解决了,分享一下心得,虽然这个帖子已经没人关注了。。。。。
1、CPAL中并没有完善对SLAVE模 ...

大哥能不能给个CPAL的简单例子,双机通信,想要个最简单的,一个发,一个收。641018299@qq.com。小弟万分感谢!!!
wuhaiduo 发表于 2015-8-23 18:09 | 显示全部楼层
香水城 发表于 2014-7-3 16:30
首先,可以在SCK线上传一个电阻,根据低电平的幅值来判断是主机、还是从机拉低了这条时钟线。

第二,F0的I ...

stm32f030k6t6 的串口怎么也配置不成  PB6 PB7
破天#mcu 发表于 2017-8-7 10:35 | 显示全部楼层
代理兆易创新(GD)32-bit ARM架构,Cortex-M3、M4内核MCU,可提供技术支持等服务;
GD32F130系列 M3内核与STM32F030/051系列,硬件pin to pin兼容;烧录器、寄存器、开发环境完全兼容;
欢迎来电咨询探讨,邱先生 电话:136 8955 5135;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

229

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部