使用中断方式的好处就是在其它地方不会调用到DMA传输BUF。如果不小心调用或修改,可能会死机。具体原因没有深究。
注意中断函数是否和.s文件里面一致,否则也会死机。
根据需求去修改中断函数内容。
dma_adc.h
#ifndef _DMA_ADC_ #define _DMA_ADC_ #include "sys.h" #define ADC1_DR_Address ((u32)0x40012400+0X4C) extern u16 ADC_buf[10]; //DMA传输BUF extern u32 ADC_BUF[10]; //滤波后保存BUF extern u8 ADC_BUF_flag; //滤波后完成标志 void ADC1_DMA_init(void); #endif
dma_adc.c
#include "dma_adc.h" #include "serial.h" #include "nrf_info.h" u16 ADC_buf[10]; u32 ADC_BUF[10]; u8 ADC_BUF_flag=0; void ADC1_DMA_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //通道引脚 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //通道引脚 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_Init(GPIOB,&GPIO_InitStructure); DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; DMA_DeInit(DMA1_Channel1); NVIC_InitTypeDef NVIC_InitStructure; /* Configure one bit for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* 配置DMA中断源*/ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address; //ADC数据寄存器地址 DMA_InitStructure.DMA_MemoryBaseAddr=(u32)ADC_buf; //将ADC1_DR_Address数据转移到ADC_buf DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //数据传输方向,外设作为数据源 DMA_InitStructure.DMA_BufferSize=9; //传输个数据 DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址固定 DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord; //表示每个传输的的数据大小 DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode=DMA_Mode_Circular; //循环传输 DMA_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道优先级 DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //禁止内存到内存传输 DMA_Init(DMA1_Channel1,&DMA_InitStructure); DMA_Cmd(DMA1_Channel1,ENABLE); //使能 DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //配置DMA发送完成后产生中断 ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式 ADC_InitStructure.ADC_ScanConvMode=ENABLE; //扫描模式,用于多通道采集 ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; //开启连续转换 ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//b不使用外部触发转换 ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//采集数据右对齐 ADC_InitStructure.ADC_NbrOfChannel=9; //要转换的个数 ADC_Init(ADC1,&ADC_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6); //6分频,12HZ //扫描顺序,55.5每个周期 ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_4,5,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_5,6,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_6,7,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_7,8,ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1,ADC_Channel_8,9,ADC_SampleTime_55Cycles5); ADC_DMACmd(ADC1,ENABLE); //向DMA发出请求 ADC_Cmd(ADC1,ENABLE); ADC_ResetCalibration(ADC1); //复位矫正寄存器 while(ADC_GetResetCalibrationStatus(ADC1)); //等待矫正完成 ADC_StartCalibration(ADC1); //ADC矫正 while(ADC_GetCalibrationStatus(ADC1)); //等待矫正完毕 ADC_SoftwareStartConvCmd(ADC1,ENABLE); //软件触发ADC转换 } static u8 count=0; extern "C" void DMA1_Channel1_IRQHandler(void) //DMA中断传输,并且处理数据。 { if(ADC_BUF_flag==0) { if(count==0) { //AD清零 for(int i=0;i<9;i++) { ADC_BUF[i]=0; } } for(int j=0;j<9;j++) { ADC_BUF[j]+=ADC_buf[j]; } count++; if(count==30) { //取平均滤波 for(int i=0;i<9;i++) { ADC_BUF[i]/=count; } //---------------------------------------拿到滤波值后------------ nrf_info.ch1=((ADC_BUF[0]*256)/4096); nrf_info.ch2=((ADC_BUF[1]*256)/4096); nrf_info.ch3=((ADC_BUF[2]*256)/4096); nrf_info.ch4=((ADC_BUF[3]*256)/4096); nrf_info.ch5=((ADC_BUF[4]*256)/4096); nrf_info.ch6=((ADC_BUF[5]*256)/4096); nrf_info.ch7=((ADC_BUF[6]*256)/4096); nrf_info.ch8=((ADC_BUF[7]*256)/4096); //---------------------------------------发送数据----------------- if(nrf_info.send_mes()) { //printf("send OK\r\n"); PCout(13)=~ PCout(13); } else { PCout(13)=1; //printf("send ERROR\r\n"); } count=0; ADC_BUF_flag=1; } } // printf("我进中断了\r\n"); DMA_ClearITPendingBit(DMA1_IT_TC1); }