【stm32】用TIM1产生6路ADC,用CCR4触发ADC1的注入通道采样
这几天一直在使用STM32来写sensorless BLDC的驱动框架,那么必须会用到TIM1的CCR1/CCR2/CCR3产生的六路互补PWM,以及用CCR4来产生一个中断,用来在PWM-ON的时候产生中断进行过零检测,以及相电流的检测等。
这几天一直在测试PWM,CCR4的中断,ADC1的采样触发+DMA等功能,现在也了解的差不多了,先记录下来,先看下我的一些设置,TIM1设置:
1 /* Time Base configuration ,init time1 freq*/ 2 TIM_TimeBaseStructure.TIM_Period = Period; 3 TIM_TimeBaseStructure.TIM_Prescaler = 0; 4 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 5 TIM_TimeBaseStructure.TIM_ClockDivision = 0; 6 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 7 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); 8 9 /* Automatic Output enable, Break, dead time and lock configuration*/ 10 TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; 11 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; 12 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; 13 TIM_BDTRInitStructure.TIM_DeadTime = 0; 14 TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; 15 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; 16 TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; 17 TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); 18 19 /*pwm driver set ,channel 1,2,3,4set pwm mode*/ 20 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 21 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; 22 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; 23 TIM_OCInitStructure.TIM_Pulse = 5; 24 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 25 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 26 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; 27 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; 28 //set OC1/OC1N 29 TIM_OC1Init(TIM1, &TIM_OCInitStructure); 30 //set oc2/oc2n 31 TIM_OCInitStructure.TIM_Pulse = 0; 32 TIM_OC2Init(TIM1, &TIM_OCInitStructure); 33 //set OC3/OC3N 34 TIM_OCInitStructure.TIM_Pulse = 0; 35 TIM_OC3Init(TIM1, &TIM_OCInitStructure); 36 //set adc sample time 37 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//CCR4这个输出使能后才能用来触发ADC1的注入通道采样 38 TIM_OCInitStructure.TIM_Pulse = 0; 39 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; 40 TIM_OC4Init(TIM1, &TIM_OCInitStructure); 41 42 //enable interrupt 43 TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); //CCR4的中断,这个通过设置CCR4的pulse来控制产生中断相当于PWM-ON的位置 44 TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); 45 TIM_ITConfig(TIM1, TIM_IT_COM,ENABLE); 46 47 /* BLDC_TIMER_NUM counter enable */ 48 TIM_Cmd(TIM1, ENABLE); 49 50 /* Main Output Enable */ 51 TIM_CtrlPWMOutputs(TIM1, ENABLE);
ADC1设置,这里采用规则通道+DMA+软件触发,注入通道+CCR4事件触发:
1 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 2 ADC_InitStructure.ADC_ScanConvMode = ENABLE; 3 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 4 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 5 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 6 ADC_InitStructure.ADC_NbrOfChannel = 5; 7 ADC_Init(ADC1, &ADC_InitStructure); 8 9 ADC_TempSensorVrefintCmd(ENABLE); 10 ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);//hand 11 ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_239Cycles5);//external temperature 12 ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_239Cycles5);//vol 13 ADC_RegularChannelConfig(ADC1,ADC_Channel_10 ,4,ADC_SampleTime_239Cycles5); 14 ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,5,ADC_SampleTime_239Cycles5); 15 //上面规则通道的设置,注意采样时间,我发现如果时间设置过的可能数据会互相干扰 16 //下面是注入通道,这里注入通道设置成TIM1的CCR4事件触发 17 ADC_InjectedSequencerLengthConfig(ADC1, 1); 18 ADC_InjectedChannelConfig(ADC1,ADC_Channel_TempSensor,1,ADC_SampleTime_7Cycles5);//CURRENT 19 ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_CC4);//这个可以使用time1的CCR4事件来触发采样 20 ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE); 21 22 ADC_ITConfig(ADC1,ADC_IT_JEOC,ENABLE);//ENABLE INJECTED INTERRUPT 23 /* Enable automatic injected conversion start after regular one */ 24 // ADC_AutoInjectedConvCmd(ADC1, ENABLE);//是否在规则通道结束之后自动开始注入通道采样 25 26 27 ADC_DMACmd(ADC1, ENABLE); 28 29 ADC_Cmd(ADC1, ENABLE);
另外我还加了一个注入通道采样结束的中断,用来快速处理相电流的一些问题,比如限流、过流的处理。
测试从发现如果把CCR4的pulse设为0,那么就不会触发ADC1的注入采样,也就不会产生ADC的中断,只有pluse设置为一定的有效数值,那么adc注入通道的采样才会被触发。