这个dma是用在adc连续扫描中的,想在中断中处理一些数据,结果中断一直生不成。经测试,dma循环传输和adc连续扫描没有问题,问题就是产生不了中断,望各位大神帮忙解决以下,多谢了!!
下面是程序
dma配置:
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
}else
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
}
DMA_DeInit(DMA_Streamx);
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = chx; //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到存储器模式
DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//存储器FEI增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;//存储器数据长度:16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
DMA_FlowControllerConfig(DMA_Streamx,DMA_FlowCtrl_Memory);
NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TCIF0,ENABLE);//使能中断
}
//开启一次DMA传输
//DMA_Streamx MA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr)
{
DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输
while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){} //确保DMA可以被设置
DMA_SetCurrDataCounter(DMA_Streamx,ndtr); //数据传输量
DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输
}
void DMA2_Stream0_IRQHandler(void)
{
if(DMA_GetITStatus(DMA2_Stream0,DMA_FLAG_TCIF0))
{
LED1=0;
}
DMA_ClearITPendingBit(DMA2_Stream0,DMA_FLAG_TCIF0);
}
adc配置:
#include "adc.h"
#include "delay.h"
//初始化ADC
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //使能ADC1时钟
//先初始化ADC1通道5 IO口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//|GPIO_Pin_1;//PA5 通道5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//|GPIO_Pin_1;//PA5 通道5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE); //ADC1复位
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE); //复位结束
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;//预分频8分频。ADCCLK=PCLK2/4=84/8=10.5Mhz,ADC时钟最好不要超过36Mhz
ADC_CommonInit(&ADC_CommonInitStructure);//初始化
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE;//FEI扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//上升沿触发检测
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1
ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
//设置指定ADC的规则组通道,一个序列,采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_480Cycles ); //ADC1,ADC通道,480个周期,提高采样时间可以提高精确度
ADC_DMACmd(ADC1,ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
ADC_Cmd(ADC1, ENABLE);//开启AD转换器
}
main.c:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "adc.h"
#include "dma.h"
#include "dacdma.h"
#include "time1.h"
//#include "time2.h"
#include "dac.h"
//ALIENTEK 探索者STM32F407开发板 实验18
//ADC模数转换实验-库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司
//作者:正点原子 @ALIENTEK
const uint16_t Buffer1[256]={0,50,100,151,201,251,301,351,401,451,501,551,601,651,700,750,
799,848,897,946,995,1044,1092,1141,1189,1237,1285,1332,1380,1427,1474,
1521,1567,1613,1660,1705,1751,1796,1841,1886,1930,1975,2019,2062,2105,
2148,2191,2233,2275,2317,2358,2399,2439,2480,2519,2559,2598,2637,2675,
2713,2750,2787,2824,2860,2896,2931,2966,3000,3034,3068,3101,3133,3166,
3197,3228,3259,3289,3319,3348,3377,3405,3433,3460,3486,3512,3538,3563,
3588,3612,3635,3658,3680,3702,3723,3744,3764,3783,3802,3821,3838,3856,
3872,3888,3904,3919,3933,3947,3960,3972,3984,3996,4006,4016,4026,4035,
4043,4051,4058,4064,4070,4075,4080,4084,4087,4090,4092,4094,4095,4095,
4095,4094,4092,4090,4087,4084,4080,4075,4070,4064,4058,4051,4043,4035,
4026,4016,4006,3996,3984,3972,3960,3947,3933,3919,3904,3888,3872,3856,
3838,3821,3802,3783,3764,3744,3723,3702,3680,3658,3635,3612,3588,3563,
3538,3512,3486,3460,3433,3405,3377,3348,3319,3289,3259,3228,3197,3166,
3133,3101,3068,3034,3000,2966,2931,2896,2860,2824,2787,2750,2713,2675,
2637,2598,2559,2519,2480,2439,2399,2358,2317,2275,2233,2191,2148,2105,
2062,2019,1975,1930,1886,1841,1796,1751,1705,1660,1613,1567,1521,1474,
1427,1380,1332,1285,1237,1189,1141,1092,1044,995,946,897,848,799,750,
700,651,601,551,501,451,401,351,301,251,201,151,100,50};
uint16_t Buffer2[1];
int main(void)
{
u16 dacval=0;
u16 adcx1;
float temp1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //初始化LCD接口
DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0
MYDACDMA_Config(DMA1_Stream5,DMA_Channel_7,(u32)&DAC->DHR12R1,(u32)Buffer1,256);
MYDACDMA_Enable(DMA1_Stream5,256);
Dac1_Init(); //DAC通道1初始化
TIM6_Int_Init(200-1,80-1);
MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)Buffer2,1);
Adc_Init(); //初始化ADC
MYDMA_Enable(DMA2_Stream0,1);
ADC_SoftwareStartConv(ADC1);
while(1)
{
if(Buffer2[0]>3061) PAout(6)=1;
if(Buffer2[0]<1861) PAout(6)=0;
}
}
adc采的是dac输出的正弦半波。A4输出,A0采入,主函数循环里面本来想在中断中完成,后来测试对主函数循环和中断服务函数内容做了修改。
望各位大神多多指教!!
|