#include "system_dumby.h" #include #include "motor.h" /** @Note * Ce fichier contient les fonctions lié à la gestions du moteur : * - L'initialisation des PIN ultisé par les moteurs et encodeurs * - L'initialisation du Timer2 servant de bases de temps aux PWM pour la charge / moteur1 et moteur2 * - L'initialisation du Timer3 servant à échantilloner les capteur magnétique de position des 2 moteurs. * - La commandes des moteurs dans leurs 3 modes de fonctionnement (AVANT, ARRIERE, FREIN) et de leurs vitesse (valeur de PWM entre 0 et 255) */ /** * TABLE DE VERITEE DU DRIVER MOTEUR * * ENABLE | INPUTS | Moteurs * | | * 0 | X | Roue Libre *-------------------------------------- * | CMDA & !CMDB| Avant * 1 | !CMDA & CMDB| Arriére * | CMDA = CMDB| Frein */ __IO uint16_t IC1ReadValue1 = 0, IC1ReadValue2 = 0, IC3ReadValue1 = 0, IC3ReadValue2 = 0; __IO uint16_t CaptureMotor1Nbr = 0, CaptureMotor2Nbr = 0; __IO uint32_t motor1Capture, motor2Capture = 0; TIM_TimeBaseInitTypeDef TIM2_TempsPWMsettings; TIM_OCInitTypeDef TIM2_Configure; uint16_t tourD = 0, tourG=0, tourPositionD, tourPositionG; // definition des variables global uint16_t G_speedRight=20, G_speedLeft=20, G_lapsLeft, G_lapsRight; /** * @brief La fonction mapMotorPin va venir configurer le E/S du GPIO pour correspondre avec le schéma electrique en ressource. * 2 pwm en alternate fonction : PA1,PA2. 4 entrée timer. PA8,PA9,PA10,PA11. 4 sortie ppull PB12,PB13,PB14,PB15 * * @param Aucun * @retval Aucun * * @Attention La definitions de ces E/S ne sera valable que dans la version du prototype n°2 de Dumby. * Si vous utilisez la versions n°1, appellez mapMotorPinOld(). */ void MAP_MotorPin(void) { /// Variable local necessaire à l'initialisation des structures GPIO_InitTypeDef Init_Structure; /// Configure les PIN A1 et A2 en output / alternate fonction Init_Structure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; //Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP; Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &Init_Structure); /// Configure les PIN B12,B13,B14, et B15 en output ppull. Init_Structure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &Init_Structure); /// Configure les PIN A12 en output ppull - enable encodeurs Init_Structure.GPIO_Pin = GPIO_Pin_12; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &Init_Structure); /// Configure les PIN A8,A9,A10, et A11 en input floating. Init_Structure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &Init_Structure); } /** * @brief La fonction pwmMotorInit() initialise le Timer2 à une fréquence de 25kHz (fc nominal) et initialise * les pwm des moteurs à un dutycycle à 0% de 255 * * @param Aucun * @retval Aucun */ void INIT_TIM2(void) { // On souhaite une résolution du PWM de 256 valeurs MOTOR1 TIM2 TIM2_TempsPWMsettings.TIM_Period = 255; TIM2_TempsPWMsettings.TIM_Prescaler = 0; TIM2_TempsPWMsettings.TIM_ClockDivision=0; TIM2_TempsPWMsettings.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM2_TempsPWMsettings); } /* * Initialisation du chanel */ void INIT_OCMotorPwm(void) { // Configuration du PWM sur le timer 2 TIM2_Configure.TIM_OCMode=TIM_OCMode_PWM2; TIM2_Configure.TIM_OutputState = TIM_OutputState_Enable; TIM2_Configure.TIM_OutputNState = TIM_OutputNState_Enable; TIM2_Configure.TIM_Pulse = 256; // Constante initialisé à 256, Pour un rapport cyclique nul TIM2_Configure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM2, &TIM2_Configure); TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable); TIM_OC2Init(TIM2, &TIM2_Configure); TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); // Enable Counter TIM_Cmd(TIM2, ENABLE); TIM_CtrlPWMOutputs(TIM2,ENABLE); } void IC_TIM1_CHANEL1(void) { TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE); } void IC_TIM1_CHANEL3(void) { TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE); } void IT_TIM1(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the TIM1 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /** * @brief La fonction cmdRightMotor() va réglé le moteur droit selon les paramétres d'éntrée. * * @param mode de fonctionnement du moteur, peut être égal aux constantes BRAKE, FORWARD, REVERSE définis dans moteur.h * @param consigne de vitesse du moteur, définis par un pwm entre 0 et 255. * @retval */ void cmdRightMotor(char mod, uint16_t pwm) { pwm = 256-pwm; switch (mod) { case BRAKE : GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); break; case FORWARD : GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); break; case REVERSE : GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_12); break; default : GPIO_ResetBits(GPIOB, 12); GPIO_ResetBits(GPIOB, 13); } TIM_SetCompare3(TIM2, pwm); } /** * @brief La fonction cmdLefttMotor() va réglé le moteur gauche selon les paramétres d'éntrée. * * @param mode de fonctionnement du moteur, peut être égal aux constantes BRAKE, FORWARD, REVERSE définis dans moteur.h * @param consigne de vitesse du moteur, définis par un pwm entre 0 et 255. * @retval */ void cmdLeftMotor(char mod, uint16_t pwm) { pwm = 256-pwm; switch (mod) { case BRAKE : GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case FORWARD : GPIO_SetBits(GPIOB, GPIO_Pin_15); GPIO_ResetBits(GPIOB, GPIO_Pin_14); break; case REVERSE : GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; default :GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); } TIM_SetCompare2(TIM2, pwm); } void majVitesseMotorG(uint16_t pwm) { pwm = 256-pwm; TIM_SetCompare2(TIM2, pwm); } void majVitesseMotorD(uint16_t pwm) { pwm = 256-pwm; TIM_SetCompare3(TIM2, pwm); } void regulationMoteur(char modRight, char modLeft, uint16_t lapsRight, uint16_t lapsLeft, uint16_t speedRight, uint16_t speedLeft) { /*Moteur Droit*/ switch (modRight) { case BRAKE : GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); break; case FORWARD : GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); break; case REVERSE : GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_12); break; default : GPIO_ResetBits(GPIOB, 12); GPIO_ResetBits(GPIOB, 13); } /* Moteur Gauche */ switch (modLeft) { case BRAKE : GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case FORWARD : GPIO_SetBits(GPIOB, GPIO_Pin_15); GPIO_ResetBits(GPIOB, GPIO_Pin_14); break; case REVERSE : GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; default : GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); } if((speedRight==0 && lapsRight>0) || (speedLeft==0 && lapsLeft>0)) { while(1); // Gestion erreur à coder } G_lapsLeft = lapsLeft; G_speedLeft = speedLeft; G_lapsRight = lapsRight; G_speedRight= speedRight; asservissement = 1; tourPositionD=0; tourPositionG=0; } /* * Incremente le nombre de passage devant les capteurs à chaque interuption de ceux ci. */ void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); tourD++; tourPositionD++; } if(TIM_GetITStatus(TIM1, TIM_IT_CC3) == SET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); tourG++; tourPositionG++; } }