蓝桥杯STM32自学记录_ADC/DAC

本文介绍了ADC和DAC的基本概念,以及如何在嵌入式系统中使用HAL库进行模数和数模转换。通过ADC实例讲解了配置过程和编程接口,同时给出了DAC的设置方法,并强调了多通道ADC使用时的注意事项。
摘要由CSDN通过智能技术生成

前言

笔记是人类的第二大脑,以前的我也总是在记录上所懈怠,遇到不会的就csdn cv 一顿操作,始终不得其内涵。从这个赛事开始,我来学习大佬在嵌入式上的理解,自己做好每次记录,辅助记忆的同时也能亲手过一次知识与项目。希望能在赛事上大放光彩


一、ADC/DAC是什么?

A指模拟信号 D指数字信号 C指转化

ADC:模数转换器,将模拟信号转化为数字信号;具体使用有:温度传感器,压力传感器等。

DAC:数模转换器,将数字信号转化为模拟信号;具体使用有:音频设备,马达控制器等。

二、常用函数

1.ADC模数常用函数

HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)

举例:HAL_ADC_Start(&hadc1);

函数描述:启动名为 hadc1 的ADC,初始化ADC并开始模数转换。

                  hadc1 是指向ADC的指针

HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)

举例:HAL_ADC_PollForConversion(&hadc1, 10);

函数描述:一个轮询函数,用来检查ADC转换是否完成。它检查ADC的EOC(End of Conversion)标志,以确定转换是否完成。参数 10 表示超时时间,单位为毫秒。如果在10毫秒内转换没有完成,这个函数将返回一个超时错误。

uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)

举例:adc = HAL_ADC_GetValue(&hadc1);

函数描述:从 hadc1指向的ADC获取转换结果,并将其存储在变量 adc 中。HAL_ADC_GetValue 函数读取ADC的数据寄存器,并返回转换后的数字值。

2.DAC数模常用函数

HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)

举例:HAL_DAC_Start(&hdac1, DAC_CHANNEL_2);
函数描述:HAL_DAC_Start 函数激活 DAC准备输出模拟信号。

HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel,
                                     uint32_t Alignment, uint32_t Data)

举例:HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_12B_R,temp);
函数描述:HAL_DAC_SetValue 函数用于配置 DAC 输出的具体电压值

                   &hdac1:指向 DAC 实例的指针。                                                                                                     DAC_CHANNEL_2:指定操作的是哪个 DAC 通道                                                                           DAC_ALIGN_12B_R:指定数据对齐式,这里是 12 位右对齐。                                                       temp:决定输出信号的具体电压,DAC 会将这个数字值转换为相应的                                                         模拟电压值!

三、模拟输出原理图

PB15——AD1
PB12——AD2

四、使用流程

adc篇

配置cubemx

以PB12与PB15为例

将PB12配置为ADC1_IN11,将PB15配置为ADC2_IN15

将ADC1中的通道11和ADC2中的通道15都配置为Single-ended

创建文本文件,写代码,再强行改后缀名改变文件类型,以第一篇中模块化的步骤移植进程序。

文件名不能为adc.c/adc.h,因为库中有这个名字的文件。所以建议改成 badc.c/badc.h。

badc.c代码

#include "main.h"
#include "adc.h"
#include "badc.h"

uint16_t getADC1(void)
{
	
	HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);

	uint16_t adc = 0;
	
	HAL_ADC_Start(&hadc1);
	adc = HAL_ADC_GetValue(&hadc1);
	
	return adc;
}
uint16_t getADC2(void)
{

	HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);

	uint16_t adc = 0;
	
	HAL_ADC_Start(&hadc2);
	adc = HAL_ADC_GetValue(&hadc2);
	
	return adc;
}

void getManyADC1(double*data,int n)
{
	HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);

	int i=0;
	for(i=0;i<n;i++)
	{
		HAL_ADC_Start(&hadc1);
		HAL_ADC_PollForConversion (&hadc1,50);
		data[i] = ((double)HAL_ADC_GetValue(&hadc1)/4096)*3.3;
	}
	HAL_ADC_Stop(&hadc1);
}

void getManyADC2(double*data,int n)
{
	HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);

	int i=0;
	for(i=0;i<n;i++)
	{
		HAL_ADC_Start(&hadc2);
		HAL_ADC_PollForConversion (&hadc2,50);
		data[i] = ((double)HAL_ADC_GetValue(&hadc2)/4096)*3.3;
	}
	HAL_ADC_Stop(&hadc2);
}

badc.h代码

#ifndef __BADC_H
#define __BADC_H
#include "main.h"

/*单adc单通道*/
uint16_t getADC1(void);//hadc1
uint16_t getADC2(void);//hadc2
/**************/

/*单adc多通道*/
void getManyADC1(double*data,int n);
void getManyADC2(double*data,int n);
/**************/

#endif

至此,已经做好了adc单通道和多通道的库了。接下来进入实际操作阶段。 

 adc实验代码

实验:使用电压采集1旋钮和电压采集2旋钮分别控制输出数字电压,并转换为模拟电压值显示在屏幕上。
即:模拟电压通过ADC变成数字电压,数字电压通过公式计算变成模拟电压显示到屏幕上。

单通道单输入实验

1.调用库

lcd_print_float(White,Red,8,getADC1()*3.3/4096);
lcd_print_float(White,Red,9,getADC2()*3.3/4096);

2.修改一下lcd的库方便显示


void page1(void)
{
	LCD_Clear(Blue);
	
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line1, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line2, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line3, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line4, (uint8_t *)"        TEST        ");
	
	LCD_SetBackColor(White);
	LCD_SetTextColor(Blue);
	LCD_DisplayStringLine(Line5, (uint8_t *)"         ON         ");
	LCD_DisplayStringLine(Line6, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line7, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line8, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line9, (uint8_t *)"                    ");
	
}
void page2(void)
{
	LCD_Clear(Blue);
	LCD_SetBackColor(Red);
	LCD_SetTextColor(White);
	
	LCD_DisplayStringLine(Line0, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line1, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line2, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line3, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line4, (uint8_t *)"        TEST        ");
	
	LCD_SetBackColor(Red);
	LCD_SetTextColor(Blue);

	LCD_DisplayStringLine(Line5, (uint8_t *)"         OFF        ");
	LCD_DisplayStringLine(Line6, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line7, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line8, (uint8_t *)"                    ");
	LCD_DisplayStringLine(Line9, (uint8_t *)"                    ");
	
}

void lcd_print_int(int backcolor,int textcolor,int Variable)
{
	LCD_SetBackColor(backcolor);
	LCD_SetTextColor(textcolor);
	char text[30];
	sprintf(text,"NUMBER:%d              ",Variable);
	LCD_DisplayStringLine(Line9, (uint8_t *)text);
}
void lcd_print_float(int backcolor,int textcolor,int line,float Variable)
{
	LCD_SetBackColor(backcolor);
	LCD_SetTextColor(textcolor);
	char text[30];
	sprintf(text,"NUMBER:%.2f              ",Variable);
	switch(line)
	{
		case 0:LCD_DisplayStringLine(Line0, (uint8_t *)text);
						break;
		case 1:LCD_DisplayStringLine(Line1, (uint8_t *)text);
						break;
		case 2:LCD_DisplayStringLine(Line2, (uint8_t *)text);
						break;
		case 3:LCD_DisplayStringLine(Line3, (uint8_t *)text);
						break;
		case 4:LCD_DisplayStringLine(Line4, (uint8_t *)text);
						break;
		case 5:LCD_DisplayStringLine(Line5, (uint8_t *)text);
						break;
		case 6:LCD_DisplayStringLine(Line6, (uint8_t *)text);
						break;
		case 7:LCD_DisplayStringLine(Line7, (uint8_t *)text);
						break;
		case 8:LCD_DisplayStringLine(Line8, (uint8_t *)text);
						break;
		case 9:LCD_DisplayStringLine(Line9, (uint8_t *)text);
						break;
	}
	
}

/*----- myself -----*/
void page1(void);
void page2(void);
void lcd_print_int(int backcolor,int textcolor,int Variable);
void lcd_print_float(int backcolor,int textcolor,int line,float Variable);
#endif /* __LCD_H */

/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

dac篇

配置cubemx

dac实验代码

// DAC1电压设置函数
void DAC1_Set_Vol(float vol)
{
	int temp; 
	temp = (4096 * vol/3.3f); 
	HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_2,DAC_ALIGN_12B_R,temp);
}
 DAC1_Set_Vol(2.4); 

adc结合dac篇

tips:一个adc开一个通道,不能开两个,否则dac检测不了。

如dac代码所示,将PA5与PA7用杜邦线连接即可


总结

adc的单通道检测很容易忽略,如果设置了多通道时候记得注意轮询。

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值