打印
[PIC®/AVR®/dsPIC®产品]

ATMEGA4809的ADC在MCC下的使用方法

[复制链接]
11054|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gaoyang9992006 于 2025-1-21 14:36 编辑

本节内容需要使用uart打印信息,关于uart的使用参考下面链接的帖子
https://bbs.21ic.com/icview-3427358-1-1.html
新建工程项目

关于IO的使用为板载LED和按钮,IO配置如下

上述配置好随时可以用于测试和指示灯。也可以巩固之前几个帖子中的内容
接下面启用ADC

时钟选择
系统时钟默认是内部高速时钟,可通过配置位设置为16MHz或20MHz,设置为16MHz可以方便分频出整数主频时钟

当时钟配置到16MHz时候,串口的波特率设置在9600就没有误差了。

开发板的引脚图上给的有ADC使用的引脚,实际可选的更多

我们先用默认的这个AIN0

配置上采用默认的配置,先进行测试

ADC的结构如下图所示

具备可选的3个参考电压
内部参考电压貌似可以配置

不过在MCC暂时没看到配置位置
#include "mcc_generated_files/system/system.h"
#include"mcc_generated_files/timer/delay.h"
/*
    Main application
*/
unsigned char i=0;
unsigned char sw_flag=0;

void sw_int_handler(void)
{
    sw_flag++;
}
int main(void)
{
    SYSTEM_Initialize();
    SW_SetInterruptHandler(sw_int_handler);
    printf("%02d Hello:%02d\n",i,sw_flag);
    Enable_global_interrupt();
    while(1)
    {
        i++;
        if(i>=100) i=0;
        DELAY_milliseconds(1000);
        ADC0_ConversionStart();
        YELLOW_LED_Toggle();
        if(sw_flag>0)
        {
            printf("%02d Hello:%02d\r\n",i,sw_flag);
            sw_flag=0;
        }
        else
        {
           // if(ADC0_IsConversionDone())
            {
                printf("ADC AIN0:%d----%x\r\n",ADC0_ConversionResultGet(),ADC0_ConversionResultGet());
            }
        }
    }   
}
编译测试,效果良好,修改为VDD作为参考电压

测试效果
经过查阅手册与生成的MCC文件,发现了配置内部参考电压的方法

注意到在MCC生成的库函数中包含了设置内部参考电压的方法的初始化函数
int8_t VREF_Initialize(void)
{
    // ADC0REFSEL Voltage reference at 0.55V; AC0REFSEL Voltage reference at 0.55V;
    VREF.CTRLA = 0x0;
   
    // ADC0REFEN disabled; AC0REFEN disabled;
    VREF.CTRLB = 0x0;


        
        return 0;
}
只需要修改该函数即可实现内部参考电压的修改
与该设置相关的枚举变量在iom4809.h头文件中
/* Voltage reference */
typedef struct VREF_struct
{
    register8_t CTRLA;  /* Control A */
    register8_t CTRLB;  /* Control B */
} VREF_t;

/* AC0 reference select */
typedef enum VREF_AC0REFSEL_enum
{
    VREF_AC0REFSEL_0V55_gc = (0x00<<0),  /* Voltage reference at 0.55V */
    VREF_AC0REFSEL_1V1_gc = (0x01<<0),  /* Voltage reference at 1.1V */
    VREF_AC0REFSEL_2V5_gc = (0x02<<0),  /* Voltage reference at 2.5V */
    VREF_AC0REFSEL_4V34_gc = (0x03<<0),  /* Voltage reference at 4.34V */
    VREF_AC0REFSEL_1V5_gc = (0x04<<0),  /* Voltage reference at 1.5V */
    VREF_AC0REFSEL_AVDD_gc = (0x07<<0)  /* AVDD */
} VREF_AC0REFSEL_t;

/* ADC0 reference select */
typedef enum VREF_ADC0REFSEL_enum
{
    VREF_ADC0REFSEL_0V55_gc = (0x00<<4),  /* Voltage reference at 0.55V */
    VREF_ADC0REFSEL_1V1_gc = (0x01<<4),  /* Voltage reference at 1.1V */
    VREF_ADC0REFSEL_2V5_gc = (0x02<<4),  /* Voltage reference at 2.5V */
    VREF_ADC0REFSEL_4V34_gc = (0x03<<4),  /* Voltage reference at 4.34V */
    VREF_ADC0REFSEL_1V5_gc = (0x04<<4)  /* Voltage reference at 1.5V */
} VREF_ADC0REFSEL_t;
既可以使用上述枚举变量来修改内部参考电压

使用特权

评论回复
沙发
小灵通2018| | 2025-1-25 16:49 | 只看该作者
第一次遇到内部参考电压可以配置的,真是太棒了。

使用特权

评论回复
板凳
598330983| | 2025-1-25 16:50 | 只看该作者
很好奇,这个参考电压可以在运行中修改吗?比如测量不到参考电压的一半,为了提高测量精度,降低参考电压?

使用特权

评论回复
地板
antusheng| | 2025-1-25 16:51 | 只看该作者
598330983 发表于 2025-1-25 16:50
很好奇,这个参考电压可以在运行中修改吗?比如测量不到参考电压的一半,为了提高测量精度,降低参考电压? ...

没说不可以,应该就是可以,如果不可以修改的,一般都是在配置位定义的,程序里的都可以改动

使用特权

评论回复
5
wanduzi| | 2025-1-25 16:52 | 只看该作者
一般也有这么应用,那个4.34V的电压需要供电5V才可以吧?

使用特权

评论回复
6
wanduzi| | 2025-1-25 16:53 | 只看该作者
好像每个功能都设置了2个控制寄存器字节。

使用特权

评论回复
7
幸福小强| | 2025-1-25 16:59 | 只看该作者
内部时钟还可配置速度。

使用特权

评论回复
8
稳稳の幸福| | 2025-1-26 17:57 | 只看该作者
支持中断触发吗?

使用特权

评论回复
9
598330983| | 2025-1-26 18:57 | 只看该作者
antusheng 发表于 2025-1-25 16:51
没说不可以,应该就是可以,如果不可以修改的,一般都是在配置位定义的,程序里的都可以改动 ...

嗯,是的,这样可以提高测量精度。

使用特权

评论回复
10
598330983| | 2025-1-26 18:58 | 只看该作者
可以默认配置最高的那个,如果不足谋几个值,就逐步调整低

使用特权

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

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2011

主题

16157

帖子

215

粉丝