打印
[AT32F421]

ADC 用5个通道DMA采样正常,为什么增加到7个的时候数据就错误

[复制链接]
509|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AD, ADC, DM, DMA, dc
这是数据保存地址
u16 adcvalue[7][6] = {0};  //ADC DMA保存地址
#define DMA1_CHANNEL1_BUFFER_SIZE        42

//初始化DMA
    wk_dma_channel_config(DMA1_CHANNEL1,
                          (uint32_t)&ADC1->odt,
                          (uint32_t)adcvalue,
                          DMA1_CHANNEL1_BUFFER_SIZE);
    dma_channel_enable(DMA1_CHANNEL1, TRUE);


//ADC初始化
void wk_adc1_init(void)
{
    /* add user code begin adc1_init 0 */

    /* add user code end adc1_init 0 */

    gpio_init_type gpio_init_struct;
    adc_base_config_type adc_base_struct;

    gpio_default_para_init(&gpio_init_struct);

    /* add user code begin adc1_init 1 */

    /* add user code end adc1_init 1 */

    /* gpio--------------------------------------------------------------------*/
    /* configure the IN0 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_0;
    gpio_init(GPIOA, &gpio_init_struct);

    /* configure the IN1 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_1;
    gpio_init(GPIOA, &gpio_init_struct);

    /* configure the IN2 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_2;
    gpio_init(GPIOA, &gpio_init_struct);

    /* configure the IN3 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_3;
    gpio_init(GPIOA, &gpio_init_struct);

    /* configure the IN4 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_4;
    gpio_init(GPIOA, &gpio_init_struct);

    /* configure the IN8 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_0;
    gpio_init(GPIOB, &gpio_init_struct);


    /* configure the IN9 pin */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_1;
    gpio_init(GPIOB, &gpio_init_struct);


    crm_adc_clock_div_set(CRM_ADC_DIV_6);

    /* adc_settings----------------------------------------------------------- */
    adc_base_default_para_init(&adc_base_struct);
    adc_base_struct.sequence_mode = TRUE;
    adc_base_struct.repeat_mode = TRUE;
    adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
    adc_base_struct.ordinary_channel_length = 7;
    adc_base_config(ADC1, &adc_base_struct);

    /* adc_ordinary_conversionmode-------------------------------------------- */
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_1, 2, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2, 3, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_3, 4, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_4, 5, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_8, 6, ADC_SAMPLETIME_71_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_9, 7, ADC_SAMPLETIME_71_5);

    adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

    adc_ordinary_part_mode_enable(ADC1, FALSE);

    adc_dma_mode_enable(ADC1, TRUE);
    /**
     * Users need to configure ADC1 interrupt functions according to the actual application.
     * 1. Call the below function to enable the corresponding ADC1 interrupt.
     *     --adc_interrupt_enable(...)
     * 2. Add the user's interrupt handler code into the below function in the at32f421_int.c file.
     *     --void ADC1_CMP_IRQHandler(void)
     */

    /* add user code begin adc1_init 2 */

    /* add user code end adc1_init 2 */

    adc_enable(ADC1, TRUE);

    /* adc calibration-------------------------------------------------------- */
    adc_calibration_init(ADC1);
    while(adc_calibration_init_status_get(ADC1));
    adc_calibration_start(ADC1);
    while(adc_calibration_status_get(ADC1));

    /* add user code begin adc1_init 3 */

    /* add user code end adc1_init 3 */
}


使用特权

评论回复
评论
xch 2025-7-15 23:28 回复TA
u16 adcvalue[7][6] 这个二维数组在地址空间的排列顺序是adcvalue[0][0],[0][1],[0][2]...[0][5],[1][0],[1][1],[1][2]...[6][7]. 7个通道ADC 结果用DMA 填入这个数组结果很难看。 
沙发
muyichuan2012| | 2025-7-14 15:51 | 只看该作者
AT32F421 DMA只有5个通道

380076874b71879cd3.png (75.79 KB )

380076874b71879cd3.png

使用特权

评论回复
评论
ArterySW 2025-7-14 19:26 回复TA
@xch :你说的很差的设计指的是ADC只能固定使用DMA1_CHANNEL1搬运数据,不能映射到其他DMA通道吗? 这个是架构限定,如果你需要支持通道随意映射的话,建议选用F425或F423等型号。 
xch 2025-7-14 17:42 回复TA
421 的 adc 仅需要一个DMA通道。 其他通道多余。 421 的ADC 仅有一个DMA触发信号,很差的设计。 
板凳
xch| | 2025-7-14 17:45 | 只看该作者
怎么个错法?

使用特权

评论回复
地板
ArterySW| | 2025-7-14 19:21 | 只看该作者
帖中源码实测数据正常。
但是由于buffer定义的adcvalue[7][6] ,所以ADC一个完整的序列的转换结果存储在adcvalue[0][0] ~adcvalue[1][0],你说的数据错误是否是看到序列与数组维数没按照维度对应?——如果是此点问题的话,直接将数组修改为adcvalue[6][7] 即可

使用特权

评论回复
5
stm32xiaobai| | 2025-7-15 17:06 | 只看该作者
看手册看一下对应芯片DMA支持的通道数,还有就是所有配置完了之后再启动DMA。不然容易数据没对准,尤其是通道多的情况下。比如通道一对到通道二的数组里去了。

使用特权

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

本版积分规则

1

主题

17

帖子

0

粉丝