野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 802|回复: 1

STM32H750XBH6 ADC采集模拟信号使用DMA输出

[复制链接]
发表于 2023-9-12 16:38:44 | 显示全部楼层 |阅读模式

请教一下大家,为什么使用串口输出一直是0啊??



#include "adc.h"

#include "delay.h"

DMA_HandleTypeDef g_DMA_Handler; //DMA句柄
ADC_HandleTypeDef g_ADC1_Handler;//ADC句柄

u8 g_adc_dma_sta = 0;      /* DMA传输状态标志, 0: 未完成 1: 已完成 */

//初始化ADC
//ch: ADC_channels
//通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void adc_dma_init(uint32_t mar)
//void adc_dma_init(void)
{

    GPIO_InitTypeDef gpio_instruct;
    ADC_ChannelConfTypeDef adc_channel_conf = {0};

    __HAL_RCC_ADC12_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();                //开启GPIOA时钟
    __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择 选择per_ck==64MHz

    __HAL_RCC_DMA1_CLK_ENABLE();

    /* 初始化DMA */
    g_DMA_Handler.Instance = DMA1_Stream7;                            /* 数据流选择 */
    g_DMA_Handler.Init.Request = DMA_REQUEST_ADC1;                    /* DMA请求ADC */
    g_DMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;              /* 外设到存储器 */
    g_DMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                  /* 外设非增量模式 */
    g_DMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                      /* 存储器增量模式 */
    g_DMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* 外设数据长度:16位 */
    g_DMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;    /* 存储器数据长度:16位 */
    g_DMA_Handler.Init.Mode = DMA_NORMAL;                             /* 普通模式 */
    g_DMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;                /* 中等优先级 */
    g_DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
//    g_DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
//    g_DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 /* 存储器突发单次传输 */
//    g_DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              /* 外设突发单次传输 */
    HAL_DMA_Init(&g_DMA_Handler);

    __HAL_LINKDMA(&g_ADC1_Handler, DMA_Handle, g_DMA_Handler);

    /* 初始化ADC */
    g_ADC1_Handler.Instance=ADC1;
    g_ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;            //4分频,ADCCLK=PER_CK/4=64/4=16MHZ
    g_ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;                      //12位模式
    g_ADC1_Handler.Init.ScanConvMode=DISABLE;                               //非扫描模式
    g_ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV;                   //关闭EOC中断
    g_ADC1_Handler.Init.LowPowerAutoWait=DISABLE;                           //自动低功耗关闭
    g_ADC1_Handler.Init.ContinuousConvMode=DISABLE;                          //开启连续转换
    g_ADC1_Handler.Init.NbrOfConversion=1;                                  //1个转换在规则序列中 也就是只转换规则序列1
    g_ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;                      //禁止不连续采样模式
    g_ADC1_Handler.Init.NbrOfDiscConversion=0;                              //不连续采样通道数为0
    g_ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;                //软件触发
    g_ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;      //使用软件触发
    g_ADC1_Handler.Init.BoostMode=ENABLE;                                          //BOOT模式关闭
    g_ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;                          //有新的数据的之后直接覆盖掉旧数据
    g_ADC1_Handler.Init.OversamplingMode=DISABLE;                                  //过采样关闭
    g_ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DR;  //规则通道的数据选择DMA单次传输ADC数据模式
    HAL_ADC_Init(&g_ADC1_Handler);                                                 //初始化

    HAL_ADCEx_Calibration_Start(&g_ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准

    gpio_instruct.Pin=GPIO_PIN_5;            //PA5
    gpio_instruct.Mode=GPIO_MODE_ANALOG;     //模拟
    gpio_instruct.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOA,&gpio_instruct);

    /* 配置ADC相关通道的相关函数 */
    adc_channel_conf.Channel=ADC_CHANNEL_19;                         //通道
    adc_channel_conf.Rank=ADC_REGULAR_RANK_1;                       //1个序列
    adc_channel_conf.SamplingTime=ADC_SAMPLETIME_387CYCLES_5;       //采样时间
    adc_channel_conf.SingleDiff=ADC_SINGLE_ENDED;                   //单边采集
    adc_channel_conf.OffsetNumber=ADC_OFFSET_NONE;
    adc_channel_conf.Offset=0;   
    HAL_ADC_ConfigChannel(&g_ADC1_Handler,&adc_channel_conf);        //通道配置

    /* 配置DMA数据流请求中断优先级 */
    HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 3, 3);
    HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);

    HAL_DMA_Start_IT(&g_DMA_Handler, (uint32_t)&ADC1->DR, mar, 0 );  /* 启动DMA 开启传输,完成中断 */
    HAL_ADC_Start_DMA(&g_ADC1_Handler, &mar, 0);                     /* 触发ADC转换 使用DMA传输数据 */

}

void adc_dma_enable(uint16_t ndtr)
{
    ADC1->CR &= ~(1 << 0);         /* 先关闭ADC */

//    DMA1_Stream7->CR &= ~(1 << 0);   /* 关闭DMA传输 */
    __HAL_DMA_DISABLE(&g_DMA_Handler);
    while (DMA1_Stream7->CR & 0X1);  /* 确保DMA可以被设置 */
    DMA1_Stream7->NDTR = ndtr;       /* 要传输的数据项数目 */
    __HAL_DMA_ENABLE(&g_DMA_Handler);
//    DMA1_Stream7->CR |= 1 << 0;      /* 开启DMA传输 */

    ADC_ENABLE(&g_ADC1_Handler);
//    ADC1->CR |= 1 << 0;            /* 重新启动ADC */
    ADC1->CR |= 1 << 2;            /* 启动常规转换通道 */
}

void DMA1_Stream7_IRQHandler(void)
{
    if (__HAL_DMA_GET_FLAG(&g_DMA_Handler, DMA_FLAG_TCIF3_7))
    {
        g_adc_dma_sta = 1;          /* 标记DMA传输完成 */
        __HAL_DMA_CLEAR_FLAG(&g_DMA_Handler, DMA_FLAG_TCIF3_7);    /* 清除DMA1 数据流7 传输完成中断 */
    }
}

主函数代码:
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "lcd.h"  
#include "sdram.h"
#include "ltdc.h"
#include "adc.h"

#define ADC_DMA_BUF_SIZE      2          /* ADC DMA采集 BUF大小 */
u16 g_adc_dma_buf[ADC_DMA_BUF_SIZE];

extern u8 g_adc_dma_sta;      /* DMA传输状态标志, 0: 未完成 1: 已完成 */

int main(void)
{
    uint16_t i;
    float temp;

    Cache_Enable();                 //打开L1-Cache
    HAL_Init();                     //初始化HAL库
    Stm32_Clock_Init(160,5,2,4);    //设置时钟,400Mhz
    delay_init(400);                //延时初始化
    uart_init(115200);              //串口初始化
    LED_Init();                     //初始化LED时钟
    KEY_Init();
    SDRAM_Init();                   //初始化SDRAM
    LCD_Init();                     //初始化LCD

    adc_dma_init((uint32_t)&g_adc_dma_buf);    /* 初始化ADC DMA采集 */


    adc_dma_enable(ADC_DMA_BUF_SIZE);         /* 启动ADC DMA采集 */

    while(1)
    {

        if (g_adc_dma_sta == 1)
        {
            /* 清D Cache */
            SCB_InvalidateDCache();

            for (i = 0;i <ADC_DMA_BUF_SIZE;i++)
            {
                printf("V1=%0.3f v\r\n",((float)g_adc_dma_buf)*(3.3 / 4096));
            }

            g_adc_dma_sta = 0;                  /* 清除DMA采集完成状态标志 */
            adc_dma_enable(ADC_DMA_BUF_SIZE);   /* 启动下一次ADC DMA采集 */
        }

//        LED0_Toggle;
//        delay_ms(100);

    }
}
回复

使用道具 举报

发表于 2023-11-1 18:40:15 | 显示全部楼层
printf("V1=%0.3f v\r\n",((float)g_adc_dma_buf)*(3.3 / 4096));

想过3.3/4096的值是多少吗?想想。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-7-24 21:06 , Processed in 0.094872 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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