gd32f303 ADC注入
时间: 2023-07-18 10:52:23 浏览: 37
gd32f303是一款基于ARM Cortex-M4内核的微控制器,其ADC模块支持多通道的ADC注入模式。使用ADC注入模式可以在不干扰常规转换的情况下进行一些特殊的测量,比如频率、周期等。以下是基本的ADC注入模式配置步骤:
1. 配置ADC时钟和时钟分频系数
2. 配置ADC外设并使能ADC时钟
3. 配置ADC通道和采样时间
4. 配置ADC注入序列
5. 配置注入触发源
6. 使能ADC注入模式
7. 启动一次注入转换
需要注意的是,在注入转换完成后需要手动清除转换标志位,并且在下一次注入转换之前必须等待转换完成。具体配置方法可以参考GD32F30x固件库中的ADC_InjectedChannelConfig函数。
相关问题
GD32F303 ADC代码
以下是使用GD32F303芯片的ADC代码示例:
```c
#include "gd32f30x.h"
void ADC_Configuration(void)
{
/* 使能 ADC0 时钟 */
rcu_periph_clock_enable(RCU_ADC0);
/* 配置 ADC0 工作模式为单次转换模式 */
adc_mode_config(ADC_MODE_FREE);
/* 配置 ADC0 外部触发源为软件触发 */
adc_external_trigger_source_config(ADC_INSERTED_CHANNEL, ADC_EXTTRIG_INSERTED_NONE);
/* 配置 ADC0 触发通道为 ADC_CHANNEL_0 */
adc_channel_length_config(ADC_INSERTED_CHANNEL, 1);
adc_inserted_channel_config(0, ADC_CHANNEL_0, ADC_SAMPLETIME_239POINT5);
/* 配置 ADC0 转换个数为1 */
adc_special_function_config(ADC_INSERTED_CHANNEL, ADC_SCAN_MODE, DISABLE);
adc_special_function_config(ADC_INSERTED_CHANNEL, ADC_CONTINUOUS_MODE, DISABLE);
adc_special_function_config(ADC_INSERTED_CHANNEL, ADC_INSERTED_SCAN, DISABLE);
/* 使能 ADC0 */
adc_enable(ADC_INSERTED_CHANNEL);
/* ADC0 开始转换 */
adc_calibration_enable(ADC_INSERTED_CHANNEL);
}
int main(void)
{
/* ADC 配置 */
ADC_Configuration();
while (1) {
/* ADC0 开始转换 */
adc_software_trigger_enable(ADC_INSERTED_CHANNEL);
/* 等待 ADC0 转换完成 */
while (RESET == adc_flag_get(ADC_INSERTED_CHANNEL, ADC_FLAG_EOC));
/* 读取 ADC0 转换结果 */
uint16_t adc_value = adc_injected_data_read(ADC_INSERTED_CHANNEL, 0);
/* 处理 ADC0 转换结果 */
// TODO
}
}
```
此代码使用单次转换模式进行 ADC0 转换,触发通道为 ADC_CHANNEL_0,转换结果存储在插入通道的第一个转换结果中。ADC0 的转换结果可以通过调用 `adc_injected_data_read` 函数来读取。
GD32F303 ADC例程
以下是基于GD32F303芯片的ADC例程,你可以参考:
```c
#include "gd32f30x.h"
#include <stdio.h>
#define ADC_GPIO_PORT GPIOA
#define ADC_GPIO_PIN GPIO_PIN_0
#define ADC_GPIO_CLK RCU_GPIOA
#define ADC_DMA_CHANNEL DMA_CH0
#define ADC_DMA_CLK RCU_DMA0
#define ADC_DMA_IRQ DMA0_Channel0_IRQn
#define ADC_DMA_IRQHANDLER DMA0_Channel0_IRQHandler
uint16_t adc_value[16];
void adc_gpio_config(void);
void adc_config(void);
void dma_config(void);
int main(void)
{
// 使能GPIOA时钟
rcu_periph_clock_enable(ADC_GPIO_CLK);
// 配置GPIOA.0为模拟输入
adc_gpio_config();
// 配置ADC
adc_config();
// 配置DMA
dma_config();
// 启动DMA传输
dma_channel_enable(DMA0, ADC_DMA_CHANNEL);
while (1)
{
// 等待DMA传输完成
while(!dma_flag_get(DMA0, ADC_DMA_CHANNEL, DMA_FLAG_FTF));
// 输出ADC值
for(int i = 0; i < 16; i++)
{
printf("ADC%d value: %d\n", i, adc_value[i]);
}
// 清除DMA传输完成标志位
dma_flag_clear(DMA0, ADC_DMA_CHANNEL, DMA_FLAG_FTF);
}
}
void adc_gpio_config(void)
{
gpio_init(ADC_GPIO_PORT, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, ADC_GPIO_PIN);
}
void adc_config(void)
{
// 使能ADC时钟
rcu_periph_clock_enable(RCU_ADC0);
// ADC时钟分频
adc_clock_config(ADC_ADCCK_PCLK2_DIV8);
// ADC模式配置
adc_mode_config(ADC_MODE_FREE);
// ADC通道配置
adc_channel_length_config(ADC_REGULAR_CHANNEL, 16);
adc_regular_channel_config(0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(2, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(3, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(4, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(5, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(6, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(7, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(8, ADC_CHANNEL_8, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(9, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(10, ADC_CHANNEL_10, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(11, ADC_CHANNEL_11, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(12, ADC_CHANNEL_12, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(13, ADC_CHANNEL_13, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(14, ADC_CHANNEL_14, ADC_SAMPLETIME_55POINT5);
adc_regular_channel_config(15, ADC_CHANNEL_15, ADC_SAMPLETIME_55POINT5);
// ADC DMA配置
adc_dma_mode_enable();
adc_dma_request_after_last_enable();
// ADC使能
adc_enable();
delay_1ms(1);
adc_calibration_enable();
delay_1ms(1);
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
}
void dma_config(void)
{
// 使能DMA时钟
rcu_periph_clock_enable(ADC_DMA_CLK);
// DMA通道配置
dma_deinit(DMA0, ADC_DMA_CHANNEL);
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_addr = (uint32_t)adc_value;
dma_init_struct.memory_inc = DMA_MEMORY_INC_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_init_struct.number = 16;
dma_init_struct.periph_addr = (uint32_t)&ADC_RDATA(ADC0);
dma_init_struct.periph_inc = DMA_PERIPH_INC_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(DMA0, ADC_DMA_CHANNEL, &dma_init_struct);
// DMA中断配置
nvic_irq_enable(ADC_DMA_IRQ, 0, 0);
dma_interrupt_enable(DMA0, ADC_DMA_CHANNEL, DMA_INT_FTF);
}
void ADC_DMA_IRQHANDLER(void)
{
dma_interrupt_flag_clear(DMA0, ADC_DMA_CHANNEL, DMA_INT_FTF);
}
```
需要注意的是,这个例程使用了DMA传输来获取ADC采样值,因此在使用之前需要先配置DMA。同时,在输出ADC值之前需要等待DMA传输完成。