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 limit the maximum current of the motor. This application uses two CCP components: CCP1 is used for PWM output to control the motor voltage, while CCP2 triggers 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 ratio 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 re-start 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, spep, 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; // Interrupt register initialization, 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; // TMR2 register initialization TMR1H = 0X00; // TMR1 register initialization 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, enable RB port interrupt 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 setting, 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; // AD sampling enabled 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 differ if (state1 != oldstate) // If sampling result is different from last time { oldstate = state1; // Update old state state1 = (oldstate >> 5); PORTC = new[state1]; // Output corresponding signal, 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 spep = 1; // Set speed closed loop operation flag ts = 0; tsh = ADRESH; // Save handle value if (count_vol == 0) { // If battery sampling time is up, select AN2 channel and collect battery voltage CHS0 = 0; CHS1 = 1; volflag = 1; x = 1; DELAY1(x); ADGO = 1; } } else if (volflag == 1) { // Battery sampled and processed accordingly CHS1 = 0; CHS0 = 1; volflag = 0; voltage = ADRESH; lowpower = 1; } else { // Other, this is 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 as 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, not reset if interference 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 end 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 this deviation curuk = curuk + curek * CURA - curep; // PI operation result 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 corresponding high time 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; // Speed register definition spep = 0; // Clear speed calculation flag if (spe == 1) speed1 = 0x00; // If speed is too low, consider it as zero else speed1 = 0x7f - speed; // Otherwise 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; } else if (speuk > GCURHILO) { // Limit speed loop output (approx. 12A) speuk = GCURHILO; gcur = GCURH; } else { gcur = (speuk >> 4) & 0x0ff; } } } //----------- 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 (spep == 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; } }

Lamp Pole

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.

Lighting Pole,Steel Lamp Pole,Street Light Poles,Garden Lamp Post

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

Posted on