GD32F310 ADC开发

工作模式

1、初始化单路ADC,开启转化,轮训等待转换完成,输出转化完成寄存器值。

问题

1、ADC中断无法正常启用
在ADC配置函数中加入中断配置语句开启ADC中断,无法找到相应的中断处理函数。
与ADC相关的中断处理函数只有ADC_CMP_IRQHandler()
定义此中断函数后,开启ADC转换确实可以触发此中断服务函数,但是中断标志无法清除,会不断触发中断。
请求大神帮忙解答!!!!!
2、多个ADC都要读取如何配置,配置完成如何读取数据
请求大神帮忙解答!!!!!
中断配置:

	使能ADC中断
//	adc_interrupt_enable(ADC_INT_EOC);
	配置ADC中断优先级
//	nvic_irq_enable(ADC_CMP_IRQn, 0, 0);

中断处理函数:

void ADC_CMP_IRQHandler()
{
printf("ADC_CMP_IRQHandler\r\n");
 if(adc_interrupt_flag_get(ADC_INT_FLAG_EOC))
 {
 // 清除ADC规则组转换结束中断标志
   adc_interrupt_flag_clear(ADC_INT_FLAG_EOC);  
 }
}

头文件 adc.h

#ifndef __ADC_H__
#define __ADC_H__
void get_adc_val_PA0();
void get_adc_val_PA1();
#endif 

源文件 adc.c

#include "gd32f3x0.h"
#include "systick.h"
#include <stdio.h>
#include "jlink_log.h"

//ADC配置结构体
typedef struct
{
//	ADC通道
  uint8_t adc_channel;
//	ADC引脚PORT
  uint32_t gpio_periph;
//	ADC引脚PIN
  uint32_t pin;
//	ADC引脚时钟
  rcu_periph_enum gpio_clock;
} struct_adc_config;

//ID1
struct_adc_config adc_config_PA0 =
{
  .adc_channel = ADC_CHANNEL_0,
  .gpio_periph = GPIOA,
  .pin = GPIO_PIN_0,
  .gpio_clock = RCU_GPIOA,
};

//ID2
struct_adc_config adc_config_PA1 =
{
  .adc_channel = ADC_CHANNEL_1,
  .gpio_periph = GPIOA,
  .pin = GPIO_PIN_1,
  .gpio_clock = RCU_GPIOA,
};

/*!
    \brief      初始化ADC
    \param[in]  adc_config ADC配置结构体
    \param[out] none
    \retval     none
*/
static void init_adc(struct_adc_config adc_config)
{
  /* 启用GPIO时钟功能 */
  rcu_periph_clock_enable(adc_config.gpio_clock);
  /* 启用ADC时钟功能 */
  rcu_periph_clock_enable(RCU_ADC);
  /* 配置ADC时钟预分频 APB2=25M 6分频后ADC时钟约为4M*/
  rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);

  /* 设置GPIO模式 */
  gpio_mode_set(adc_config.gpio_periph, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, adc_config.pin);

  /* 配置 ADC 为连续模式(扫描模式只在 DMA 模式下使用) */
  adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
  /* 配置 ADC 的触发方式 此处设置为软件触发 */
  adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
  /* ADC 对齐设置为右对齐 */
  adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
  /* 配置通道数 */
  adc_channel_length_config(ADC_REGULAR_CHANNEL, 1U);

  /* 配置使用哪一个 ADC 通道 */
  adc_regular_channel_config(0U, adc_config.adc_channel, ADC_SAMPLETIME_55POINT5);
  // 开启 ADC 的常规通道组
  adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
  
	使能ADC中断
//	adc_interrupt_enable(ADC_INT_EOC);
	配置ADC中断优先级
//	nvic_irq_enable(ADC_CMP_IRQn, 0, 0);

  /* 使能ADC */
  adc_enable();
  delay_1ms(1U);
  /* 校准和复位校准 ADC*/
  adc_calibration_enable();
}
/*!
    \brief      获取ADC值
    \param[in]  *adc_val ADC值存储地址
    \param[out] 0--获取成功,其他值获取失败
    \retval     none
*/
static int get_adc_val(uint16_t *adc_val)
{
//	清除转换标志位
	adc_flag_clear(ADC_FLAG_STRC | ADC_FLAG_EOC);
	//软件触发 ADC 转换开始
  adc_software_trigger_enable(ADC_REGULAR_CHANNEL);

//	轮训等待转换完成
  for(int i = 0; i < 1000; i++)
  {
    if(SET == adc_flag_get(ADC_FLAG_STRC))
    {
      if(SET == adc_flag_get(ADC_FLAG_EOC))
      {
        *adc_val = adc_regular_data_read();
				adc_flag_clear(ADC_FLAG_STRC | ADC_FLAG_EOC);
				printf("i:%d\r\n", i);
				return 0;
      }
      else
      {
        continue;
      }
    }
		delay_1ms(1);
  }
	//获取ADC值超时返回失败
	printf("get ADC val overtimer\r\n");
	return -1;
}

/*!
    \brief      获取PA0 ADC值
    \param[in]  *adc_val ADC值存储地址
    \param[out] 0--获取成功,其他值获取失败
    \retval     none
*/
int get_adc_val_PA0(uint16_t *adc_val)
{
	printf("get_adc_val_PA0\r\n");
	init_adc(adc_config_PA0);
	return get_adc_val(adc_val);
}

/*!
    \brief      获取PA1 ADC值
    \param[in]  *adc_val ADC值存储地址
    \param[out] 0--获取成功,其他值获取失败
    \retval     none
*/
int get_adc_val_PA1(uint16_t *adc_val)
{
	printf("get_adc_val_PA1\r\n");
	init_adc(adc_config_PA1);
	return get_adc_val(adc_val);
}

main.c

#include "adc.h"
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
  /* system clocks configuration */
  rcu_config();
  /* systick configuration */
  systick_config();
  uint16_t adc_val;
  get_adc_val_PA0(&adc_val);
  printf("get_adc_val_PA0: 0%d\r\n", adc_value);
  get_adc_val_PA1(&adc_val);
  printf("get_adc_val_PA1: 0%d\r\n", adc_value);
  while(1) {}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值