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

在这里插入图片描述


这篇文章必须配合这个连接文件一起看,即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 通道 0
                00001: ADC 通道 1
                00010: ADC 通道 2
                00011: ADC 通道 3
                00100: ADC 通道 4
                00101: ADC 通道 5
                00110: ADC 通道 6
                00111: ADC 通道 7
                01000: ADC 通道 8
                01001: ADC 通道 9
                01010: ADC 通道 10
                01011: ADC 通道 11
                01100: ADC 通道 12
                01101: ADC 通道 13
                01110: ADC 通道 14
                01111: ADC 通道 15
                10000: ADC 通道 16
                10001: 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    控制寄存器 0
    union{
        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 TRGO
                001:定时器 0 CH3
                010:定时器 1 TRGO
                011:定时器 1 CH0
                100:定时器 2 CH3
                101:定时器 3 TRGO
                110:中断线 15/定时器 7 CH3
                111:软件触发
                对于 ADC2:
                000:定时器 0 TRGO
                001:定时器 0 CH3
                010:定时器 3 CH2
                011:定时器 7 CH1
                100:定时器 7 CH3
                101:定时器 4 TRGO
                110:定时器 4 CH3
                111:软件触发
            */
            __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 CH0
                001:定时器 0 CH1
                010:定时器 0 CH2
                011:定时器 1 CH1
                100:定时器 2 TRGO
                101:定时器 3 CH3
                110:中断线 11/定时器 7 TRGO
                111:软件触发
                对于 ADC2:
                000:定时器 2 CH0
                001:定时器 1 CH2
                010:定时器 0 CH2
                011:定时器 7 CH0
                100:定时器 7 TRGO
                101:定时器 4 CH0
                110:定时器 4 CH2
                111:软件触发
            */
            __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    控制寄存器 1
    union{
        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    采样时间寄存器 0
    union{
        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    采样时间寄存器 1
    union{
        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    注入通道数据偏移寄存器 0
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF1;    // 地址偏移: 0x18    注入通道数据偏移寄存器 1
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF2;    // 地址偏移: 0x1C    注入通道数据偏移寄存器 2
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF3;    // 地址偏移: 0x20    注入通道数据偏移寄存器 3
    union{
        struct
        {
            __IO uint32_t WDHT            :12;//模拟看门狗高阈值
            __IO uint32_t                 :20;//31:12 保留 必须保持复位值。
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_WDHT;    // 地址偏移: 0x24    看门狗高阈值寄存器    模拟看门狗高阈值,0..4095
    union{
        struct
        {
            __IO uint32_t WDLT            :12;//模拟看门狗低阈值 这些位定义了模拟看门狗的低阈值。
            __IO uint32_t                 :20;//31:12 保留 必须保持复位值。
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_WDLT;    // 地址偏移: 0x28    看门狗低阈值寄存器    模拟看门狗低阈值,0..4095
    union{
        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    规则序列寄存器 0
    union{
        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    规则序列寄存器 1
    union{
        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    规则序列寄存器 2
    union{
        struct
        {
            __IO uint32_t ISQ0             :5;//通道编号(0..17)写入这些位来选择注入组的第 n 个转换的通道
            /*
                和规则通道转换序列不同的是,如果 IL[1:0]长度不足 4,注入通道转换从(4-IL[1:0]-
                1) 开始。
                IL 注入通道转换顺序
                3 ISQ0 >> ISQ1 >> ISQ2 >> ISQ3
                2 ISQ1 >> ISQ2 >> ISQ3
                1 ISQ2 >> ISQ3
                0 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    注入数据寄存器 0
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA1;    // 地址偏移: 0x40    注入数据寄存器 1
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA2;    // 地址偏移: 0x44    注入数据寄存器 2
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA3;    // 地址偏移: 0x48    注入数据寄存器 3
    union{
        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:2x
                    001:4x
                    010:8x
                    011:16x
                    100:32x
                    101:64x
                    110:128x
                    111: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 通道 0
                00001: ADC 通道 1
                00010: ADC 通道 2
                00011: ADC 通道 3
                00100: ADC 通道 4
                00101: ADC 通道 5
                00110: ADC 通道 6
                00111: ADC 通道 7
                01000: ADC 通道 8
                01001: ADC 通道 9
                01010: ADC 通道 10
                01011: ADC 通道 11
                01100: ADC 通道 12
                01101: ADC 通道 13
                01110: ADC 通道 14
                01111: ADC 通道 15
                10000: ADC 通道 16
                10001: 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    控制寄存器 0
    union{
        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 TRGO
                001:定时器 0 CH3
                010:定时器 1 TRGO
                011:定时器 1 CH0
                100:定时器 2 CH3
                101:定时器 3 TRGO
                110:中断线 15/定时器 7 CH3
                111:软件触发
                对于 ADC2:
                000:定时器 0 TRGO
                001:定时器 0 CH3
                010:定时器 3 CH2
                011:定时器 7 CH1
                100:定时器 7 CH3
                101:定时器 4 TRGO
                110:定时器 4 CH3
                111:软件触发
            */
            __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 CH0
                001:定时器 0 CH1
                010:定时器 0 CH2
                011:定时器 1 CH1
                100:定时器 2 TRGO
                101:定时器 3 CH3
                110:中断线 11/定时器 7 TRGO
                111:软件触发
                对于 ADC2:
                000:定时器 2 CH0
                001:定时器 1 CH2
                010:定时器 0 CH2
                011:定时器 7 CH0
                100:定时器 7 TRGO
                101:定时器 4 CH0
                110:定时器 4 CH2
                111:软件触发
            */
            __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    控制寄存器 1
    union{
        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    采样时间寄存器 0
    union{
        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    采样时间寄存器 1
    union{
        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    注入通道数据偏移寄存器 0
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF1;    // 地址偏移: 0x18    注入通道数据偏移寄存器 1
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF2;    // 地址偏移: 0x1C    注入通道数据偏移寄存器 2
    union{
        struct
        {
            __IO uint32_t IOFF            :12;
            __IO uint32_t                 :20;
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IOFF3;    // 地址偏移: 0x20    注入通道数据偏移寄存器 3
    union{
        struct
        {
            __IO uint32_t WDHT            :12;//模拟看门狗高阈值
            __IO uint32_t                 :20;//31:12 保留 必须保持复位值。
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_WDHT;    // 地址偏移: 0x24    看门狗高阈值寄存器    模拟看门狗高阈值,0..4095
    union{
        struct
        {
            __IO uint32_t WDLT            :12;//模拟看门狗低阈值 这些位定义了模拟看门狗的低阈值。
            __IO uint32_t                 :20;//31:12 保留 必须保持复位值。
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_WDLT;    // 地址偏移: 0x28    看门狗低阈值寄存器    模拟看门狗低阈值,0..4095
    union{
        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    规则序列寄存器 0
    union{
        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    规则序列寄存器 1
    union{
        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    规则序列寄存器 2
    union{
        struct
        {
            __IO uint32_t ISQ0             :5;//通道编号(0..17)写入这些位来选择注入组的第 n 个转换的通道
            /*
                和规则通道转换序列不同的是,如果 IL[1:0]长度不足 4,注入通道转换从(4-IL[1:0]-
                1) 开始。
                IL 注入通道转换顺序
                3 ISQ0 >> ISQ1 >> ISQ2 >> ISQ3
                2 ISQ1 >> ISQ2 >> ISQ3
                1 ISQ2 >> ISQ3
                0 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    注入数据寄存器 0
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA1;    // 地址偏移: 0x40    注入数据寄存器 1
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA2;    // 地址偏移: 0x44    注入数据寄存器 2
    union{
        struct
        {
            __I uint32_t IDATAn             :16;//注入转换的数据 n 这些位包含了注入通道的转换结果,只读。
            __I uint32_t                    :16;
        }Bits;
        __I uint32_t Byte;    // 复位值: 0x0000 0000
    }ADC_IDATA3;    // 地址偏移: 0x48    注入数据寄存器 3
    union{
        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:2x
                    001:4x
                    010:8x
                    011:16x
                    100:32x
                    101:64x
                    110:128x
                    111: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;    // 地址偏移: 0x18
    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_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;    // 地址偏移: 0x2C
    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_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;    // 地址偏移: 0x40
    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_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;    // 地址偏移: 0x54
    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_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;    // 地址偏移: 0x68
    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_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;    // 地址偏移: 0x7C
    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_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 alignment
    uint32_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    时钟配置寄存器 0
    union{
        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;  //0
    RCU->RCU_CFG0.Bits.ADCPSC_Bit2 =1;   //1
    RCU->RCU_CFG0.Bits.ADCPSC_Bit1_0 =3; //11

    //ADC配置 占4个位
    ADC0->ADC_CTL0.Bits.SYNCM =0;   //独立模式 0000

    ADC0->ADC_CTL0.Bits.SM =1;      //扫描转换模式

#if (CONTINUE_MODE == 1)
    ADC0->ADC_CTL1.Bits.CTN = 1;				// 0:禁止连续模式,1:使能连续模式
#else
    ADC0->ADC_CTL1.Bits.CTN = 0;
#endif
    ADC0->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 1011
    ADC0->ADC_RSQ2.Bits.RSQ1 = ADC_CHANNEL_12;	//PC2 Mag_CUR_ADC9-16_COM   0x0C=0000 1100
    ADC0->ADC_RSQ2.Bits.RSQ2 = ADC_CHANNEL_13;	//PC3 Mag_CUR_ADC17-24_COM  0x0D=0000 1101
    ADC0->ADC_RSQ2.Bits.RSQ3 = ADC_CHANNEL_14;	//PC4 Mag_CUR_ADC25-32_COM  0x0E=0000 1110
    ADC0->ADC_RSQ2.Bits.RSQ4 = ADC_CHANNEL_15;	//PC5 Mag_CUR_ADC33-40_COM  0x0F=0000 1111
    ADC0->ADC_RSQ2.Bits.RSQ5 = ADC_CHANNEL_10;	//PC0 按键                   0x0A=0000 1001

    ADC0->ADC_SAMPT0.Byte = 0x00ffffff;         //0000 0000 1111 1111 1111 1111 11111 1111
    ADC0->ADC_SAMPT1.Byte = 0x3fffffff;			// 所有通道采样时间为ADC时钟周期 * 239.5

    ADC0->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-bit
    DMA0->DMA_CH0CTL.Bits.PWIDTH = 1;							//外设的传输数据宽度   01: 16-bit
    DMA0->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个长度数据给array
        memcpy(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转化结果zhi
    static 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个不参与下轮比较,第一轮比较完成后最右边的值即为该数组的最大值
        {								//1
            if ((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通道x
     const 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 参数初始化 start
    uint32_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 0
    char 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 =16
        strlen =3
        i =-5
        i =23
        i =64
    */
   int ret =snprintf(buf,sizeof (buf),"%s","12345678901234567890");
    printf("ret size =%d \n",ret);
    printf("buf =%s \n",buf);
    /*  显然给buf的字符串长度不能超出buf的大小 否侧出现写入不全
        sizeof =16
        strlen =0
        ret size =-1
        buf =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;
}

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Qt历险记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值