IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32复习笔记(十三) —— ADC(多通道)采集电压 -> 正文阅读

[嵌入式]STM32复习笔记(十三) —— ADC(多通道)采集电压

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.\r\n", ADC_CurrentValue[0]);	

		/* 通过串口输出 */
		printf("ADC_RealValue_1 = %.2f V.\r\n\r\n", ADC_RealValue[0]);

		/* 通过串口输出 */
		printf("ADC_CurrentValue_2 = %d.\r\n", ADC_CurrentValue[1]);	

		/* 通过串口输出 */
		printf("ADC_RealValue_2 = %.2f V.\r\n\r\n", ADC_RealValue[1]);
		
		/* 通过串口输出 */
		printf("ADC_CurrentValue_3 = %d.\r\n", ADC_CurrentValue[2]);	

		/* 通过串口输出 */
		printf("ADC_RealValue_3 = %.2f V.\r\n\r\n", ADC_RealValue[2]);
		
		/* 换行 */
		printf("--------- --------- ---------\r\n");
		
		/* 延时一段时间 */
		delay_(500);
	}
}

/* 粗略延时 */
static void delay_(uint32_t count)
{
	__IO uint32_t delay_count = (12000 * count);
	
	while(delay_count--);
}

点击编译,如无错误可进入仿真界面
SSS13.001
打开串口
SSS13.002
点击运行
SSS13.003
此时被检测的引脚上 (即 ADC 检测的三个通道) 并未施加电压,所以输出为0V

于三个引脚上分别施加 1V 2V 3V 电压,观察输出变化
SSS13.004
此时已经检测到电压值并输出显示,程序运行结果与预想一致

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:33:13  更:2021-10-18 17:33:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:39:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码