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

HAL库I2C使用DMA发送数据的问题

[复制链接]
ldptest 提问时间:2018-1-17 14:19 /
阅读主题, 点击返回1楼
收藏 1 评论17 发布时间:2018-1-17 14:19
17个回答
ldptest 回答时间:2018-1-23 12:19:22
toofree 发表于 2018-1-23 10:39
刚上手STM32的时候,项目中用STM32F10CBT6控制过EEPROM AT24C02。
刚开始使用硬件I2C,在开发板上试是好的 ...

谢谢你的经验。
我的现象也是单步DEBUG能正常运行,一起执行就卡。
我查查相关手册看看有没有类似间隔问题。
ldptest 回答时间:2018-1-23 12:20:08
toofree 发表于 2018-1-23 11:00
下面这个或许可以参考一下。本人英语不行,就不翻译了。

谢谢,我英文也不行,慢慢看ing
ldptest 回答时间:2018-1-23 12:53:28
的确是两次发送去DMA时间过短导致。为了解决问题,我有两个方案。
方法一:加延时,固定延时,程序效率比较低,代码如下
void OLED_WR_Byte(uint8_t Byte,uint8_t DC)
{
      uint8_t SendBuff[2];
      SendBuff[0] = DC;
      SendBuff[1] = Byte;
      I2C_Master_Transmit_DMA(OLED_ADDRESS,SendBuff,2);
      HAL_Delay(1);
}

方法二:加I2C总线状态判断,程序不卡,但没显示,不知什么原因?
void I2C_Master_Transmit_DMA(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
  while (HAL_I2C_GetState(&hi2c1)!=HAL_I2C_STATE_READY)  {}
  while (HAL_I2C_Master_Transmit_DMA(&hi2c1,DevAddress,pData,Size)!= HAL_OK)
  {
    if (HAL_I2C_GetError(&hi2c1)!= HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }
}
nyszx 回答时间:2018-1-23 16:51:20
学习了~看库代码,可以重写HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c),增加一个完成标记,检测完成标记在启动下一次DMA传输,比使用delay来延时好,楼主可以试试
ldptest 回答时间:2018-1-23 20:40:16
nyszx 发表于 2018-1-23 16:51
学习了~看库代码,可以重写HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c),增加一个完成标记,检 ...

我在发送前增加检查DMA是否完成,结果还是一样的卡
void I2C_Master_Transmit_DMA(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
  while ((HAL_DMA_GetState(&hdma_i2c2_tx) != HAL_DMA_STATE_READY) && (HAL_DMA_GetState(&hdma_i2c2_rx) != HAL_DMA_STATE_READY)) {}  while (HAL_I2C_Master_Transmit_DMA(&hi2c1,DevAddress,pData,Size)!= HAL_OK)
  {
    if (HAL_I2C_GetError(&hi2c1)!= HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }
}
ldptest 回答时间:2018-1-30 00:02:06
本帖最后由 ldptest 于 2018-1-30 00:03 编辑

1、发送控制命令没有使用DMA方式,直接采用HAL_I2C_Master_Transmit
2、发送显示内容采用以下方式
void I2C_Master_Transmit_DMA(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
  while (HAL_I2C_GetState(&hi2c1)!=HAL_I2C_STATE_READY)  {}
  while (HAL_I2C_Master_Transmit_DMA(&hi2c1,DevAddress,pData,Size)!= HAL_OK)
  {
    if (HAL_I2C_GetError(&hi2c1)!= HAL_I2C_ERROR_AF)
    {
      Error_Handler();
    }
  }
}

void OLED_ShowChar(uint8_t chr)
{
        uint8_t c=0,i;
        c = chr - ' ';              //得到字库地址码
      uint8_t SendBuff[7];
      SendBuff[0] =  OLED_DATA;
      for(i=0;i<6;i++)
      {
        SendBuff[i+1] = F6x8[i + 5 * c];
      }
    I2C_Master_Transmit_DMA(OLED_ADDRESS,SendBuff,7);
}

结果:能显示,但连续显示字符时,第一个字符显示不出来,后续字符显示均正常,在第一个字符前加延时也不行。
XYX12306 回答时间:2019-4-8 14:30:22
你好,可以跟我讲讲:STM32F103的HAL库通过IIC方式驱动1.3寸OLED是怎样编写驱动程序的吗?
ldptest 回答时间:2019-4-8 16:10:26
本帖最后由 ldptest 于 2019-4-8 16:12 编辑
XYX12306 发表于 2019-4-8 14:30
你好,可以跟我讲讲:STM32F103的HAL库通过IIC方式驱动1.3寸OLED是怎样编写驱动程序的吗? ...

/*******************************************************************************
* 名    称: OLED_WR_Byte
* 功    能: OLED写入一个数据或命令
* 形    参: Byte:数据内容;DC:命令(0x00)/数据(0x40)
* 返    回: 无
* 说    明: 无
* 更新日期:2019-1-30
******************************************************************************/
void OLED_WR_Byte(u8 Byte,u8 DC)
{
      HAL_I2C_Mem_Write(&hi2c1,OLED_ADDRESS,DC,I2C_MEMADD_SIZE_8BIT,&Byte,1,OLED_I2C_TIMEOUT);
}
12

所属标签

相似问题

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