GD32F470 ADC常规并行+DMA开发 梁山派板

GD32F470 ADC常规并行+过采样+DMA传输开发,使用梁山派开发板开发

特性

  • 高性能:
    – ADC采样分辨率: 采样分辨率: 采样分辨率: 12位、 10位、 8位、或者 位、或者 6位分辨率; 位分辨率; 位分辨率;
    – ADC采样率: 采样率: 12位分辨率为 位分辨率为 位分辨率为 2.6 MSPs,10位分辨率为 位分辨率为 3.0 MSPs。分辨率越低,转 。分辨率越低,转 。分辨率越低,转 。分辨率越低,转 换越快;
    – 自校准时间 自校准时间 :131个ADC时钟周期 时钟周期 ;
    – 可编程采样时间; 可编程采样时间; 可编程采样时间;
    – 数据 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低; 存储模式:最高有效位对齐和低;
    – DMA请求。
  • 模拟输入通道:
    – 16个外部模拟输入通道; 个外部模拟输入通道; 个外部模拟输入通道; 个外部模拟输入通道;
    – 1个内部温度传感通道 个内部温度传感通道 个内部温度传感通道 (VSENSE);
    – 1个内部参考电压输入通道 个内部参考电压输入通道 个内部参考电压输入通道 个内部参考电压输入通道 (VREFINT);
    – 1个外部监测电池 个外部监测电池 个外部监测电池 VBAT供电引脚输入通道。 供电引脚输入通道。 供电引脚输入通道。
  • 转换开始的发起:
    – 软件触发; 软件触发;
    – 硬件触发。 硬件触发。
  • 运行模式:
    – 转换单个通道,或者扫描一序列的; 转换单个通道,或者扫描一序列的; 转换单个通道,或者扫描一序列的; 转换单个通道,或者扫描一序列的; 转换单个通道,或者扫描一序列的; 转换单个通道,或者扫描一序列的;
    – 单次 运行模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道; 模式,每次触发转换一选择的输入通道;
    – 连续 运行模式,连续转换所选择的输入通道; 模式,连续转换所选择的输入通道; 模式,连续转换所选择的输入通道; 模式,连续转换所选择的输入通道; 模式,连续转换所选择的输入通道; 模式,连续转换所选择的输入通道;
    – 间断 运行模式;
    – 同步模式(适用于具有两个 或多同步模式(适用于具有两个 或多同步模式(适用于具有两个 或多同步模式(适用于具有两个 或多同步模式(适用于具有两个 或多ADC的设备)。 的设备)。 的设备)。 的设备)。
  • 转换结果阈值监测器功能:模拟看门狗。
  • 中断产生:
    – 常规 转换结束 转换结束 ;
    – 模拟看门狗事件; 模拟看门狗事件; 模拟看门狗事件;
    – 溢出事件。 溢出事件。
  • 过采样:
    – 16位的数据寄存器; 位的数据寄存器; 位的数据寄存器;
    – 可调整的过采样率,从 可调整的过采样率,从 可调整的过采样率,从 2x到256x;
    – 高达 8位的可编程数据移。 位的可编程数据移。 位的可编程数据移。 位的可编程数据移。 位的可编程数据移。
  • 模块供电要求:2.6V到3.6V,一般电源电压为3.3V。
  • 通道输入范围:VREFN ≤VIN ≤VREFP。

结构图

在这里插入图片描述

ADC时钟配置

配置为HCLK的10分频。系统频率设置为HCLK=200MHZ,则ADC_CLK=20MHZ。
在这里插入图片描述

使用扫描模式

使用不连续的扫描运行模式,框图如下:
在这里插入图片描述

数据模式

分辨率12位,数据左对齐。
在这里插入图片描述

片上硬件过采样

过采样到14bit,同时有一定滤波作用。过采样率N=64,,左移4位,即M=4.。此时采样的最大值为0x3FFC。在这里插入图片描述

ADC同步模式

在这里插入图片描述
配置为常规并行模式,ADC0、ADC1并行,ADC2独立。
在这里插入图片描述
DMA模式使用ADC同步 DMA模式 1。传输宽度32bit。

驱动代码

/*
* Dasen - 2023/5/8
* adc.h
*/

#ifndef USER_INC_ADC_H_
#define USER_INC_ADC_H_

#include "gd32f4xx.h"
#include "M4systick.h"

#define I_GAIN ((3.3/0x3ffc)*10.0)
#define I_OFFSET ((3.3/2)*10.0)
#define V_GAIN ((3.3/0x3ffc)*11.0)
#define V_gain	(3.3/0x3ffc)

extern uint32_t FOC_CURR_AB;

void ADC_gpioInit(void);
void ADC_init(void);
void ADC_DMA_init(void);

#endif 
/*
* Dasen - 2023/5/8
* adc.c
*/

#include "adc.h"



void ADC_gpioInit(void)
{
	RCU_AHB1EN |=(1<<0);//GPIOA时钟使能
	
	gpio_mode_set(GPIOA,GPIO_MODE_ANALOG,GPIO_PUPD_NONE,GPIO_PIN_0|GPIO_PIN_1);
}


/*
* 扫描运行、常规并行模式
* ADC0: ADC-CH0(Ia)
* ADC1: ADC-CH1(Ib)
* 总转换时间=采样时间+12.5 个CK_ADC 周期。
*/
void ADC_init(void)
{
	ADC_gpioInit();
	ADC_DMA_init();
	
	RCU_APB2EN |=(1<<8);//ADC0时钟使能
	RCU_APB2EN |=(1<<9);//ADC1时钟使能
	
	ADC_CTL1(ADC0) &=~(1<<0);//0:禁止ADC关闭电源;1:使能ADC
	ADC_CTL1(ADC1) &=~(1<<0);//0:禁止ADC关闭电源;1:使能ADC
	
	//ADC时钟配置
	ADC_SYNCCTL=0;
	ADC_SYNCCTL |=(6<<16);//ADCCK: 这些位配置所有ADC的时钟 ADC_CLK_MAX <= 40MHZ
												//100:HCLK 5分频 ADC_CLK=HCLK/5=200MHZ/5=40MHZ
												//101:HCLK 6分频
												//110:HCLK 10分频 ADC_CLK=HCLK/10=200MHZ/10=20MHZ
	
	/*************************** ADC0 SATRT****************************/
	ADC_STAT(ADC0) =0;//状态寄存器清零
	
	ADC_CTL0(ADC0) =0;//控制寄存器0清零
	ADC_CTL0(ADC0) |=(0<<24);//ADC数据分辨率: 00: 12位;01: 10位;10: 8位;11: 6位
	ADC_CTL0(ADC0) |=(0<<23);//0:常规序列看门狗禁止;1:常规序列看门狗使能
	
	ADC_CTL0(ADC0) |=(0<<11);//常规序列间断模式:0:间断运行模式禁止;1:间断运行模式使能
	ADC_CTL0(ADC0) |=(1<<8);//扫描模式:0:扫描运行模式禁止;1:扫描运行模式使能
	
	ADC_CTL1(ADC0) =0;//控制寄存器1清零
	ADC_CTL1(ADC0) |=(0<<28);//常规序列外部触发模式:
													//00:常规序列外部触发失能
													//01:常规序列外部触发上升沿使能
													//01:常规序列外部触发下降沿使能
													//11:常规序列外部触发双边沿使能
													
	ADC_CTL1(ADC0) |=(13<<24);//常规序列外部触发选择:1101: 定时器7通道0 ; 1110: 定时器7 TRGO
	ADC_CTL1(ADC0) |=(0<<11);//数据对齐:0:最低有效位对齐;1:最高有效位对齐
	ADC_CTL1(ADC0) |=(1<<9);//DMA失能模式
													//0:DMA机制在DMA控制器的传输结束信号之后失能。
													//1:当DMA=1,在每个常规转换结束时DMA机制产生一个DMA请求。
	
	ADC_CTL1(ADC0) |=(1<<8);//0:DMA请求禁止;1:DMA请求使能
	ADC_CTL1(ADC0) |=(0<<1);//0:禁止连续运行模式;1:使能连续运行模式
	
	ADC_SAMPT1(ADC0) =0;//采样时间寄存器清零
	ADC_SAMPT1(ADC0) |=(3<<0);//规则转换通道0采样时间:4-84周期,3-56,2-28
	
	ADC_RSQ0(ADC0) &=~(0X0F<<20);
	ADC_RSQ0(ADC0) |=(0<<20);//常规序列长度:常规通道转换序列中的总的通道数目为RL[3:0]+1。
	ADC_RSQ2(ADC0) =0;
	ADC_RSQ2(ADC0) |=(0<<0);//规则转换通道0 ->ADC_CH0
//	ADC_RDATA(ADC0);
	
	ADC_OVSAMPCTL(ADC0)=0;
	ADC_OVSAMPCTL(ADC0) |=(4<<5);//移位4位, 14bit-0x3ffc
	ADC_OVSAMPCTL(ADC0) |=(5<<2);//过采样率:64x
	ADC_OVSAMPCTL(ADC0) |=(1<<0);//过采样使能
	
	ADC_SYNCCTL |=(2<<14);//ADC同步DMA模式选择
												//00:ADC同步DMA失能:
												//01:ADC同步DMA模式0
												//10:ADC同步DMA模式1
												//11:保留
												
	ADC_SYNCCTL |=(1<<13);	//ADC同步DMA使能模式	
													//0:当检测到来自DMA控制器的传输结束信号后,DMA机制失能
													//1:当SYNCDMA不为00时,根据SYNCDMA位来产生DMA请求。	
	
	ADC_SYNCCTL |=(6<<0);//ADC同步模式
											//00110:ADC0和ADC1工作在常规并行模式。ADC2 独立工作。
											//10110:所有的ADC都工作在常规并行模式。
	/*************************** ADC0 END****************************/
	
	/*************************** ADC1 SATRT****************************/
	ADC_STAT(ADC1) =0;//状态寄存器清零
	
	ADC_CTL0(ADC1) =0;//控制寄存器0清零
	ADC_CTL0(ADC1) |=(0<<24);//ADC数据分辨率: 00: 12位;01: 10位;10: 8位;11: 6位
	ADC_CTL0(ADC1) |=(0<<23);//0:常规序列看门狗禁止;1:常规序列看门狗使能
	
	ADC_CTL0(ADC1) |=(0<<11);//常规序列间断模式:0:间断运行模式禁止;1:间断运行模式使能
	ADC_CTL0(ADC1) |=(1<<8);//扫描模式:0:扫描运行模式禁止;1:扫描运行模式使能
	
	ADC_CTL1(ADC1) =0;//控制寄存器1清零
	ADC_CTL1(ADC1) |=(0<<28);//常规序列外部触发模式:
													//00:常规序列外部触发失能
													//01:常规序列外部触发上升沿使能
													//01:常规序列外部触发下降沿使能
													//11:常规序列外部触发双边沿使能
													
	ADC_CTL1(ADC1) |=(13<<24);//常规序列外部触发选择:1101: 定时器7通道0 ; 1110: 定时器7 TRGO
	ADC_CTL1(ADC1) |=(0<<11);//数据对齐:0:最低有效位对齐;1:最高有效位对齐
	ADC_CTL1(ADC1) |=(1<<9);//DMA失能模式
													//0:DMA机制在DMA控制器的传输结束信号之后失能。
													//1:当DMA=1,在每个常规转换结束时DMA机制产生一个DMA请求。
	
	ADC_CTL1(ADC1) |=(1<<8);//0:DMA请求禁止;1:DMA请求使能
	ADC_CTL1(ADC1) |=(0<<1);//0:禁止连续运行模式;1:使能连续运行模式
	
	ADC_SAMPT1(ADC1) =0;//采样时间寄存器清零
	ADC_SAMPT1(ADC1) |=(3<<0);//规则转换通道0采样时间:4-84周期,3-56,2-28
	
	ADC_RSQ0(ADC1) &=~(0X0F<<20);
	ADC_RSQ0(ADC1) |=(0<<20);//常规序列长度:常规通道转换序列中的总的通道数目为RL[3:0]+1。
	ADC_RSQ2(ADC1) =0;
	ADC_RSQ2(ADC1) |=(1<<0);//规则转换通道0 ->ADC_CH1

	ADC_OVSAMPCTL(ADC1)=0;
	ADC_OVSAMPCTL(ADC1) |=(4<<5);//移位4位, 14bit-0x3ffc
	ADC_OVSAMPCTL(ADC1) |=(5<<2);//过采样率:64x
	ADC_OVSAMPCTL(ADC1) |=(1<<0);//过采样使能
	
	/*************************** ADC1 END****************************/


	/*****************ADC开启及校准*******************/
	//ADC0
	//enable adc0
	ADC_CTL1(ADC0) |=(1<<0);//0:禁止ADC关闭电源;1:使能ADC
	DS_M4delay_us(500);
	ADC_CTL1(ADC0) |=(1<<3);//校准复位:0:校准寄存器初始化结束.;1:校准寄存器初始化开始
	ADC_CTL1(ADC0) |=(1<<2);//ADC校准:0:校准结束;1:校准开始
	while((ADC_CTL1(ADC0)&(1<<2))!=0);//等待校准完成
	
	//ADC1
	//enable adc1
	ADC_CTL1(ADC1) |=(1<<0);//0:禁止ADC关闭电源;1:使能ADC
	DS_M4delay_us(500);
	ADC_CTL1(ADC1) |=(1<<3);//校准复位:0:校准寄存器初始化结束.;1:校准寄存器初始化开始
	ADC_CTL1(ADC1) |=(1<<2);//ADC校准:0:校准结束;1:校准开始
	while((ADC_CTL1(ADC1)&(1<<2))!=0);//等待校准完成
	
	DS_M4delay_us(500);
}


uint32_t FOC_CURR_AB;
void ADC_DMA_init(void)
{
	RCU_AHB1EN |=(1<<22);//使能DMA1
	
	DMA_INTC0(DMA1) |=0X3D;//清除DMA1 CH0中断标志位
	
	DMA_CH0CTL(DMA1)=0;//(CHEN位为1时,其他位不能被配置,先清CHEN)。
	DMA_CH0CTL(DMA1) |=(0<<25);//PERIEN[2:0]-外设使能, 000:使能外设0
	DMA_CH0CTL(DMA1) |=(2<<16);//软件优先级:00:低;01:中;10:高;11:极高
	DMA_CH0CTL(DMA1) |=(2<<13);//存储器的传输数据宽度:00:8-bit;01:16-bit;10:32-bit;11:保留
	DMA_CH0CTL(DMA1) |=(2<<11);//外设的传输数据宽度:00:8-bit;01:16-bit;10:32-bit;11:保留
	DMA_CH0CTL(DMA1) |=(1<<10);//存储器的地址生成算法:0:固定地址模式;1:增量地址模式
	DMA_CH0CTL(DMA1) |=(0<<9);//外设的地址生成算法:0:固定地址模式;1:增量地址模式
	DMA_CH0CTL(DMA1) |=(1<<8);//0:禁止循环模式;1:使能循环模式(DMA作为传输控制器时有效)
	DMA_CH0CTL(DMA1) |=(0<<6);//传输方向:0:从外设读出并写入存储器;1:从存储器读出并写入外设
	DMA_CH0CTL(DMA1) |=(0<<5);//TFCS:传输控制器选择
														//0:DMA作为传输控制器
														//1:外设作为传输控制器
	
	DMA_CH0CTL(DMA1) |=(0<<18);//SBMEN:存储切换模式使能
															//0:关闭存储切换模式
															//1:打开存储切换模式
	
	DMA_CH0CTL(DMA1) |=(0<<19);//MBS:存储器缓冲选择
														//0:存储器0作为存储器传输区域
														//1:存储器1作为存储器传输区域
	
	DMA_CH0CTL(DMA1) |=(0<<2);//0:禁止通道错误中断
	DMA_CH0CTL(DMA1) |=(0<<3);//0:禁止通道半传输完成中断
	DMA_CH0CTL(DMA1) |=(0<<4);//0:禁止通道传输完成中断
	
	DMA_CH0CNT(DMA1) =0;
	DMA_CH0CNT(DMA1) |=(0X01<<0);//传输计数: 该寄存器表明还有多少数据等待被传输。一旦通道使能,该寄存器为只读的,并在每个DMA传输之后值减1。如果该寄存器的值为0,无论通道开启与否,都不会有数据传输。如果该通道工作在循环模式下,一旦通道的传输任务完成,该寄存器会被自动重装载为初始设置值。
	
	DMA_CH0PADDR(DMA1) = (uint32_t)(&ADC_SYNCDATA);//外设基地址
	DMA_CH0M0ADDR(DMA1) = (uint32_t)(&FOC_CURR_AB);//存储器基地址
	
	DMA_CH0CTL(DMA1) |=(1<<0);//0:禁止该通道;1:使能该通道
}


调用步骤如下:

	float ia,ib;
	/*adc采样**********/
	ADC_CTL1(ADC0)|=(1<<30);//SWRCST-常规序列软件启动转换
	while((DMA_INTF0(DMA1)&(1<<5))==0);//等待转换完成
	DMA_INTC0(DMA1) |=0X3D;//清除DMA1 CH0中断标志位
	
	ia=(float)((FOC_CURR_AB&0x3fff)*I_GAIN - I_OFFSET);
	ib=(float)((FOC_CURR_AB>>16)*I_GAIN - I_OFFSET);

	/***********/
	printf("i:%0.5f,%0.5f\n",ia,ib);

使用VOFA+读取数据绘制的曲线如下

在这里插入图片描述

Thanks,END。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木龠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值