GD32F30x系列ADC源码

  • 【1】adc_reg.h [参考]
  • 【2】ctrl_adc.h [重点]
  • 【3】gd32f30x_dma_reg.h [参考]
  • 【4】mon_adc.h [参考 +1]
  • 【5】rcu.h [参考]
  • 【6】ctrl_adc.c [重要]
  • 【7】mon_adc.c [参考+1]
  • 【8】main.c [参考+2]


这篇文章必须配合这个连接文件一起看,即ADC手册
嵌入式通用const和volatile和static inline关键字 (记得不懂const和volatile可以看这篇)


学习完ADC寄存器后,其他寄存器都是模仿式学习,做嵌入式重在坚持,贵在坚持


【1】adc_reg.h [参考]

#ifndef CTRL_ADC_H
#define CTRL_ADC_H
#ifdef __cplusplus
extern "C" {#endif#include <stdint.h>
#include <stdio.h>#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const    //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数#if defined(__CC_ARM)#pragma anon_unions   //keil中默认是不支持匿名结构体的,需要编译指令#pragma anon_unions指名。
#elif defined(CCARM__)#pragma language=extended //IAR对所用语言(这里是C)做的一些扩展,也就是说这里可以用扩展的功能
#elif defined (__ICCARM__)
/* anonymous unions are enabled by default:默认启用匿名联合 */
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)#pragma warning 586
#else#warning Not supported compiler type //警告不支持编译器类型
#endif/*============================控制MCU部分==========================*/
/* 通道号 */
#define ADC_CHANNEL_0                    0x00
#define ADC_CHANNEL_1                    0x01
#define ADC_CHANNEL_2                    0x02
#define ADC_CHANNEL_3                    0x03
#define ADC_CHANNEL_4                    0x04
#define ADC_CHANNEL_5                    0x05
#define ADC_CHANNEL_6                    0x06
#define ADC_CHANNEL_7                    0x07
#define ADC_CHANNEL_8                    0x08
#define ADC_CHANNEL_9                    0x09
#define ADC_CHANNEL_10                   0x0A
#define ADC_CHANNEL_11                   0x0B
#define ADC_CHANNEL_12                   0x0C
#define ADC_CHANNEL_13                   0x0D
#define ADC_CHANNEL_14                   0x0E
#define ADC_CHANNEL_15                   0x0F
#define ADC_CHANNEL_16                   0x10
#define ADC_CHANNEL_17                   0x11/* 规则组长度 ADC_RSQ0.Bits.RL */
#define REGULAR_LEN_1                    0x00
#define REGULAR_LEN_2                    0x01
#define REGULAR_LEN_3                    0x02
#define REGULAR_LEN_4                    0x03
#define REGULAR_LEN_5                    0x04
#define REGULAR_LEN_6                    0x05
#define REGULAR_LEN_7                    0x06
#define REGULAR_LEN_8                    0x07
#define REGULAR_LEN_9                    0x08
#define REGULAR_LEN_10                   0x09
#define REGULAR_LEN_11                   0x0A
#define REGULAR_LEN_12                   0x0B
#define REGULAR_LEN_13                   0x0C
#define REGULAR_LEN_14                   0x0D
#define REGULAR_LEN_15                   0x0E
#define REGULAR_LEN_16                   0x0F
/*注入组长度 注入通道,x=0,1,2,3  数据偏移值,取值范围为0~4095*/
#define INSERTED_LEN_1                    0x00
#define INSERTED_LEN_2                    0x01
#define INSERTED_LEN_3                    0x02
#define INSERTED_len_4                    0x03
/*ADC的采样时间*/
#define ADC_SAMPLETIME_1POINT5          //1.5 周期
#define ADC_SAMPLETIME_7POINT5          //7.5 周期
#define ADC_SAMPLETIME_13POINT5         //13.5 周期
#define ADC_SAMPLETIME_28POINT5         //28.5 周期
#define ADC_SAMPLETIME_41POINT5         //41.5 周期
#define ADC_SAMPLETIME_55POINT5         //55.5 周期
#define ADC_SAMPLETIME_71POINT5         //71.5 周期
#define ADC_SAMPLETIME_239POINT5        //239.5 周期/*ADC 分辨率*/
#define ADC_RESOLUTION_12B  //12位
#define ADC_RESOLUTION_10B  //10位
#define ADC_RESOLUTION_8B   //8位
#define ADC_RESOLUTION_6B   //6位/*ADC 通道组*/  //间断模式下的转换数目,规则通道组取值为1..8,注入通道组取值无意义
//ADC通道选择ADC_CHANNEL_x(x=0..17)  ADC 通道x (x=0..17)(只有ADC0,可取值x=16和17 )
#define ADC_REGULAR_CHANNEL //规则通道组
#define ADC_INSERTED_CHANNEL//注入通道组/*ADC 运行模式*/
#define ADC_MODE_FREE  //所有ADC运行于独立模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL //ADC0和ADC1运行在规则并行+注入并行组合模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION //ADC0和ADC1运行在规则并行+交替触发组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST    //ADC0和ADC1运行在注入并行+快速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW    //ADC0和ADC1运行在注入并行+慢速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL      //ADC0和ADC1运行在注入并行模式
#define ADC_DAUL_REGULAL_PARALLEL       //ADC0和ADC1运行在规则并行模式
#define ADC_DAUL_REGULAL_FOLLOWUP_FAST  //ADC0和ADC1运行在快速交叉模式
#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW  //ADC0和ADC1运行在慢速交叉模式
#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION //ADC0和ADC1运行在交替触发模式/*ADC 功能配置*/
#define ADC_SCAN_MODE               //扫描模式选择
#define ADC_INSERTED_CHANNEL_AUTO   //注入组自动转换
#define ADC_CONTINUOUS_MODE         //连续模式选择/*ADC 规则通道组或注入通道组触发源*/
#define ADC0_1_EXTTRIG_REGULAR_T0_CH0           //TIMER0 CH0事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH1           //TIMER0 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH2           //TIMER0 CH2事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T1_CH1           //TIMER1 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO          //TIMER2TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T3_CH3           //TIMER3 CH3事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T7_TRGO          //TIMER7 TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_EXTI_11          //外部中断线11(规则组)
#define ADC2_EXTTRIG_REGULAR_T2_CH0             //TIMER2 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T1_CH2             //TIMER1 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T0_CH2             //TIMER0 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_CH0             //TIMER7CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_TRGO            //TIMER7  TRGO事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH0             //TIMER4 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH2             //TIMER4  CH2事件(规则组)
#define ADC0_1_2_EXTTRIG_REGULAR_NONE           //软件触发(规则组)
#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO         //TIMER0 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T0_CH3          //TIMER0 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO         //TIMER1 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_CH0          //TIMER1 CH0事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T2_CH3          //TIMER2 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO         //TIMER3 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_EXTI_15         //外部中断线15 (注入组)
#define ADC0_1_EXTTRIG_INSERTED_T7_CH3          //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_TRGO           //TIMER0 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_CH3            //TIMER0 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T3_CH2            //TIMER3 CH2事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH1            //TIMER7 CH1事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH3            //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_TRGO           //TIMER4 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_CH3            //TIMER4 CH3事件(注入组)
#define ADC0_1_2_EXTTRIG_INSERTED_NONE          //软件触发(注入组)/*ADC标志位*/
#define ADC_FLAG_WDE    //模拟看门狗事件标志位
#define ADC_FLAG_EOC    //转换结束标志位
#define ADC_FLAG_EOIC   //注入通道组转换结束标志位
#define ADC_FLAG_STIC   //注入通道组转换开始标志位
#define ADC_FLAG_STRC   //规则通道组转换开始标志位/*ADC过采样触发模式*/
#define ADC_OVERSAMPLING_ALL_CONVERT        //在一个触发之后,对一个通道连续进行过采样转换
#define ADC_OVERSAMPLING_ONE_CONVERT        //在一个触发之后,对一个通道只进行一次过采样转换
typedef struct {union{struct//ADC标志位  从低位->高位{   //WDE-》转换电压超过ADC_WDLT和ADC_WDHT寄存器设定的阈值时由硬件置1,软件写0清除。__IO uint32_t WDE              :1;      //模拟看门狗事件 1:产生模拟看门狗事件 0:没有模拟看门狗事件__IO uint32_t EOC              :1;      //组转换结束    1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除或读ADC_RDATA寄存器清除__IO uint32_t EOIC             :1;      //注入通道组转换结束 1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除__IO uint32_t STIC             :1;      //注入通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除__IO uint32_t STRC             :1;      //规则通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除__IO uint32_t                  :27;     //保留 必须保留复位值}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 C000 -》0000 0000 0000 0000 1100 0000 0000 0000 (32位)}ADC_STAT;    // 地址偏移: 0x00   状态寄存器union{struct{__IO uint32_t WDCHSEL          :5; //模拟看门狗通道选择/**  00000: ADC 通道 000001: ADC 通道 100010: ADC 通道 200011: ADC 通道 300100: ADC 通道 400101: ADC 通道 500110: ADC 通道 600111: ADC 通道 701000: ADC 通道 801001: ADC 通道 901010: ADC 通道 1001011: ADC 通道 1101100: ADC 通道 1201101: ADC 通道 1301110: ADC 通道 1401111: ADC 通道 1510000: ADC 通道 1610001: ADC 通道 17其他值保留注意: ADC0 的模拟输入通道 16 和通道 17 分别连接到温度传感器和 VREFINT。ADC1 的模拟输入通道 16 和通道 17 内部都连接到 VSSA。 ADC2 的模拟输入通道16 和通道 17 内部都连接到 VSSA。*/__IO uint32_t EOCIE            :1; //EOC中断使能    0:EOC 中断禁止 1:EOC 中断使能__IO uint32_t WDEIE            :1; //模拟看门狗事件 中断使能 0:WDE 中断禁止 1:WDE 中断使能__IO uint32_t EOICIE           :1;  //EOIC 中断使能 0:禁止 1:使能__IO uint32_t SM               :1;  //扫描转换模式   0:禁止 1:使能__IO uint32_t WDSC             :1;  //扫描模式下,模拟看门狗在单通道有效 0:模拟看门狗在所有通道有效 1:模拟看门狗在单通道有效__IO uint32_t ICA              :1;  //注入组自动转换  0:禁止 1:使能__IO uint32_t DISRC            :1;  //规则组间断模式  0:禁止 1:使能__IO uint32_t DISIC            :1;  //注入组间断模式  0:禁止 1:使能__IO uint32_t DISNUM           :3;  //间断模式下的转换数目 触发后即将被转换的通道数目将变成 DISNUM[2:0]+1__IO uint32_t SYNCM            :4;  //ADC 同步模式选择 0000:独立模式/*0000:独立模式0001:规则并行+注入并行组合模式0010:规则并行+交替触发组合模式0011:注入并行+快速交叉组合模式0100:注入并行+慢速交叉组合模式0101:注入并行模式0110:规则并行模式0111:快速交叉模式1000:慢速交叉模式1001:交替触发模式注意:在 ADC1 和 ADC2 中这些位为保留位。在同步模式下,改变通道的配置会产生一个重新开始的条件,会导致同步丢失,建议在任何配置之前关闭同步模式。*/__IO uint32_t                  :2;__IO uint32_t IWDEN            :1;//注入组看门狗使能 0:禁止 1:使能__IO uint32_t RWDEN            :1;//规则组看门狗使能 0:禁止 1:使能__IO uint32_t                  :8;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_CTL0;    // 地址偏移: 0x04    控制寄存器 0union{struct{__IO uint32_t ADCON            :1;  //ADC 上电使能位 0:禁止 ADC 关闭电源 1:使能 ADC/*开启 ADC。该位从‘0’变成‘1’将在稳定时间结束后唤醒 ADC。当该位被置位以后,不改变寄存器的其他位仅仅对该位写‘1’, 将开启转换。*/__IO uint32_t CTN              :1;  //0:禁止连续模式,1:使能连续模式__IO uint32_t CLB              :1;  /* ADC 校准 : 0:校准结束  1:校准开始 */__IO uint32_t RSTCLB           :1;  /* 校准复位: 软件置位(1), 在校准寄存器初始化后该位硬件清零 0:校准结束  1:校准开始*/__IO uint32_t                  :4;  //7:4 保留 必须保持复位值。__IO uint32_t DMA              :1;  //DMA 请求使能 0:禁止 1:使能__IO uint32_t                  :2;  //10:9 保留 必须保持复位值。__IO uint32_t DAL              :1;  //数据对齐 0:最低有效位对齐 1:最高有效位对齐__IO uint32_t ETSIC            :3;  //注入组外部触发选择/*14:12 ETSIC[2:0]对于 ADC0 与 ADC1:000:定时器 0 TRGO001:定时器 0 CH3010:定时器 1 TRGO011:定时器 1 CH0100:定时器 2 CH3101:定时器 3 TRGO110:中断线 15/定时器 7 CH3111:软件触发对于 ADC2:000:定时器 0 TRGO001:定时器 0 CH3010:定时器 3 CH2011:定时器 7 CH1100:定时器 7 CH3101:定时器 4 TRGO110:定时器 4 CH3111:软件触发*/__IO uint32_t ETEIC            :1;  //注入组外部触发使能 0:禁止 1:使能__IO uint32_t                  :1;  //必须保持复位值。__IO uint32_t ETSRC            :3;  //规则组外部触发选择: 111:软件触发/*19:17 ETSRC[2:0]对于 ADC0 与 ADC1:000:定时器 0 CH0001:定时器 0 CH1010:定时器 0 CH2011:定时器 1 CH1100:定时器 2 TRGO101:定时器 3 CH3110:中断线 11/定时器 7 TRGO111:软件触发对于 ADC2:000:定时器 2 CH0001:定时器 1 CH2010:定时器 0 CH2011:定时器 7 CH0100:定时器 7 TRGO101:定时器 4 CH0110:定时器 4 CH2111:软件触发*/__IO uint32_t ETERC            :1;  //规则组外部触发使能 0:禁止 1:使能__IO uint32_t SWICST           :1;  //注入组转换开始: 如果 ETSRC 是 111,该位置‘1’开启规则组转换。软件置位,软件清零,或转换开始后,由硬件清零__IO uint32_t SWRCST           :1;  //规则组转换开始: 如果 ETSIC 是 111,该位置‘1’开启注入组转换。软件置位,软件清零,或转换开始后,由硬件清零__IO uint32_t TSVREN           :1;  // 将ADC_CTL1 寄存器的 TSVREN 位置 1可以使能温度传感器通道(ADC0_CH16)和 VREFINT通道(ADC0_CH17)。__IO uint32_t                  :8;  //保留 必须保持复位值}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_CTL1;    // 地址偏移: 0x08    控制寄存器 1union{struct{__IO uint32_t SPT10            :3;//通道采样时间/*000:1.5     周期001:7.5     周期010:13.5    周期011:28.5    周期100:41.5    周期101:55.5    周期110:71.5    周期111:239.5   周期*/__IO uint32_t SPT11            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT12            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT13            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT14            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT15            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT16            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT17            :3;//参考 SPT10[2:0]的描述__IO uint32_t                  :8;//31:24 保留 必须保持复位值。}Bits;  0000 0000 1111 1111 1111 1111 11111 1111__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_SAMPT0;    // 地址偏移: 0x0C    采样时间寄存器 0union{struct{__IO uint32_t SPT0            :3;//通道采样时间/*000:1.5 周期001:7.5 周期010:13.5 周期011:28.5 周期100:41.5 周期101:55.5 周期110:71.5 周期111:239.5 周期*/__IO uint32_t SPT1            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT2            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT3            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT4            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT5            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT6            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT7            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT8            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT9            :3;//参考 SPT0[2:0]的描述__IO uint32_t                 :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_SAMPT1;    // 地址偏移: 0x10    采样时间寄存器 1union{struct{__IO uint32_t IOFF            :12;//注入通道 x 的数据偏移/*当转换注入通道时,这些位定义了用于从原始转换数据中减去的数值。转换的结果可以在 ADC_IDATAx 寄存器中读出。*/__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF0;    // 地址偏移: 0x14    注入通道数据偏移寄存器 0union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF1;    // 地址偏移: 0x18    注入通道数据偏移寄存器 1union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF2;    // 地址偏移: 0x1C    注入通道数据偏移寄存器 2union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF3;    // 地址偏移: 0x20    注入通道数据偏移寄存器 3union{struct{__IO uint32_t WDHT            :12;//模拟看门狗高阈值__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_WDHT;    // 地址偏移: 0x24    看门狗高阈值寄存器    模拟看门狗高阈值,0..4095union{struct{__IO uint32_t WDLT            :12;//模拟看门狗低阈值 这些位定义了模拟看门狗的低阈值。__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_WDLT;    // 地址偏移: 0x28    看门狗低阈值寄存器    模拟看门狗低阈值,0..4095union{struct{__IO uint32_t RSQ12            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ13            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ14            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ15            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RL               :4;//规则组长度,0-F表示1-16个 规则通道转换序列中的总的通道数目为 RL[3:0]+1。__IO uint32_t                  :8;//31:24 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ0;    // 地址偏移: 0x2C    规则序列寄存器 0union{struct{__IO uint32_t RSQ6             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ7             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ8             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ9             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ10            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ11            :5;//参考 RSQ0[4:0]的描述__IO uint32_t                  :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ1;    // 地址偏移: 0x30    规则序列寄存器 1union{struct{__IO uint32_t RSQ0             :5;//通道编号(0..17)写入这些位来选择规则通道的第 n 个转换的通道__IO uint32_t RSQ1             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ2             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ3             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ4             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ5             :5;//参考 RSQ0[4:0]的描述__IO uint32_t                  :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ2;    // 地址偏移: 0x34    规则序列寄存器 2union{struct{__IO uint32_t ISQ0             :5;//通道编号(0..17)写入这些位来选择注入组的第 n 个转换的通道/*和规则通道转换序列不同的是,如果 IL[1:0]长度不足 4,注入通道转换从(4-IL[1:0]-1) 开始。IL 注入通道转换顺序3 ISQ0 >> ISQ1 >> ISQ2 >> ISQ32 ISQ1 >> ISQ2 >> ISQ31 ISQ2 >> ISQ30 ISQ3*/__IO uint32_t ISQ1             :5;//参考 ISQ0[4:0]的描述__IO uint32_t ISQ2             :5;//参考 ISQ0[4:0]的描述__IO uint32_t ISQ3             :5;//参考 ISQ0[4:0]的描述__IO uint32_t IL               :2;//注入序列长度 注入组总的通道数目为 IL[1:0]+1。__IO uint32_t                  :10;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_ISQ;    // 地址偏移: 0x38    注入序列寄存器union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA0;    // 地址偏移: 0x3C    注入数据寄存器 0union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA1;    // 地址偏移: 0x40    注入数据寄存器 1union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA2;    // 地址偏移: 0x44    注入数据寄存器 2union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA3;    // 地址偏移: 0x48    注入数据寄存器 3union{struct{__I uint32_t RDATA             :16; //规则通道数据 这些位包含了规则通道的转换结果,只读。/*ADC0:在同步模式下,这些位包含着 ADC1 的规则通道数据ADC1 和 ADC2:这些位没有使用.*/__I uint32_t ADC1RDTR          :16; //规则通道数据 ADC1}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RDATA;    // 地址偏移: 0x4C    规则数据寄存器
/*============================================================================*///注意:当 ADCON= 0 时软件才允许写该位(确定没有转换正在进行) 本次项目禁用这项union{struct{__IO uint32_t OVSEN :1;  //过滤采样使能 0:过滤采样失能 1:过滤采样使能 注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行)__IO uint32_t :1;   //1 保留 必须保持复位值。__IO uint32_t OVSR  :3;  //过采样率/*这些位定义了过采样率的大小.000:2x001:4x010:8x011:16x100:32x101:64x110:128x111:256x注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行)*/__IO uint32_t OVSS  :4;  //过滤采样移位/*该位通过软件设置和清除.0000:不移位0001:移 1 位0010:移 2 位0011:移 3 位0100:移 4 位0101:移 5 位0110:移 6 位0111:移 7 位1000:移 8 位其他保留注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行).*/__IO uint32_t TOVS  :1;  //触发过滤采样/*该位通过软件设置和清除.0:所有的过滤采样连续转换完成一个触发后1:对于过采样通道的每次转换都需要一次触发,触发次数由过采样率(OVSR[2:0])决定。注意:当 ADCON= 0 时软件才允许写该位(确定没有转换正在进行).*/__IO uint32_t :2;__IO uint32_t DRES  :2;  //ADC 分辨率/*13:12 DRES[1:0] ADC 分辨率ADC 分辨率00:12 位01:10 位10:8 位11:6 位*/__IO uint32_t :18;}Bits;__I uint32_t Byte;}ADC_OVSAMPCTL;//过采样控制寄存器 地址偏移:0x80  复位值:0x0000 0000
} ADC_Type;typedef enum IRQn
{/* interruput numbers */WWDGT_IRQn                   = 0,      /*!<看门狗定时器中断              */RCU_CTC_IRQn                 = 5,      /*!< RCU_BASE and CTC interrupt                                    */ADC0_1_IRQn                  = 18,     /*!< ADC0 and ADC1 interrupt                                  */
}IRQn_Type;/* 总线映射 */
#define APB1_BUS_BASE         ((uint32_t)0x40000000U)
#define APB2_BUS_BASE         ((uint32_t)0x40010000U)
#define AHB1_BUS_BASE         ((uint32_t)0x40018000U)
#define AHB3_BUS_BASE         ((uint32_t)0x60000000U)/* APB2内存映射 */
#define ADC_BASE              (APB2_BUS_BASE + 0x00002400U)/* ADC寄存器地址偏移 */
/* ADC0基地址:0x4001 2400* ADC1基地址:0x4001 2800* ADC2基地址:0x4001 3C00*/
#define ADC0_BASE             (ADC_BASE + 0x00000000U)
#define ADC1_BASE             (ADC_BASE + 0x00000400U)
//#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
#define ADC2_BASE             (ADC_BASE + 0x00001800U)#define ADC0              ((ADC_Type *)(ADC0_BASE))
#define ADC1              ((ADC_Type *)(ADC1_BASE))
#define ADC2              ((ADC_Type *)(ADC2_BASE))#define ADC_BASES         {ADC0, ADC1, ADC2}#define BUTTON_SAMPLE_CNT        11#define CHECK_BY_AD       1  //1以AD值方式对比,0以电压方式对比typedef enum      /* 等号左边为电磁阀管路图编号 */
{                   /* 右边数字为原理图中的电磁阀编号 ,0表示没有使用到 */V101 = 1,V102 = 2,V103 = 3,V104 = 4,V105 = 5,V106 = 6,V107 = 7,V108 = 8,V109 = 9,V110 = 10,V201 = 11,V202 = 12,V203 = 13,V204 = 14,V205 = 15,V206 = 16,V207 = 17,V208 = 18,V209 = 19,V210 = 20,V301 = 21,V302 = 22,V303 = 23,V304 = 24,V305 = 25,V306 = 26,V307 = 27,V308 = 28,V309 = 29,V310 = 30,V401 = 31,V402 = 32,V403 = 33,V404 = 34,V405 = 35,V406 = 36,V407 = 37,V408 = 38,V409 = 39,V410 = 40,
} e_Vxxx;void Adc0_Init(void);
void Adc0_GetRSQVal(uint16_t *array, uint8_t offset, uint8_t len);void RB_ADC_Init(void);
void RB_ADC_ScanButton(void);
void Fun_BubbleSort(uint16_t *array, uint8_t len, uint8_t sort_dir);
void RB_ADC_ScanButton2(void);#ifdef __cplusplus
}
#endif
#endif // CTRL_ADC_H

【2】ctrl_adc.h [重点]

#ifndef CTRL_ADC_H
#define CTRL_ADC_H
#ifdef __cplusplus
extern "C" {#endif#include <stdint.h>
#include <stdio.h>#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const    //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数#if defined(__CC_ARM)#pragma anon_unions   //keil中默认是不支持匿名结构体的,需要编译指令#pragma anon_unions指名。
#elif defined(CCARM__)#pragma language=extended //IAR对所用语言(这里是C)做的一些扩展,也就是说这里可以用扩展的功能
#elif defined (__ICCARM__)
/* anonymous unions are enabled by default:默认启用匿名联合 */
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)#pragma warning 586
#else#warning Not supported compiler type //警告不支持编译器类型
#endif/*============================控制MCU部分==========================*/
/* 通道号 */
#define ADC_CHANNEL_0                    0x00
#define ADC_CHANNEL_1                    0x01
#define ADC_CHANNEL_2                    0x02
#define ADC_CHANNEL_3                    0x03
#define ADC_CHANNEL_4                    0x04
#define ADC_CHANNEL_5                    0x05
#define ADC_CHANNEL_6                    0x06
#define ADC_CHANNEL_7                    0x07
#define ADC_CHANNEL_8                    0x08
#define ADC_CHANNEL_9                    0x09
#define ADC_CHANNEL_10                   0x0A
#define ADC_CHANNEL_11                   0x0B
#define ADC_CHANNEL_12                   0x0C
#define ADC_CHANNEL_13                   0x0D
#define ADC_CHANNEL_14                   0x0E
#define ADC_CHANNEL_15                   0x0F
#define ADC_CHANNEL_16                   0x10
#define ADC_CHANNEL_17                   0x11/* 规则组长度 ADC_RSQ0.Bits.RL */
#define REGULAR_LEN_1                    0x00
#define REGULAR_LEN_2                    0x01
#define REGULAR_LEN_3                    0x02
#define REGULAR_LEN_4                    0x03
#define REGULAR_LEN_5                    0x04
#define REGULAR_LEN_6                    0x05
#define REGULAR_LEN_7                    0x06
#define REGULAR_LEN_8                    0x07
#define REGULAR_LEN_9                    0x08
#define REGULAR_LEN_10                   0x09
#define REGULAR_LEN_11                   0x0A
#define REGULAR_LEN_12                   0x0B
#define REGULAR_LEN_13                   0x0C
#define REGULAR_LEN_14                   0x0D
#define REGULAR_LEN_15                   0x0E
#define REGULAR_LEN_16                   0x0F
/*注入组长度 注入通道,x=0,1,2,3  数据偏移值,取值范围为0~4095*/
#define INSERTED_LEN_1                    0x00
#define INSERTED_LEN_2                    0x01
#define INSERTED_LEN_3                    0x02
#define INSERTED_len_4                    0x03
/*ADC的采样时间*/
#define ADC_SAMPLETIME_1POINT5          //1.5 周期
#define ADC_SAMPLETIME_7POINT5          //7.5 周期
#define ADC_SAMPLETIME_13POINT5         //13.5 周期
#define ADC_SAMPLETIME_28POINT5         //28.5 周期
#define ADC_SAMPLETIME_41POINT5         //41.5 周期
#define ADC_SAMPLETIME_55POINT5         //55.5 周期
#define ADC_SAMPLETIME_71POINT5         //71.5 周期
#define ADC_SAMPLETIME_239POINT5        //239.5 周期/*ADC 分辨率*/
#define ADC_RESOLUTION_12B  //12位
#define ADC_RESOLUTION_10B  //10位
#define ADC_RESOLUTION_8B   //8位
#define ADC_RESOLUTION_6B   //6位/*ADC 通道组*/  //间断模式下的转换数目,规则通道组取值为1..8,注入通道组取值无意义
//ADC通道选择ADC_CHANNEL_x(x=0..17)  ADC 通道x (x=0..17)(只有ADC0,可取值x=16和17 )
#define ADC_REGULAR_CHANNEL //规则通道组
#define ADC_INSERTED_CHANNEL//注入通道组/*ADC 运行模式*/
#define ADC_MODE_FREE  //所有ADC运行于独立模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL //ADC0和ADC1运行在规则并行+注入并行组合模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION //ADC0和ADC1运行在规则并行+交替触发组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST    //ADC0和ADC1运行在注入并行+快速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW    //ADC0和ADC1运行在注入并行+慢速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL      //ADC0和ADC1运行在注入并行模式
#define ADC_DAUL_REGULAL_PARALLEL       //ADC0和ADC1运行在规则并行模式
#define ADC_DAUL_REGULAL_FOLLOWUP_FAST  //ADC0和ADC1运行在快速交叉模式
#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW  //ADC0和ADC1运行在慢速交叉模式
#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION //ADC0和ADC1运行在交替触发模式/*ADC 功能配置*/
#define ADC_SCAN_MODE               //扫描模式选择
#define ADC_INSERTED_CHANNEL_AUTO   //注入组自动转换
#define ADC_CONTINUOUS_MODE         //连续模式选择/*ADC 规则通道组或注入通道组触发源*/
#define ADC0_1_EXTTRIG_REGULAR_T0_CH0           //TIMER0 CH0事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH1           //TIMER0 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH2           //TIMER0 CH2事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T1_CH1           //TIMER1 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO          //TIMER2TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T3_CH3           //TIMER3 CH3事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T7_TRGO          //TIMER7 TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_EXTI_11          //外部中断线11(规则组)
#define ADC2_EXTTRIG_REGULAR_T2_CH0             //TIMER2 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T1_CH2             //TIMER1 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T0_CH2             //TIMER0 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_CH0             //TIMER7CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_TRGO            //TIMER7  TRGO事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH0             //TIMER4 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH2             //TIMER4  CH2事件(规则组)
#define ADC0_1_2_EXTTRIG_REGULAR_NONE           //软件触发(规则组)
#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO         //TIMER0 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T0_CH3          //TIMER0 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO         //TIMER1 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_CH0          //TIMER1 CH0事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T2_CH3          //TIMER2 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO         //TIMER3 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_EXTI_15         //外部中断线15 (注入组)
#define ADC0_1_EXTTRIG_INSERTED_T7_CH3          //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_TRGO           //TIMER0 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_CH3            //TIMER0 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T3_CH2            //TIMER3 CH2事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH1            //TIMER7 CH1事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH3            //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_TRGO           //TIMER4 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_CH3            //TIMER4 CH3事件(注入组)
#define ADC0_1_2_EXTTRIG_INSERTED_NONE          //软件触发(注入组)/*ADC标志位*/
#define ADC_FLAG_WDE    //模拟看门狗事件标志位
#define ADC_FLAG_EOC    //转换结束标志位
#define ADC_FLAG_EOIC   //注入通道组转换结束标志位
#define ADC_FLAG_STIC   //注入通道组转换开始标志位
#define ADC_FLAG_STRC   //规则通道组转换开始标志位/*ADC过采样触发模式*/
#define ADC_OVERSAMPLING_ALL_CONVERT        //在一个触发之后,对一个通道连续进行过采样转换
#define ADC_OVERSAMPLING_ONE_CONVERT        //在一个触发之后,对一个通道只进行一次过采样转换
typedef struct {union{struct//ADC标志位  从低位->高位{   //WDE-》转换电压超过ADC_WDLT和ADC_WDHT寄存器设定的阈值时由硬件置1,软件写0清除。__IO uint32_t WDE              :1;      //模拟看门狗事件 1:产生模拟看门狗事件 0:没有模拟看门狗事件__IO uint32_t EOC              :1;      //组转换结束    1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除或读ADC_RDATA寄存器清除__IO uint32_t EOIC             :1;      //注入通道组转换结束 1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除__IO uint32_t STIC             :1;      //注入通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除__IO uint32_t STRC             :1;      //规则通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除__IO uint32_t                  :27;     //保留 必须保留复位值}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 C000 -》0000 0000 0000 0000 1100 0000 0000 0000 (32位)}ADC_STAT;    // 地址偏移: 0x00   状态寄存器union{struct{__IO uint32_t WDCHSEL          :5; //模拟看门狗通道选择/**  00000: ADC 通道 000001: ADC 通道 100010: ADC 通道 200011: ADC 通道 300100: ADC 通道 400101: ADC 通道 500110: ADC 通道 600111: ADC 通道 701000: ADC 通道 801001: ADC 通道 901010: ADC 通道 1001011: ADC 通道 1101100: ADC 通道 1201101: ADC 通道 1301110: ADC 通道 1401111: ADC 通道 1510000: ADC 通道 1610001: ADC 通道 17其他值保留注意: ADC0 的模拟输入通道 16 和通道 17 分别连接到温度传感器和 VREFINT。ADC1 的模拟输入通道 16 和通道 17 内部都连接到 VSSA。 ADC2 的模拟输入通道16 和通道 17 内部都连接到 VSSA。*/__IO uint32_t EOCIE            :1; //EOC中断使能    0:EOC 中断禁止 1:EOC 中断使能__IO uint32_t WDEIE            :1; //模拟看门狗事件 中断使能 0:WDE 中断禁止 1:WDE 中断使能__IO uint32_t EOICIE           :1;  //EOIC 中断使能 0:禁止 1:使能__IO uint32_t SM               :1;  //扫描转换模式   0:禁止 1:使能__IO uint32_t WDSC             :1;  //扫描模式下,模拟看门狗在单通道有效 0:模拟看门狗在所有通道有效 1:模拟看门狗在单通道有效__IO uint32_t ICA              :1;  //注入组自动转换  0:禁止 1:使能__IO uint32_t DISRC            :1;  //规则组间断模式  0:禁止 1:使能__IO uint32_t DISIC            :1;  //注入组间断模式  0:禁止 1:使能__IO uint32_t DISNUM           :3;  //间断模式下的转换数目 触发后即将被转换的通道数目将变成 DISNUM[2:0]+1__IO uint32_t SYNCM            :4;  //ADC 同步模式选择 0000:独立模式/*0000:独立模式0001:规则并行+注入并行组合模式0010:规则并行+交替触发组合模式0011:注入并行+快速交叉组合模式0100:注入并行+慢速交叉组合模式0101:注入并行模式0110:规则并行模式0111:快速交叉模式1000:慢速交叉模式1001:交替触发模式注意:在 ADC1 和 ADC2 中这些位为保留位。在同步模式下,改变通道的配置会产生一个重新开始的条件,会导致同步丢失,建议在任何配置之前关闭同步模式。*/__IO uint32_t                  :2;__IO uint32_t IWDEN            :1;//注入组看门狗使能 0:禁止 1:使能__IO uint32_t RWDEN            :1;//规则组看门狗使能 0:禁止 1:使能__IO uint32_t                  :8;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_CTL0;    // 地址偏移: 0x04    控制寄存器 0union{struct{__IO uint32_t ADCON            :1;  //ADC 上电使能位 0:禁止 ADC 关闭电源 1:使能 ADC/*开启 ADC。该位从‘0’变成‘1’将在稳定时间结束后唤醒 ADC。当该位被置位以后,不改变寄存器的其他位仅仅对该位写‘1’, 将开启转换。*/__IO uint32_t CTN              :1;  //0:禁止连续模式,1:使能连续模式__IO uint32_t CLB              :1;  /* ADC 校准 : 0:校准结束  1:校准开始 */__IO uint32_t RSTCLB           :1;  /* 校准复位: 软件置位(1), 在校准寄存器初始化后该位硬件清零 0:校准结束  1:校准开始*/__IO uint32_t                  :4;  //7:4 保留 必须保持复位值。__IO uint32_t DMA              :1;  //DMA 请求使能 0:禁止 1:使能__IO uint32_t                  :2;  //10:9 保留 必须保持复位值。__IO uint32_t DAL              :1;  //数据对齐 0:最低有效位对齐 1:最高有效位对齐__IO uint32_t ETSIC            :3;  //注入组外部触发选择/*14:12 ETSIC[2:0]对于 ADC0 与 ADC1:000:定时器 0 TRGO001:定时器 0 CH3010:定时器 1 TRGO011:定时器 1 CH0100:定时器 2 CH3101:定时器 3 TRGO110:中断线 15/定时器 7 CH3111:软件触发对于 ADC2:000:定时器 0 TRGO001:定时器 0 CH3010:定时器 3 CH2011:定时器 7 CH1100:定时器 7 CH3101:定时器 4 TRGO110:定时器 4 CH3111:软件触发*/__IO uint32_t ETEIC            :1;  //注入组外部触发使能 0:禁止 1:使能__IO uint32_t                  :1;  //必须保持复位值。__IO uint32_t ETSRC            :3;  //规则组外部触发选择: 111:软件触发/*19:17 ETSRC[2:0]对于 ADC0 与 ADC1:000:定时器 0 CH0001:定时器 0 CH1010:定时器 0 CH2011:定时器 1 CH1100:定时器 2 TRGO101:定时器 3 CH3110:中断线 11/定时器 7 TRGO111:软件触发对于 ADC2:000:定时器 2 CH0001:定时器 1 CH2010:定时器 0 CH2011:定时器 7 CH0100:定时器 7 TRGO101:定时器 4 CH0110:定时器 4 CH2111:软件触发*/__IO uint32_t ETERC            :1;  //规则组外部触发使能 0:禁止 1:使能__IO uint32_t SWICST           :1;  //注入组转换开始: 如果 ETSRC 是 111,该位置‘1’开启规则组转换。软件置位,软件清零,或转换开始后,由硬件清零__IO uint32_t SWRCST           :1;  //规则组转换开始: 如果 ETSIC 是 111,该位置‘1’开启注入组转换。软件置位,软件清零,或转换开始后,由硬件清零__IO uint32_t TSVREN           :1;  // 将ADC_CTL1 寄存器的 TSVREN 位置 1可以使能温度传感器通道(ADC0_CH16)和 VREFINT通道(ADC0_CH17)。__IO uint32_t                  :8;  //保留 必须保持复位值}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_CTL1;    // 地址偏移: 0x08    控制寄存器 1union{struct{__IO uint32_t SPT10            :3;//通道采样时间/*000:1.5     周期001:7.5     周期010:13.5    周期011:28.5    周期100:41.5    周期101:55.5    周期110:71.5    周期111:239.5   周期*/__IO uint32_t SPT11            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT12            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT13            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT14            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT15            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT16            :3;//参考 SPT10[2:0]的描述__IO uint32_t SPT17            :3;//参考 SPT10[2:0]的描述__IO uint32_t                  :8;//31:24 保留 必须保持复位值。}Bits;  0000 0000 1111 1111 1111 1111 11111 1111__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_SAMPT0;    // 地址偏移: 0x0C    采样时间寄存器 0union{struct{__IO uint32_t SPT0            :3;//通道采样时间/*000:1.5 周期001:7.5 周期010:13.5 周期011:28.5 周期100:41.5 周期101:55.5 周期110:71.5 周期111:239.5 周期*/__IO uint32_t SPT1            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT2            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT3            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT4            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT5            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT6            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT7            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT8            :3;//参考 SPT0[2:0]的描述__IO uint32_t SPT9            :3;//参考 SPT0[2:0]的描述__IO uint32_t                 :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_SAMPT1;    // 地址偏移: 0x10    采样时间寄存器 1union{struct{__IO uint32_t IOFF            :12;//注入通道 x 的数据偏移/*当转换注入通道时,这些位定义了用于从原始转换数据中减去的数值。转换的结果可以在 ADC_IDATAx 寄存器中读出。*/__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF0;    // 地址偏移: 0x14    注入通道数据偏移寄存器 0union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF1;    // 地址偏移: 0x18    注入通道数据偏移寄存器 1union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF2;    // 地址偏移: 0x1C    注入通道数据偏移寄存器 2union{struct{__IO uint32_t IOFF            :12;__IO uint32_t                 :20;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IOFF3;    // 地址偏移: 0x20    注入通道数据偏移寄存器 3union{struct{__IO uint32_t WDHT            :12;//模拟看门狗高阈值__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_WDHT;    // 地址偏移: 0x24    看门狗高阈值寄存器    模拟看门狗高阈值,0..4095union{struct{__IO uint32_t WDLT            :12;//模拟看门狗低阈值 这些位定义了模拟看门狗的低阈值。__IO uint32_t                 :20;//31:12 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_WDLT;    // 地址偏移: 0x28    看门狗低阈值寄存器    模拟看门狗低阈值,0..4095union{struct{__IO uint32_t RSQ12            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ13            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ14            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ15            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RL               :4;//规则组长度,0-F表示1-16个 规则通道转换序列中的总的通道数目为 RL[3:0]+1。__IO uint32_t                  :8;//31:24 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ0;    // 地址偏移: 0x2C    规则序列寄存器 0union{struct{__IO uint32_t RSQ6             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ7             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ8             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ9             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ10            :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ11            :5;//参考 RSQ0[4:0]的描述__IO uint32_t                  :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ1;    // 地址偏移: 0x30    规则序列寄存器 1union{struct{__IO uint32_t RSQ0             :5;//通道编号(0..17)写入这些位来选择规则通道的第 n 个转换的通道__IO uint32_t RSQ1             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ2             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ3             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ4             :5;//参考 RSQ0[4:0]的描述__IO uint32_t RSQ5             :5;//参考 RSQ0[4:0]的描述__IO uint32_t                  :2;//31:30 保留 必须保持复位值。}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RSQ2;    // 地址偏移: 0x34    规则序列寄存器 2union{struct{__IO uint32_t ISQ0             :5;//通道编号(0..17)写入这些位来选择注入组的第 n 个转换的通道/*和规则通道转换序列不同的是,如果 IL[1:0]长度不足 4,注入通道转换从(4-IL[1:0]-1) 开始。IL 注入通道转换顺序3 ISQ0 >> ISQ1 >> ISQ2 >> ISQ32 ISQ1 >> ISQ2 >> ISQ31 ISQ2 >> ISQ30 ISQ3*/__IO uint32_t ISQ1             :5;//参考 ISQ0[4:0]的描述__IO uint32_t ISQ2             :5;//参考 ISQ0[4:0]的描述__IO uint32_t ISQ3             :5;//参考 ISQ0[4:0]的描述__IO uint32_t IL               :2;//注入序列长度 注入组总的通道数目为 IL[1:0]+1。__IO uint32_t                  :10;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}ADC_ISQ;    // 地址偏移: 0x38    注入序列寄存器union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA0;    // 地址偏移: 0x3C    注入数据寄存器 0union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA1;    // 地址偏移: 0x40    注入数据寄存器 1union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA2;    // 地址偏移: 0x44    注入数据寄存器 2union{struct{__I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。__I uint32_t                    :16;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_IDATA3;    // 地址偏移: 0x48    注入数据寄存器 3union{struct{__I uint32_t RDATA             :16; //规则通道数据 这些位包含了规则通道的转换结果,只读。/*ADC0:在同步模式下,这些位包含着 ADC1 的规则通道数据ADC1 和 ADC2:这些位没有使用.*/__I uint32_t ADC1RDTR          :16; //规则通道数据 ADC1}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}ADC_RDATA;    // 地址偏移: 0x4C    规则数据寄存器
/*============================================================================*///注意:当 ADCON= 0 时软件才允许写该位(确定没有转换正在进行) 本次项目禁用这项union{struct{__IO uint32_t OVSEN :1;  //过滤采样使能 0:过滤采样失能 1:过滤采样使能 注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行)__IO uint32_t :1;   //1 保留 必须保持复位值。__IO uint32_t OVSR  :3;  //过采样率/*这些位定义了过采样率的大小.000:2x001:4x010:8x011:16x100:32x101:64x110:128x111:256x注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行)*/__IO uint32_t OVSS  :4;  //过滤采样移位/*该位通过软件设置和清除.0000:不移位0001:移 1 位0010:移 2 位0011:移 3 位0100:移 4 位0101:移 5 位0110:移 6 位0111:移 7 位1000:移 8 位其他保留注意:当 ADCON=0 时软件才允许写该位(确定没有转换正在进行).*/__IO uint32_t TOVS  :1;  //触发过滤采样/*该位通过软件设置和清除.0:所有的过滤采样连续转换完成一个触发后1:对于过采样通道的每次转换都需要一次触发,触发次数由过采样率(OVSR[2:0])决定。注意:当 ADCON= 0 时软件才允许写该位(确定没有转换正在进行).*/__IO uint32_t :2;__IO uint32_t DRES  :2;  //ADC 分辨率/*13:12 DRES[1:0] ADC 分辨率ADC 分辨率00:12 位01:10 位10:8 位11:6 位*/__IO uint32_t :18;}Bits;__I uint32_t Byte;}ADC_OVSAMPCTL;//过采样控制寄存器 地址偏移:0x80  复位值:0x0000 0000
} ADC_Type;typedef enum IRQn
{/* interruput numbers */WWDGT_IRQn                   = 0,      /*!<看门狗定时器中断              */RCU_CTC_IRQn                 = 5,      /*!< RCU_BASE and CTC interrupt                                    */ADC0_1_IRQn                  = 18,     /*!< ADC0 and ADC1 interrupt                                  */
}IRQn_Type;/* 总线映射 */
#define APB1_BUS_BASE         ((uint32_t)0x40000000U)
#define APB2_BUS_BASE         ((uint32_t)0x40010000U)
#define AHB1_BUS_BASE         ((uint32_t)0x40018000U)
#define AHB3_BUS_BASE         ((uint32_t)0x60000000U)/* APB2内存映射 */
#define ADC_BASE              (APB2_BUS_BASE + 0x00002400U)/* ADC寄存器地址偏移 */
/* ADC0基地址:0x4001 2400* ADC1基地址:0x4001 2800* ADC2基地址:0x4001 3C00*/
#define ADC0_BASE             (ADC_BASE + 0x00000000U)
#define ADC1_BASE             (ADC_BASE + 0x00000400U)
//#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
#define ADC2_BASE             (ADC_BASE + 0x00001800U)#define ADC0              ((ADC_Type *)(ADC0_BASE))
#define ADC1              ((ADC_Type *)(ADC1_BASE))
#define ADC2              ((ADC_Type *)(ADC2_BASE))#define ADC_BASES         {ADC0, ADC1, ADC2}#define BUTTON_SAMPLE_CNT        11#define CHECK_BY_AD       1  //1以AD值方式对比,0以电压方式对比typedef enum      /* 等号左边为电磁阀管路图编号 */
{                   /* 右边数字为原理图中的电磁阀编号 ,0表示没有使用到 */V101 = 1,V102 = 2,V103 = 3,V104 = 4,V105 = 5,V106 = 6,V107 = 7,V108 = 8,V109 = 9,V110 = 10,V201 = 11,V202 = 12,V203 = 13,V204 = 14,V205 = 15,V206 = 16,V207 = 17,V208 = 18,V209 = 19,V210 = 20,V301 = 21,V302 = 22,V303 = 23,V304 = 24,V305 = 25,V306 = 26,V307 = 27,V308 = 28,V309 = 29,V310 = 30,V401 = 31,V402 = 32,V403 = 33,V404 = 34,V405 = 35,V406 = 36,V407 = 37,V408 = 38,V409 = 39,V410 = 40,
} e_Vxxx;void Adc0_Init(void);
void Adc0_GetRSQVal(uint16_t *array, uint8_t offset, uint8_t len);void RB_ADC_Init(void);
void RB_ADC_ScanButton(void);
void Fun_BubbleSort(uint16_t *array, uint8_t len, uint8_t sort_dir);
void RB_ADC_ScanButton2(void);#ifdef __cplusplus
}
#endif
#endif // CTRL_ADC_H

【3】gd32f30x_dma_reg.h [参考]

DMA寄存器不是本节重点,后面会学到,这里主要用于和ADC的规则数据寄存器RDATA和注入数据寄存器IDATA配合处理采集的ADC数据


#ifndef GD32F30X_DMA_REG_H
#define GD32F30X_DMA_REG_H#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <stdint.h>
/********************************************************************************* @brief     GD32F30x DMA寄存器地址映射、位域映射*******************************************************************************/#ifndef _GD32F30X_DMA_REG_H_
#define _GD32F30X_DMA_REG_H_
#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const    //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数typedef struct {union{struct{__I uint32_t GIF0            :1;__I uint32_t FTFIF0          :1;__I uint32_t HTFIF0          :1;__I uint32_t ERRIF0          :1;__I uint32_t GIF1            :1;__I uint32_t FTFIF1          :1;__I uint32_t HTFIF1          :1;__I uint32_t ERRIF1          :1;__I uint32_t GIF2            :1;__I uint32_t FTFIF2          :1;__I uint32_t HTFIF2          :1;__I uint32_t ERRIF2          :1;__I uint32_t GIF3            :1;__I uint32_t FTFIF3          :1;__I uint32_t HTFIF3          :1;__I uint32_t ERRIF3          :1;__I uint32_t GIF4            :1;__I uint32_t FTFIF4          :1;__I uint32_t HTFIF4          :1;__I uint32_t ERRIF4          :1;__I uint32_t GIF5            :1;__I uint32_t FTFIF5          :1;__I uint32_t HTFIF5          :1;__I uint32_t ERRIF5          :1;__I uint32_t GIF6            :1;__I uint32_t FTFIF6          :1;__I uint32_t HTFIF6          :1;__I uint32_t ERRIF6          :1;__I uint32_t                 :4;}Bits;__I uint32_t Byte;    // 复位值: 0x0000 0000}DMA_INTF;    // 地址偏移: 0x00   中断标志位寄存器union{struct{__IO uint32_t GIFC0            :1;__IO uint32_t FTFIFC0          :1;__IO uint32_t HTFIFC0          :1;__IO uint32_t ERRIFC0          :1;__IO uint32_t GIFC1            :1;__IO uint32_t FTFIFC1          :1;__IO uint32_t HTFIFC1          :1;__IO uint32_t ERRIFC1          :1;__IO uint32_t GIFC2            :1;__IO uint32_t FTFIFC2          :1;__IO uint32_t HTFIFC2          :1;__IO uint32_t ERRIFC2          :1;__IO uint32_t GIFC3            :1;__IO uint32_t FTFIFC3          :1;__IO uint32_t HTFIFC3          :1;__IO uint32_t ERRIFC3          :1;__IO uint32_t GIFC4            :1;__IO uint32_t FTFIFC4          :1;__IO uint32_t HTFIFC4          :1;__IO uint32_t ERRIFC4          :1;__IO uint32_t GIFC5            :1;__IO uint32_t FTFIFC5          :1;__IO uint32_t HTFIFC5          :1;__IO uint32_t ERRIFC5          :1;__IO uint32_t GIFC6            :1;__IO uint32_t FTFIFC6          :1;__IO uint32_t HTFIFC6          :1;__IO uint32_t ERRIFC6          :1;__IO uint32_t                  :4;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_INTC;    // 地址偏移: 0x04   中断标志位清除寄存器union{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH0CTL;    // 地址偏移: 0x08    通道 0 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH0CNT;    // 地址偏移: 0x0C    通道 0 计数寄存器__IO uint32_t DMA_CH0PADDR    :32;    // 地址偏移: 0x10    通道 0 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH0MADDR    :32;    // 地址偏移: 0x14    通道 0 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x18union{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH1CTL;    // 地址偏移: 0x1C    通道 1 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH1CNT;    // 地址偏移: 0x20    通道 1 计数寄存器__IO uint32_t DMA_CH1PADDR    :32;    // 地址偏移: 0x24    通道 1 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH1MADDR    :32;    // 地址偏移: 0x28    通道 1 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x2Cunion{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH2CTL;    // 地址偏移: 0x30    通道 2 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH2CNT;    // 地址偏移: 0x34    通道 2 计数寄存器__IO uint32_t DMA_CH2PADDR    :32;    // 地址偏移: 0x38    通道 2 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH2MADDR    :32;    // 地址偏移: 0x3C    通道 2 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x40union{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH3CTL;    // 地址偏移: 0x44    通道 3 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH3CNT;    // 地址偏移: 0x48    通道 3 计数寄存器__IO uint32_t DMA_CH3PADDR    :32;    // 地址偏移: 0x4C    通道 3 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH3MADDR    :32;    // 地址偏移: 0x50    通道 3 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x54union{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH4CTL;    // 地址偏移: 0x58    通道 4 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH4CNT;    // 地址偏移: 0x5C    通道 4 计数寄存器__IO uint32_t DMA_CH4PADDR    :32;    // 地址偏移: 0x60    通道 4 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH4MADDR    :32;    // 地址偏移: 0x64    通道 4 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x68union{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH5CTL;    // 地址偏移: 0x6C    通道 5 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH5CNT;    // 地址偏移: 0x70    通道 5 计数寄存器__IO uint32_t DMA_CH5PADDR    :32;    // 地址偏移: 0x74    通道 5 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH5MADDR    :32;    // 地址偏移: 0x78    通道 5 存储器基地址寄存器  复位值: 0x0000 0000__IO uint32_t                 :32;    // 地址偏移: 0x7Cunion{struct{__IO uint32_t CHEN               :1;__IO uint32_t FTFIE              :1;__IO uint32_t HTFIE              :1;__IO uint32_t ERRIE              :1;__IO uint32_t DIR                :1;__IO uint32_t CMEN               :1;__IO uint32_t PNAGA              :1;__IO uint32_t MNAGA              :1;__IO uint32_t PWIDTH             :2;__IO uint32_t MWIDTH             :2;__IO uint32_t PRIO               :2;__IO uint32_t M2M                :1;__IO uint32_t                    :17;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH6CTL;    // 地址偏移: 0x80    通道 6 控制寄存器union{struct{__IO uint32_t CNT              :16;__IO uint32_t                  :16;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}DMA_CH6CNT;    // 地址偏移: 0x84    通道 6 计数寄存器__IO uint32_t DMA_CH6PADDR    :32;    // 地址偏移: 0x88    通道 6 外设基地址寄存器  复位值: 0x0000 0000__IO uint32_t DMA_CH6MADDR    :32;    // 地址偏移: 0x8C    通道 6 存储器基地址寄存器  复位值: 0x0000 0000
} DMA_Type;/* 总线映射 */
#define AHB1_BUS_BASE         ((uint32_t)0x40018000U)
/* AHB1内存映射 */
#define DMA_BASE              (AHB1_BUS_BASE + 0x00008000U)
/* DMA寄存器地址偏移 */
#define DMA0_BASE             (DMA_BASE + 0x00000000U)
#define DMA1_BASE             (DMA_BASE + 0x00000400U)#define DMA0                           ((DMA_Type *)(DMA0_BASE))
#define DMA1                           ((DMA_Type *)(DMA1_BASE))#define DMA_BASES                      {DMA0, DMA1}#endif#endif // GD32F30X_DMA_REG_H

【4】mon_adc.h [参考 +1]

#ifndef ADC_H
#define ADC_H#include "adc_reg.h"
#ifdef __cplusplus
extern "C" {#endif
/*============================监控MCU部分==========================*/
typedef void (*ADC_CallbackType)(void);                         ///< ADC回调函数指针
//静态函数指针数组 初始化函数指针类型的NULL
static ADC_CallbackType g_adcCallback[1] = {(ADC_CallbackType)NULL};
//ADC 输入通道
#define ADC_CHANNEL_AD0                                 0x0 ///< ADC input channel 0
#define ADC_CHANNEL_AD1                                 0x1 ///< ADC input channel 1
#define ADC_CHANNEL_AD2                                 0x2 ///< ADC input channel 2
#define ADC_CHANNEL_AD3                                 0x3 ///< ADC input channel 3
#define ADC_CHANNEL_AD4                                 0x4 ///< ADC input channel 4
#define ADC_CHANNEL_AD5                                 0x5 ///< ADC input channel 5
#define ADC_CHANNEL_AD6                                 0x6 ///< ADC input channel 6
#define ADC_CHANNEL_AD7                                 0x7 ///< ADC input channel 7
#define ADC_CHANNEL_AD8                                 0x8 ///< ADC input channel 8
#define ADC_CHANNEL_AD9                                 0x9 ///< ADC input channel 9
#define ADC_CHANNEL_AD10                                0xa ///< ADC input channel 10
#define ADC_CHANNEL_AD11                                0xb ///< ADC input channel 11
#define ADC_CHANNEL_AD12                                0xc ///< ADC input channel 12
#define ADC_CHANNEL_AD13                                0xd ///< ADC input channel 13
#define ADC_CHANNEL_AD14                                0xe ///< ADC input channel 14
#define ADC_CHANNEL_AD15                                0xf ///< ADC input channel 15
#define ADC_CHANNEL_AD16                                0x10///< ADC input channel 16
#define ADC_CHANNEL_AD17                                0x11///< ADC input channel 17
//ADC 输入通道带隙
#define ADC_CHANNEL_AD16_BANDGAP                        0x10///< ADC input channel bandgap
//ADC 输入通道内部温度传感器
#define ADC_CHANNEL_AD17_TEMPSENSOR                     0x11///< ADC input channel internal temperature sensor//ADC 时钟除 num(1-16)
#define ADC_ADIV_DIVIDE_1                               0x00///< ADC clock divide by 1
#define ADC_ADIV_DIVIDE_2                               0x01///< ADC clock divide by 2
#define ADC_ADIV_DIVIDE_3                               0x02///< ADC clock divide by 3
#define ADC_ADIV_DIVIDE_4                               0x03///< ADC clock divide by 4
#define ADC_ADIV_DIVIDE_5                               0x04///< ADC clock divide by 5
#define ADC_ADIV_DIVIDE_6                               0x05///< ADC clock divide by 6
#define ADC_ADIV_DIVIDE_7                               0x06///< ADC clock divide by 7
#define ADC_ADIV_DIVIDE_8                               0x07///< ADC clock divide by 8
#define ADC_ADIV_DIVIDE_9                               0x08///< ADC clock divide by 9
#define ADC_ADIV_DIVIDE_10                              0x09///< ADC clock divide by 10
#define ADC_ADIV_DIVIDE_11                              0x0A///< ADC clock divide by 11
#define ADC_ADIV_DIVIDE_12                              0x0B///< ADC clock divide by 12
#define ADC_ADIV_DIVIDE_13                              0x0C///< ADC clock divide by 13
#define ADC_ADIV_DIVIDE_14                              0x0D///< ADC clock divide by 14
#define ADC_ADIV_DIVIDE_15                              0x0E///< ADC clock divide by 15
#define ADC_ADIV_DIVIDE_16                              0x0F///< ADC clock divide by 16
//ADC IDR 偏移值
#define IDR_Offset       0x3C
//ADC 注入通道选择 1-4
#define ADC_InjectedChannel_1                           0x00///<Injected Channel1 selected
#define ADC_InjectedChannel_2                           0x04///<Injected Channel2 selected
#define ADC_InjectedChannel_3                           0x08///<Injected Channel3 selected
#define ADC_InjectedChannel_4                           0x0C///<Injected Channel4 selected
//ADC 模拟监视器/监视器标志
#define ADC_FLAG_AMO                                    0x01///<Analog monitor/watchdog flag
//ADC 转换标志结束
#define ADC_FLAG_EOC                                    0x02///<End of conversion flag
//ADC 注入组转换标志结束
#define ADC_FLAG_IEOC                                   0x04///<End of injected group conversion flag
//ADC 转换数据右对齐
#define ADC_DataAlign_Right                             ((uint32_t)0x00)///<Conversion Data right alignment
//ADC 转换数据左对齐
#define ADC_DataAlign_Left                              ((uint32_t)0x01)///<Conversion Data left alignment
//ADC 转换触发源软件
#define ADC_TrigSource_Internal                         ((uint32_t)0x00)///<Conversion trig source software
//ADC 外部转换触发源
#define ADC_TrigSource_External                         ((uint32_t)0x01)///<Conversion trig source external
//ADC 监视器通道启用
#define ADC_AnalogWatchDog_SingleChannelEnable          ((uint32_t)0x01)///<WatchDog Channel Enable
//ADC 监视器规则组启用
#define ADC_AnalogWatchDog_OnRegularEnable              ((uint32_t)0x01)///<WatchDog Regular group Enable
//ADC 监视器注入组启用
#define ADC_AnalogWatchDog_OnInjectEnable               ((uint32_t)0x01)///<WatchDog Inject group Enable
//ADC 监控器配置复位
#define AMO_SETTING_RESET                               (0xffffff1f)///<Monitor configt reset
//转换触发源复位
#define TRIG_SOURCE_SETTING_RESET                       (0xffcfffff)///<Conversion trig source reset
//ADC 转换模式复位
#define ADC_MODE_RESET                                  (0xffff07ff)///<ADC Conversion Mode reset
//ADC 采样时间周期
#define ADC_SampleTime_6Cycle                           ((uint8_t)0x00)///<ADC Sample 6 Clock Cycle
#define ADC_SampleTime_14Cycle                          ((uint8_t)0x01)///<ADC Sample 14 Clock Cycle
#define ADC_SampleTime_29Cycle                          ((uint8_t)0x02)///<ADC Sample 29 Clock Cycle
#define ADC_SampleTime_42Cycle                          ((uint8_t)0x03)///<ADC Sample 42 Clock Cycle
#define ADC_SampleTime_56Cycle                          ((uint8_t)0x04)///<ADC Sample 56 Clock Cycle
#define ADC_SampleTime_72Cycle                          ((uint8_t)0x05)///<ADC Sample 72 Clock Cycle
#define ADC_SampleTime_215Cycle                         ((uint8_t)0x06)///<ADC Sample 215 Clock Cycle
#define ADC_SampleTime_3Cycle                           ((uint8_t)0x07)///<ADC Sample 3 Clock Cycle
//ADC 转换规则组单通道一次模式
#define ADC_Regular_Single_One_Mode                     ((uint8_t)0x01)///<ADC Conversion Regular Group Single Channel one times Mode
//ADC 转换规则组单通道连续模式
#define ADC_Regular_Single_Continous_Mode               ((uint8_t)0x02)///<ADC Conversion Regular Group Single Channel continous Mode
//ADC 转换规则组多通道 通道和自动注入组一次模式
#define ADC_Regular_Multiple_One_Mode                   ((uint8_t)0x03)///<ADC Conversion Regular Group Multipe Channel and Auto Inject Group one time Mode
//ADC 转换规则组多通道一次模式
#define ADC_Regular_Multiple_AutoInject_Mode            ((uint8_t)0x04)///<ADC Conversion Regular Group Multipe Channel one time Mode
//ADC 转换规则组多通道连续模式
#define ADC_Regular_Multiple_Continous_Mode             ((uint8_t)0x05)///<ADC Conversion Regular Group Multipe Channel continous Mode
//ADC 转换规则组多通道 通道和自动注入组连续模式
#define ADC_Regular_Multiple_Continous_AutoInject_Mode  ((uint8_t)0x06)///<ADC Conversion Regular Group Multipe Channel and Auto Inject Group continous Mode
//ADC 转换规则组多通道 通道通过中断一次性模式
#define ADC_Regular_Multiple_Discontinous_Mode          ((uint8_t)0x07)///<ADC Conversion Regular Group Multipe Channel by Disnum one time Mode
//ADC 转换注入组通过中断一次性模式
#define ADC_Inject_Multiple_Discontinous_Mode           ((uint8_t)0x08)///<ADC Conversion Inject Group by Disnum one time Mode
//ADC使能 不使能
#define ADC_ENABLE                                      1///<Set enable
#define ADC_DISABLE                                     0///<Set disable
//外设时钟控制使能
#define PERI_CLK_EN_0 0x40000004
#define PERI_CLK_EN_1 0x40000008
//外设软件复位失效
#define PERI_SFT_RST1 0x40000018
#define PERI_SFT_RST2 0x4000001c//虚假替换 实际值不知
#define CLK_ADC     0x40080000
#define SRST_ADC    0x40084000
typedef struct {uint32_t dataAlign;                                 ///< Data Alignment: 0 Right alignment; 1 left alignmentuint32_t scanMode;                                  ///< 常规和注入组的扫描模式已启用/禁用uint32_t continousMode;                             ///< 启用/禁用连续模式uint32_t disContinousModeOnRegularGroup;            ///< 规则组的间断模式uint32_t disContinousModeOnInjectGroup;             ///< 注入组的间断模式uint32_t injectAutoMode;                            ///< 注入组的反运动模式uint32_t discNum;                                   ///< 间断的模式,连续的数量
} ADC_InitType;
typedef struct {uint32_t regularTrigSource;                         ///< 规则组选择内部或外部触发器源uint32_t injectTrigSource;                          ///< 注入组选择内部或外部触发器源
} ADC_TrigSourceType;
typedef struct {uint32_t analogWatchDogSingleMode;                  ///< 选择监视器单通道模式uint32_t analogWatchDogOnRegularGroup;              ///< 选择监视器的齿轮组模式uint32_t analogWatchDogOnInjectGroup;               ///< 选择监视器注入组模式uint32_t analogWatchDogChannel;                     ///< 选择监视器adc通道
} ADC_AnalogWatchDogType;void ADC_DMAInit(void);
void ADC_Init(void);
void ADC_Deinit(void) ;
uint32_t GetAdcChannelValue(uint32_t Channel);   //设置AD转换通道,同时获取转换值void ADC_IRQHandler(void);//中断服务函数#endif // ADC_H

【5】rcu.h [参考]

#ifndef RCU_H
#define RCU_H// GD32F30x 复位和时钟单元RCU寄存器地址映射、位域映射
#include <stdint.h>#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const    //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数typedef struct {union{struct{__IO uint32_t IRC8MEN     :1; // bit0__I  uint32_t IRC8MSTB    :1; // bit1__IO uint32_t             :1; // bit2__IO uint32_t IRC8MADJ    :5; // bit[7:3]__I  uint32_t IRC8MCALIB  :8; // bit[15:8]__IO uint32_t HXTALEN     :1; // bit16__I  uint32_t HXTALSTB    :1; // bit17__IO uint32_t HXTALBPS    :1; // bit18__IO uint32_t CKMEN       :1; // bit19__IO uint32_t             :4; // bit[23:20]__IO uint32_t PLLEN       :1; // bit24__I  uint32_t PLLSTB      :1; // bit25__IO uint32_t             :6; // bit[31:26]}Bits;__IO uint32_t Byte;    // 复位值: 0x4444 xx83}RCU_CTL;    // 地址偏移: 0x00   控制寄存器union{struct{__IO uint32_t SCS          :2;__I  uint32_t SCSS         :2;__IO uint32_t AHBPSC       :4;__IO uint32_t APB1PSC      :3;__IO uint32_t APB2PSC      :3;__IO uint32_t ADCPSC_Bit1_0:2;__IO uint32_t PLLSEL       :1;__IO uint32_t PREDV0       :1;__IO uint32_t PLLMF_Bit3_0 :4;__IO uint32_t USBFSPSC     :2;__IO uint32_t CKOUT0SEL    :3;__IO uint32_t PLLMF_Bit4   :1;__IO uint32_t ADCPSC_Bit2  :1;__IO uint32_t              :1;__IO uint32_t PLLMF_Bit5   :1;__IO uint32_t USBFSPSC_Bit2:1;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_CFG0;    // 地址偏移: 0x04    时钟配置寄存器 0union{struct{__I  uint32_t IRC40KSTBIF         :1;__I  uint32_t LXTALSTBIF          :1;__I  uint32_t IRC8MSTBIF          :1;__I  uint32_t HXTALSTBIF          :1;__I  uint32_t PLLSTBIF            :1;__IO uint32_t                     :2;__I  uint32_t CKMIF               :1;__IO uint32_t IRC40KSTBIE         :1;__IO uint32_t LXTALSTBIE          :1;__IO uint32_t IRC8MSTBIE          :1;__IO uint32_t HXTALSTBIE          :1;__IO uint32_t PLLSTBIE            :1;__IO uint32_t                     :3;__IO uint32_t IRC40KSTBIC         :1;__IO uint32_t LXTALSTBIC          :1;__IO uint32_t IRC8MSTBIC          :1;__IO uint32_t HXTALSTBIC          :1;__IO uint32_t PLLSTBIC            :1;__IO uint32_t                     :2;__IO uint32_t CKMIC               :1;__IO uint32_t                     :8;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_INT;    // 地址偏移: 0x08    时钟中断寄存器union{struct{__IO uint32_t AFRST         :1;__IO uint32_t               :1;__IO uint32_t PARST         :1;__IO uint32_t PBRST         :1;__IO uint32_t PCRST         :1;__IO uint32_t PDRST         :1;__IO uint32_t PERST         :1;__IO uint32_t PFRST         :1;__IO uint32_t PGRST         :1;__IO uint32_t ADC0RST       :1;__IO uint32_t ADC1RST       :1;__IO uint32_t TIMER0RST     :1;__IO uint32_t SPI0RST       :1;__IO uint32_t TIMER7RST     :1;__IO uint32_t USART0RST     :1;__IO uint32_t ADC2RST       :1;__IO uint32_t               :3;__IO uint32_t TIMER8RST     :1;__IO uint32_t TIMER9RST     :1;__IO uint32_t TIMER10RST    :1;__IO uint32_t               :10;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_APB2RST;    // 地址偏移: 0x0C    APB2 复位寄存器union{struct{__IO uint32_t TIMER1RST          :1;__IO uint32_t TIMER2RST          :1;__IO uint32_t TIMER3RST          :1;__IO uint32_t TIMER4RST          :1;__IO uint32_t TIMER5RST          :1;__IO uint32_t TIMER6RST          :1;__IO uint32_t TIMER11RST         :1;__IO uint32_t TIMER12RST         :1;__IO uint32_t TIMER13RST         :1;__IO uint32_t                    :2;__IO uint32_t WWDGTRST           :1;__IO uint32_t                    :2;__IO uint32_t SPI1RST            :1;__IO uint32_t SPI2RST            :1;__IO uint32_t                    :1;__IO uint32_t USART1RST          :1;__IO uint32_t USART2RST          :1;__IO uint32_t UART3RST           :1;__IO uint32_t UART4RST           :1;__IO uint32_t I2C0RST            :1;__IO uint32_t I2C1RST            :1;__IO uint32_t USBDRST            :1;__IO uint32_t                    :1;__IO uint32_t CAN0RST            :1;__IO uint32_t                    :1;__IO uint32_t BKPIRST            :1;__IO uint32_t PMURST             :1;__IO uint32_t DACRST             :1;__IO uint32_t                    :2;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_APB1RST;    // 地址偏移: 0x10    APB1 复位寄存器union{struct{__IO uint32_t DMA0EN            :1; //DMA0 时钟开启__IO uint32_t DMA1EN            :1;__IO uint32_t SRAMSPEN          :1;__IO uint32_t                   :1;__IO uint32_t FMCSPEN           :1;__IO uint32_t                   :1;__IO uint32_t CRCEN             :1;__IO uint32_t                   :1;__IO uint32_t EXMCEN            :1;__IO uint32_t                   :3;__IO uint32_t USBFSEN           :1;__IO uint32_t                   :19;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0014}RCU_AHBEN;    // 地址偏移: 0x14    位清除寄存器union{struct{__IO uint32_t AFEN          :1;__IO uint32_t               :1;__IO uint32_t PAEN          :1;__IO uint32_t PBEN          :1;__IO uint32_t PCEN          :1; //时钟开启__IO uint32_t PDEN          :1;__IO uint32_t PEEN          :1;__IO uint32_t PFEN          :1;__IO uint32_t PGEN          :1;__IO uint32_t ADC0EN        :1; //ADC0 时钟开启__IO uint32_t ADC1EN        :1;__IO uint32_t TIMER0EN      :1;__IO uint32_t SPI0EN        :1;__IO uint32_t TIMER7EN      :1;__IO uint32_t USART0EN      :1;__IO uint32_t ADC2EN        :1;__IO uint32_t               :3;__IO uint32_t TIMER8EN      :1;__IO uint32_t TIMER9EN      :1;__IO uint32_t TIMER10EN     :1;__IO uint32_t               :10;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_APB2EN;    // 地址偏移: 0x18    APB2 使能寄存器union{struct{__IO uint32_t TIMER1EN           :1;__IO uint32_t TIMER2EN           :1;__IO uint32_t TIMER3EN           :1;__IO uint32_t TIMER4EN           :1;__IO uint32_t TIMER5EN           :1;__IO uint32_t TIMER6EN           :1;__IO uint32_t TIMER11EN          :1;__IO uint32_t TIMER12EN          :1;__IO uint32_t TIMER13EN          :1;__IO uint32_t                    :2;__IO uint32_t WWDGTEN            :1;__IO uint32_t                    :2;__IO uint32_t SPI1EN             :1;__IO uint32_t SPI2EN             :1;__IO uint32_t                    :1;__IO uint32_t USART1EN           :1;__IO uint32_t USART2EN           :1;__IO uint32_t UART3EN            :1;__IO uint32_t UART4EN            :1;__IO uint32_t I2C0EN             :1;__IO uint32_t I2C1EN             :1;__IO uint32_t USBDEN             :1;__IO uint32_t                    :1;__IO uint32_t CAN0EN             :1;__IO uint32_t                    :1;__IO uint32_t BKPIEN             :1;__IO uint32_t PMUEN              :1;__IO uint32_t DACEN              :1;__IO uint32_t                    :2;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_APB1EN;    // 地址偏移: 0x1C    APB1 使能寄存器union{struct{__IO uint32_t LXTALEN            :1;__I  uint32_t LXTALSTB           :1;__IO uint32_t LXTALBPS           :1;__IO uint32_t LXTALDRI           :2;__IO uint32_t                    :3;__IO uint32_t RTCSRC             :2;__IO uint32_t                    :5;__IO uint32_t RTCEN              :1;__IO uint32_t BKPRST             :1;__IO uint32_t                    :15;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0018}RCU_BDCTL;    // 地址偏移: 0x20   备份域控制寄存器union{struct{__IO uint32_t IRC40KEN            :1;__I  uint32_t IRC40KSTB           :1;__IO uint32_t                     :22;__IO uint32_t RSTFC               :1;__IO uint32_t                     :1;__I  uint32_t EPRSTF              :1;__I  uint32_t PORRSTF             :1;__I  uint32_t SWRSTF              :1;__I  uint32_t FWDGTRSTF           :1;__I  uint32_t WWDGTRSTF           :1;__I  uint32_t LPRSTF              :1;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_RSTSCK;    // 地址偏移: 0x24   复位源/时钟寄存器__IO uint32_t RCU_AHBRST;    // 复位值: 0x0000 0000   // 地址偏移: 0x28   AHB 复位寄存器  (互联型CL独有?)union{struct{__IO uint32_t                   :29;__IO uint32_t ADCPSC_Bit3       :1;__IO uint32_t PLLPRESEL         :1;__IO uint32_t                   :1;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 0000}RCU_CFG1;    // 地址偏移: 0x2C   时钟配置寄存器 1
} RCU_Type;/* 总线映射 */
#define AHB1_BUS_BASE         ((uint32_t)0x40018000U) //系统总线基地址
/* AHB1内存映射 */
#define RCU_BASE              (AHB1_BUS_BASE + 0x00009000U) //4002 1000
// GD32F30x 复位和时钟单元RCU寄存器地址映射、位域映射
#define RCU                  ((RCU_Type *)(RCU_BASE))//寄存器的基地址=4002 1000#endif // RCU_H

【6】ctrl_adc.c [重要]

代码有冒泡排序

#include "ctrl_adc.h"
#include "rcu.h"
#include "gd32f30x_dma_reg.h"
#include <string.h>
//========================ADC0 测电磁阀 采样电压为例
/*============================控制MCU部分==========================*/
#define CONTINUE_MODE   1   //1连续扫描转换 0单次扫描转换。 连续模式会自动循环转换
#define ADC_RSQ_CNT     (uint8_t)6  //ADC规则组要转换的通道数量
uint16_t Array_RSQ_AD[ADC_RSQ_CNT] = {0x00,0x01,0x02,0x03,0x04,0x05};//DMA0 ch0存储器地址,存储adc0转换值
static double Button_SampleVoltage[BUTTON_SAMPLE_CNT];void Adc0_Init()
{RCU->RCU_APB2EN.Bits.PCEN = 1;  //时钟开启RCU->RCU_APB2EN.Bits.ADC0EN =1; //ADC0 时钟开启RCU->RCU_AHBEN.Bits.DMA0EN =1;  //DMA0 时钟开启/* ADC时钟来源:APB2分频 *//* 0001: CK_ADC = CK_APB2 / 4 , 0111: CK_ADC = CK_APB2 / 16, ADC时钟40MHz MAX*/RCU->RCU_CFG1.Bits.ADCPSC_Bit3 = 0;  //0RCU->RCU_CFG0.Bits.ADCPSC_Bit2 =1;   //1RCU->RCU_CFG0.Bits.ADCPSC_Bit1_0 =3; //11//ADC配置 占4个位ADC0->ADC_CTL0.Bits.SYNCM =0;   //独立模式 0000ADC0->ADC_CTL0.Bits.SM =1;      //扫描转换模式#if (CONTINUE_MODE == 1)ADC0->ADC_CTL1.Bits.CTN = 1;                // 0:禁止连续模式,1:使能连续模式
#elseADC0->ADC_CTL1.Bits.CTN = 0;
#endifADC0->ADC_CTL1.Bits.DMA = 1;              // 1: DMA 请求使能//占4个位ADC0->ADC_RSQ0.Bits.RL = ADC_RSQ_CNT - 1;    //规则组长度,0-F表示1-16个  6-1=5=0101//各占5个位ADC0->ADC_RSQ2.Bits.RSQ0 = ADC_CHANNEL_11;    //PC1 Mag_CUR_ADC1-8_COM    0x0B=0000 1011ADC0->ADC_RSQ2.Bits.RSQ1 = ADC_CHANNEL_12;   //PC2 Mag_CUR_ADC9-16_COM   0x0C=0000 1100ADC0->ADC_RSQ2.Bits.RSQ2 = ADC_CHANNEL_13;   //PC3 Mag_CUR_ADC17-24_COM  0x0D=0000 1101ADC0->ADC_RSQ2.Bits.RSQ3 = ADC_CHANNEL_14;   //PC4 Mag_CUR_ADC25-32_COM  0x0E=0000 1110ADC0->ADC_RSQ2.Bits.RSQ4 = ADC_CHANNEL_15;   //PC5 Mag_CUR_ADC33-40_COM  0x0F=0000 1111ADC0->ADC_RSQ2.Bits.RSQ5 = ADC_CHANNEL_10;   //PC0 按键                   0x0A=0000 1001ADC0->ADC_SAMPT0.Byte = 0x00ffffff;         //0000 0000 1111 1111 1111 1111 11111 1111ADC0->ADC_SAMPT1.Byte = 0x3fffffff;         // 所有通道采样时间为ADC时钟周期 * 239.5ADC0->ADC_CTL1.Bits.ETERC = 1;               // 规则组外部触发使能ADC0->ADC_CTL1.Bits.ETSRC = 7;              // 规则组外部触发选择: 111:软件触发ADC0->ADC_CTL1.Bits.DAL = 0;               // 数据对齐:最低有效位对齐 右对齐(ADC_RDATA寄存器中)/*规则通道单次转换结束后,转换数据将被存放于ADC_RDATA寄存器中,EOC将会置1(硬件自动置位)。如果EOCIE位被置1,将产生一个中断。*/ADC0->ADC_STAT.Bits.EOC = 0;                //clear 组转换结束标志ADC0->ADC_CTL1.Bits.ADCON = 1;               // 使能/* 须在校正前 使能后延时14个ADC时钟周期 *///UserTimer_Reset(&time);//while (UserTimer_Read(&time) < 1);/* 校准复位: 软件置位, 在校准寄存器初始化后该位硬件清零 */ADC0->ADC_CTL1.Bits.RSTCLB = 1;while (ADC0->ADC_CTL1.Bits.RSTCLB);/* ADC 校准 : 0:校准结束  1:校准开始 */ADC0->ADC_CTL1.Bits.CLB = 1;while (ADC0->ADC_CTL1.Bits.CLB);/* DMA配置 */DMA0->DMA_CH0CTL.Bits.CHEN = 0;                              //配置DMA前须关闭通道DMA0->DMA_CH0CTL.Bits.M2M = 0;                             //0: 禁止存储器到存储器模式DMA0->DMA_CH0CTL.Bits.DIR = 0;                               //0:从外设读出并写入存储器DMA0->DMA_CH0CTL.Bits.CMEN = 1;                               //1: 使能循环模式DMA0->DMA_CH0CTL.Bits.PRIO = 2;                               //软件优先级 10: 高DMA0->DMA_CH0CTL.Bits.MNAGA = 1;                            //存储器的地址生成算法 1: 增量地址模式DMA0->DMA_CH0CTL.Bits.PNAGA = 0;                           //外设的地址生成算法 0: 固定地址模式DMA0->DMA_CH0CTL.Bits.MWIDTH = 1;                           //存储器的传输数据宽度 01: 16-bitDMA0->DMA_CH0CTL.Bits.PWIDTH = 1;                         //外设的传输数据宽度   01: 16-bitDMA0->DMA_CH0PADDR = (uint32_t)(&ADC0->ADC_RDATA);        //ADC0规则数据寄存器地址
#if (CONTINUE_MODE == 1)DMA0->DMA_CH0MADDR = (uint32_t)(&Array_RSQ_AD);           //ADC0规则数据存放基地址DMA0->DMA_CH0CNT.Bits.CNT = ADC_RSQ_CNT;                 //x个数据等待被传输DMA0->DMA_CH0CTL.Bits.CHEN = 1;                              //1:使能该通道
#else#endif#if (CONTINUE_MODE == 1)ADC0->ADC_CTL1.Bits.SWRCST = 1;                 // 规则组转换开始#else#endif
}// 获取AD转换结果
void Adc0_GetRSQVal(uint16_t *array, uint8_t offset, uint8_t len)
{if ((offset < ADC_RSQ_CNT) && ((offset + len) <= ADC_RSQ_CNT)){//从 Array_RSQ_AD+offset 拷贝len*2个长度数据给arraymemcpy(array, Array_RSQ_AD+offset, len*2); //内存拷贝 len*2 >2*unsigned char = unsigned short}
}/*** @brief  配置并开始组转换* @note   每次扫描5个通道* @param  x = 0 - 7*/
void Adc0_GroupScan(void)
{#if (CONTINUE_MODE == 0)static uint8_t convert = 1;if (convert == 1){DMA0->DMA_CH0CTL.Bits.CHEN = 0;                               //配置DMA前须关闭通道DMA0->DMA_CH0MADDR = (uint32_t)(&Array_RSQ_AD);            //ADC0规则数据存放基地址DMA0->DMA_CH0CNT.Bits.CNT = 5;                               //x个数据等待被传输DMA0->DMA_CH0CTL.Bits.CHEN = 1;                              //1:使能该通道ADC0->ADC_CTL1.Bits.SWRCST = 1;                             // 规则组转换开始convert = 0;                 //转换中}else{if (Adc0_GroupScan_IsOK() == true){convert = 1;               //转换完成}}
#endif
}
//main 函数调用
void RB_ADC_Init()
{/* ADC0 */Adc0_Init();
}
//main 函数调用
void RB_ADC_ScanButton()
{uint16_t AD[1] = {0};//ADC0转化结果zhistatic uint8_t SampleCnt = 0; //本函数的调用次数uint16_t Voltage = 0;//电压中间值if(SampleCnt == 11)return;Adc0_GetRSQVal(AD, 5, 1);//获取AD值 偏移5  长度1  每次获取最后一个值Button_SampleVoltage[SampleCnt++] = 3300.0 * AD[0] / 4096;printf("AD =0x0%x \n",AD[0]);printf("AD VCC+ = %.2lf \n",Button_SampleVoltage[0]);if (SampleCnt >= BUTTON_SAMPLE_CNT) //完成一组采样{Fun_BubbleSort(Button_SampleVoltage, BUTTON_SAMPLE_CNT, 1);    //从小到大排序for(int i =0;i<BUTTON_SAMPLE_CNT;i++){printf("AD VCC+ = %.2lf \n",Button_SampleVoltage[i]);}Voltage = Button_SampleVoltage[BUTTON_SAMPLE_CNT / 2];   //取中间值printf("need VCC = %hd\n",Voltage);}
}//冒泡排序
void Fun_BubbleSort(uint16_t *array, uint8_t len, uint8_t sort_dir)
{uint8_t i = 0;uint8_t j = 0;uint16_t temp = 0;for (i = 0; i < len-1; i++) //有len个数则需要比较len-1轮, 8个数比较7轮后就剩下一个数,不需比较{for (j = 0; j < len-i-1; j++) //i:每完成1轮,就多1个不参与下轮比较,第一轮比较完成后最右边的值即为该数组的最大值{                              //1if ((sort_dir == 0 && array[j] < array[j + 1]) //从大到小的顺序,且前一个数小于后一个|| (sort_dir == 1 && array[j] > array[j + 1]))//从小到大的顺序,且前一个数大于后一个{temp = array[j];array[j] = array[j + 1];    //交换array[j + 1] = temp;}}}
}
static uint16_t Valve_Adc_Value[40] = {0}; //存放电磁阀AD采样结果
//main 函数调用 获取ADC的值 从0开始获取5个
void RB_ADC_ScanButton2()
{uint16_t adcVal[5] = {0};//获取5个ad值static uint8_t CD4051_Chx = 0; //cd4051通道xconst uint8_t ch0[5] = {V303 - 1, V401 - 1, V307 - 1, V405 - 1, V409 - 1};  //当5片CD4051都选择通道0时,adVal[0-4]的值对应V303, V401......static int adcont=0;if(CD4051_Chx == 8)return;Adc0_GetRSQVal(adcVal, 0, 5);//获取ad的值printf("AD val =%hd \n",adcVal[adcont++]);for (int i = 0; i < 5; i++){Valve_Adc_Value[ch0[i]] = adcVal[i];printf("Valve_Adc_Value VCC = %hd\n",Valve_Adc_Value[ch0[i]]);}//函数调用次数=5次不在调用if (++CD4051_Chx >= 5) CD4051_Chx = 8;
}

【7】mon_adc.c [参考+1]

#include "mon_adc.h"//初始化测试用
void InitTest()
{printf("ADC = %p\r\n",ADC);printf("ADC_ANA_CHANNEL = %p\r\n",ADC_ANA_CHANNEL);printf("ADC_AUXADC_CFG0 = %p\r\n",ADC_AUXADC_CFG0);printf("ADC_MCU_ADCBUF_CFG0 = %p\r\n",ADC_MCU_ADCBUF_CFG0);//    uint8_t flag =0;
//    while(!flag); // 真 原地踏步printf("Next\n");struct node {union{struct{__IO uint32_t WDE              :1;__IO uint32_t EOC              :1;__IO uint32_t EOIC             :1;__IO uint32_t STIC             :1;__IO uint32_t STRC             :1;__IO uint32_t                  :27;}Bits;__IO uint32_t Byte;    // 复位值: 0x0000 C000}ADC_STAT;    // 地址偏移: 0x00   状态寄存器};struct node node_t;node_t.ADC_STAT.Byte=0x11111111;printf("%x \t",node_t.ADC_STAT.Bits.WDE);printf("%x \t",node_t.ADC_STAT.Bits.EOC);printf("%x \t",node_t.ADC_STAT.Bits.EOIC);printf("%x \t",node_t.ADC_STAT.Bits.STIC);printf("%x \t",node_t.ADC_STAT.Bits.STRC);printf("%x \t",node_t.ADC_STAT.Byte);}/*============================监控MCU部分==========================*/
//DAM 直接存储访问 初始化暂不使用
void ADC_DMAInit()
{/* ****** 配置ADC模块寄存器,使能ADC DMA功能 ****** */ADC->CTRL1 |= ADC_CTRL1_DMAEN_Msk ;
}
//初始化多通道的ADC采集
void ADC_Init()
{ADC_InitType ADCconfig={0};ADC_TrigSourceType ADCtrigsrc={0};//ADC引脚配置//ADC 参数配置ADCconfig.dataAlign = ADC_DataAlign_Right; //数据右对其ADCconfig.scanMode = ADC_Regular_Single_One_Mode;//一次只转换一个通道,mode1//ADC 参数初始化 startuint32_t tmp =0;//外设时钟使能控制*(volatile unsigned int *)(PERI_CLK_EN_1) |=  (uint32_t)(1<<(uint32_t)(CLK_ADC-32));//外设软件复位*(volatile unsigned int *)(PERI_SFT_RST2) |=  (uint32_t)(1<<(uint32_t)(SRST_ADC-32));//ADC模式选择tmp = ADC->CTRL1;//CTRL1寄存器的11~15位为 Mode 选择tmp &= ADC_MODE_RESET;//ADC 转换模式复位tmp |= ((uint32_t)(ADCconfig.injectAutoMode| ((uint32_t)ADCconfig.disContinousModeOnInjectGroup << 1)\| ((uint32_t)ADCconfig.disContinousModeOnRegularGroup << 2)\| ((uint32_t)ADCconfig.continousMode << 3)\| ((uint32_t)ADCconfig.scanMode << 4))) << 11;ADC->CTRL1 = tmp; //或运算 同时具备这些项的功能//ADC 数据的对齐方式ADC->CTRL1 = (ADC->CTRL1 & ~(ADC_CTRL1_ALIGN_Msk)) | ((((uint32_t)(((uint32_t)(ADCconfig.dataAlign))<<ADC_CTRL1_ALIGN_Pos))&ADC_CTRL1_ALIGN_Msk));//ADC 不连续的转换长度配置ADC->CTRL1 = (ADC->CTRL1 & ~(ADC_CTRL1_DISCNUM_Msk)) | (((uint32_t)(((uint32_t)(ADCconfig.discNum))<<ADC_CTRL1_DISCNUM_Pos))&ADC_CTRL1_DISCNUM_Msk);//两个结构体的位清空ADC_AUXADC_CFG0->ADC_RSV1 &=~ ADC_AUXADC_CFG0_RSRV1_Msk;ADC_MCU_ADCBUF_CFG0->ADCBUF_RSV1 &=~ ADC_MCU_ADCBUF_CFG0_RSRV1_Msk;ADC_AUXADC_CFG0->ADC_RSV1 &=~ ADC_AUXADC_CFG0_RSRV0_Msk;ADC_MCU_ADCBUF_CFG0->ADCBUF_RSV1 &=~ ADC_MCU_ADCBUF_CFG0_RSRV0_Msk;//ADC 参数初始化 end//ADC 规则组 触发源设置ADCtrigsrc.regularTrigSource = ADC_TrigSource_Internal;//软件触发;规则组 选择内部触发ADC->CTRL1 &=TRIG_SOURCE_SETTING_RESET;//转换触发源复位ADC->CTRL1 = (ADC->CTRL1 & ~(ADC_CTRL1_EXTTRIG_Msk)) | (((uint32_t)(((uint32_t)(ADCtrigsrc.regularTrigSource))<<ADC_CTRL1_EXTTRIG_Pos))&ADC_CTRL1_EXTTRIG_Msk);ADC->CTRL1 = (ADC->CTRL1 & ~(ADC_CTRL1_IEXTTRIG_Msk))|(((uint32_t)(((uint32_t)(ADCtrigsrc.injectTrigSource))<<ADC_CTRL1_IEXTTRIG_Pos))&ADC_CTRL1_IEXTTRIG_Msk);/* ****** 设置分频系数,48M/8=6Mhz ****** */ADC->CTRL2 = (ADC->CTRL2 & ~(ADC_CTRL2_PSC_Msk)) |(((uint32_t)(((uint32_t)(ADC_ADIV_DIVIDE_8))<<ADC_CTRL2_PSC_Pos))&ADC_CTRL2_PSC_Msk);/* ****** 规则组,通道总数只有1个 ****** */uint32_t length=1;ADC->RSQR1 = (ADC->RSQR1 & ~(ADC_RSQR1_RSQL_Msk))|(((uint32_t)(((uint32_t)(length-1))<<ADC_RSQR1_RSQL_Pos))&ADC_RSQR1_RSQL_Msk);/* ****** ADC 使能  ****** */ADC->CTRL2 |=ADC_CTRL2_ADON_Msk;}//复位ADCx外设
void ADC_Deinit()
{//外设时钟控制失能*(volatile unsigned int *)(PERI_CLK_EN_1) &= ~((uint32_t)(1<< (uint32_t)(CLK_ADC-32)));//外设软件复位失效*(volatile unsigned int *)(PERI_SFT_RST2) &= ~((uint32_t)(1<< (SRST_ADC-32)));printf("ADC_Deinit\r\n");
}
//获取指定ADC通道值
uint32_t GetAdcChannelValue(uint32_t Channel)
{/* ****** 选择转换通道 ****** */uint32_t seq=0;if(Channel ==0 || Channel ==1 || Channel ==2 || Channel ==8 ||Channel==11 || Channel==12 ){seq =1;}if(seq <7)//ADC 规则组序列配置寄存器3{ADC->RSQR3 &=~((0x1FUL)<<((seq-1)*5));ADC->RSQR3 |= ((Channel)<<((seq-1)*5));}else if(seq <13)//ADC 规则组序列配置寄存器2{ADC->RSQR2 &=~((0x1FUL)<<((seq-7)*5));ADC->RSQR2 |= ((Channel)<<((seq-7)*5));}else //>=13 ADC 规则组序列配置寄存器1{ADC->RSQR2 &=~((0x1FUL)<<((seq-13)*5));ADC->RSQR2 |= ((Channel)<<((seq-13)*5));}//ADC 通道状态寄存器ADC_ANA_CHANNEL->MODE &=~ (0x01UL<<(31-Channel));/* ****** 设置通道采样时间 ****** */if (Channel < 10)//ADC 采样时间设置寄存器2{ADC->SPT2 &= ~(0x7UL << ((Channel) * 3));ADC->SPT2 |= (ADC_SampleTime_14Cycle << ((ADC_SampleTime_14Cycle) * 3));}else//ADC 采样时间设置寄存器1{ADC->SPT1 &= ~(0x7UL << ((Channel - 10) * 3));ADC->SPT1 |= (ADC_SampleTime_14Cycle << ((Channel - 10) * 3));}/* ****** 软件触发转换 ****** */ADC->CTRL1 |= ADC_CTRL1_SWSTART_Msk;while(!(ADC->STR & ADC_FLAG_EOC));//等待转换完成 即有值的时候就退出循环return ((uint16_t)ADC->RDR);//返回转换结果 ADC规则组数据寄存器
}
//ADC 中断服务程序
void ADC_IRQHandler()
{if (g_adcCallback[0]){g_adcCallback[0]();printf("fun start callback\r\n");}printf("fun ptr NULL\r\n");
}

【8】main.c [参考+2]

//#include "mon_adc.h"
#include "ctrl_adc.h"
/*项目总入口*/
int main()
{//# if defined (F1)
#if (0)FILE *fd;const char *p ="123456789"; //['1''2''3''4''5''6''7''8'9']="123456789"fd = fopen("C://Users//sujieyin//Desktop//QT//MCU//1.txt","w");//只写方式打开 不存在就创建printf("%d ",strlen(p));//字符串实际长度for (uint_fast32_t i=0;i<strlen(p);i++) {int ret = fputc(p[i],fd);//传入的整数被当作ASCII字符printf("ret =%d \n",ret);//返回ASCII码的10进制}fclose(fd);
#endif
#if 0char buf[16]={0};//正确形式//char buf[16];//不初始化 里面存有随机值printf("sizeof =%d \n",sizeof (buf));printf("strlen =%d \n",strlen(buf));for (int i=0;i<strlen(buf);i++) {printf("i =%d \n",buf[i]);}/* 输出结果*  sizeof =16strlen =3i =-5i =23i =64*/int ret =snprintf(buf,sizeof (buf),"%s","12345678901234567890");printf("ret size =%d \n",ret);printf("buf =%s \n",buf);/*  显然给buf的字符串长度不能超出buf的大小 否侧出现写入不全sizeof =16strlen =0ret size =-1buf =1234567890123456*/
#endif/*==========================控制MCU调用ADC实例=======================*//*医疗设备 电磁阀的控制和监控 初始化*/printf("\r\n  ADC0 init ok \r\n");//RB_ADC_Init();while(2022){/* 屏幕下方物理按键 */RB_ADC_ScanButton();/*监控电磁阀实际动作和配置是否相符*/RB_ADC_ScanButton2();}return 0;
}

GD32F30x系列ADC源码,对初学者参考价值巨大,(非常详细篇)万字源码相关推荐

  1. qj71c24n通讯实例_Q系列串行口通信模块用户参考手册QJ71C24N(基础篇).pdf

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp电子工程/通信技术&nbsp>&nbsp数据通信与网络 Q系列串行口通信模块用户参考手册QJ ...

  2. spring-boot-2.0.3不一样系列之源码篇 - springboot源码一,绝对有值得你看的地方

    前言 上篇:spring-boot-2.0.3不一样系列之shiro - 搭建篇,实现了spring-boot与shiro的整合,效果大家也看到了,工程确实集成了shiro的认证与授权功能.如果大家能 ...

  3. 全新STM32 PID温控‘包括‘PID源码‘PCB‘源理图 全新自整定PID温控 STM32温控源码 … 资料参考价值较高,内含PCB+原理图+程序,内容完整。

    全新STM32 PID温控'包括'PID源码'PCB'源理图 全新自整定PID温控 STM32温控源码 - 资料参考价值较高,内含PCB+原理图+程序,内容完整. 注:STM32程序使用IAR打开 注 ...

  4. 微信活码云-裂变系统破除微信加群限制(含源码及数据库文件)-供参考学习

    微信活码 活码的原理就是通过扫描活码后,看到一个你自己的真实二维码,而这个二维码可以在后台随意更换,或者按照一定规则自动切换的形式. 群裂变利器 通过微信活码进行群裂变,二维码永不过期啦!还可以根据用 ...

  5. 【vue-router源码】十二、useRoute、useRouter、useLink源码分析

    [vue-rouer源码]系列文章 [vue-router源码]一.router.install解析 [vue-router源码]二.createWebHistory.createWebHashHis ...

  6. GD32F30x系列系统及存储器架构

    GD32F30x系列系统及存储器架构 1. 系统及存储器架构 1.1. Arm® Cortex®-M4 处理器 1.2. 系统架构 1.3. 存储器映射 1.3.1. 位带操作 1.3.2. 片上 S ...

  7. [源码解析] PyTorch分布式优化器(1)----基石篇

    [源码解析] PyTorch分布式优化器(1)----基石篇 文章目录 [源码解析] PyTorch分布式优化器(1)----基石篇 0x00 摘要 0x01 从问题出发 1.1 示例 1.2 问题点 ...

  8. 13、PIC32系列-ADC采样模块

    PIC32系列-ADC采样模块 1.PIC32参考资源 2.10位ADC转换器简介 3.控制寄存器 4.ADC工作原理及配置 5.使用Harmony工具生成ADC工程代码 6.实际代码分析 7.实验验 ...

  9. 若川诚邀你加源码共读群,帮助更多人学会看源码~

    小提醒:若川视野公众号面试.源码等文章合集在菜单栏中间[源码精选]按钮,欢迎点击阅读,也可以星标我的公众号,便于查找. 回复pdf,可以获取前端优质书籍. 最近我创建了一个源码共读的前端交流群,希望尝 ...

最新文章

  1. Maya 2020面部绑定动画学习视频教程 Facial Rigging 101 – Maya 2020
  2. 【转载】基于ASP.NET Web Application的插件实现,附DEMO
  3. 快速实现dNet三层架构项目图解
  4. Paper之DL:深度学习高质量论文分类推荐(建议收藏,持续更新)
  5. AJAX Tookits -- ConfirmButton
  6. 获得系统中某个进程的cpu使用率
  7. LoadRunner培训初级教程
  8. php表格位于页面中央,怎么为表格所在的页面添加编辑限制保护
  9. 计算机音乐专业学什么软件有哪些内容,电脑音乐入门装备(软件篇)
  10. 如何引用阿里云矢量图标库
  11. jJava基础篇--IO流
  12. 彻底解决Ubuntu18.04搜狗拼音输入法问题---支持Pycharm、WPS
  13. 【Java的Excel操作】MyExcel
  14. 互联网早报 | 2月2日 星期二 | 小米之家完成江苏河南县级全覆盖;知乎正式启动首部科幻剧;盼达用车宣布暂停运营...
  15. x264 - 高品质 H.264 编码器
  16. LOJ10155 一本通1577 数字转换 题解
  17. Vuex 4源码学习笔记 - 做好changelog更新日志很重要(十)
  18. 微信小程序——【云音乐播放器】
  19. 安装服务器的win pe系统教程,u盘pe安装win7系统教程图解
  20. CVPR2020/UDA/图像翻译-Cross-domain Correspondence Learning for Exemplar-based Image Translation基于范例的跨域对应

热门文章

  1. 上海一级计算机试卷,上海计算机一级考试试题及答案
  2. T-test数据分析
  3. 全国首个DCMM5级!牛X了我的国家电网!!!
  4. 我国计算机的创新,浅析计算机技术的创新过程
  5. 使用ps优化图片,减少图片内存大小
  6. chrome硬件加速_如何在Chrome中打开和关闭硬件加速
  7. Unity_滚动文本字幕
  8. kafka自定义生产者分区器、自定义消费者分区器
  9. 电脑计算机管理看AHCI,怎么将电脑硬盘模式修改为ahci模式?
  10. java文档注释用什么开头,极其重要