打印
[应用相关]

DMA从内存搬运数据到I2C

[复制链接]
448|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
598330983|  楼主 | 2023-4-26 22:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "stm32f4xx_hal.h"

I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_tx;

/* 定义数据缓存区 */
uint8_t data_buf[10] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A};

int main(void)
{
  /* STM32初始化 */
  HAL_Init();

  /* 配置I2C1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

  /* 配置I2C1的DMA传输 */
  hdma_i2c1_tx.Instance = DMA1_Stream7;
  hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1;
  hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_i2c1_tx.Init.Mode = DMA_NORMAL;
  hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_HIGH;
  hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_LINKDMA(&hi2c1, hdmatx, hdma_i2c1_tx);

  /* 启动I2C1的DMA传输 */
  if (HAL_I2C_Mem_Write_DMA(&hi2c1, 0xA0, 0x00, I2C_MEMADD_SIZE_8BIT, data_buf, 10) != HAL_OK)
  {
    Error_Handler();
  }

  /* 死循环 */
  while (1)
  {
  }
}

/* 错误处理函数 */
void Error_Handler(void)
{
  while (1)
  {
  }
}

/* DMA中断处理函数 */
void DMA1_Stream7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_i2c1_tx);
}


使用特权

评论回复
沙发
598330983|  楼主 | 2023-4-26 22:03 | 只看该作者
以上代码中,首先初始化了I2C1接口和DMA传输通道。然后将数据缓存区data_buf中的数据通过DMA传输到I2C1的0xA0地址中,传输长度为10字节。传输的过程使用了HAL库提供的HAL_I2C_Mem_Write_DMA函数,该函数会将数据缓存区的数据通过DMA传输到指定地址中。

在初始化DMA传输通道之后,使用__HAL_LINKDMA宏将I2C1接口的发送DMA通道和DMA传输通道关联起来。然后,调用HAL_I2C_Mem_Write_DMA函数启动I2C1的DMA传输。

使用特权

评论回复
板凳
598330983|  楼主 | 2023-4-26 22:04 | 只看该作者
最后,在代码中还提供了一个错误处理函数Error_Handler,以及一个DMA中断处理函数DMA1_Stream7_IRQHandler。当DMA传输完成或出现错误时,会触发DMA中断,该中断处理函数会被调用。在中断处理函数中调用HAL_DMA_IRQHandler函数处理中断。

注意,在使用DMA传输时,需要确保数据缓存区的空间和传输长度的大小是足够的,否则会导致数据溢出。同时,需要根据具体的硬件平台和需求设置DMA传输通道的参数,以确保传输的正确性和稳定性。

使用特权

评论回复
地板
童雨竹| | 2024-6-11 08:02 | 只看该作者

让PCB顶层和底层一样,将它们通过一些过孔(或通孔)连接

使用特权

评论回复
5
Wordsworth| | 2024-6-11 09:05 | 只看该作者

孔璧里头必须经过电镀

使用特权

评论回复
6
Clyde011| | 2024-6-11 10:08 | 只看该作者

需要将阻焊漆(阻焊油墨)覆盖在最外层的PCB设计布线上

使用特权

评论回复
7
公羊子丹| | 2024-6-11 11:01 | 只看该作者

电源中都有一个交流电压最大的节点

使用特权

评论回复
8
万图| | 2024-6-11 12:04 | 只看该作者

做多层板可将做好的两块双面板用特制的粘合剂“压合”起来

使用特权

评论回复
9
Uriah| | 2024-6-11 13:07 | 只看该作者

清除与电镀动作都会在化学过程中完成

使用特权

评论回复
10
帛灿灿| | 2024-6-11 15:03 | 只看该作者

将整个表面铺上一层薄薄的铜箔,并且把多余的部份给消除

使用特权

评论回复
11
Bblythe| | 2024-6-11 16:06 | 只看该作者

在开始电镀之前,必须先清掉孔内的杂物。

使用特权

评论回复
12
周半梅| | 2024-6-11 18:02 | 只看该作者

电容工作在额定的纹波电流下

使用特权

评论回复
13
Pulitzer| | 2024-6-11 19:05 | 只看该作者

在孔璧内部作金属处理后,可以让内部的各层线路能够彼此连接。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

245

主题

5383

帖子

22

粉丝