硬汉嵌入式论坛

 找回密码
 立即注册
查看: 877|回复: 10
收起左侧

[STM32H7] H750 ADC DMA采集数据长度减半

[复制链接]

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
发表于 2024-6-25 15:33:12 | 显示全部楼层 |阅读模式
使用DMA来传输ADC数据,出现两个数据合并,同时造成后面的数据是0的问题。考虑到后面想用W5500传输,所以改成ADC为8位的,但是这个缓存区只能是32位的,想请问大家有什么好办法?

数据不对齐

数据不对齐


部分函数如下:
uint32_t g_adc3_dma_data1[ADC_DATA_LENGTH];//定义adc3采集数据存放数组

HAL_ADC_Start_DMA(&hadc3, g_adc3_dma_data1,ADC_DATA_LENGTH);//ADC的dma开始采集
有一个问题就是这个函数里面的变量只能是32的,

if(g_adc3_dma_complete_flag == 1)//采集数据没完成,采集完成后再发送 111
                        {
                                for(i=0;i<2048;i++)
                                {
                                       
                                        printf("%d\r\n",g_adc3_dma_data1&0x0000ffff);取低16位
                       
                                }
                                g_adc3_dma_complete_flag = 0;               
                                memset(g_adc3_dma_data1,0,ADC_DATA_LENGTH);//清除数据
                                HAL_ADC_Start_DMA(&hadc3, g_adc3_dma_data1,ADC_DATA_LENGTH);//ADC的dma开始采集
                        }
  }

这是DMA的配置:
    hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

这是ADC的配置:
  hadc3.Instance = ADC3;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = ENABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
  hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;















回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-6-25 16:03:17 | 显示全部楼层
uint32_t g_adc3_dma_data1[ADC_DATA_LENGTH]; 改成 uint16_t g_adc3_dma_data1[ADC_DATA_LENGTH];

因为你的是16bit的ADC配置。然后注意MPU/Cache问题,可以阶段可以直接Disable Dcashe试试
回复

使用道具 举报

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
 楼主| 发表于 2024-6-25 16:08:48 | 显示全部楼层
eric2013 发表于 2024-6-25 16:03
uint32_t g_adc3_dma_data1[ADC_DATA_LENGTH]; 改成 uint16_t g_adc3_dma_data1[ADC_DATA_LENGTH];

因为 ...

错误.png MPU和cache我都没有开启,如果改成16的话,HAL_ADC_Start_DMA这个函数编译报错,要强制转换成uint32,ADC精度我改成8bit也是一样的问题
回复

使用道具 举报

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
 楼主| 发表于 2024-6-25 16:22:32 | 显示全部楼层
eric2013 发表于 2024-6-25 16:03
uint32_t g_adc3_dma_data1[ADC_DATA_LENGTH]; 改成 uint16_t g_adc3_dma_data1[ADC_DATA_LENGTH];

因为 ...

我没有开启MPU和 Dcache ,然后那个aDC的精度我就算改成了8bit也是一样,主要是dma传输的地址增量还有那个缓存区设置,我改成uint16_t的话,就会编译不通过,因为HAL_ADC_Start_DMA这个函数里面地址的变量要求是32的, 错误.png
回复

使用道具 举报

85

主题

781

回帖

1036

积分

至尊会员

积分
1036
发表于 2024-6-25 22:08:44 | 显示全部楼层
不吃鱼的猫大人 发表于 2024-6-25 16:22
我没有开启MPU和 Dcache ,然后那个aDC的精度我就算改成了8bit也是一样,主要是dma传输的地址增量还有那 ...

有没有可能DMA那个要配置成word
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-6-26 08:43:16 | 显示全部楼层
不吃鱼的猫大人 发表于 2024-6-25 16:22
我没有开启MPU和 Dcache ,然后那个aDC的精度我就算改成了8bit也是一样,主要是dma传输的地址增量还有那 ...

DMA带宽配置16bit,ADC配置16bit分辨率,这种无法正常采集,程序中配置肯定是有点问题的。
回复

使用道具 举报

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
 楼主| 发表于 2024-6-26 11:48:49 | 显示全部楼层
庄永 发表于 2024-6-25 22:08
有没有可能DMA那个要配置成word

嗯 你说的对,就是你说的DMA传输地址递增那个配置成WORD,    hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
    hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

    hdma_adc3.Init.Mode = DMA_NORMAL;
然后缓冲数组还是定义为Uint32_t,这样就没问题了,但是要是我再把这个缓存区的数据利用以太网发送的话,强制转为Uint8的话可以吗?
回复

使用道具 举报

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
 楼主| 发表于 2024-6-26 12:00:33 | 显示全部楼层
eric2013 发表于 2024-6-26 08:43
DMA带宽配置16bit,ADC配置16bit分辨率,这种无法正常采集,程序中配置肯定是有点问题的。

可以采集,就是HAL_ADC_START_DMA那个函数里面的参数必须得强制转为uint32位的,HAL_ADC_Start_DMA(&hadc3,(uint32_t *)g_adc3_dma_data1,ADC_DATA_LENGTH);//ADC的dma开始采集
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-6-27 09:01:25 | 显示全部楼层
不吃鱼的猫大人 发表于 2024-6-26 12:00
可以采集,就是HAL_ADC_START_DMA那个函数里面的参数必须得强制转为uint32位的,HAL_ADC_Start_DMA(&hadc ...

我想表达的意思是说,你的ADC配置的16bit的,你的数据DAM带宽和数据缓冲也要配置成16bit的。这样才合理。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-6-27 09:02:57 | 显示全部楼层
不吃鱼的猫大人 发表于 2024-6-26 11:48
嗯 你说的对,就是你说的DMA传输地址递增那个配置成WORD,    hdma_adc3.Init.Request = DMA_REQUEST_ADC ...

你的ADC是16bit的,你的DMA每次触发传输32bit,这样操作不好。无谓的多占用一半带宽。
回复

使用道具 举报

18

主题

92

回帖

146

积分

初级会员

积分
146
QQ
 楼主| 发表于 2024-6-27 10:37:52 | 显示全部楼层
eric2013 发表于 2024-6-27 09:02
你的ADC是16bit的,你的DMA每次触发传输32bit,这样操作不好。无谓的多占用一半带宽。

谢谢,明白了
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-29 06:07 , Processed in 0.354196 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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