无刷电机控制——软件部分

简介:下面程序基于STM32F103RCT6,部分内容来源于网络。

一、具有互补功能的电机驱动程序

void initPWM()
{
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
	//initialize LIHE
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	

	//initialize Tim1 PWM outputs
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);


	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

	// Time Base configuration
	TIM_TimeBaseStructure.TIM_Prescaler = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_Period = BLDC_CHOPPER_PERIOD;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

	// Channel 1, 2, 3 – set to PWM mode - all 6 outputs

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0; // initialize to zero output

	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_High TIM_OCPolarity_Low
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;//TIM_OCNPolarity_Low TIM_OCNPolarity_Low
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;

	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
	TIM_OC2Init(TIM1, &TIM_OCInitStructure);
	TIM_OC3Init(TIM1, &TIM_OCInitStructure);
	TIM_OC4Init(TIM1, &TIM_OCInitStructure); //for ADC

	TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
	TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
	TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;


	// DeadTime[ns] = value * (1/SystemCoreFreq) (on 72MHz: 7 is 98ns)
	TIM_BDTRInitStructure.TIM_DeadTime = BLDC_NOL;

	TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

	//no break functionality
	TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
	TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;

	TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);


	//Commutation event mapped to TIM4 - We are not using commute event, but interrupt from Hall timer directly to commute.
	//Not optimal solution?
	//TIM_SelectInputTrigger(TIM1, TIM_TS_ITR3);


	TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); //adc sampling interrupt
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

	NVIC_Init(&NVIC_InitStructure);


	TIM_Cmd(TIM1, ENABLE);
	 // enable motor timer main output (the bridge signals)
	TIM_CtrlPWMOutputs(TIM1, ENABLE);	
			
	pwm_motorStop();

}
void pwm_motorStart()
{
	uint16_t newhallpos;
	newhallpos = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)? (((GPIO_ReadInputData(GPIOA)>>6)&0x03) | 0x04) : ((GPIO_ReadInputData(GPIOA)>>6)&0x03);
	hallpos = newhallpos;
	pwm_Hall(hallpos);
	TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE); //enable HALL interrupts
}

void pwm_motorStop()
{
	//motor_running=0;
	TIM1->CCR1 = 0;
	TIM1->CCR2 = 0;
	TIM1->CCR3 = 0;
	TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
	TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
	TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);

	TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
	TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
	TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);

	TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, DISABLE); //disable HALL interrupts, no commutation!
}

二、霍尔信号接口的对应程序

void initHALL()
{
    GPIO_InitTypeDef GPIO_InitStructure;    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;    
    TIM_ICInitTypeDef  TIM_ICInitStructure;    
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    //Hall sensor is connected to TIM3
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    lasthallpos = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)? ((GPIO_ReadInputData(GPIOA)>>6)| 0x04) : (GPIO_ReadInputData(GPIOA)>>6);
    hallpos = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)? ((GPIO_ReadInputData(GPIOA)>>6)| 0x04) : (GPIO_ReadInputData(GPIOA)>>6);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_TimeBaseStructure.TIM_Prescaler = 126;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 65535;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    TIM_SelectHallSensor(TIM3, ENABLE);
    TIM_SelectInputTrigger(TIM3, TIM_TS_TI1F_ED);
    TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);


    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    // listen to T1, the  HallSensorEvent
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
    // Div:1, every edge
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

    // input noise filter
    TIM_ICInitStructure.TIM_ICFilter = 0xF;
    TIM_ICInit(TIM3, &TIM_ICInitStructure);
    

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_Pulse = BLDC_DELAY; // 1 is no delay; 2000 = 7ms
    TIM_OC2Init(TIM3, &TIM_OCInitStructure);

    // clear interrupt flag
    TIM_ClearFlag(TIM3, TIM_FLAG_CC2);


    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_OC2Ref);

    TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);

    TIM_Cmd(TIM3, ENABLE);

    // we use preemption interrupts here,  BLDC Bridge switching and
    // Hall has highest priority    
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


}

void TIM3_IRQHandler(void) {
    uint16_t newhallpos;
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
    // calculate motor  speed or else with CCR1 values

  }
  else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
//#ifndef SINUSOID_DRIVE
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

        newhallpos = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)? (((GPIO_ReadInputData(GPIOA)>>6)&0x03) | 0x04) : ((GPIO_ReadInputData(GPIOA)>>6)&0x03);
        if (newhallpos == hallpos) return;
        hallpos = newhallpos;
        pwm_Hall(hallpos);

  } 
  else if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) 
  {
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);    
//    TIM_SetCounter(TIM3,0);     
  }
}

三、根据霍尔位置进行切换控制

下面程序中“if(fr)    hall = 7 - hall;”为后来添加(反转执行),一开始的程序是正反转分别有一组switch不同的语句(根据电机表写的)但正转正常反转有抖动,后来发现只需要一个switch反转时对霍尔数据做处理即可。

void pwm_Hall(uint8_t hall)
{
	uint32_t duty=750;
	uint8_t fr=1;
	duty = BLDC_CHOPPER_PERIOD*500/1000;
	if(duty>MAX_DUTY) duty = MAX_DUTY;
	
	if(fr)	hall = 7 - hall;
	switch(hall)//Õýת ×óÐÐ
	{
		case 4: //U+ W- Next step: 6
		TIM_SetCompare2(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);								

		TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);			
		TIM_SetCompare1(TIM1,duty);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);	
		TIM_CCxNCmd(TIM1,TIM_Channel_1, TIM_CCxN_Enable);	

		TIM_SetCompare3(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);								
		break;
		case 6: //V+ W-  Next step: 2
		TIM_SetCompare1(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);   
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);	                    

		TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);			
		TIM_SetCompare2(TIM1,duty);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Enable);    
		TIM_CCxNCmd(TIM1,TIM_Channel_2, TIM_CCxN_Enable); 
		
		TIM_SetCompare3(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);								
		break;
		case 2: //V+ U-  Next step: 3
		TIM_SetCompare3(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);		

		TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_OCMode_PWM1);			
		TIM_SetCompare2(TIM1,duty);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Enable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);	

		TIM_SetCompare1(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);				
		break;
		case 3: //W+ U-  Next step: 1 
		TIM_SetCompare2(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);												

		TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);			
		TIM_SetCompare3(TIM1,duty);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);	
		
		TIM_SetCompare1(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);		
		break;
		case 1: //W+ V-  Next step: 5
		TIM_SetCompare1(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);		// ¹Ø±Õ U ÉÏÇűÛ
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable); // ¹Ø±Õ U ÏÂÇÅ±Û     			
		
		TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_OCMode_PWM1);			
		TIM_SetCompare3(TIM1,duty);														// ͨµÀ 3 ÅäÖõÄÕ¼¿Õ±È
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);	//Ö®ËùÒÔÕ¼¿Õ±È²»ÄÜΪ100%¾ÍÊÇÒòΪÏÂÇűÛÐëÓе¼Í¨Ê±¼äÒÔ¸ø×Ô¾ÙµçÈݳäµç
		// ¿ªÆô V ÏÂÇűÛ	
		TIM_SetCompare2(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);				
		break;
		case 5: //U+  V-  Next step: 4
		TIM_SetCompare3(TIM1,0);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);	

		TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_OCMode_PWM1);			
		TIM_SetCompare1(TIM1,duty);
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);

		TIM_SetCompare2(TIM1,0);
		TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_ForcedAction_Active);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);						
		break;
		default:
		TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Disable);
		TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Disable);
		TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Disable);
		TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Disable);
		
		break;
	}
}	

四、电机电流采集

void initADC()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;	
	DMA_InitTypeDef  DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//--Enable ADC1 and GPIOA--
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);


	GPIO_StructInit(&GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	//ADC1 configuration

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;

	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//!

	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	//load structure values to control and status registers
	ADC_Init(ADC1, &ADC_InitStructure);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_41Cycles5);
	//Enable ADC1
	ADC_Cmd(ADC1, ENABLE);
	//enable DMA for ADC
	ADC_DMACmd(ADC1, ENABLE);
	//Enable ADC1 reset calibration register
	ADC_ResetCalibration(ADC1);
	//Check the end of ADC1 reset calibration register
	while(ADC_GetResetCalibrationStatus(ADC1));
	//Start ADC1 calibration
	ADC_StartCalibration(ADC1);
	//Check the end of ADC1 calibration
	while(ADC_GetCalibrationStatus(ADC1));


	//enable DMA1 clock
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	//reset DMA1 channe1 to default values;
	DMA_DeInit(DMA1_Channel1);

	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

	DMA_InitStructure.DMA_Priority = DMA_Priority_High;

	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;

	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

	DMA_InitStructure.DMA_BufferSize = 1;

	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_value;
	//send values to DMA registers
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	// Enable DMA1 Channel Transfer Complete interrupt
	DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
	DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1

	//Enable DMA1 channel IRQ Channel */
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

}


void ADC1_2_IRQHandler(void) {
  if (ADC_GetITStatus(ADC1, ADC_IT_EOC) != RESET)
  {

	  ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);

  }
}


void DMA1_Channel1_IRQHandler(void) {
	uint16_t ADC_temp;
	
  if(DMA_GetITStatus(DMA1_IT_TC1)) {
		DMA_ClearITPendingBit(DMA1_IT_GL1);
		DMA_Cmd(DMA1_Channel1, ENABLE);
		ADC_buf[ADC_index] = ADC_value;
  }
} 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值