• GD32F303固件库开发(10)----双ADC轮询模式扫描多个通道


    概述

    本章主要配置,双ADC轮询模式扫描多个通道,通过串口进行打印。
    查阅手册可以得知,PA9、PA10为串口0的输出和输入口。
    查阅手册可以得知,PA9、PA10为串口0的输出和输入口。需要GD样片的可以加群申请:615061293 。
    在这里插入图片描述

    视频教学

    GD32F303固件库开发(10)----双ADC轮询模式扫描多个通道

    https://www.bilibili.com/video/BV1N94y1D7Yh/

    csdn课程

    课程更加详细。
    https://download.csdn.net/course/detail/37144

    硬件准备

    这里准备了1块开发板进行验证,分别是GD32303C_START开发板。
    在这里插入图片描述

    keil配置

    microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,如果要使用printf(),必须开启。
    在这里插入图片描述

    使能串口

      /* 使能GPI0A,用PA9、PA10为串口 */
        rcu_periph_clock_enable(RCU_GPIOA);
    
        /*使能串口0的时钟 */
        rcu_periph_clock_enable(RCU_USART0);
    
        /*配置USARTx_Tx(PA9)为复用推挽输出*/
        gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
     
        /*配置USARTx_RxPA9)为浮空输入 */
        gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
    
        /* USART 配置 */
        usart_deinit(USART0);//重置串口0
        usart_baudrate_set(USART0, 115200U);//设置串口0的波特率为115200
        usart_word_length_set(USART0, USART_WL_8BIT);      	// 帧数据字长
    		usart_stop_bit_set(USART0, USART_STB_1BIT);      	 	// 停止位1位
        usart_parity_config(USART0, USART_PM_NONE);       	// 无奇偶校验位
        usart_receive_config(USART0, USART_RECEIVE_ENABLE);//使能接收器
        usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//使能发送器
        usart_enable(USART0);//使能USART
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    串口重定向

    /* retarget the C library printf function to the USART */
    int fputc(int ch, FILE *f)
    {
        usart_data_transmit(USART0, (uint8_t)ch);
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
        return ch;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    串口重定向后就可以使用printf进行打印。

    ADC通道设置

    在这里插入图片描述
    在这里插入图片描述

    ADC0初始化

    
    ///*************时钟配置******************/
    
        /*使能GPIOA时钟 */
        rcu_periph_clock_enable(RCU_GPIOA);
        /*使能ADC时钟 */
        rcu_periph_clock_enable(RCU_ADC0);
        /* 配置ADC速率 */
        rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ADC0配置

    /*------------------ADC GPIO配置------------------*/
    // 必须为模拟输入
        gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2);
    
    /*------------------ADC工作模式配置------------------*/
    		// 设置adc工作在独立模式
    		adc_mode_config(ADC_MODE_FREE);
    		// 多通道用扫描模式
    		//    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    		// 单通道用连续转换模式
    //		adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); 
    
    
    		// 结果转换右对齐
    		adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    		// 转换通道1个
    		adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 3);
    
        /* ADC regular channel config */
        adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
        adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
        adc_regular_channel_config(ADC0, 2, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
    
    
    		// 不用外部触发转换,软件开启即可
    		adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
    		adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
        
    		// 使能ADC
    		adc_enable(ADC0);
    		delay_1ms(1);                                                   // 等待1ms
    		// 使能ADC校准
    		adc_calibration_enable(ADC0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ADC1初始化

    /*************时钟配置******************/
    
        /*使能GPIOA时钟 */
        rcu_periph_clock_enable(RCU_GPIOB);
        /*使能ADC时钟 */
        rcu_periph_clock_enable(RCU_ADC1);
        /* 配置ADC速率 */
        rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ADC1配置

    /*------------------ADC GPIO配置------------------*/
    // 必须为模拟输入
        gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_7);
        gpio_init(GPIOB, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0 | GPIO_PIN_1);
    /*------------------ADC工作模式配置------------------*/
    		// 设置adc工作在独立模式
    		adc_mode_config(ADC_MODE_FREE);
    		// 多通道用扫描模式
    		//    adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    		// 单通道用连续转换模式
    //		adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE); 
    
    
    		// 结果转换右对齐
    		adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
    		// 转换通道1个
    		adc_channel_length_config(ADC1, ADC_REGULAR_CHANNEL, 3);
    
        /* ADC regular channel config */
        adc_regular_channel_config(ADC1, 0, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
        adc_regular_channel_config(ADC1, 1, ADC_CHANNEL_8, ADC_SAMPLETIME_55POINT5);
        adc_regular_channel_config(ADC1, 2, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
    
    
    		// 不用外部触发转换,软件开启即可
    		adc_external_trigger_source_config(ADC1, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
    		adc_external_trigger_config(ADC1, ADC_REGULAR_CHANNEL, ENABLE);
        
    		// 使能ADC
    		adc_enable(ADC1);
    		delay_1ms(1);                                                   // 等待1ms
    		// 使能ADC校准
    		adc_calibration_enable(ADC1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ADC数据采集

    uint16_t  get_adc(uint32_t adc_periph , uint8_t adc_channel)
    {
    /* 配置规则通道采集*/
        adc_regular_channel_config(adc_periph, 0, adc_channel, ADC_SAMPLETIME_55POINT5);
    		// 由于没有采用外部触发,所以使用软件触发ADC转换
    		adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL);   
    				
    		while(!adc_flag_get(adc_periph, ADC_FLAG_EOC));                       // 等待采样完成
    		adc_flag_clear(adc_periph, ADC_FLAG_EOC);                             // 清除结束标志
    				
    		return  adc_regular_data_read(adc_periph);                         // 读取ADC数据
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    数据采集

        while (1){
            
    		uint16_t adc0Value0 = 0;
    		uint16_t adc0Value1 = 0;
    		uint16_t adc0Value2 = 0;
    	
    		adc0Value0=get_adc(ADC0 ,ADC_CHANNEL_0);
    		adc0Value1=get_adc(ADC0 ,ADC_CHANNEL_1);
    		adc0Value2=get_adc(ADC0 ,ADC_CHANNEL_2);
    
    
    	printf("\nadc0_IN0(PA0)=%4.0d,电压=%1.4f",adc0Value0,adc0Value0*3.3f/4095);
    	printf("\nadc0_IN1(PA1)=%4.0d,电压=%1.4f",adc0Value1,adc0Value1*3.3f/4095);
    	printf("\nadc0_IN2(PA2)=%4.0d,电压=%1.4f",adc0Value2,adc0Value2*3.3f/4095);
    			
    		uint16_t adc1Value0 = 0;
    		uint16_t adc1Value1 = 0;
    		uint16_t adc1Value2 = 0;
    		
    		adc1Value0=get_adc(ADC1 ,ADC_CHANNEL_7);
    		adc1Value1=get_adc(ADC1 ,ADC_CHANNEL_8);
    		adc1Value2=get_adc(ADC1 ,ADC_CHANNEL_9);
    
    	printf("\nadc1_IN7(PA7)=%4.0d,电压=%1.4f",adc1Value0,adc1Value0*3.3f/4095);
    	printf("\nadc1_IN8(PB0)=%4.0d,电压=%1.4f",adc1Value1,adc1Value1*3.3f/4095);
    	printf("\nadc1_IN9(PB1)=%4.0d,电压=%1.4f",adc1Value2,adc1Value2*3.3f/4095);
    	delay_1ms(1000);					
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    测试结果

    输入固定电压进行测试。

    在这里插入图片描述
    测试结果如下。

    在这里插入图片描述

    最后

    以上的代码会在Q群里分享。QQ群:615061293。
    或者关注微信公众号『记帖』,持续更新文章和学习资料,可加作者的微信交流学习!
    在这里插入图片描述

  • 相关阅读:
    一文带你深入浅出C语言文件操作
    电子器件系列44:环形线圈电感
    12306购票辅助工具
    睡岗离岗识别检测系统
    Set、Map、WeakSet 和 WeakMap 的区别?
    vue内容自适应方法
    Sklearn机器学习中的主要算法原理以及实现
    Nginx配置文件及Nginx服务优化
    C++之委托构造函数实例(二百四十三)
    html写一个table表
  • 原文地址:https://blog.csdn.net/qq_24312945/article/details/125990354