OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9280|回复: 7

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

[复制链接]

14

主题

140

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1116
金钱
1116
注册时间
2015-12-20
在线时间
118 小时
发表于 2018-1-19 08:57:14 | 显示全部楼层 |阅读模式
5金钱
大家好:
我用STM32F10C8T6 连接IIC 接口的OLED。
STM32cubeMX进行初始化设置,以及修改了一下DMA发送函数,发现不能显示
接口驱动是没问题的,以前用3.5库(没使用DMA)是能正常显示的。
使用板上的LED灯检查卡在哪,发现卡在第二次发送上。
问题应该出在启动了DMA或I2C后,没有把它停掉。
现象与https://community.st.com/thread/ ... p-in-hali2cgetstate一样。
何时怎样停掉?

下面是精简后的程序,还请大神指导一下。

int main(void)
{
   HAL_Init();
   SystemClock_Config();
   MX_GPIO_Init();
   MX_DMA_Init();
   MX_I2C1_Init();
   OLED_Init();
   while (1)
   {
   }
}
void I2C_Master_Transmit_DMA(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
   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_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);
}
void OLED_Init(void)
{  
   delay_ms(200);              //
OLED_WR_Byte(0xAE,OLED_CMD);//--display off关闭显示
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address 设置开始低列地址为SEG0
    /*************目的测试卡在哪*********************/
         HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address设置高列地址为0000b
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  设置开始行地址
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address        设置开始页地址PAGE0
OLED_WR_Byte(0x81,OLED_CMD); // contrast control对比度控制,双字节命令
OLED_WR_Byte(0xFF,OLED_CMD);//--对比度为256
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap SEG0列地址为127
OLED_WR_Byte(0xA6,OLED_CMD);//--设置为正常显示(正常 / 反相显示)
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)设置驱动路数
OLED_WR_Byte(0x3F,OLED_CMD);//--驱动路数为1/32 duty占空比
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction: Scan from COM[N-1] to COM0
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
OLED_WR_Byte(0x00,OLED_CMD);//
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh设置电压
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable设置电荷泵
OLED_WR_Byte(0x14,OLED_CMD);//开电荷泵
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel,开始显示
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2018-1-19 22:27:05 | 显示全部楼层
F1的硬件I2C有问题的,建议你用IO模拟的,如果非要用硬件I2C的话,建议你换MCU,030或者302的MCU硬件I2C是可以使用的
回复

使用道具 举报

14

主题

140

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1116
金钱
1116
注册时间
2015-12-20
在线时间
118 小时
 楼主| 发表于 2018-1-20 11:49:17 | 显示全部楼层
模拟I2C无法使用
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2018-1-21 00:50:13 | 显示全部楼层

一定要用dma,那就慢慢调了,准备个十天半个月的,打长久战吧
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2014-11-6
在线时间
11 小时
发表于 2018-4-23 13:37:47 | 显示全部楼层
CubeMX的I2C初始化代码有问题,你试试修改i2c.c,把__HAL_RCC_I2C1_CLK_ENABLE(); 提前到GPIO初始化之前


[mw_shl_code=cpp,true]void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */
         __HAL_RCC_I2C1_CLK_ENABLE(); //提前初始化I2C时钟
  /* USER CODE END I2C1_MspInit 0 */
  
    /**I2C1 GPIO Configuration   
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C1 clock enable */
//    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }[/mw_shl_code]


回复

使用道具 举报

14

主题

140

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1116
金钱
1116
注册时间
2015-12-20
在线时间
118 小时
 楼主| 发表于 2018-4-26 16:23:30 | 显示全部楼层
simonliu009 发表于 2018-4-23 13:37
CubeMX的I2C初始化代码有问题,你试试修改i2c.c,把__HAL_RCC_I2C1_CLK_ENABLE(); 提前到GPIO初始化之前

...

谢谢,我回去试试
回复

使用道具 举报

0

主题

1

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2018-3-22
在线时间
13 小时
发表于 2022-3-21 16:10:12 | 显示全部楼层
请问这个问题最后怎么解决的呢?
回复

使用道具 举报

14

主题

140

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1116
金钱
1116
注册时间
2015-12-20
在线时间
118 小时
 楼主| 发表于 2022-5-15 15:51:44 | 显示全部楼层
Beita 发表于 2022-3-21 16:10
请问这个问题最后怎么解决的呢?

太久了,
当年好像是找了个笨办法,
自己增加一个标志位
发送时先检查这标志位,如果标志位为0,设置这标志位并发送,
DMA传输完成中断后恢复
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 05:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表