1, Realize function
Key K_Start_Stop stops and starts the motor, and the default power on stop
Key K_Syntropy_Reverse switches the direction of two motors
Key K_ UP_ Press the speed key to accelerate
Key K_ Down_ Press the speed deceleration button to decelerate
This program is mainly based on STM32F103C8T6 to drive some actions of MAX1508 motor. The action change is to use four keys to control the start and stop of two motors, reverse in the same direction, acceleration and deceleration.
2, Hardware list
- MAX1508 dual H-axle motor drive module
- STM32F103C8T6/STC89C52RC
- SWD or JLINK emulator (it's OK to burn directly with CH340 serial port module, but pay attention to configuring BOOT)
- DC motor (2)
- 4-bit key module
- The power supply is about 8V (two 18650 are used here)
3, Data list
Program code
Documentation
4, Introduction to MAX1508 dual H-axle motor drive module
- Dual circuit 1.5A*2, peak current can reach 2.5A, built-in overheating protection circuit, do not be afraid of motor blocking and burning, and automatically recover after temperature drop.
2. Truth table of DC motor drive logic:
Product parameters:
1. Dual H-bridge motor drive, which can drive two DC motors or a 4-wire two-phase stepping motor at the same time;
2. Module power supply voltage 2V-10V;
3. Input voltage of signal terminal is 1.8-7V;
4. Single channel working current is 1.5A, peak current can reach 2.5A, and low standby current (less than 0.1uA);
5. Built in anti common conduction circuit, the motor will not misoperate when the input end is suspended;
6. Built in overheating protection circuit (TSD) with hysteresis effect, so there is no need to worry about motor locked rotor;
7. Product size: 24.7215mm (length, width and height), ultra small volume, suitable for assembly and vehicle mounted;
8. Diameter of mounting hole: 2 mm.
9. Weight: 5g
matters needing attention:
1. The reverse connection of the positive pole and negative pole of the power supply will certainly cause circuit damage.
2. The chip will be thermally protected when the output is short circuited to ground or the output is short circuited, and the motor is locked, but the chip will also be burned when the voltage is close to or exceeds 10V and the peak current greatly exceeds 2.5A.
5, Wiring
6, Code description
Take code 32 as an example,
- IN1-IN4 pin configuration
/****Initialize PWM output pin****/ void GENERAL_TIM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // Output comparison channel 1 GPIO initialization RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure); // Output comparison channel 2 GPIO initialization RCC_APB2PeriphClockCmd(GENERAL_TIM_CH2_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH2_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure); // Output comparison channel 3 GPIO initialization RCC_APB2PeriphClockCmd(GENERAL_TIM_CH3_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH3_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH3_PORT, &GPIO_InitStructure); // Output comparison channel 4 GPIO initialization RCC_APB2PeriphClockCmd(GENERAL_TIM_CH4_GPIO_CLK, ENABLE); GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH4_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure); }
- Timer and hardware PWM configuration
/****Initialize PWM output pin****/ /* ---------------- PWM Calculation of signal period and duty cycle--------------- */ // ARR: value of automatic reload register // CLK_cnt: the clock of the counter, equal to Fck_int / (psc+1) = 72M/(psc+1) // Period T of PWM signal = arr * (1 / clk_cnt) = arr * (PSC + 1) / 72m // Duty cycle P=CCR/(ARR+1) void GENERAL_TIM_Mode_Config(void) { // Turn on the timer clock, i.e. the internal clock CK_INT=72M GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK,ENABLE); /*--------------------Time base structure initialization-------------------------*/ // The configuration cycle is 100K here TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Automatically reload the value of the register, accumulating Tim_ An update or interrupt is generated after period + 1 frequency TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period; // Clock driving CNT counter = Fck_int/(psc+1) TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler; // Clock frequency division factor, which is required when configuring dead time TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // Counter counting mode, set to count up TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // Repeat the value of the counter. Don't worry if you don't use it TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // Initialization timer TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure); /*--------------------Output comparison structure initialization-------------------*/ // Duty cycle configuration uint16_t CCR1_Val = 0; uint16_t CCR2_Val = 0; uint16_t CCR3_Val = 0; uint16_t CCR4_Val = 0; TIM_OCInitTypeDef TIM_OCInitStructure; // Configured as PWM mode 1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // Output enable TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // Output channel level polarity configuration TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // Output comparison channel 1 TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // Output comparison channel 2 TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // Output comparison channel 3 TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // Output comparison channel 4 TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure); TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable); // Enable counter TIM_Cmd(GENERAL_TIM, ENABLE); } void GENERAL_TIM_Init(void) { GENERAL_TIM_GPIO_Config(); GENERAL_TIM_Mode_Config(); }
- Key pin configuration
void Key_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; /*Turn on the clock of the key port*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //Select the pin of the key GPIO_InitStructure.GPIO_Pin = K_Start_Stop; // Set the pin of the key as the pull-up input GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); //Select the pin of the key GPIO_InitStructure.GPIO_Pin = K_Syntropy_Reverse; GPIO_Init(GPIOB, &GPIO_InitStructure); //Select the pin of the key GPIO_InitStructure.GPIO_Pin = K_UP_Speed; GPIO_Init(GPIOB, &GPIO_InitStructure); //Select the pin of the key GPIO_InitStructure.GPIO_Pin = K_Down_Speed; GPIO_Init(GPIOB, &GPIO_InitStructure); }
- Key scan function
void Scan_key(void) { uint16_t Key_Dat=0; Key_Dat=GPIO_ReadInputData(GPIOB); Key_Dat=Key_Dat&0x00F0; Key_Dat=Key_Dat^0x00F0; Key_Dat_Buf=Key_Dat; if(Key_Dat==K_Start_Stop) { DelayMs(10); if(Key_Dat==K_Start_Stop) { Flag_Start_Stop=~Flag_Start_Stop; } while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4)); } else if(Key_Dat==K_Syntropy_Reverse) { DelayMs(10); if(Key_Dat==K_Syntropy_Reverse) { Flag_Syntropy_Reverse=~Flag_Syntropy_Reverse; } while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5)); } else if(Key_Dat==K_UP_Speed) { DelayMs(10); if(Key_Dat==K_UP_Speed) { Speed=Speed+5; if(Speed>=999) { Speed=999; } } while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)); } else if(Key_Dat==K_Down_Speed) { DelayMs(10); if(Key_Dat==K_Down_Speed) { Speed=Speed-5; if(Speed<=10) { Speed=10; } } while(!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)); } }
- Motor drive function
/***Rotation in the same direction***/ void turn_Syntropy() { TIM_SetCompare1(GENERAL_TIM, Speed); //IN_1 TIM_SetCompare2(GENERAL_TIM, 0); //IN_2 TIM_SetCompare3(GENERAL_TIM, Speed); //IN_3 TIM_SetCompare4(GENERAL_TIM, 0); //IN_4 } /***Reverse rotation***/ void turn_Reverse() { TIM_SetCompare1(GENERAL_TIM, 0); //IN_1 TIM_SetCompare2(GENERAL_TIM, Speed); //IN_2 TIM_SetCompare3(GENERAL_TIM, 0); //IN_3 TIM_SetCompare4(GENERAL_TIM, Speed); //IN_4 } /***Stop turning***/ void turn_Stop() { TIM_SetCompare1(GENERAL_TIM, 0);//IN_1 TIM_SetCompare2(GENERAL_TIM, 0);//IN_2 TIM_SetCompare3(GENERAL_TIM, 0);//IN_3 TIM_SetCompare4(GENERAL_TIM, 0);//IN_4 }
- Main function
/** * @brief Main function * @param nothing * @retval nothing */ int main(void) { /* timer initiated */ GENERAL_TIM_Init(); DelayInit(); Key_GPIO_Init(); turn_Stop(); // turn_Syntropy(); while(1) { Scan_key(); if(Flag_Start_Stop) { if(!Flag_Syntropy_Reverse) { turn_Syntropy(); } else { turn_Reverse(); } } else { turn_Stop(); } } }
7, Data acquisition
Add group private chat. Group owners can get it for free. Group number: 1041406448.