定时器-CP采样

交流,CP的PWM发波、检测的介绍

  1. CP电压的ADC模拟量采集
    介绍:CP为充电桩的枪头电压,需要通过ADC来采集CP的电压变化来确定CP的电压值。ADC通过定时器2PWM的电平变化来触发ADC的采样,定时器的PWM变化是25us一次,1s内采集40个点。注意采样点要大于ADC的转换时间。
    1.1 定时器2
    1.1.1 定时器2的时基APB1-60Mhz,1个滴答为1us,周期25us。代码配置如下所示。
void Timer2Config(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	// TIM2 clock enable
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	// 自动重装载寄存器周期的值(计数值)
	TIM_TimeBaseStructure.TIM_Period = (25 - 1);

	// 累计 TIM_Period个频率后产生一个更新或者中断
	// 这个就是预分频系数
	TIM_TimeBaseStructure.TIM_Prescaler = (60 - 1);

	// 采样分频
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

	// 向上计数模式
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	// 初始化定时器2
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	// 清除溢出中断标志
	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

	// 溢出中断使能
	//TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	/* Output Compare Timing Mode configuration: Channel1 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 10;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OC3Init(TIM2, &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM2, ENABLE);
	// 计数器使能
	//TIM_Cmd(TIM2, ENABLE);
	/* TIM Interrupts enable */
	 TIM_ITConfig(TIM2, TIM_IT_CC3|TIM_IT_Update, ENABLE);
	/* Slave Mode selection: TIM2 */
	TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Trigger);
	TIM_SelectInputTrigger(TIM2,TIM_TS_ITR0);
	/* Select the Master Slave Mode */
	TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Disable);
	TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_OC3Ref);
	TIM_Cmd(TIM2, DISABLE);
	//TIM_Cmd(TIM2, ENABLE);
}

1.2.ADC1/2
1.2.1 ADC1的最大输入时钟频率14Mhz。双通道同时采样并在DMA中断读取每次转换的结果,对两路信号进行ADC同时采样。由于一路信号将作为参考信号解调另一路信号,所以要确保两路信号的每次采样是同时进行的。所以,需要将ADC设置成“多重ADC模式”中的“规则同时模式”下的“双重ADC模式”(ADC_DualMode_RegSimult)。ADC的每次转换由定时器触发(ADC_ExternalTrigConvEdge_Rising)。

adc的配置

void BSP_ADC_Config(void)
{	
	ADC_InitTypeDef       ADC_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	/*ADC  Clock config----------------------------------------------*/
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);
	/*ADC init------------------------------------------------------*/
	 ADC_DeInit();
	/*ADC1,2 DMA config-----------------------------------------------*/
	ADC12_DMA_Config(DMA2_Stream4,(u32)&ADC->CDR,(u32)&AD_DATA,NUM_AD12_CHANNEL);
	/*ADC3 DMA config-----------------------------------------------*/
	/* ADC Common config ------------------------------------------*/
	ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;	
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;	
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
	ADC_CommonInit(&ADC_CommonInitStructure);			
	/* ADC1 configuration --------------------------------------------*/
	ADC_StructInit(&ADC_InitStructure);
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;	//CP1 PWM
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_CC3;
	
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据右对齐
	ADC_InitStructure.ADC_NbrOfConversion = NUM_ADC1_CHANNEL;
	ADC_Init(ADC1, &ADC_InitStructure);	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_3Cycles);	//PC0 ADC_SampleTime_13Cycles5
	/* Enable ADC1 DMA */
	ADC_DMACmd(ADC1, ENABLE);
	/* ADC2 configuration ************************************/
	ADC_StructInit(&ADC_InitStructure);
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;	//CP2 PWM
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T2_CC3;
	
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据右对齐
	ADC_InitStructure.ADC_NbrOfConversion = NUM_ADC2_CHANNEL;
	ADC_Init(ADC2, &ADC_InitStructure);		
	ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 1, ADC_SampleTime_3Cycles);	//PC2
	/* Enable DMA request after last transfer (multi-ADC mode) */
	ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
	ADC_ITConfig(ADC1,ADC_IT_OVR,ENABLE);
	ADC_ITConfig(ADC2,ADC_IT_OVR,ENABLE);	
	/* Enable ADC1,2,3 **************************************************************/
	ADC_Cmd(ADC1, ENABLE);
	ADC_Cmd(ADC2, ENABLE);
	/* Enable ADC IT **************************************************************/
	//over IT
	
	//EOC IT
	//ADC_ITConfig(ADC3,ADC_IT_EOC,ENABLE);
	/* Start ADC1 Software Conversion */
	
}

DMA的配置如下。开启半输出中断及输出结束中断。

void ADC12_DMA_Config(DMA_Stream_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);	//使能DMA时钟
	DMA_InitTypeDef DMA_InitStructure;
	DMA_StructInit(&DMA_InitStructure);
	DMA_DeInit(DMA_CHx);   									//将DMA的通道1寄存器重设为缺省值
	DMA_InitStructure.DMA_Channel = DMA_Channel_0;	
	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  		//DMA外设基地址
	DMA_InitStructure.DMA_Memory0BaseAddr = cmar;  			//DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;  	//数据传输方向,从外设发送到内存  DMA_CCRX位4
	DMA_InitStructure.DMA_BufferSize = cndtr;  				//DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  //外设数据宽度为16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word; 		//内存数据宽度为16位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  							//工作在循环缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; 						//DMA通道 x拥有高优先级

	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_CHx, &DMA_InitStructure);  	//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
	DMA_ClearITPendingBit(DMA_CHx,DMA_IT_HTIF4);
	//DMA_ClearITPendingBit(DMA_CHx,DMA_IT_TCIF1);
		
	DMA_ITConfig(DMA_CHx,DMA_IT_HT|DMA_IT_TC,ENABLE);
	//DMA_ITConfig(DMA_CHx,DMA_IT_TC,ENABLE);
	DMA_Cmd(DMA_CHx, ENABLE);//启动DMA通道
}
  1. 模拟量的处理
    1. 介绍
      采集的CP模拟量需要进行数据定标、校准,
      这里需要对CP的模拟量特别说下,正常CP采集到的点是40个点,但由于CP在发波时,是PWM的波形,所以仅对有效电平(高电平)进行滤波判断。如32A时,PWM的重载值533,周期为1000,53340/1000=21,去掉电平变化的3个点,对18个点求平均值。最后计算的值为CP的模拟量值。
      数据定标:进行比例增益矫正。
      AD采样值Va(0-4096)定标出CP值电压Vb(0-12V)。根据Vb=Va
      K1+B1公式,K1,B1为定标默认值。
      数据校准:。
      瞬时值:计算出来的值为瞬时值,CP电压的判断,工装的值均为瞬时值。
      滤波值:进行滤波偏移。多用来进行工装、wifi后台显示。
      模拟量处理步骤
  2. CP的PWM发波
    3.1 介绍
    CP的发波,通过定时器1来发波,滴答1us,周期1000,1ms,也就是国标要求的1Khz。
    参考代码如下。
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	uint16_t PrescalerValue = 0;
	TIM_OCStructInit(&TIM_OCInitStructure);
								 //120000000
	PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1;	//预分频系数
	
		// TIM1 clock enable
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
		//TIM_DeInit(TIM1); 
		// 自动重装载寄存器周期的值(计数值)
	TIM_TimeBaseStructure.TIM_Period = (1000-1);
	
		// 累计 TIM_Period个频率后产生一个更新或者中断
		// 这个就是预分频系数
	TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
	
		// 采样分频
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	
		// 向上计数模式
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
		// 初始化定时器1
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
	
		// 清除溢出中断标志
	TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
	
		// 溢出中断使能
	TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

	/* Output Compare Timing Mode configuration: Channel1 */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 533;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);			
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
	/* Output Compare Timing Mode configuration: Channel2 */
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 533;
	TIM_OC2Init(TIM1, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM1, ENABLE);
	//* TIM1 enable counter */
	
	TIM_Cmd(TIM1, ENABLE);
	/* TIM Interrupts enable */
	TIM_ITConfig(TIM1, TIM_IT_CC1 | TIM_IT_CC2| TIM_IT_Update, ENABLE);
	/* Select the Master Slave Mode */
	TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
	TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_OC1Ref);
	
	TIM_CtrlPWMOutputs(TIM1, ENABLE);
  注意,在发波使,使能pwm接口即可,如:使能:TIM_ForcedOC1Config(TIM1,TIM_OCMode_PWM1);
  禁止:TIM_ForcedOC1Config(TIM1,TIM_ForcedAction_Active);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值