概述
STM32复习笔记(十三) —— ADC(多通道)采集电压
1.本例程软件设计思路
1)使用 ADC1 扫描检测三个通道引脚上被施加的电压值
2)经过 ADC 转换完成后,通过 DMA 传输到存储器中
3)再由串口打印显示
注意:此处测量的电压范围仅适用于 0 - 3.3V,不得高于 3.3V
2.代码编写
于 main.c 中编写代码
#include "stm32f10x.h"
#include "dr_usart.h"
/* 用于读取转换后的AD值 */
uint16_t ADC_CurrentValue[3] = {0};
/* 用于计算出真实值 */
float ADC_RealValue[3] = {0.0, 0.0, 0.0};
/* 粗略延时 */
static void delay_(uint32_t count);
void ADC1_GPIO_Config(void)
{
/* 开启 GPIOA 时钟 */
RCC->APB2ENR |= ((uint16_t)0x01 << 2);
/* 配置 PA1 PA2 PA3 模拟输入,作为 ADC1_IN1 IN2 IN3 */
GPIOA->CRL &= ~((uint32_t)0x0fff << 4);
}
static void ADC1_DMA_Config(void)
{
/* 开启 DMA1 时钟 */
RCC->AHBENR |= ((uint16_t)0x01 << 0);
/* 清除 CCR 寄存器,DMA_Channel1 对应 ADC1 */
DMA1_Channel1->CCR &= ((uint32_t)0xFFFF8000);
/* 外设到存储器模式 */
DMA1_Channel1->CCR &= ~((uint32_t)0x01 << 14);
/* 通道优先级 中 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 12);
/* 存储器数据宽度 16位 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 10);
/* 外设数据宽度 16位 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 8);
/* 存储器地址递增 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 7);
/* 外设地址固定 */
DMA1_Channel1->CCR &= ~((uint32_t)0x01 << 6);
/* 循环操作 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 5);
/* 从外设读 */
DMA1_Channel1->CCR &= ~((uint32_t)0x01 << 4);
/* 传输数量 */
DMA1_Channel1->CNDTR = ((uint32_t)3);
/* 外设地址 */
DMA1_Channel1->CPAR = ((uint32_t)(ADC1_BASE + 0x4C));
/* 存储器地址 */
DMA1_Channel1->CMAR = ((uint32_t)ADC_CurrentValue);
/* 开启通道 */
DMA1_Channel1->CCR |= ((uint32_t)0x01 << 0);
}
void ADC1_Config(void)
{
/* ADC GPIO 配置 */
ADC1_GPIO_Config();
/* ADC DMA 配置 */
ADC1_DMA_Config();
/* 开启 ADC1 时钟 */
RCC->APB2ENR |= ((uint16_t)0x01 << 9);
/* 独立模式 */
ADC1->CR1 &= ~((uint32_t)0x0f << 16);
/* 使用扫描模式 */
ADC1->CR1 |= ((uint32_t)0x01 << 8);
/* 软件触发模式 */
ADC1->CR2 |= ((uint32_t)0x0F << 17);
/* 数据右对齐 */
ADC1->CR2 &= ~((uint32_t)0x01 << 11);
/* 连续转换模式 */
ADC1->CR2 |= ((uint32_t)0x01 << 1);
/* 转换3个通道 */
ADC1->SQR1 |= ((uint32_t)0x02 << 20);
/* 配置 ADC 时钟8分频 */
RCC->CFGR |= ((uint32_t)0x03 << 14);
/* 采样时间均为239.5周期 */
ADC1->SMPR2 |= ((uint32_t)0x01FF << 3);
/* 转换顺序 IN1 -> IN2 -> IN3 */
ADC1->SQR3 |= ((uint32_t)0x0C41 << 0);
/* 使用 DMA 模式 */
ADC1->CR2 |= ((uint32_t)0x01 << 8);
/* 开启ADC并启动转换 */
ADC1->CR2 |= ((uint32_t)0x01 << 0);
/* 初始化校准寄存器 */
ADC1->CR2 |= ((uint32_t)0x01 << 3);
/* 等待初始化完成 */
while(0 != (ADC1->CR2 & ((uint32_t)0x01 << 3)));
/* 开始校准 */
ADC1->CR2 |= ((uint32_t)0x01 << 2);
/* 等待校准完成 */
while(0 != (ADC1->CR2 & ((uint32_t)0x01 << 2)));
/* 使用软件触发 ADC 开始转换 */
ADC1->CR2 |= ((uint32_t)0x01 << 22);
}
int main(void)
{
User_Init(); /* Group Priority and USART1 */
/* 配置 ADC1 */
ADC1_Config();
while(1)
{
/* 转换成模拟值 */
ADC_RealValue[0] = (float)ADC_CurrentValue[0]/4096*3.3 + 0.005;
/* 转换成模拟值 */
ADC_RealValue[1] = (float)ADC_CurrentValue[1]/4096*3.3 + 0.005;
/* 转换成模拟值 */
ADC_RealValue[2] = (float)ADC_CurrentValue[2]/4096*3.3 + 0.005;
/* 通过串口输出 */
printf("ADC_CurrentValue_1 = %d.rn", ADC_CurrentValue[0]);
/* 通过串口输出 */
printf("ADC_RealValue_1 = %.2f V.rnrn", ADC_RealValue[0]);
/* 通过串口输出 */
printf("ADC_CurrentValue_2 = %d.rn", ADC_CurrentValue[1]);
/* 通过串口输出 */
printf("ADC_RealValue_2 = %.2f V.rnrn", ADC_RealValue[1]);
/* 通过串口输出 */
printf("ADC_CurrentValue_3 = %d.rn", ADC_CurrentValue[2]);
/* 通过串口输出 */
printf("ADC_RealValue_3 = %.2f V.rnrn", ADC_RealValue[2]);
/* 换行 */
printf("--------- --------- ---------rn");
/* 延时一段时间 */
delay_(500);
}
}
/* 粗略延时 */
static void delay_(uint32_t count)
{
__IO uint32_t delay_count = (12000 * count);
while(delay_count--);
}
点击编译,如无错误可进入仿真界面
打开串口
点击运行
此时被检测的引脚上 (即 ADC 检测的三个通道) 并未施加电压,所以输出为0V
于三个引脚上分别施加 1V 2V 3V 电压,观察输出变化
此时已经检测到电压值并输出显示,程序运行结果与预想一致
最后
以上就是孝顺枫叶为你收集整理的STM32复习笔记(十三) —— ADC(多通道)采集电压的全部内容,希望文章能够帮你解决STM32复习笔记(十三) —— ADC(多通道)采集电压所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复