实验目的
通过LCD显示电压值,并通过旋转R37改变电压值
ADC相关知识
STM32 HAL库学习系列第1篇 ADC配置 及 DAC配置
硬件设计
原理图
STM32CubeMX配置
1、引脚选用PB15测电压
2、时钟源选择HSE
3、设置时钟频率。在HCLK处输入80回车
4、配置ADC对应的GPIO引脚。此处只加了别名R37
5、选用ADC2的通道15测量电压。
6、ADC参数配置。时钟预分频系数设置为“2分频的异步时钟模式” ,其他采用默认配置。
7、设置工程名、选择编译软件
8、只引用所需库文件;生成各模块单独的.c和.h文件。
9、生成代码
Keil配置
1、添加LCD相关文件。将赛点资源包提供的fonts.h和lcd.h添加到新建工程的Inc文件夹中
路径:D:\MX_project\ADC2\Core\Inc
将赛点资源包提供的lcd.c添加到新建工程的Src文件夹中
路径:D:\MX_project\ADC2\Core\Src
2、下载器选择及相关配置
软件设计
1、main.c中添加头文件。(注:所有代码放到BEGIN和END之间,防止重新生成代码时将原来的代码覆盖掉)
#include "stdio.h"
#include "string.h"
#include "lcd.h"
2、获取ADC电压值的函数
uint16_t getADC(void)
{
uint16_t adc = 0;
HAL_ADC_Start(&hadc2); //轮询模式,需放在循环中不断开启
adc = HAL_ADC_GetValue(&hadc2); //读取ADC的值
return adc;
}
3、定义一个字符数组存储电压值
char buf[20];
4、LCD初始化等处理(想更详细了解LCD,请看LCD篇)
LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(Line0, (uint8_t *)" ");
LCD_DisplayStringLine(Line1, (uint8_t *)" ");
LCD_DisplayStringLine(Line2, (uint8_t *)" ADC Test ");
LCD_DisplayStringLine(Line3, (uint8_t *)" ");
LCD_DisplayStringLine(Line4, (uint8_t *)" ");
LCD_SetBackColor(White);
LCD_SetTextColor(Blue);
LCD_DisplayStringLine(Line5, (uint8_t *)" ");
LCD_DisplayStringLine(Line6, (uint8_t *)" ADC2 CH15 ");
LCD_DisplayStringLine(Line7, (uint8_t *)" ");
LCD_DisplayStringLine(Line8, (uint8_t *)" ");
LCD_DisplayStringLine(Line9, (uint8_t *)" ");
5、轮询读取电压值,并将电压值显示到LCD上
ADC采用12位分辨率,2^12=4096
电压最大值:3.3V
获取到的电压值*3.3/4096 = 十进制的电压值
LCD_SetTextColor(Red);
sprintf(buf, " VAL:%.2fV", getADC()*3.3/4096);
HAL_Delay(100);
LCD_DisplayStringLine(Line8, (uint8_t *)buf);
编译、擦除、下载
1、编译工程
编译成功
2、擦除程序
擦除成功
3、下载程序
或者
下载成功
函数位置
ADC
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc);
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc);
ADC初始化
static void MX_ADC2_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; //时钟分频 //1分频,ADCCLK=PCLK2/1=
hadc2.Init.Resolution = ADC_RESOLUTION_12B; //ADC的分辨率,12位模式
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐,低12有效
hadc2.Init.GainCompensation = 0;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE; //关闭扫描模式,即单通道有效
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc2.Init.LowPowerAutoWait = DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE; //单次转化模式,关闭连续转换
hadc2.Init.NbrOfConversion = 1; //通道数量为1
hadc2.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发
hadc2.Init.DMAContinuousRequests = DISABLE; //关闭DMA请求
hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc2.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_15;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
LCD
void LCD_Init(void);
void LCD_SetTextColor(vu16 Color);
void LCD_SetBackColor(vu16 Color);
void LCD_Clear(u16 Color);
void LCD_DisplayStringLine(u8 Line, u8 *ptr);
实验现象
通过旋转R37电位器可以改变电压
问题
电压最大只有3.23V。不知道是误差还是什么原因导致的。有大佬知道原因的请指教。