vuint16_t SampleValueRaw[8];//ADC采样原始值
void dma_init() //DMA初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
//?DMA??,????,?????????
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority=1; //?????1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ????
NVIC_Init(&NVIC_InitStructure); //??????????NVIC???
/* Configure ADC Channel as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7; //ADC //7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure); //A
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //ADC //2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure); //b
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
ADC_DeInit(ADC1); //ADC恢复默认设置
ADC_StructInit(&ADC_InitStructure); //初始化ADC结构
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位精度
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//ENABLE; //规定模式装换工作在连续模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;//ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对其为右对齐
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; // ADC_ScanDirection_Backward; //ADC的扫描方向
ADC_Init(ADC1, &ADC_InitStructure);
ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_55_5Cycles); //CP
ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_55_5Cycles); //插头温度
ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_55_5Cycles); //输出电压
ADC_ChannelConfig(ADC1, ADC_Channel_4, ADC_SampleTime_55_5Cycles); //pe电压
ADC_ChannelConfig(ADC1, ADC_Channel_6, ADC_SampleTime_55_5Cycles); //1.5V
ADC_ChannelConfig(ADC1, ADC_Channel_7, ADC_SampleTime_55_5Cycles); //输出电流
ADC_ChannelConfig(ADC1, ADC_Channel_8, ADC_SampleTime_55_5Cycles); //输入电压
ADC_ChannelConfig(ADC1, ADC_Channel_9, ADC_SampleTime_55_5Cycles); //温度
ADC_GetCalibrationFactor(ADC1); /* ADC Calibration */
ADC_Cmd(ADC1, ENABLE); /* Enable ADCperipheral[PerIdx] */
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY))
; /* Wait the ADCEN falg */
//设置DMA要在校准ADC之后
DMA_DeInit(DMA1_Channel1); /* DMA1 Channel1 Config */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) 0x40012440; //ADC1->DR; //外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) SampleValueRaw; //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据传输的来源
DMA_InitStructure.DMA_BufferSize = CHANNEL_NUM; //
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器不变
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA_Priority设定DMA通道x的软件优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);/* DMA1 Channel1 enable */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); /* Enable ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);//DMA_IT_HT
DMA_ClearFlag(DMA1_FLAG_TC1);
ADC_StartOfConversion(ADC1); /* ADC1 regular Software Start Conv */
}
#define CP(A) TIM_SetCompare1(TIM1,48*A)//输出0-1000‰的pwm
void pwm_init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* GPIOA Configuration: PA6(TIM3 CH1) as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2);
/* Enable TIM1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 48000 - 1; //不分频,PWM 频率=72000/72000=1Khz//设置自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = 0;//设置用来作为TIMx时钟频率预分频值,100Khz计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//PWM初始化 //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
/* Channel1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//cnt<ccr1 为有效
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//PWM输出使能
TIM_OCInitStructure.TIM_Pulse = 1200;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
/* Enable TIM1 */
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* Enable GPIOA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* Enable TIM1 clock */
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* Enable TIM3 */
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
CP(1000);
}
关键一步:需要在TIM1中添加下面一行:
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
然后在ADC选择定时器1触发:
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
void DMA1_Channel1_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC1)) //判断DMA传输完成中断
{
//在这里将AD采集到的数据进行累计,并且计算累加的次数。
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
}
最后