[CH582M入门第三步]ADC配置

本文介绍了STM32单片机的ADC配置,包括单通道配置和结合DMA的使用,适合初学者入门。通过电阻分压电路进行电压采样,并通过MounRiver Studio串口打印浮点数展示ADC转换结果。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


一、ADC是什么?

ADC名为模数转换,也是单片机最基础的东西。尤其是做电压电流采样这样项目。

二、ADC配置

1.单通道ADC配置

ADC.h

#ifndef __ADC_H
#define __ADC_H
#include "CH58x_common.h"
#include "USART.h"

#define ADC_IN0 GPIO_Pin_4


void ADC_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga);
uint16_t ADC_OUTPUT_Dat(void);
#endif

ADC.c

#include "ADC.h"

signed short RoughCalib_Value = 0; // ADC粗调偏差值
uint16_t abcBuff[8];
uint16_t adc_sum;
uint16_t adc_average;
static void ADC_GPIO_Init(void){

    GPIOA_ModeCfg(ADC_IN0, GPIO_ModeIN_Floating);

}

void ADC_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga){ //单通道采样
    ADC_GPIO_Init();
    ADC_ExtSingleChSampInit(sp, ga);

    RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
    printf("RoughCalib_Value =%d \n", RoughCalib_Value);

    ADC_ChannelCfg(0);
}

uint16_t ADC_OUTPUT_Dat(void){
    ADC_ChannelCfg(0);
    adc_sum=0;
       for(int i=0;i<8;i++){
           RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
           abcBuff[i] = ADC_ExcutSingleConver()+ RoughCalib_Value; // 连续采样20次
           adc_sum+=abcBuff[i];
       }
       adc_average=adc_sum/8;

       printf("%d\n", adc_average); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象
       printf("RoughCalib_Value->%d\n", RoughCalib_Value);

    return adc_average;

}

手上没有什么ADC的模块,直接两个电阻搞一个分压电路。
在这里插入图片描述
在这里插入图片描述

2.ADC+DMA

ADC.h

#ifndef __ADC_H
#define __ADC_H
#include "CH58x_common.h"
#include "USART.h"

#define ADC_IN0 GPIO_Pin_4


void ADC_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga);
uint16_t ADC_OUTPUT_Dat(void);

void ADC_DMA_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga);
uint16_t ADC_DMA_OUTPUT_Dat(void);

#endif

ADC.c

#include "ADC.h"

signed short RoughCalib_Value = 0; // ADC粗调偏差值
uint16_t abcBuff[8];
uint16_t adc_sum;
uint16_t adc_average;


volatile uint8_t DMA_end = 0;
volatile uint8_t adclen;
static void ADC_GPIO_Init(void){

    GPIOA_ModeCfg(ADC_IN0, GPIO_ModeIN_Floating);

}

void ADC_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga){ //单通道采样
    ADC_GPIO_Init();
    ADC_ExtSingleChSampInit(sp, ga);

    RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
    printf("RoughCalib_Value =%d \n", RoughCalib_Value);

    ADC_ChannelCfg(0);
}

void ADC_DMA_Init(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga){
    /* DMA单通道采样:选择adc通道0做采样,对应 PA4引脚 */
     ADC_GPIO_Init();
     ADC_ExtSingleChSampInit(sp, ga);
     ADC_ChannelCfg(0);
     ADC_AutoConverCycle(192); // 采样周期 为 (256-192)*16个系统时钟
     ADC_DMACfg(ENABLE, (uint16_t)(uint32_t)&abcBuff[0], (uint16_t)(uint32_t)&abcBuff[40], ADC_Mode_LOOP);
     PFIC_EnableIRQ(ADC_IRQn);
     ADC_StartDMA();
     while(!DMA_end);
     DMA_end = 0;
     printf("ADC DMA end \n");
//     for(i = 0; i < 40; i++)
//     {
//         PRINT("%d \n", abcBuff[i]);
//     }

}
uint16_t ADC_DMA_OUTPUT_Dat(void){

       ADC_StartDMA();
       while(!DMA_end);
       DMA_end = 0;
       printf("%d \n", abcBuff[0]);
   return abcBuff[0];

}
/*********************************************************************
 * @fn      ADC_IRQHandler
 *
 * @brief   ADC中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void ADC_IRQHandler(void) //adc中断服务程序
{
    if(ADC_GetDMAStatus())
    {
        ADC_ClearDMAFlag();
        ADC_StopDMA();
        R16_ADC_DMA_BEG = (uint16_t)(uint32_t)&abcBuff[0];
        DMA_end = 1;
    }
//    if(ADC_GetITStatus()) //ADC中断
//    {
//        ADC_ClearITFlag();
//        if(adclen < 20)
//        {
//            abcBuff[adclen] = ADC_ReadConverValue();
//            ADC_StartUp(); // 作用清除中断标志并开启新一轮采样
//        }
//
//        adclen++;
//    }
}


uint16_t ADC_OUTPUT_Dat(void){
    ADC_ChannelCfg(0);
    adc_sum=0;
       for(int i=0;i<8;i++){
           RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
           abcBuff[i] = ADC_ExcutSingleConver()+ RoughCalib_Value; // 连续采样20次
           adc_sum+=abcBuff[i];
       }
       adc_average=adc_sum/8;

       printf("%d\n", adc_average); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象
       printf("RoughCalib_Value->%d\n", RoughCalib_Value);

    return adc_average;

}

最后是MounRiver Studio软件串口打印浮点数,看下图
在这里插入图片描述

最终效果图:
在这里插入图片描述


总结

这就是CH582M的ADC的一些基本配置。对比STM32来说配置还是很简单的

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单片有机机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值