```c
#include "hpm6360.h"
#define ADC_SEQ_LEN 3 // 采集通道数
#define ADC_DMA_LEN 1 // DMA缓存组数
#define TIMER_FREQ 1000 // 定时器频率,1ms中断一次
uint16_t adc_values[ADC_SEQ_LEN * ADC_DMA_LEN];
volatile uint8_t dma_complete = 0;
void adc_dma_callback(uint32_t dma_event, void *context)
{
dma_complete = 1;
}
void adc_init(void)
{
// 使能 ADC 和 DMA 时钟
hpm_adc_clock_enable(HPM_ADC0_CLOCK);
hpm_dma_clock_enable(HPMDMA_CLOCK);
// 配置 ADC 时钟,使用 HSI16 时钟,分频系数为 2
hpm_adc_set_clock(HPM_ADC0_CLOCK, HPM_ADC_CLOCK_SRC_HSI16, 2);
// 配置 PC05, PC07, PC08 为模拟输入
hpm_gpio_configure_pin(HPM_GPIO_PC05, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
hpm_gpio_configure_pin(HPM_GPIO_PC07, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
hpm_gpio_configure_pin(HPM_GPIO_PC08, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
// 配置 ADC 采样时间,选择 ADC 时钟为采样时钟
hpm_adc_set_sample_time(HPM_ADC0, HPM_ADC_SAMPLE_TIME_239CYC, HPM_ADC_CLOCK_SRC_ADCCLK);
// 配置 ADC 触发源为软件触发
hpm_adc_set_trigger(HPM_ADC0, HPM_ADC_TRIGGER_SOFTWARE);
// 配置 ADC 为正常模式,转换序列长度为 3,DMA 使能
hpm_adc_set_mode(HPM_ADC0, HPM_ADC_MODE_NORMAL);
hpm_adc_set_sequence_length(HPM_ADC0, ADC_SEQ_LEN);
hpm_adc_dma_enable(HPM_ADC0);
// 配置 DMA
hpm_dma_configure_channel(HPMDMA_CHANNEL1, HPM_DMA_PERIPH_TO_MEM);
hpm_dma_set_data_width(HPMDMA_CHANNEL1, HPM_DMA_DATA_WIDTH_HALFWORD);
hpm_dma_set_peripheral_increment(HPMDMA_CHANNEL1, HPM_DMA_PERIPH_INCREMENT_DISABLE);
hpm_dma_set_memory_increment(HPMDMA_CHANNEL1, HPM_DMA_MEMORY_INCREMENT_ENABLE);
hpm_dma_set_peripheral_address(HPMDMA_CHANNEL1, (uint32_t)&(HPM_ADC0->DR));
hpm_dma_set_memory_address(HPMDMA_CHANNEL1, (uint32_t)adc_values);
hpm_dma_set_transfer_length(HPMDMA_CHANNEL1, ADC_SEQ_LEN * ADC_DMA_LEN);
hpm_dma_set_callback(HPMDMA_CHANNEL1, adc_dma_callback, NULL);
// 配置定时器,中断频率为 1KHz
hpm_timer_clock_enable(HPM_TIMER6_CLOCK);
hpm_timer_set_prescaler(HPM_TIMER6, 16000 - 1);
hpm_timer_set_autoreload(HPM_TIMER6, 1 - 1);
hpm_timer_enable_irq(HPM_TIMER6, HPM_TIMER_IRQ_UPDATE);
// 启动 DMA
hpm_dma_start_channel(HPMDMA_CHANNEL1);
}
void adc_start_conversion(void)
{
// 手动触发 ADC 转换
hpm_adc_start_conversion(HPM_ADC0);
// 等待转换完成
while (!dma_complete);
// 清空 DMA 完成标志位
dma_complete = 0;
}
void timer6_irq_handler(void)
{
// 定时器中断处理函数, 每隔1ms触发一次ADC采集
adc_start_conversion();
// 清除定时器中断标志位
hpm_timer_clear_irq(HPM_TIMER6, HPM_TIMER_IRQ_UPDATE);
}
int main(void)
{
adc_init();
while (1);
return 0;
}
```
```c
#include "hpm6360.h"
#define ADC_SEQ_LEN 3 // 采集通道数
#define ADC_DMA_LEN 1 // DMA缓存组数
#define TIMER_FREQ 1000 // 定时器频率,1ms中断一次
uint16_t adc_values[ADC_SEQ_LEN * ADC_DMA_LEN];
volatile uint8_t dma_complete = 0;
void adc_dma_callback(uint32_t dma_event, void *context)
{
dma_complete = 1;
}
void adc_init(void)
{
// 使能 ADC 和 DMA 时钟
hpm_adc_clock_enable(HPM_ADC0_CLOCK);
hpm_dma_clock_enable(HPMDMA_CLOCK);
// 配置 ADC 时钟,使用 HSI16 时钟,分频系数为 2
hpm_adc_set_clock(HPM_ADC0_CLOCK, HPM_ADC_CLOCK_SRC_HSI16, 2);
// 配置 PC05, PC07, PC08 为模拟输入
hpm_gpio_configure_pin(HPM_GPIO_PC05, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
hpm_gpio_configure_pin(HPM_GPIO_PC07, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
hpm_gpio_configure_pin(HPM_GPIO_PC08, HPM_GPIO_MODE_ANALOG, HPM_GPIO_NOPULL);
// 配置 ADC 采样时间,选择 ADC 时钟为采样时钟
hpm_adc_set_sample_time(HPM_ADC0, HPM_ADC_SAMPLE_TIME_239CYC, HPM_ADC_CLOCK_SRC_ADCCLK);
// 配置 ADC 触发源为软件触发
hpm_adc_set_trigger(HPM_ADC0, HPM_ADC_TRIGGER_SOFTWARE);
// 配置 ADC 为正常模式,转换序列长度为 3,DMA 使能
hpm_adc_set_mode(HPM_ADC0, HPM_ADC_MODE_NORMAL);
hpm_adc_set_sequence_length(HPM_ADC0, ADC_SEQ_LEN);
hpm_adc_dma_enable(HPM_ADC0);
// 配置 DMA
hpm_dma_configure_channel(HPMDMA_CHANNEL1, HPM_DMA_PERIPH_TO_MEM);
hpm_dma_set_data_width(HPMDMA_CHANNEL1, HPM_DMA_DATA_WIDTH_HALFWORD);
hpm_dma_set_peripheral_increment(HPMDMA_CHANNEL1, HPM_DMA_PERIPH_INCREMENT_DISABLE);
hpm_dma_set_memory_increment(HPMDMA_CHANNEL1, HPM_DMA_MEMORY_INCREMENT_ENABLE);
hpm_dma_set_peripheral_address(HPMDMA_CHANNEL1, (uint32_t)&(HPM_ADC0->DR));
hpm_dma_set_memory_address(HPMDMA_CHANNEL1, (uint32_t)adc_values);
hpm_dma_set_transfer_length(HPMDMA_CHANNEL1, ADC_SEQ_LEN * ADC_DMA_LEN);
hpm_dma_set_callback(HPMDMA_CHANNEL1, adc_dma_callback, NULL);
// 配置定时器,中断频率为 1KHz
hpm_timer_clock_enable(HPM_TIMER6_CLOCK);
hpm_timer_set_prescaler(HPM_TIMER6, 16000 - 1);
hpm_timer_set_autoreload(HPM_TIMER6, 1 - 1);
hpm_timer_enable_irq(HPM_TIMER6, HPM_TIMER_IRQ_UPDATE);
// 启动 DMA
hpm_dma_start_channel(HPMDMA_CHANNEL1);
}
void adc_start_conversion(void)
{
// 手动触发 ADC 转换
hpm_adc_start_conversion(HPM_ADC0);
// 等待转换完成
while (!dma_complete);
// 清空 DMA 完成标志位
dma_complete = 0;
}
void timer6_irq_handler(void)
{
// 定时器中断处理函数, 每隔1ms触发一次ADC采集
adc_start_conversion();
// 清除定时器中断标志位
hpm_timer_clear_irq(HPM_TIMER6, HPM_TIMER_IRQ_UPDATE);
}
int main(void)
{
adc_init();
while (1);
return 0;
}
```
举报