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

news2024/11/18 8:50:39

GD32F30x系列ADC源码

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

在这里插入图片描述


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


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


【1】adc_reg.h [参考]

#ifndef CTRL_ADC_H
#define CTRL_ADC_H
#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdio.h>

#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const	  //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数

#if defined(__CC_ARM)
  #pragma anon_unions   //keil中默认是不支持匿名结构体的,需要编译指令#pragma anon_unions指名。
#elif defined(CCARM__)
  #pragma language=extended //IAR对所用语言(这里是C)做的一些扩展,也就是说这里可以用扩展的功能
#elif defined (__ICCARM__)
/* anonymous unions are enabled by default:默认启用匿名联合 */
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)
  #pragma warning 586
#else
  #warning Not supported compiler type //警告不支持编译器类型
#endif

/*============================控制MCU部分==========================*/
/* 通道号 */
#define ADC_CHANNEL_0                    0x00
#define ADC_CHANNEL_1                    0x01
#define ADC_CHANNEL_2                    0x02
#define ADC_CHANNEL_3                    0x03
#define ADC_CHANNEL_4                    0x04
#define ADC_CHANNEL_5                    0x05
#define ADC_CHANNEL_6                    0x06
#define ADC_CHANNEL_7                    0x07
#define ADC_CHANNEL_8                    0x08
#define ADC_CHANNEL_9                    0x09
#define ADC_CHANNEL_10                   0x0A
#define ADC_CHANNEL_11                   0x0B
#define ADC_CHANNEL_12                   0x0C
#define ADC_CHANNEL_13                   0x0D
#define ADC_CHANNEL_14                   0x0E
#define ADC_CHANNEL_15                   0x0F
#define ADC_CHANNEL_16                   0x10
#define ADC_CHANNEL_17                   0x11

/* 规则组长度 ADC_RSQ0.Bits.RL */
#define REGULAR_LEN_1                    0x00
#define REGULAR_LEN_2                    0x01
#define REGULAR_LEN_3                    0x02
#define REGULAR_LEN_4                    0x03
#define REGULAR_LEN_5                    0x04
#define REGULAR_LEN_6                    0x05
#define REGULAR_LEN_7                    0x06
#define REGULAR_LEN_8                    0x07
#define REGULAR_LEN_9                    0x08
#define REGULAR_LEN_10                   0x09
#define REGULAR_LEN_11                   0x0A
#define REGULAR_LEN_12                   0x0B
#define REGULAR_LEN_13                   0x0C
#define REGULAR_LEN_14                   0x0D
#define REGULAR_LEN_15                   0x0E
#define REGULAR_LEN_16                   0x0F
/*注入组长度 注入通道,x=0,1,2,3  数据偏移值,取值范围为0~4095*/
#define INSERTED_LEN_1                    0x00
#define INSERTED_LEN_2                    0x01
#define INSERTED_LEN_3                    0x02
#define INSERTED_len_4                    0x03
/*ADC的采样时间*/
#define ADC_SAMPLETIME_1POINT5          //1.5 周期
#define ADC_SAMPLETIME_7POINT5          //7.5 周期
#define ADC_SAMPLETIME_13POINT5         //13.5 周期
#define ADC_SAMPLETIME_28POINT5         //28.5 周期
#define ADC_SAMPLETIME_41POINT5         //41.5 周期
#define ADC_SAMPLETIME_55POINT5         //55.5 周期
#define ADC_SAMPLETIME_71POINT5         //71.5 周期
#define ADC_SAMPLETIME_239POINT5        //239.5 周期

/*ADC 分辨率*/
#define ADC_RESOLUTION_12B  //12位
#define ADC_RESOLUTION_10B  //10位
#define ADC_RESOLUTION_8B   //8位
#define ADC_RESOLUTION_6B   //6位

/*ADC 通道组*/  //间断模式下的转换数目,规则通道组取值为1..8,注入通道组取值无意义
//ADC通道选择ADC_CHANNEL_x(x=0..17)  ADC 通道x (x=0..17)(只有ADC0,可取值x=16和17 )
#define ADC_REGULAR_CHANNEL //规则通道组
#define ADC_INSERTED_CHANNEL//注入通道组

/*ADC 运行模式*/
#define ADC_MODE_FREE  //所有ADC运行于独立模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL //ADC0和ADC1运行在规则并行+注入并行组合模式
#define ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION //ADC0和ADC1运行在规则并行+交替触发组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_FAST    //ADC0和ADC1运行在注入并行+快速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL_REGULAL_FOLLOWUP_SLOW    //ADC0和ADC1运行在注入并行+慢速交叉组合模式
#define ADC_DAUL_INSERTED_PARALLEL      //ADC0和ADC1运行在注入并行模式
#define ADC_DAUL_REGULAL_PARALLEL       //ADC0和ADC1运行在规则并行模式
#define ADC_DAUL_REGULAL_FOLLOWUP_FAST  //ADC0和ADC1运行在快速交叉模式
#define ADC_DAUL_REGULAL_FOLLOWUP_SLOW  //ADC0和ADC1运行在慢速交叉模式
#define ADC_DAUL_INSERTED_TRRIGGER_ROTATION //ADC0和ADC1运行在交替触发模式

/*ADC 功能配置*/
#define ADC_SCAN_MODE               //扫描模式选择
#define ADC_INSERTED_CHANNEL_AUTO   //注入组自动转换
#define ADC_CONTINUOUS_MODE         //连续模式选择

/*ADC 规则通道组或注入通道组触发源*/
#define ADC0_1_EXTTRIG_REGULAR_T0_CH0           //TIMER0 CH0事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH1           //TIMER0 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T0_CH2           //TIMER0 CH2事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T1_CH1           //TIMER1 CH1事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T2_TRGO          //TIMER2TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T3_CH3           //TIMER3 CH3事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_T7_TRGO          //TIMER7 TRGO事件(规则组)
#define ADC0_1_EXTTRIG_REGULAR_EXTI_11          //外部中断线11(规则组)
#define ADC2_EXTTRIG_REGULAR_T2_CH0             //TIMER2 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T1_CH2             //TIMER1 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T0_CH2             //TIMER0 CH2事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_CH0             //TIMER7CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T7_TRGO            //TIMER7  TRGO事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH0             //TIMER4 CH0事件(规则组)
#define ADC2_EXTTRIG_REGULAR_T4_CH2             //TIMER4  CH2事件(规则组)
#define ADC0_1_2_EXTTRIG_REGULAR_NONE           //软件触发(规则组)
#define ADC0_1_EXTTRIG_INSERTED_T0_TRGO         //TIMER0 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T0_CH3          //TIMER0 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_TRGO         //TIMER1 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T1_CH0          //TIMER1 CH0事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T2_CH3          //TIMER2 CH3事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_T3_TRGO         //TIMER3 TRGO事件(注入组)
#define ADC0_1_EXTTRIG_INSERTED_EXTI_15         //外部中断线15 (注入组)
#define ADC0_1_EXTTRIG_INSERTED_T7_CH3          //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_TRGO           //TIMER0 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T0_CH3            //TIMER0 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T3_CH2            //TIMER3 CH2事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH1            //TIMER7 CH1事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T7_CH3            //TIMER7 CH3事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_TRGO           //TIMER4 TRGO事件(注入组)
#define ADC2_EXTTRIG_INSERTED_T4_CH3            //TIMER4 CH3事件(注入组)
#define ADC0_1_2_EXTTRIG_INSERTED_NONE          //软件触发(注入组)

/*ADC标志位*/
#define ADC_FLAG_WDE    //模拟看门狗事件标志位
#define ADC_FLAG_EOC    //转换结束标志位
#define ADC_FLAG_EOIC   //注入通道组转换结束标志位
#define ADC_FLAG_STIC   //注入通道组转换开始标志位
#define ADC_FLAG_STRC   //规则通道组转换开始标志位

/*ADC过采样触发模式*/
#define ADC_OVERSAMPLING_ALL_CONVERT        //在一个触发之后,对一个通道连续进行过采样转换
#define ADC_OVERSAMPLING_ONE_CONVERT        //在一个触发之后,对一个通道只进行一次过采样转换
typedef struct {
    union{
        struct//ADC标志位  从低位->高位
        {   //WDE-》转换电压超过ADC_WDLT和ADC_WDHT寄存器设定的阈值时由硬件置1,软件写0清除。
            __IO uint32_t WDE              :1;      //模拟看门狗事件 1:产生模拟看门狗事件 0:没有模拟看门狗事件
            __IO uint32_t EOC              :1;      //组转换结束    1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除或读ADC_RDATA寄存器清除
            __IO uint32_t EOIC             :1;      //注入通道组转换结束 1:转化结束 0:未结束转化  转化结束时硬件会置1 软件写0清除
            __IO uint32_t STIC             :1;      //注入通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除
            __IO uint32_t STRC             :1;      //规则通道组转换开始 1:开始转化 0:未开启转化  转化开始时硬件会置1 软件写0清除
            __IO uint32_t                  :27;     //保留 必须保留复位值
        }Bits;
        __IO uint32_t Byte;    // 复位值: 0x0000 C000 -》0000 0000 0000 0000 1100 0000 0000 0000 (32位)
    }ADC_STAT;    // 地址偏移: 0x00   状态寄存器
    union{
        struct
        {
            __IO uint32_t WDCHSEL          :5; //模拟看门狗通道选择
            /*
             *  00000: ADC 通道 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;
}

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

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

相关文章

我的学校网页期末作业(纯html+css实现)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

在js中使用grpc(包括代理)后端使用Go

叙述 最近在研究web端的聊天系统&#xff0c;准备使用grpc作为通讯协议&#xff0c;因为客户端要主动的接受到消息&#xff0c;所以想要使用双向流的grpc。 但是经过几天的研究发现&#xff0c;grpc在浏览器上是不支持的&#xff0c;因为浏览器使用的协议是http1.1&#xff0c…

Apipost自动化测试功能详解

如何快速掌握接口自动化测试&#xff1f;首先我们看看&#xff1a; 1、什么是接口自动化测试&#xff1f; 通常&#xff0c;在设计了测试用例并通过评审之后&#xff0c;由测试人员根据测试用例中描述的规程一步步执行测试&#xff0c;得到实际结果与期望结果的比较。自动化测…

新浪股票行情数据接口有什么作用?

通过新浪股票行情数据接口可以让投资者在实际交易当中能够更加精准的洞悉盘口变化。该接口可以说是目前最好用的免费股票行情数据接口了&#xff0c;虽然一直并未公开&#xff0c;但暂时使用良好。大家用浏览器访问新浪的股票行情数据接口就能查看最新行情数据了。那么今天小编…

New Features Of JDK - JDK9 Modular System

Modular System 是 JAVA9 中提供的新特性&#xff0c;它从一个独立的开源项目而来&#xff0c;名为 Jigsaw Project。在此之前&#xff0c;我们对于 Java 技术栈中模块化的认知是基于 OSGI 的&#xff0c;实际上 OSGI 也确实形成了它自己独有的体系&#xff0c;并且是一定程度上…

TFT espi相关

文章目录1 .库文件设置1-1&#xff1a;这是库文件 tft _espi1-2&#xff1a;如何确定像素排列方式1-3&#xff1a;颜色显示异常处理方法2 .显示图片3.显示图片方法1 .库文件设置 1-1&#xff1a;这是库文件 tft _espi 链接&#xff1a;https://pan.baidu.com/s/1sT6s6VtpuwNV…

Spring【五大类注解的存储和读取Bean方法注解】

Spring【5大类注解的存储和读取Bean对象】&#x1f34e;一. 五大类存储 Bean 对象&#x1f352;1.1 配置spring-config.xml扫描路径&#x1f352;1.2 添加五大类注解存储 Bean 对象&#x1f349;1.2.1 Controller&#xff08;控制器存储&#xff09;&#x1f349;1.2.2 Service…

ADAU1860调试心得(14)单片机启动与控制ADAU1860详解

ADAU1860实现脱机运行&#xff0c;是开发这个DSP的最后一步。这颗芯片有一颗HIFI 3Z的蓝牙MCU内嵌&#xff0c;用户可以用这颗MCU来进行脱机&#xff0c;甚至直接用C来开发1860&#xff08;有专门的SDK&#xff0c;不在此做更多阐述&#xff09;&#xff0c;但是这个HIFI 3Z的软…

零代码使用air32做USB转串口

零代码实现USB转串口 环境搭建参考Air32F103使用手册 创建工程 新建工程 选择设备为AIR32F103CB 在弹出的RTE窗口勾选如下组件 配置工程 修改编译器为AC5&#xff0c;并启用MicroLIB 启用C99标准支持 添加代码 添加功能代码&#xff0c;在Source Group文件夹右键&#xff…

观测云产品更新|应用性能新增服务清单功能;用户访问监测 Session 查看器调整;事件新增移动端跳转选项等

观测云更新 应用性能新增服务清单功能 应用性能监测服务清单&#xff0c;支持实时查看不同服务的所有权、依赖关系、性能、关联的仪表版以及关联分析&#xff0c;快速发现和解决服务的性能问题&#xff0c;帮助团队高效地构建及管理大规模的端到端的分布式应用。 更多详情可…

FineReport可视化数据图表- 函数计算组成和语法示例

1.1设计报表 例如&#xff0c;使用内置数据集「销量」创建数据集ds1&#xff0c;对不同地区销量高低做判断。 将「地区」字段拖入 A2&#xff0c;将「销量」字段拖入B2&#xff0c;并设置「销量」展示方式为求和&#xff0c;然后对不同地区的销量情况进行求和&#xff0c;如下…

【吴恩达机器学习笔记】九、机器学习系统的设计

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…

Allegro如何用list文件抓取器件操作指导

Allegro如何用list文件抓取器件操作指导 Allegro支持list文件在PCB上抓取器件,具体操作如下 在pcb相同目录下新建一个后缀为.lst文件,任意命名一个名字比如123.lst 原理图中批量选择需要抓取器件的信息,支持批量选择,无用的信息框选进去也是可以的 复制到新建lst文件中去…

主流嵌入式操作系统有哪些

嵌入式操作系统EOS(Embedded OperatingSystem)是一种用途广泛的系统软件&#xff0c;过去它主要应用于工业控制和国防系统领域。常见的嵌入式操作系统有wince、PALM OS、linux、Android、FreeRTOS。 WINDOWS CE是微软开发的一个开放的、可升级的32位嵌入式操作系统&#xff0c;…

【Matplotlib绘制图像大全】(二十六):Matplotlib读取本地图像

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

基于SpringBoot和Vue的厨到家服务平台的设计与实现毕业设计源码063133

springboot厨到家服务系统 摘 要 在社会快速发展的影响下&#xff0c;餐饮迅速发展&#xff0c;大大增加了餐饮服务信息管理的数量、多样性、质量等等的要求&#xff0c;使餐饮的管理和运营比过去十年更加困难。依照这一现实为基础&#xff0c;设计一个快捷而又方便的厨到家服…

十二条后端开发经验分享,纯干货

前言 本文是博主从事后端开发以来&#xff0c;对公司、个人项目的经验总结&#xff0c;包含代码编写、功能推荐、第三方库使用及优雅配置等&#xff0c;希望大家看到都能有所收获 博主github地址: github.com/wayn111 一. 优雅的进行线程池异常处理 在Java开发中&#xff0c…

【Recurrent Neural Network(RNN)】循环神经网络——李宏毅机器学习阅读笔记

Recurrent Neural Network(RNN) Example Application Slot Filling 智慧订票系统&#xff1a; How to represent each word as a vector? 但是光这样&#xff0c;feedforward Network是无法solve这一问题的&#xff0c;因为他无法区别是leave Taipei还是arrive Taipei。…

stable diffusion webui安装部署教程

系统环境&#xff1a; 腾讯云服务器&#xff0c;centos 7.6 基础环境安装 git 安装&#xff08;直接安装高版本的&#xff09; (默认安装的是1.8 版本的。没有 -c 命令&#xff0c;需要升级&#xff09; 参考&#xff1a; https://blog.csdn.net/qq_28903377/article/detai…

[附源码]Python计算机毕业设计SSM康健医药公司进销存管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…