GD32F103VE使用DMA传输读取内部温度和参考电压值

GD32F103VE使用DMA传输读取内部温度和参考电压值。出厂CPU芯片不同,温度误差不同,不要纠结了。

GD32F103的ADC为12位AD转换器,ADC转换结果保存在16位数据寄存器中;

模拟输入通道:
16个外部模拟输入通道;
1个内部温度传感器通道(Vsense)
1个内部参考电压输入通道(VrefInt)

触发转换:
软件触发;
硬件触发;

转换模式:
单通道转换或多通道扫描转换;
单次模式,选择指定的模拟输入通道后,触发一次,则转换一次;
连续模式,选择指定的模拟输入通道后,连续进行AD转换;用于DMA
同步模式,当同时使用ADC0,ADC1和ADC2时,这3个设备就可以同时进行AD转换;
间断模式;

ADC的VDDA电源引脚需要接入3.3V;
ADC输入模拟量的范围:Vref- 至Vref+之间;

ADC_RSQ0~ADC_RSQ2寄存器规定了"规则组通道"的选择;
ADC_RSQ0的RL[3:0]用来指定"规则通道组"转换序列的长度,即"规则通道组"选择;
连续进行AD转换的通道总数为(RL[3:0]+1),在DMA传输中要知道有多少个通道参与AD转换

ADC_ISQ寄存器规定了"注入组通道"的选择;
ADC_ISQ0的IL[3:0]用来指定"整个注入通道组"转换序列的长度,即"规则通道组"选择
连续进行AD转换的通道总数为(IL[3:0]+1),在DMA传输中要知道有多少个通道参与AD转换

注意:ADC同时使用"规则组通道"和"注入组通道",则"注入组通道"的采样周期不能1.5和7.5个采样周期;

GD32F103的ADC0映射到DMA0的通道0
GD32F103的ADC2映射到DMA1的通道4
GD32F103的ADC1没有DMA功能
注意:在多通道AD转换中,DMA使用循环工作模式比较好;

ADC0_CH16为温度传感器通道,Internal temperature sensor output voltage;
ADC0_CH17为内部参考电压通道,Internal voltage reference output voltage;
Vref-引脚必须连接至VSSA引脚,Vref+连接到VDDA,但在64脚以下的CPU(含64脚),其Vref+和Vref-已经在内部连接至VDDA和VSSA;
注意:ST和GD的手册里都写着不同芯片最大偏差45度

#include "ADC.h"
#include "delay.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()/*
GD32F103的ADC为12位AD转换器,ADC转换结果保存在16位数据寄存器中;模拟输入通道:
16个外部模拟输入通道;
1个内部温度传感器通道(Vsense)
1个内部参考电压输入通道(VrefInt)触发转换:
软件触发;
硬件触发;转换模式:
单通道转换或多通道扫描转换;
单次模式,选择指定的模拟输入通道后,触发一次,则转换一次;
连续模式,选择指定的模拟输入通道后,连续进行AD转换;用于DMA
同步模式,当同时使用ADC0,ADC1和ADC2时,这3个设备就可以同时进行AD转换;
间断模式;ADC的VDDA电源引脚需要接入3.3V;
ADC输入模拟量的范围:Vref- 至Vref+之间;ADC_RSQ0~ADC_RSQ2寄存器规定了"规则组通道"的选择;
ADC_RSQ0的RL[3:0]用来指定"规则通道组"转换序列的长度,即"规则通道组"选择;
连续进行AD转换的通道总数为(RL[3:0]+1),在DMA传输中要知道有多少个通道参与AD转换ADC_ISQ寄存器规定了"注入组通道"的选择;
ADC_ISQ0的IL[3:0]用来指定"整个注入通道组"转换序列的长度,即"规则通道组"选择
连续进行AD转换的通道总数为(IL[3:0]+1),在DMA传输中要知道有多少个通道参与AD转换注意:ADC同时使用"规则组通道"和"注入组通道",则"注入组通道"的采样周期不能1.5和7.5个采样周期;GD32F103的ADC0映射到DMA0的通道0
GD32F103的ADC2映射到DMA1的通道4
GD32F103的ADC1没有DMA功能
注意:在多通道AD转换中,DMA使用循环工作模式比较好;ADC0_CH16为温度传感器通道,Internal temperature sensor output voltage;
ADC0_CH17为内部参考电压通道,Internal voltage reference output voltage;
Vref-引脚必须连接至VSSA引脚,Vref+连接到VDDA,但在64脚以下的CPU(含64脚),其Vref+和Vref-已经在内部连接至VDDA和VSSA;
注意:ST和GD的手册里都写着不同芯片最大偏差45度
*/#define ADC0_CH_Number   2
#define ADC0_cnt         20
#define ADC0_Buffer_Size 40
uint16_t ADC0_Buffer[ADC0_cnt][ADC0_CH_Number];void DMA0_DMA_CH0_config(void);
void ADC0_Init(void);
void ADC0_To_DMA0_Init(void);
void Read_TemperatureValue(void);void DMA0_DMA_CH0_config(void)
{dma_parameter_struct dma_init_ADC0;dma_deinit(DMA0,DMA_CH0);dma_init_ADC0.direction = DMA_PERIPHERAL_TO_MEMORY;//DMA传送方向:从外设到内存dma_init_ADC0.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));//源数据块首地址为:ADC0寄存器dma_init_ADC0.periph_inc = DMA_PERIPH_INCREASE_DISABLE;  //源数据块地址不递增dma_init_ADC0.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; //源数据块的数据宽度为16位dma_init_ADC0.memory_addr = (uint32_t)(&ADC0_Buffer);//目的数据首地址为:ADC0_Buffer[]dma_init_ADC0.memory_inc = DMA_MEMORY_INCREASE_ENABLE;//目的数据块地址递增dma_init_ADC0.memory_width = DMA_MEMORY_WIDTH_16BIT;//目的数据块的数据宽度为16位dma_init_ADC0.number = (uint32_t)ADC0_Buffer_Size;//目的数据块的数据长度dma_init_ADC0.priority = DMA_PRIORITY_ULTRA_HIGH;      //超高的优先级dma_init(DMA0,DMA_CH0,&dma_init_ADC0);//使用dma_init_struct数据结构初始化DMA0通道0配置"DMA0通道5工作模式"开始///dma_circulation_enable(DMA0,DMA_CH0);//使能"DMA0通道0循环工作模式"//DMA0触发后,会按照指定的序号,循环触发读取ADC的值//在多通道AD转换中,DMA使用循环工作模式比较好
//	dma_circulation_disable(DMA0, DMA_CH0);//不使能"DMA0通道0循环工作模式"dma_memory_to_memory_disable(DMA0, DMA_CH0); //不使能"DMA0通道0内存到内存传输模式"
配置"DMA0通道5工作模式"结束///
///配置串口DMA接收开结束dma_channel_enable(DMA0,DMA_CH0);//使能指定的DMA0通道0	
}void ADC0_Init(void)
{adc_deinit(ADC0);//reset ADC0adc_tempsensor_vrefint_enable();//channel 16 and 17 enable of ADC0 //使能温度传感器通道和内部参考电压通道adc_mode_config(ADC_MODE_FREE);//只使用一个ADC,属于独立模式adc_special_function_config(ADC0,ADC_SCAN_MODE,ENABLE);//在多通道AD转换,要使用"扫描模式"adc_special_function_config(ADC0,ADC_CONTINUOUS_MODE,ENABLE);//设置AD转换为"连续模式"adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);//使用软件触发AD转换,ADC trigger configadc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);//ADC data alignment configadc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL,2);//连续进行AD转换的通道总数为2,在DMA传输中要知道有多少个通道参与AD转换/* ADC regular channel config */adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_16, ADC_SAMPLETIME_71POINT5);//将ADC0中ADC_CHANNEL_16通道放在第0位置优先进行AD转换,采样时间为71.5个时钟周期//配置读取内部温度adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_17, ADC_SAMPLETIME_71POINT5);//将ADC0中ADC_CHANNEL_17通道放在第1位置优先进行AD转换,采样时间为71.5个时钟周期//配置读取内部参考电压adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);//使用软件触发AD转换adc_external_trigger_config(ADC0,ADC_REGULAR_CHANNEL,ENABLE);//使能ADC规则通道组外部触发,enable ADC regular channel group external triggeradc_enable(ADC0);//使能ADC0delay_ms(10);     //等待10msadc_calibration_enable(ADC0);//等待ADC0校准完成adc_dma_mode_enable(ADC0);//使能ADC转DMA功能,ADC DMA function enableadc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);//触发ADC0设备执行1次AD转换//由于前面配置"ADC0为连续转换模式",所以启动转换后,就可以连续执行AD转换了
}void ADC0_To_DMA0_Init(void)
{rcu_periph_clock_enable(RCU_ADC0);//使能ADC0时钟rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);//配置ADC时钟8分频//由于ADC最大时钟频率为14MHz,经过8分频后,变为1.75MHz//	rcu_periph_clock_enable(RCU_GPIOA);//使能GPIOA端口时钟
//	rcu_periph_clock_enable(RCU_GPIOB);
//	rcu_periph_clock_enable(RCU_GPIOC);//使能GPIOC端口时钟
//	rcu_periph_clock_enable(RCU_GPIOD);
//	rcu_periph_clock_enable(RCU_GPIOE);
//	rcu_periph_clock_enable(RCU_GPIOF);
//	rcu_periph_clock_enable(RCU_GPIOG);//	rcu_periph_clock_enable(RCU_AF);rcu_periph_clock_enable(RCU_DMA0);
//	rcu_periph_clock_enable(RCU_DMA1);
//	rcu_periph_clock_enable(RCU_I2C1);
//	rcu_periph_clock_enable(RCU_ADC0);
//	rcu_periph_clock_enable(RCU_ADC2);
//	rcu_periph_clock_enable(RCU_ADC1);//使能ADC1时钟
//  rcu_periph_clock_enable(RCU_TIMER1);//	gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);//使用SW下载,不使用JTAG下载,管脚用作其它功能//  gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6);//配置PA4,PA5和PA6引脚为模拟输入口//PA4复用到ADC01_IN4引脚,即ADC0/ADC1的第4通道//PA5复用到ADC01_IN5引脚,即ADC0/ADC1的第5通道//PA6复用到ADC01_IN6引脚,即ADC0/ADC1的第6通道
//	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
//	//配置PA4引脚为模拟输入口,复用到ADC01_IN4引脚,即ADC0/ADC1的第4通道
//	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
//	//配置PA5引脚为模拟输入口,复用到ADC01_IN5引脚,即ADC0/ADC1的第5通道
//	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
//	//配置PA6引脚为模拟输入口,复用到ADC01_IN6引脚,即ADC0/ADC1的第6通道//  gpio_init(GPIOC,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_3 | GPIO_PIN_4);//配置PC3和PC4引脚为模拟输入口//PC3复用到ADC012_IN13引脚,即ADC0/ADC1/ADC2的第13通道//PC4复用到ADC01_IN14,即ADC0/ADC1的第14通道
//	gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ,GPIO_PIN_3);
//	//配置PC3引脚为模拟输入口,复用到ADC012_IN13引脚,即ADC0/ADC1/ADC2的第13通道
//	gpio_init(GPIOC, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
//	//配置PC4引脚为模拟输入口,复用到ADC01_IN14,即ADC0/ADC1的第14通道DMA0_DMA_CH0_config();ADC0_Init();
}/*
温度(°C) = {(V25 - VSENSE) / Avg_Slope} + 25
V25 = VSENSE在25°C时的数值,这里取1.43V
Avg_Slope = 温度与VSENSE曲线的平均斜率,4.3mV/°C
即:(1.43 - voltage) / 0.0043 + 25;
ST和GD的手册里都写着不同芯片最大偏差45度,
*/
void Read_TemperatureValue(void)
{uint8_t i;uint32_t sum1,sum2;uint16_t *p;float f;sum1=0;sum2=0;p=&ADC0_Buffer[0][0];for(i=0;i<ADC0_cnt;i++){sum1=*p+sum1;p++;//内部温度数据累加sum2=*p+sum2;p++;//内部电压数据累加}sum1=sum1/ADC0_cnt;//计算平均值sum2=sum2/ADC0_cnt;//计算平均值printf("\r\nADC0_16: %d ", sum1);f = sum1;f = f	* 3.300;f = f / 4096;  //转换成电压值单位为Vprintf("\r\nADC0_16_Voltage: %0.3fV", f);f = V25 -f;f =f / AvgSlope;f= f+25; //计算温度值printf("\r\nTmoerature: %0.1f\r\n", f);printf("\r\nADC0_17: %d ", sum2);f = sum2;f = f	* 3.300;f = f / 4096;  //转换成电压值单位为Vprintf("\r\nInternalVoltage: %0.3fV\r\n", f);
}
#ifndef __ADC_H
#define __ADC_H#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t#define V25       1.430   //V
#define AvgSlope  0.0043  //V/°Cextern void ADC0_To_DMA0_Init(void);
extern void Read_TemperatureValue(void);
#endif

main.c如下:
 

#include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "delay.h"#include "UART3.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "ADC.h"uint16_t volValue = 0;const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{//NVIC_PRIGROUP_PRE4_SUB0:抢占优先级为4bit(取值为0~15),子优先级为0bit(没有响应优先级)//NVIC_PRIGROUP_PRE3_SUB1:抢占优先级为3bit(取值为0~7),子优先级为1bit(取值为0~1)//NVIC_PRIGROUP_PRE2_SUB2:抢占优先级为2bit(取值为0~3),子优先级为2bit(取值为0~3)//NVIC_PRIGROUP_PRE1_SUB3:抢占优先级为1bit(取值为0~1),子优先级为3bit(取值为0~7)//NVIC_PRIGROUP_PRE0_SUB4:抢占优先级为0bit(没有抢占优先级),子优先级为3bit(取值为0~15)nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);//设置系统中断优先级"抢占优先级为4bit,子优先级为0bit"delay_init();INTX_ENABLE();//开启所有中断UART3_Init(115200);//初始化UART3printf("%s",CPU_Reset_REG);//调试串口输出"\r\nCPU reset!\r\n"ADC0_To_DMA0_Init();while(1){delay_ms(500);Read_TemperatureValue();}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【electron】electron安装过慢和打包报错:Unable to load file:

文章目录 一、安装过慢问题:二、打包报错&#xff1a;Unable to load file: 一、安装过慢问题: 一直处于安装过程 【解决】 #修改npm的配置文件 npm config edit#添加配置 electron_mirrorhttps://cdn.npm.taobao.org/dist/electron/二、打包报错&#xff1a;Unable to load…

camera hal|如何学习一个新平台

全网最具价值的Android Camera开发学习系列资料~ 作者:8年Android Camera开发,从Camera app一直做到Hal和驱动~ 欢迎订阅,相信能扩展你的知识面,提升个人能力~ 我自己目前从事的是android camera hal 的工作,工作上接触到的芯片平台要么是高通的,要么是mtk的。 其实…

c语言作业

作业1&#xff1a; 关于实参和形参 形参是实参的一份临时拷贝。 形参是在函数调用的时候才实例化&#xff0c;才开辟内存空间。 函数调用如果采用传值调用&#xff0c;改变形象不影响实参。 改变形参不是影响实参。 作业2&#xff1a; 函数调用exec&#xff08;&#xf…

C++QT教程3——手册4.11.1自带教程(笔记)——创建一个基于Qt Widget的应用程序

文章目录 创建一个基于Qt Widget的应用程序创建Text Finder项目素材文件 填补缺失的部分设计用户界面完成头文件完成源文件创建资源文件 编译和运行程序 参考文章 创建一个基于Qt Widget的应用程序 本教程介绍如何使用Qt Creator创建一个小型Qt应用程序&#xff0c;名为Text F…

电脑IP地址错误无法上网怎么办?

电脑出现IP地址错误后就将无法连接网络&#xff0c;从而无法正常访问互联网。那么当电脑出现IP地址错误时该怎么办呢&#xff1f; 确认是否禁用本地连接 你需要先确定是否禁用了本地网络连接&#xff0c;如果发现禁用&#xff0c;则将其启用即可。 启用方法&#xff1a;点击桌…

Spring 使用注解开发、代理模式、AOP

使用注解开发 在Spring4之后&#xff0c;要使用注解开发&#xff0c;必须要保证AOP的包导入了 项目搭建&#xff1a; 在配置文件中导入约束&#xff0c;增加注解支持 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.spri…

uniapp把城市换成26个字母和城市排序

后端返回的数据 我们要得效果 <template><view><view v-for"(value,key) in cities" :key"key"><view style"color: red;"> {{ key }} </view><view style"border: 1rpx solid black;"><tex…

PostgreSql 备份恢复

一、概述 数据库备份一般可分为物理备份和逻辑备份&#xff0c;其中物理备份又可分为物理冷备和物理热备&#xff0c;下面就各种备份方式进行详细说明&#xff08;一般情况下&#xff0c;生产环境采取的定时物理热备逻辑备份的方式&#xff0c;均是以下述方式为基础进一步研发编…

Linux 基础

巩固基础&#xff0c;砥砺前行 。 只有不断重复&#xff0c;才能做到超越自己。 能坚持把简单的事情做到极致&#xff0c;也是不容易的。 linux的目录结构 linux的文件系统采用树状的目录结构&#xff0c;在此结构的最上层是根目录“/”&#xff0c; 然后在此目录下再创建其他…

【算法——双指针】LeetCode 1089 复写零

千万不要被这道题标注着“简单”迷惑了&#xff0c;实际上需要注意的细节很多。 题目描述&#xff1a; 解题思路&#xff1a; 正序遍历&#xff0c;确定结果数组的最后一个元素所在的位置&#xff1b;知道最后一个元素的位置后倒序进行填充。 先找到最后一个需要复写的数 先…

javaee dom4j读取xml文件

引入jar包 dom4j-1.6.1.jar 创建xml文件 <?xml version"1.0" encoding"UTF-8"?> <books><book id"1"><title ID"t1">背影</title><price>88</price><author>三毛</author>…

Excel表格制作,快速提升效率好方法!

“作为一个刚开始工作的职场新人&#xff0c;每天要做各种不同的表格&#xff0c;真的让我很崩溃&#xff0c;感觉我对这些表格制作一点都不了解&#xff0c;Excel表格制作有什么比较好的方法吗&#xff1f;” Excel作为一款广泛应用于各个领域的管理和分析工作&#xff0c;给我…

【STM32】FreeRTOS消息队列和信号量学习

一、消息队列&#xff08;queue&#xff09; 队列是一种用于实现任务与任务之间&#xff0c;任务与中断之间消息交流的机制。 注意&#xff1a;1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验&#xff1a;创建一个消息队列…

解决 Oracle 数据库中表被锁问题的方案和方法

我们经常会遇到表被锁的情况&#xff0c;这可能会严重影响数据库的性能和可用性。我将与大家分享如何识别、分析和解决这些问题&#xff0c;以及如何使用特定的 SQL 查询来执行解锁操作。 了解表锁的原因 首先&#xff0c;让我们来了解一下导致表被锁的常见原因。长时间运行的…

(四)Unity开发Vision Pro——参考文档

4.参考文档 4.1 支持的功能和组件 4.1.1 支持的 Unity 功能和组件 大多数 Unity 组件无需修改即可在此平台上运行 - 包括大多数自定义 MonoBehaviours、动画逻辑、物理、输入处理、资产管理、AI 等。然而&#xff0c;需要渲染的组件需要特殊的支持。因此&#xff0c;一些组件…

qt5.15.2 使用mysql8.1

报错&#xff1a; QMYSQL driver not loaded 报错&#xff1a;无 QMYSQL 使用 QStringList drivers QSqlDatabase::drivers(); //获取现在可用的数据库驱动 foreach(QString driver, drivers) qDebug() << driver; “QSQLITE” “QMARIADB” “QMYSQL” “QMYSQL3” “…

Linux常用命令——dmidecode命令

在线Linux命令查询工具 dmidecode 在Linux系统下获取有关硬件方面的信息 补充说明 dmidecode命令可以让你在Linux系统下获取有关硬件方面的信息。dmidecode的作用是将DMI数据库中的信息解码&#xff0c;以可读的文本方式显示。由于DMI信息可以人为修改&#xff0c;因此里面…

网络编程的使用

文章目录 基础代码URL类进行传输编码解码 协议TCPUDPhttp PORT端口协议的实现TCPUDP 模拟服务器 基础代码 最后一个是&#xff1a;只要再timeout时间内连接上就是true URL类 导了一个common-iojar包&#xff0c;那个IOUtils就是那个里面的工具类 进行传输编码解码 协议 TC…

多线程:线程池

线程池 提前创建多个线程放入线程池中&#xff0c;使用时直接获取&#xff0c;使用完直接放入池中&#xff1b;可以避免频繁创建销毁&#xff0c;实现重复利用&#xff0c;类似生活中的公共交通工具。好处&#xff1a;提高相应速度&#xff1b;降低资源消耗&#xff1b;便于线…

【Spring Cloud +Vue+UniApp】智慧建筑工地平台源码

智慧工地源码 、智慧工地云平台源码、 智慧建筑源码支持私有化部署&#xff0c;提供SaaS硬件设备运维全套服务。 前言&#xff1a;互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;从施工现场源头抓起&#xff0c;最大程度的收集人员、安全、环境、材…