野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 428|回复: 14

STM32 H750 ADC采样

[复制链接]
发表于 2023-9-20 15:39:48 | 显示全部楼层 |阅读模式
各位大佬:请教一下,我使用H750采集模拟信号,开始设置预分频为4 就是ADC时钟频率为16MHz,可以正常采集模拟信号,但是我把预分频设置为2,即ADC时钟频率为32Mhz,这个时候,ADC采集0v电压的时候,串口打印出的是1v左右,不是正常的0v,请问这是由什么原因导致的,应该怎么解决?

回复

使用道具 举报

发表于 2023-9-21 13:52:15 | 显示全部楼层
我试了一下ADC时钟频率为16MHz和32MHz没有出现你说的问题,要不你把代码放出来
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-21 15:05:02 | 显示全部楼层
MO12138 发表于 2023-9-21 13:52
我试了一下ADC时钟频率为16MHz和32MHz没有出现你说的问题,要不你把代码放出来 ...

这是我的代码
#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 DMA
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_DMA1_CLK_ENABLE();
    __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择 选择per_ck==64MHz
   
    /* 初始化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_10B;                      //10位模式
    g_ADC1_Handler.Init.ScanConvMode=ADC_SCAN_DISABLE;                      //非扫描模式
    g_ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV;                   //关闭EOC中断
    g_ADC1_Handler.Init.LowPowerAutoWait=DISABLE;                           //自动低功耗关闭
    g_ADC1_Handler.Init.ContinuousConvMode=ENABLE;                          //开启连续转换
    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=DISABLE;                                          //BOOT模式关闭
    g_ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN;                          //有新的数据的之后直接覆盖掉旧数据
    g_ADC1_Handler.Init.OversamplingMode=DISABLE;                                  //过采样关闭
    g_ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_ONESHOT;  //规则通道的数据选择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_2CYCLES_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      200          /* 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;
   
    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_init();
   

    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("%0.3f v\r\n",((float)g_adc_dma_buf)*(3.3 / 1024));
            }
            
            g_adc_dma_sta = 0;                  /* 清除DMA采集完成状态标志 */
            adc_dma_enable(ADC_DMA_BUF_SIZE);   /* 启动下一次ADC DMA采集 */
        }
//        temp = adc_get_result();
//        printf("V1=%0.3f v\r\n",temp*(3.3 / 4096));

        LED0_Toggle;
        delay_ms(100);

    }
}
回复 支持 反对

使用道具 举报

发表于 2023-9-21 15:51:00 | 显示全部楼层
上传整个压缩包
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-21 16:20:35 | 显示全部楼层
MO12138 发表于 2023-9-21 15:51
上传整个压缩包

好的,已上传

ADC实验.zip

1.58 MB, 下载次数: 4

回复 支持 反对

使用道具 举报

发表于 2023-9-22 09:33:56 | 显示全部楼层
用的那个板子?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-22 11:27:00 | 显示全部楼层
MO12138 发表于 2023-9-22 09:33
用的那个板子?

STM32H750XBH6
回复 支持 反对

使用道具 举报

发表于 2023-9-22 15:27:59 | 显示全部楼层
正点原子的吗,我一下载就锁芯片
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-23 10:38:54 | 显示全部楼层
MO12138 发表于 2023-9-22 15:27
正点原子的吗,我一下载就锁芯片

对,正点原子的
回复 支持 反对

使用道具 举报

发表于 2023-9-23 23:46:50 | 显示全部楼层

你就说你是不是害人精吧
回复 支持 反对

使用道具 举报

发表于 2023-9-23 23:48:15 | 显示全部楼层
MO12138 发表于 2023-9-22 15:27
正点原子的吗,我一下载就锁芯片

这种人,拒绝再搭理就行了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-9-24 15:36:39 | 显示全部楼层
coxswain 发表于 2023-9-23 23:48
这种人,拒绝再搭理就行了

????怎么了,买正点原子的板子不能来这边提问吗?
回复 支持 反对

使用道具 举报

发表于 2023-9-25 08:50:01 | 显示全部楼层
coxswain 发表于 2023-9-23 23:48
这种人,拒绝再搭理就行了

没事,不至于
回复 支持 反对

使用道具 举报

发表于 2023-9-25 15:47:03 | 显示全部楼层
coxswain 发表于 2023-9-23 23:46
你就说你是不是害人精吧

没事没事,锁芯片是小事
回复 支持 反对

使用道具 举报

发表于 2023-9-25 15:48:15 | 显示全部楼层
研究生不会研究 发表于 2023-9-24 15:36
????怎么了,买正点原子的板子不能来这边提问吗?

没事,随便提问,锁芯片小事来的
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-30 05:00 , Processed in 0.168715 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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