Single-chip controlled electric bicycle drive system

Single chip microcomputer STM32L151CCU6
1206RGB (single)
#include // Electric vehicle double closed-loop program, using double closed-loop mode to control the motor for optimal speed performance and can limit the maximum current of the motor. This application uses two CCP components: CCP1 is used for PWM output to control motor voltage; CCP2 is used to trigger AD, timer TMR2, TMR1, INT interrupt, RB port level change interrupt, watchdog, and 6 general-purpose I/O ports. #define AND 0xe0 // Status acquisition bits 5, 6, 7 #define CURA 0x0a // Sum of current loop ratio and integral coefficient #define CURB 0x09 // Current loop proportional coefficient #define THL 0x6400 // Current loop maximum output #define FULLDUTY 0x0FF // High time when duty cycle is 1 #define SPEA 0x1d // Sum of speed loop ratio and integral coefficient #define SPEB 0x1c // Speed loop proportional coefficient #define GCURHILO 0x0330 // Maximum output of the speed loop #define GCURH 0x33 // Maximum given current #define GSPEH 0x67 // Maximum speed reference #define TSON 0x38 // Handle opening voltage is 1.1V, TSON*2 is the handle opening voltage after braking (2.2V) #define VOLON 0x4c // Low voltage protection reactivation voltage (3.0V or 33V) #define VOLOFF 0x49 // Low voltage protection shutdown voltage (2.86V or 31.5V) volatile unsigned char DELAYH, DELAYL, oldstate, speed, speedcount, tsh, count_ts, count_vol, gcur, currenth, voltage; // Register definition static bit sp1, spe, ts, volflag, spepid, lowpower, off, shutdown, curpid; // Flag definition static volatile unsigned char new[10] = {0xaf, 0xbe, 0xff, 0x7e, 0xcf, 0xff, 0xd7, 0x77, 0xff, 0xff}; // Status register table //------------ PIC16F877 initialization subroutine ------------ void INIT877() { PORTC = 0X0FF; // Turn off all MOSFETs TRISC = 0X02; // Set C port as output PIE1 = 0X00; // Initialize interrupt registers, disable all interrupts TRISA = 0XCF; // Set RA4, RA5 as output TRISB = 0XEF; // RB port high three bits as input, collect motor three-phase Hall signal PORTC = new[(PORTB & AND) >> 5]; // Collect first Hall signal, output corresponding signal, turn on two MOSFETs T2CON = 0X01; // TMR2 prescaler set to 4 CCPR1L = 0X0FF; // Initial PWM output full duty CCP1CON = 0X0FF; // CCP1 set to PWM mode CCP2CON = 0X0B; // CCP2 set to special mode to trigger AD ADCON0 = 0X81; // AD clock divided by 32, enable AD, select AN0 channel for handle voltage TMR2 = 0X00; // Initialize TMR2 register TMR1H = 0X00; // Initialize TMR1 register TMR1L = 0X00; T1CON = 0X00; // TMR1 prescaler set to 1 CCPR2H = 0X08; CCPR2L = 0X00; // Current sampling period set to TAD = 512μs PR2 = 0XC7; // PWM frequency set to 5kHz ADCON1 = 0X02; // AD results left-aligned OPTION = 0XFB; // INT rising edge trigger TMR2ON = 1; // Start PWM INTCON = 0XD8; // Enable global and peripheral interrupts, RBIE ADIE = 1; // Enable AD interrupt speedcount = 0x00; // Speed count register speed = 0x7f; // Speed holding register spe = 1; // Low speed flag sp1 = 1; // Low speed flag oldstate = 0x0ff; // Initial state settings, different from other states count_ts = 0x08; // Current sampling 8 times, collect 1 handle count_vol = 0x00; // Sample 256 handles, collect 1 battery voltage ts = 1; // Flag to collect handle value ADGO = 1; // Enable AD sampling TMR1ON = 1; // Start CCP2 parts } //------------ Delay subroutine --------------- #pragma interrupt_level 1 void DELAY1(char x) { DELAYH = x; // Delay parameter setting #asm DELAY2 MOVLW 0X06 MOVWF_DELAYL DELAY1 DECFSZ_DELAYL GOTO DELAY1 DECFSZ_DELAYH GOTO DELAY2 #endasm } //----------- Status collection subroutine ---------------------- void sample() { char state1, state2, state3, x; do { x = 1; state1 = (PORTB & AND); // Hall signal acquisition DELAY1(x); state2 = (PORTB & AND); } while (state1 - state2); // Continue collecting if three samples are different if (state1 != oldstate) // If the result is different from last time { oldstate = state1; // Set this state as the old state state1 = (oldstate >> 5); PORTC = new[state1]; // Output corresponding signal to trigger two MOSFETs if (sp1 == 1) { spe = 1; sp1 = 0; } else { spe = 0; sp1 = 0; speedcount <<= 1; state3 = (TMR1H >> 2); // Count speed speed = speedcount + state3; // Add 1 every 256μs } speedcount = 0; } } //-----------------AD sampling subroutine -------------------- void AD() { char x; ADIF = 0; // Clear AD interrupt flag if (ts == 1) { // If handle is sampled, sample handle value CHS0 = 1; // Select current sampling channel count_vol = count_vol + 1; // Battery sample count register spepid = 1; // Set speed closed-loop operation flag ts = 0; tsh = ADRESH; // Save handle value if (count_vol == 0) { // If battery sampling is done, select AN2 and collect battery voltage CHS0 = 0; CHS1 = 1; volflag = 1; x = 1; DELAY1(x); ADGO = 1; } } else if (volflag == 1) { // Process battery sampling CHS1 = 0; CHS0 = 1; volflag = 0; voltage = ADRESH; lowpower = 1; } else { // Other, it's a current sampling interrupt speedcount = speedcount + 1; // Increment speedcount for speed measurement if (speedcount > 0x3d) sp1 = 1; // If speed is lower than 1000000μs/(512μs*3eh*3), consider it low speed currenth = ADRESH; curpid = 1; count_ts = count_ts - 1; if (count_ts == 0) { // If handle time is up, switch to handle sampling channel CHS0 = 0; count_ts = 0x08; ts = 1; x = 1; DELAY1(x); ADGO = 1; } } } //-------------Brake processing subroutine ------------------ void BREAKON() { char x; off = 0; // Clear off flag, if interference, don't reset shutdown = 0; if (RB0 == 1) { // If brake signal is true, stop output voltage ADIE = 0; // Disable AD interrupt INTE = 0; // Disable brake interrupt CCPR1L = FULLDUTY; // Output voltage 0 TMR1ON = 0; // Disable CCP2, no longer trigger AD for (; ADGO == 1;) continue; // Wait for sampling to finish ADIF = 0; // Clear ADIF bit CHS0 = 0; // Select channel 0 for handle sampling CHS1 = 0; x = 1; DELAY1(x); do { ADGO = 1; for (; ADIF == 0;) continue; ADIF = 0; CCPR1L = FULLDUTY; asm("CLRWDT"); tsh = (ADRESH >> 1); } while (tsh > TSON || RB0 == 1); // Execute while handle value > 2.2V or brake continues off = 1; // Reset flag } } //---------Underprotected subroutine ------------------- void POWER() { char x; lowpower = 0; voltage >>= 1; // Convert voltage to 7 bits for single-byte operation if (voltage < voloff) { ADIE = 0; INTE = 0; TMR1ON = 0; CCPR1L = FULLDUTY; for (; ADGO == 1;) continue; ADIF = 0; CHS0 = 0; CHS1 = 1; x = 1; DELAY1(x); do { ADGO = 1; for (; ADIF == 0;) continue; ADIF = 0; voltage = (ADRESH >> 1); CCPR1L = FULLDUTY; asm("CLRWDT"); } while (voltage < volon); off = 1; // Reset flag } } //------------ Current loop operation subroutine ----------------- void CURPI() { static int curep = 0x00, curek = 0x00, curuk = 0x00; union data { int pwm; char a[2]; } b; // Define current loop arithmetic register curpid = 0; // Clear current operation flag curep = curek * CURB; // Calculate product of last deviation and scale factor if (currenth < 2) currenth = 2; // If current is zero, consider small current to help speed drop currenth >>= 1; curek = gcur - currenth; // Calculate current deviation curuk = curuk + curek * CURA - curep; // PI operation for current loop if (curuk < 0x00) { // If output is less than zero, treat as zero curuk = 0; CCPR1L = FULLDUTY; CCP1X = 0; CCP1Y = 0; } else if (curuk - THL >= 0) { // If output exceeds limit, output max voltage curuk = THL; CCPR1L = 0; CCP1X = 0; CCP1Y = 0; } else { // Otherwise, output proportionally b.pwm = THL - curuk; b.pwm <<= 1; CCPR1L = b.a[1]; // High nibble of PWM register if (b.pwm & 0x80) CCP1X = 1; else CCP1X = 0; if (b.pwm & 0x40) CCP1Y = 1; else CCP1Y = 0; } } //---------------Speed loop operation subroutine ----------------------- void SPEPI() { static int speep = 0x00, speek = 0x00, speuk = 0x00; int tsh1, speed1; // Define speed register spepid = 0; // Clear speed calculation flag if (spe == 1) speed1 = 0x00; // If speed is too low, consider it zero else speed1 = 0x7f - speed; // Calculate actual speed if (speed1 < 0) speed1 = 0; speep = speek * SPEB; tsh1 = tsh - 0x38; // Get handle value for calculation speek = tsh1 - speed1; if (tsh1 < 0) { speuk = 0; gcur = 0; } else { if (tsh1 >= GSPEH) // Limit maximum speed tsh1 = GSPEH; speuk = speuk + speek * SPEA - speep; // Calculate speed loop output if (speuk <= 0X00) { speuk = 0x00; gcur = 0x00; // Process speed loop output } else if (speuk > GCURHILO) { // Limit speed loop output, i.e., limit maximum current around 12A speuk = GCURHILO; gcur = GCURH; } else { gcur = (speuk >> 4) & 0x0ff; // Output in speed state } } } //----------- main program ------------------------- void main() { for (;;) { INIT877(); // After MCU reset, initialize first off = 0; // Clear reset flag for (; off == 0;) { // If reset flag is zero, execute the following program, otherwise reset if (curpid == 1) CURPI(); // Current PI operation else if (spepid == 1) SPEPI(); // Speed PI operation else if (lowpower == 1) POWER(); else if (shutdown == 1) BREAKON(); asm("CLRWDT"); } } } //---------Interrupt service subroutine --------------------- #pragma interrupt_level 1 void interrupt INTS(void) { if (RBIF == 1) { RBIF = 0; sample(); } else if (ADIF == 1) AD(); else if (INTF == 1) { shutdown = 1; INTF = 0; // Brake interrupt, set brake flag } }

Traffic Signal Pole

we offer a wide selection of traffic Steel Pole structures in standard and custom designs.

Yixing Futao Metal Structural Unit Co. Ltd. is com manded of Jiangsu Futao Group.

It is located in the beach of scenic and rich Taihu Yixing with good transport service.
The company is well equipped with advanced manufacturing facilities.
We own a large-sized numerical control hydraulic pressure folding machine with once folding length 16,000mm and the thickness 2-25mm.
We also equipped with a series of numerical control conveyor systems of flattening, cutting, folding and auto-welding, we could manufacture all kinds of steel poles and steel towers.
Our main products: high & medium mast lighting, road lighting, power poles, sight lamps, courtyard lamps, lawn lamps, traffic signal poles, monitor poles, microwave communication poles, etc. Our manufacturing process has been ISO9001 certified and we were honored with the title of the AAA grade certificate of goodwill"
Presently 95% of our products are far exported to Europe, America, Middle East, and Southeast Asia, and have enjoyed great reputation from our customers,
So we know the demand of different countries and different customers.
We are greatly honored to invite you to visit our factory and cheerfully look forward to cooperating with you.

Traffic Signal Pole,Traffic Light Pole,Led Traffic Signals,Solar Traffic Signal Pole,Traffic Steel Pole

JIANGSU XINJINLEI STEEL INDUSTRY CO.,LTD , https://www.chinasteelpole.com

Posted on