打印

GD32F303 ADC DMA 中断

[复制链接]
2115|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
EDAStarer|  楼主 | 2020-7-9 17:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
想用一个定时器输出PWM。然后用这个PWM的上升沿触发ADC。ADC采用DMA的方式。
ADC产生DMA中断后,去USART发送DMA发过来的数据。
现在看起来没有进入中断函数去执行。
器件:GD32F303CC 48pin
timer0产生PWM作为ADC0的源。使用TIMER0_CH0输出PWM作为ADC0的触发源。
ADC0的DMA配置为DMA0_CH0。
有定义中断函数DMA0_Channel0_IRQHandler();
有配置ADC以及DMA。
有定义
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable(ADC0_1_IRQn, 0, 0);
看起来DMA发送完成后没有进入中断函数。

使用特权

评论回复
沙发
sonicll| | 2020-7-10 09:19 | 只看该作者
DMA的传输完成中断使能了吗,NVIC配置DMA的中断了吗,你的用法是不需要配ADC中断的,只需要配DMA通道的中断

使用特权

评论回复
板凳
EDAStarer|  楼主 | 2020-7-10 15:41 | 只看该作者
sonicll 发表于 2020-7-10 09:19
DMA的传输完成中断使能了吗,NVIC配置DMA的中断了吗,你的用法是不需要配ADC中断的,只需要配DMA通道的中断 ...

多谢。是不需要ADC中断。

使用特权

评论回复
地板
EDAStarer|  楼主 | 2020-7-10 17:56 | 只看该作者
sonicll 发表于 2020-7-10 09:19
DMA的传输完成中断使能了吗,NVIC配置DMA的中断了吗,你的用法是不需要配ADC中断的,只需要配DMA通道的中断 ...

器件:GD32F303CC 48pin
用Timer0_CH0输出PWM,触发ADC0。ADC0转换的数据用DMA传输。
在中断处理函数中让一个变量自加。debug,发现这个变量的值没有变化。应该没有进入中断函数去执行。请帮忙看看哪里有问题。

rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_DMA0);
rcu_periph_clock_enable(RCU_ADC0);
rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);
rcu_periph_clock_enable(RCU_TIMER0);
gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_2);
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_irq_enable(DMA0_Channel0_IRQn, 0, 0);

dma_parameter_struct dma_data_parameter;
dma_deinit(DMA0, DMA_CH0);//
// initialize DMA single data mode //
dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
dma_data_parameter.memory_addr  = (uint32_t)(&adc_buf);
dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_8BIT;  
dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
dma_data_parameter.number       = 1024;
dma_data_parameter.priority     = DMA_PRIORITY_HIGH;
dma_init(DMA0, DMA_CH0, &dma_data_parameter);
dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);//channel full transfer finish interrupt
dma_channel_enable(DMA0, DMA_CH0);
//ADC0 单次,非扫描,独立
adc_special_function_config(ADC0, ADC_SCAN_MODE, DISABLE);
adc_discontinuous_mode_config(ADC0, ADC_CHANNEL_DISCON_DISABLE, 1);
adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_2, ADC_SAMPLETIME_1POINT5);
adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);       
// ADC trigger source - Timer0_CH0
adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T0_CH0);
adc_data_alignment_config(ADC0,ADC_DATAALIGN_RIGHT);
adc_mode_config(ADC_MODE_FREE);  
adc_channel_length_config(ADC0,ADC_REGULAR_CHANNEL,1);
adc_resolution_config(ADC0, ADC_RESOLUTION_8B);
adc_enable(ADC0);
delay_1ms(1);   
adc_calibration_enable(ADC0);
adc_dma_mode_enable(ADC0);

void DMA0_Channel0_IRQHandler(void)
{
var++;
}

使用特权

评论回复
5
EDAStarer|  楼主 | 2020-7-10 18:19 | 只看该作者
sonicll 发表于 2020-7-10 09:19
DMA的传输完成中断使能了吗,NVIC配置DMA的中断了吗,你的用法是不需要配ADC中断的,只需要配DMA通道的中断 ...

已解决,多谢了

使用特权

评论回复
6
EDAStarer|  楼主 | 2020-7-14 08:28 | 只看该作者
sonicll 发表于 2020-7-10 09:19
DMA的传输完成中断使能了吗,NVIC配置DMA的中断了吗,你的用法是不需要配ADC中断的,只需要配DMA通道的中断 ...

我现在在主程序的while(1)循环中增加了UART发送,就是把ADC采集的数据发送到UART。
碰到的情况是始终无法执行主程序中的while(1)里面的内容。
感觉就是DMA中断优先级很高,而且ADC的触发频率很高,导致一直在中断处理函数中执行。
我有在中断函数中设置标志,在主程序中根据此标志来发送到UART。
怎样才能让主函数中的UART执行?
多谢了

使用特权

评论回复
7
sonicll| | 2020-7-14 09:14 | 只看该作者
EDAStarer 发表于 2020-7-14 08:28
我现在在主程序的while(1)循环中增加了UART发送,就是把ADC采集的数据发送到UART。
碰到的情况是始终无 ...

你是需要把每一次的采样数据都发送出来,不能漏掉数据吗?如果你是1M采样速率,想用串口发出来,那串口波特率至少要到10M以上,以F303的主频,这不现实,只能降低采样速率,或者改用其他通信接口输出,比如速率更高的SPI,或者并行接口。
如果不需要每次采样都输出,可以漏数据,那不要开DMA的中断就行了

使用特权

评论回复
8
EDAStarer|  楼主 | 2020-7-14 11:07 | 只看该作者
sonicll 发表于 2020-7-14 09:14
你是需要把每一次的采样数据都发送出来,不能漏掉数据吗?如果你是1M采样速率,想用串口发出来,那串口波 ...

多谢了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

52

帖子

0

粉丝