6227|0

282

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【GD32L233C-START评测】11.DAC输出电压值_ADC读取外部电压值 [复制链接]

本帖最后由 hehung 于 2022-2-12 14:25 编辑

之前的帖子可以参考:

 

【GD32L233C-START评测】1.开箱

【GD32L233C-START评测】2.手把手创建新工程

【GD32L233C-START评测】3.移植FreeRTOS到GD32L233

【GD32L233C-START评测】4. 移植RT-Thread到GD32L233

【GD32L233C-START评测】5. IIC驱动OLED

【GD32L233C-START评测】6. 获取RTC时间并通过OLED显示

【GD32L233C-START评测】7. PWM驱动LED

【GD32L233C-START评测】8. TRNG真随机数生成

【GD32L233C-START评测】9. CRC检验

【GD32L233C-START评测】10. ADC读取芯片内部温度

 

本帖讲解将如何使用DAC模块输出电压值并通过ADC模块外部引脚会读DAC输出的电压值。

本来是想专门一个章节用来描述如何使用ADC的外部引脚来读取电压值的,但是呢,手头没有一个传感器是模拟电压输出的,不能进行验证,怎么办呢?

我想到可以使用单片机的DAC模块来输出电压值,然后用ADC外部引脚来会读不就可以了嘛,说干就干。

 

一、模拟端口查询

我们看GD32L233C开发板上模拟引脚是PA1-PA5,对应的ADC通道为1-5,可以在数据手册中查到,如下:

二、ADC模块

ADC模块在上一篇贴已经有了初步的了解,不同的是这篇帖子使用的是外部引脚。

ADC使用软件触发,12位宽度采样。

使用PA1-ADC的通道1来做采样通道。

 

三、DAC模块使用

见用户手册14. 数模转换器( 数模转换器(DAC )

同样适用12位宽度,软件触发,不使用缓冲。

使用DAC输出通道,即PA4-DAC_OUT来做模拟电压输出通道,如下图:

四、代码编辑

1. 时钟初始化

初始化需要初始化GPIOA时钟,ADC时钟,APH时钟,DAC时钟

void rcu_config(void)
{
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC);;
    /* config ADC clock */
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
	/* enable DAC clock */
	rcu_periph_clock_enable(RCU_DAC);
}

 

2. GPIO时钟

void gpio_config(void)
{
    /* config the GPIO as analog mode */
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1 | GPIO_PIN_4);
}

3. ADC初始化

void adc_config(void)
{
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
    /* ADC external trigger config */
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable();
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable();
}

4. ADC读取

uint16_t adc_channel_sample(uint8_t channel)
{
    /* ADC regular channel config */
    adc_regular_channel_config(0U, channel, ADC_SAMPLETIME_7POINT5);
    /* ADC software trigger enable */
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);

    /* wait the end of conversion flag */
    while(!adc_flag_get(ADC_FLAG_EOC));
    /* clear the end of conversion flag */
    adc_flag_clear(ADC_FLAG_EOC);
    /* return regular channel sample value */
    return (adc_regular_data_read());
}

5. DAC初始化

void dac_config(void)
{
    dac_deinit();
    /* output buffer config */
    dac_output_buffer_enable();
    dac_output_buffer_disable();

    /* trigger config */
    dac_trigger_source_config(DAC_TRIGGER_SOFTWARE);

    /* dac enable */
    dac_enable();

    /* enable software trigger */
    dac_software_trigger_enable();
}

6. 输出DAC模拟电压值

DAC电压使用数字来表示,因为是12bit,最大值为4096.

从0开始输出,每一秒钟加100,大于4096之后从0开始从新输出电压值。

		if(dac_value > DAC_VALUE_MAX)
		{
			dac_value = 0;
		}
		else
		{
			dac_value += 100;
		}
		/* output data config */
		dac_data_set(DAC_ALIGN_12B_R, dac_value);

7. 阅读输出的模拟电压值并通过串口输出

		/* read adc value */
        adc_value = adc_channel_sample(ADC_CHANNEL_1);
		printf("read dac value:%d,voltage:%.2f\r\n", adc_value, dac_value/4096.0*3.3);

8.main函数

int main(void)
{
    /* system clocks configuration */
    rcu_config();
    /* systick configuration */
    systick_config();
	/* USART configuration */
    gd_eval_com_init(EVAL_COM);
    /* GPIO configuration */
    gpio_config();
    /* ADC configuration */
    adc_config();
	/* configure the DAC */
    dac_config();
	
	dac_value = 0;

    while(1) {
		if(dac_value > DAC_VALUE_MAX)
		{
			dac_value = 0;
		}
		else
		{
			dac_value += 100;
		}
		/* output data config */
		dac_data_set(DAC_ALIGN_12B_R, dac_value);
		printf("output dac value:%d, voltage:%.2f\r\n",dac_value, dac_value/4096.0*3.3);
		
		/* read adc value */
        adc_value = adc_channel_sample(ADC_CHANNEL_1);
		printf("read dac value:%d,voltage:%.2f\r\n", adc_value, dac_value/4096.0*3.3);
		
		printf("---\r\n");
		
		delay_1ms(1000);
    }
}

8. 使用大全局变量与宏定义

#define DAC_VALUE_MAX     (4096)

uint16_t adc_value;
uint16_t dac_value;

 

五、效果演示

如上所说,使用PA4输出模拟电压值0-3.3V,对于数字为0-4095。

使用PA1来读取模拟电压值,所以需要将PA4与PA1连接在一起,

PA1 ---- PA4

如下图:

效果如下:

可以看到输出的模拟电压值和读取的模拟电压值有几个数值的差值,但是换成电压之后,取两位小数之后输出的模拟电压和采集的电压基本相同,精度还是很高的,可以满足绝大部分场合的使用要求。

 

此帖出自GD32 MCU论坛
点赞 关注
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表