- int main(void)
- {
- GPIO_BSRET_T bit = Bit_RESET;
- __disable_irq();
- /* config peripherals */
- MC_SystemClockInit();
- /* M0CP */
- M0CP_Firmware_Init();
- RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_M0CP);
- RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_M0CP);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_M0CP);
- M0CP_HardInit();
- *(volatile unsigned int*)(0x40024000+0x10) = 0;
- /* TIMER1 */
- Drv_Pwm_Init(PWM_PERIOD,DEAD_TIME);
- PWM_CompareConfig(PWM_PERIOD, PWM_PERIOD, PWM_PERIOD);
- /* ADC */
- Drv_Adc_Init();
- /* OPA */
- OPA_Init();
- /* COMP */
- COMP_Init();
- /* GPIO */
- IO_Init();
- Pilot_uart_init();
- /* SYSTICK */
- Systick_Init(SystemCoreClock / 1000);
- /* Initialize motor control parameters */
- Init_Parameter(&Motor_type);
- /* Initialize interrupts */
- Interrupt_Init();
- /* Wait until ADC is ready */
- while (!ADC_ReadStatusFlag(ADC_FLAG_ADRDY));
- ADC_StartConversion();
- WWDTInit();
- __enable_irq(); //Enable all interrupts
- TMR_EnablePWMOutputs(TMR1);
- while (1)
- {
- //Reads key from demoboard.
- NewDIRKey = GPIO_ReadInputBit(GPIOC,GPIO_PIN_13); //PC13 Direction方向按键
- if(NewDIRKey == BIT_RESET)
- {
- /*设定新方向为反转CCW*/
- Motor_type.User.s8NewDir = -1;
- }
- else{
- /*设定新方向为正转CW*/
- Motor_type.User.s8NewDir = 1;
- }
- if(Motor_type.User.s8NewDir != Motor_type.User.s8Direction)
- {
- /*启动转向切换功能*/
- Motor_type.User.bDirSwitchEnable = true;
- }
-
- if(Motor_type.User.bSlowLoopFlag)
- {
- WWDTFeedDog();
- /* Slow Loop Statemachine */
- s_STATE_SLOW[eM1_MainState]();
- Motor_type.User.bSlowLoopFlag = 0;
- }
- if( Get_Systick_Cnt() % 300 == 0)
- {
- GPIO_WriteBitValue(GPIO_LedErr,GPIO_Pin_LedErr,bit);
- bit = !bit;
- }
- if( Get_Systick_Cnt() % 100 == 0)
- {
- //speed_rate = 20;
- speed_rpm = hall_cnt*20;
- hall_cnt = 0;
- printf("<plots,%d,%d,%d,%d>\r\n",\
- Motor_type.Foc.s16SpdFilt,\
- Motor_type.stc_SmoPara.s16q15_Ealpha,\
- speed_rpm,\
- Motor_type.Foc.stc_Idq.s16q15_Q\
- );
- // Motor_type.Foc.stc_Idq.s16q15_D,\
- // Motor_type.Foc.stc_Idq.s16q15_Q,\
- // Motor_type.Foc.stc_IdqCmd.s16q15_D,\
- // Motor_type.Foc.stc_IdqCmd.s16q15_Q);
- }
- }
- }
main函数主要是对外设的配置初始化;
主循环是简单的按键识别反向选择、喂狗等;
主要需要看的是PWM和adc的初始化
先看pwm
- void Drv_Pwm_Init(uint16_t u16_Period,uint16_t u16_DeadTime)
- {
- TMR_TimeBase_T TIM_TimeBaseInitStructure;
- TMR_OCConfig_T TIM_OCInitStructure;
- TMR_BDTInit_T TIM_BDTRInitStructure;
-
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG | RCM_APB2_PERIPH_TMR1 );
-
- /* Time Base configuration ,init time1 freq*/
- TIM_TimeBaseInitStructure.period = u16_Period; //(SYSTEM_FREQUENCY/2/8000) - 1;
- TIM_TimeBaseInitStructure.div = 0;
- TIM_TimeBaseInitStructure.counterMode = TMR_COUNTER_MODE_CENTERALIGNED2;
- TIM_TimeBaseInitStructure.clockDivision = TMR_CKD_DIV1;
- TIM_TimeBaseInitStructure.repetitionCounter = 1;
- TMR_ConfigTimeBase(TMR1, &TIM_TimeBaseInitStructure);
- /* Automatic Output enable, Break, dead time and lock configuration*/
- TIM_BDTRInitStructure.RMOS_State = TMR_RMOS_STATE_ENABLE;//--------
- TIM_BDTRInitStructure.IMOS_State = TMR_IMOS_STATE_ENABLE;//--------
- TIM_BDTRInitStructure.lockLevel = TMR_LOCK_LEVEL_OFF;//00:锁定关闭,寄存器无写保护;01:锁定级别1,不能写入TIMx_BDTR寄存器的DTG、BKE、BKP、AOE位和TIMx_CR2寄存器的OISx/OISxN位;
- TIM_BDTRInitStructure.deadTime = u16_DeadTime;//死区时间
- /**
- * Brake configuration: enable brake
- * Brake input polarity: active in low level
- * Auto output enable configuration: Disable MOE bit hardware control
- */
- TIM_BDTRInitStructure.breakState = TMR_BREAK_STATE_ENABLE;//TMR_BREAK_STATE_ENABLE TMR_BREAK_STATE_DISABLE;
- TIM_BDTRInitStructure.breakPolarity = TMR_BREAK_POLARITY_HIGH;
- TIM_BDTRInitStructure.automaticOutput = TMR_AUTOMATIC_OUTPUT_DISABLE;
- TMR_ConfigBDT(TMR1, &TIM_BDTRInitStructure);
- /*pwm driver set,channel 1,2,3,4set pwm mode*/
- TIM_OCInitStructure.OC_Mode = TMR_OC_MODE_PWM2;
- TIM_OCInitStructure.OC_OutputState = TMR_OUTPUT_STATE_ENABLE; //TMR_OUTPUT_STATE_DISABLE;
- TIM_OCInitStructure.OC_OutputNState = TMR_OUTPUT_NSTATE_ENABLE; //TMR_OUTPUT_NSTATE_DISABLE;//------------
- TIM_OCInitStructure.Pulse = u16_Period;
- TIM_OCInitStructure.OC_Polarity = TMR_OC_POLARITY_HIGH;
- TIM_OCInitStructure.OC_NPolarity = TMR_OC_NPOLARITY_HIGH; //互补输出极性-------
- TIM_OCInitStructure.OC_Idlestate = TMR_OCIDLESTATE_RESET; // TMR_OCIDLESTATE_SET; //
- TIM_OCInitStructure.OC_NIdlestate = TMR_OCNIDLESTATE_RESET; // TMR_OCNIDLESTATE_SET;//
- //set OC1/OC1N
- TMR_OC1Config(TMR1, &TIM_OCInitStructure);
- //set oc2/oc2N
- TIM_OCInitStructure.Pulse = u16_Period;
- TMR_OC2Config(TMR1, &TIM_OCInitStructure);
- //set OC3/OC3N
- TIM_OCInitStructure.Pulse = u16_Period;
- TMR_OC3Config(TMR1, &TIM_OCInitStructure);
-
- TIM_OCInitStructure.OC_Mode = TMR_OC_MODE_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
- TIM_OCInitStructure.OC_OutputState = TMR_OUTPUT_STATE_ENABLE; //CH1比较输出使能
- TIM_OCInitStructure.OC_OutputNState = TMR_OUTPUT_NSTATE_ENABLE; //CH1N比较输出使能
- TIM_OCInitStructure.OC_Polarity = TMR_OC_POLARITY_HIGH; //CH1输出极性:TIM输出比较极性高
- TIM_OCInitStructure.OC_NPolarity = TMR_OC_NPOLARITY_HIGH; //CH1N输出极性:TIM输出比较极性高
- TIM_OCInitStructure.OC_Idlestate = TMR_OCIDLESTATE_RESET; //CH1输出空闲状态:0
- TIM_OCInitStructure.OC_NIdlestate = TMR_OCNIDLESTATE_SET; //CH1N输出空闲状态:0
- //set OC4
- TIM_OCInitStructure.Pulse = 10;
- TMR_OC4Config(TMR1, &TIM_OCInitStructure);//OC4
- //enable interrupt
- TMR_EnableInterrupt(TMR1, TMR_INT_BRK);
- TMR_EnableAUTOReload(TMR1);//TIMx_ARR寄存器被装入缓冲器
- TMR_OC1PreloadConfig(TMR1,TMR_OC_PRELOAD_ENABLE);
- TMR_OC2PreloadConfig(TMR1,TMR_OC_PRELOAD_ENABLE);//比较值预装载使能
- TMR_OC3PreloadConfig(TMR1,TMR_OC_PRELOAD_ENABLE);
- TMR_OC4PreloadConfig(TMR1,TMR_OC_PRELOAD_ENABLE);
-
- TMR_EnableAUTOReload(TMR1);
-
- TMR_Enable(TMR1);
- TMR1->REPCNT = 1;
- /* Main Output Enable */
- TMR_EnablePWMOutputs(TMR1);
-
- /* GPIO config */
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.pin = GPIO_PIN_PWM_UH_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_UH_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_VH_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_VH_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_WH_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_WH_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_UL_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_UL_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_VL_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_VL_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_WL_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_WL_Mobile, &GPIO_InitStructure);
- GPIO_InitStructure.pin = GPIO_PIN_PWM_Break_Mobile;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AF;
- GPIO_InitStructure.pupd = GPIO_PUPD_PD;
- GPIO_Config(GPIO_PWM_Break_Mobile, &GPIO_InitStructure);
- //复用映射,需参考文档
- GPIO_ConfigPinAF(GPIO_PWM_UH_Mobile,GPIO_PIN_SOURCE_PWM_UH_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_VH_Mobile,GPIO_PIN_SOURCE_PWM_VH_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_WH_Mobile,GPIO_PIN_SOURCE_PWM_WH_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_UL_Mobile,GPIO_PIN_SOURCE_PWM_UL_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_VL_Mobile,GPIO_PIN_SOURCE_PWM_VL_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_WL_Mobile,GPIO_PIN_SOURCE_PWM_WL_Mobile,GPIO_AF_PIN2);
- GPIO_ConfigPinAF(GPIO_PWM_Break_Mobile,GPIO_PIN_SOURCE_PWM_Break_Mobile,GPIO_AF_PIN3);
- }
pwm使用的是timr1,频率为16K,死区时间为1us。
使用高级定时器,产生互补pwm。
其次是ADC的配置:
- void Drv_Adc_Init(void)
- {
- ADC_Config_T ADC_InitStructure;
- DMA_Config_T DMA_InitStructure;
- DMA_InitStructure.peripheralAddress = (uint32_t)&(ADC->DATA);//ADC地址
- DMA_InitStructure.memoryAddress = (uint32_t)&ADC_ConvertedValue[0]; //内存地址
- DMA_InitStructure.direction = DMA_DIR_PERIPHERAL; //方向(从外设到内存)
- DMA_InitStructure.bufferSize = TOTAL_CHANNEL;//TOTAL_CHANNEL; //传输内容的大小---传输次数
- DMA_InitStructure.peripheralInc = DMA_PERIPHERAL_INC_DISABLE; //外设地址固定
- DMA_InitStructure.memoryInc = DMA_MEMORY_INC_ENABLE;//DMA_MEMORY_INC_ENABLE; //内存地址固定
- DMA_InitStructure.peripheralDataSize = DMA_PERIPHERAL_DATASIZE_HALFWORD ; //外设数据单位
- DMA_InitStructure.memoryDataSize = DMA_MEMORY_DATASIZE_HALFWORD ; //内存数据单位
- DMA_InitStructure.circular = DMA_CIRCULAR_ENABLE ; //DMA模式:循环传输
- DMA_InitStructure.priority = DMA_PRIORITY_LEVEL_VERYHIGH ; //优先级:高
- DMA_InitStructure.memoryTomemory = DMA_M2M_DISABLE; //禁止内存到内存的传输
- ADC_Reset();
- DMA_Config(DMA_CHANNEL_1, &DMA_InitStructure); //配置DMA的1通道
- DMA_Enable(DMA_CHANNEL_1);
- ADC_ClockMode(ADC_CLOCK_MODE_ASYNCLK);//48M/4=12mADC_CLOCK_MODE_SYNCLKDIV4
- ADC_ConfigStructInit(&ADC_InitStructure);
- ADC_InitStructure.convMode = ADC_CONVERSION_SINGLE;
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD;
- ADC_InitStructure.extTrigConv1 = ADC_EXT_TRIG_CONV_TRG1; // timer1 CC4
- ADC_InitStructure.extTrigEdge1 = ADC_EXT_TRIG_EDGE_RISING;
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B;
- ADC_Config(&ADC_InitStructure);
- /*ADC_CHANNEL_2 :PA4 IV;ADC_CHANNEL_8:PB0 IU;ADC_CHANNEL_6:PA6 Vbus;ADC_CHANNEL_7:PA7 Handle;ADC_CHANNEL_12:PB10 Ibus*/
- ADC_ConfigChannel(ADC_CHANNEL_2 | ADC_CHANNEL_8 | ADC_CHANNEL_6 | ADC_CHANNEL_7| ADC_CHANNEL_12 ,ADC_SAMPLE_TIME_1_5);
- ADC->CFG1_B.OVRMAG = 1;
- ADC_EnableInterrupt(ADC_INT_CS);
- //=========================ADC中断使用=================================================
- NVIC_EnableIRQ(ADC_COMP_IRQn);
- NVIC_SetPriority(ADC_COMP_IRQn,0);
- ADC_DMARequestMode(ADC_DMA_MODE_CIRCULAR);
- ADC_EnableDMA();
- ADC_Enable();
- ADC_StartConversion();//必需要启动一下
-
- /* Config IO */
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.pin = GPIO_Pin_ADC_VDC;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_Config(GPIO_ADC_VDC, &GPIO_InitStructure);
-
- GPIO_InitStructure.pin = GPIO_Pin_ADC_Handle;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_Config(GPIO_ADC_Handle, &GPIO_InitStructure);
-
- GPIO_InitStructure.pin = GPIO_Pin_ADC_IU;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_Config(GPIO_ADC_IU, &GPIO_InitStructure);
-
- GPIO_InitStructure.pin = GPIO_Pin_ADC_IV;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_Config(GPIO_ADC_IV, &GPIO_InitStructure);
-
- GPIO_InitStructure.pin = GPIO_Pin_ADC_IBUS;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_Config(GPIO_ADC_IBUS, &GPIO_InitStructure);
- // GPIO_InitStructure.pin = GPIO_Pin_ADC_VOT;
- // GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- // GPIO_InitStructure.mode = GPIO_MODE_AN;
- // GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- // GPIO_Config(GPIO_ADC_VOT, &GPIO_InitStructure);
- }
ADC配置为DMA模式,使用TIMER1的CC4的上升沿进行触发,也就是说,TIMER1的通道4,每产生一个PWM的上升沿,就会检测一次ADC的数据;
为什么使用通道4?
因为TIMER1的通道1~3要控制三相桥,通道4空余的作为一个触发源,并不会真正的产生一个PWM信号;
会在ADC的中断内进行数据的读取;