//wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww/** I N C L U D E S **********************************************************/ #include #include #include #include #include #include #include #include"LCD\\xlcd.h" #define Light_ON LATCbits.LATC6 // output Light ON #define Brake_ON LATCbits.LATC5 // output Brake ON #define LCD_ON LATCbits.LATC4 // output LCD ON #define LED LATBbits.LATB3 // output for LED #define T1 LATDbits.LATD7 // output -T1 high side left MOSFET #define T2 LATDbits.LATD6 // output -T2 high side right MOSFET #define T3 LATDbits.LATD5 // output -T3 low side left MOSFET #define T4 LATDbits.LATD4 // output -T4 low side right MOSFET #define B7 PORTBbits.RB7 // input UP #define B6 PORTBbits.RB6 // input DOWN #define B5 PORTBbits.RB5 // input LEFT #define B4 PORTBbits.RB4 // input RIGHT #define Brake PORTBbits.RB0 // input Brake #pragma config OSC = HS //HS Speed (IRCIO7 interner Takt) Internal RC with OS as RA7 and OSC2 as divide by 4 clock out #pragma config FCMENB = OFF //Fail-safe clock monitor disab #pragma config IESOB = OFF //Internal OSC switch over bit #pragma config PWRT = ON //Power up timer ON #pragma config BOR = BOACTIVE //enabled whenever part is active, SBOREN disabled #pragma config BORV = 42 //Reset if Vcc smaller 4,2V; 2,7V; 2,0V #pragma config WDT = ON //Watchdog ON #pragma config WDTPS = 16384 //after 65,5 s reset #pragma config PBADEN = ON //Pins are configured as analog input channels on Reset #pragma config LPT1OSC = OFF //bei 0; Timer1 configured for higher power operation #pragma config MCLRE = ON //Reset at MCLR ON #pragma config LVP = OFF //LVP OFF //12.04.2015 TRISx bestimmt die Richtung. PORTx zeigt Eingänge, LATx setzt Ausgänge //Always read inputs from PORTx and write outputs to LATx. If you need to read what you set an output to, read LATx." //-------------------------------------------------------------------------------------------------------------------- void InterruptHandlerHigh(void); void InterruptHandlerLow(void); void DelayFor18TCY( void ) { int i; for (i=0; i<36; i++) { Nop(); } } //--------------------------------------------------------- void DelayPORXLCD( void ) { Delay1KTCYx(75); //Delay of 15ms (was 200 bei 4 MHz) //75 return; } //--------------------------------------------------------- void DelayXLCD( void ) { Delay1KTCYx(25); //Delay of 5ms (was 100 bei 4 MHz) //25 return; } //--------------------------------------------------------- int getADC(int channel) { SetChanADC(channel); ConvertADC(); while( BusyADC() ); return ReadADC(); } volatile unsigned char START = 0; // part in ISR 0 -> 255 volatile unsigned char LastKnownPORTB; //part in ISR volatile unsigned char PORTB7 =0; //part in ISR volatile unsigned char PORTB6 =0; //part in ISR volatile unsigned char PORTB5 =0; //part in ISR volatile unsigned char PORTB4 =0; //part in ISR //--------------------------------------------------------- volatile unsigned int AN0; // not part in ISR 0 -> 65535 throttle volatile unsigned char AN0_offset = 200; // not part in ISR 0 -> 255 Offset value (200) throttle plus safety margin // Throttle max. 858 @ 5.00 V (858-200= 658 throttle resolution) // max PWM 1024 / 658 = 1,556 / Check 1,55* 658 = 1020 volatile unsigned float AN0_DC =1.55; // Kommazahl Umrechnung ANO zu Duty cycle volatile unsigned short ERG = 0; // part in ISR 0 -> 65535 calculated duty cycle for PWM //--------------------------------------------------------- volatile unsigned int AN1; // not part in ISR 0 -> 65535 Light dependend Resistor //--------------------------------------------------------- volatile unsigned int AN2; // part in ISR 0 -> 65535 Motor Current volatile unsigned int AN2_raising; // part in ISR 0 -> 65535 Motor Current raising edge volatile unsigned int AN2_falling; // part in ISR 0 -> 65535 Motor Current falling edge volatile unsigned int MOTOR_CURRENT; // not part in ISR 0 -> 65535 Motor Current //--------------------------------------------------------- volatile unsigned int AN4; // not part in ISR 0 -> 65535 BATTERIE volatile unsigned int BAT_WERT; // not part in ISR 0 -> 65535 BATTERIE //--------------------------------------------------------- volatile unsigned int DC_max = 1023; // part in ISR 0 -> 65535 volatile unsigned int DC_alt = 0; // part in ISR 0 -> 65535 volatile unsigned int DC_act = 0; // part in ISR 0 -> 65535 volatile unsigned char DC_speed = 20; // part in ISR 0 -> 255 stepwide for duty cycle volatile unsigned int SW_Z = 0; // part in ISR 0 -> 65535 counter intervall volatile unsigned int SW_Intervall = 290; // part in ISR 0 -> 65535 Intervall 1/5000* Wert = Intervall volatile unsigned char Gas = 0; // part in ISR 0 -> 255 volatile unsigned int RPM_count = 0; // part in ISR 0 -> 65535 volatile unsigned int RPM = 0; // part in ISR 0 -> 65535 unsigned int Speed = 0; // not part in ISR 0 -> 65535 volatile unsigned char Go = 0; // part in ISR 0 -> 255 volatile unsigned int Display_refresh = 0; // part in ISR 0 -> 65535 volatile unsigned char Display_update = 0; // part in ISR volatile unsigned int break_blinking = 0; // part in ISR 0 -> 65535 //--------------------------------------------------------- volatile unsigned char B4_count = 0; // part in ISR 0 -> 255 volatile unsigned int B4_counter = 0; // part in ISR 0 -> 65535 volatile unsigned char B5_count = 0; // part in ISR 0 -> 255 volatile unsigned int B5_counter = 0; // part in ISR 0 -> 65535 volatile unsigned char B6_count = 0; // part in ISR 0 -> 255 volatile unsigned int B6_counter = 0; // part in ISR 0 -> 65535 volatile unsigned char B7_count = 0; // part in ISR 0 -> 255 volatile unsigned int B7_counter = 0; // part in ISR 0 -> 65535 volatile unsigned char display_page = 0; // not part in ISR 0 -> 255 // 0 = main page volatile unsigned char driving_direction = 0; // not part in ISR 0 -> 255 // 0 = forward 1 = backward //--------------------------------------------------------- volatile unsigned long cm = 0; // not part in ISR 0 bis 4294967295 volatile unsigned char distance = 0; // part in ISR unsigned long tmp; char LCDdata1[40]; // not part in ISR char LCDdata2[40]; // not part in ISR char LCDdata3[40]; // not part in ISR char Buffer[20]; void main(void) { LATDbits.LATD7=0; // T1 OFF LATDbits.LATD6=0; // T2 OFF LATDbits.LATD5=0; // T3 OFF LATDbits.LATD4=0; // T4 OFF TRISDbits.TRISD7 = 0; // set PORTD7 as output port T1 TRISDbits.TRISD6 = 0; // set PORTD6 as output port T2 TRISDbits.TRISD5 = 0; // set PORTD5 as output port T3 TRISDbits.TRISD4 = 0; // set PORTD4 as output port T4 LATCbits.LATC6=0; // set to LOW Light ON LATCbits.LATC5=0; // set to LOW brake ON LATCbits.LATC4=0; // set to LOW LCD on LATBbits.LATB3=0; // set to LOW LED TRISBbits.TRISB7 = 1; // set PORTB7 as input port TRISBbits.TRISB6 = 1; // set PORTB6 as input port TRISBbits.TRISB5 = 1; // set PORTB5 as input port TRISBbits.TRISB4 = 1; // set PORTB4 as input port TRISBbits.TRISB0 = 1; // set PORTB0 as input port Brake signal TRISCbits.TRISC6 = 0; // set PORTC6 as output port Light_ON TRISCbits.TRISC5 = 0; // set PORTC5 as output port Brake_ON TRISCbits.TRISC4 = 0; // set PORTC4 as output port LCD_ON TRISBbits.TRISB3 = 0; // set PORTB3 as output port LED TRISCbits.TRISC2 = 0; // set PORTC2 as output port PWM TRISAbits.TRISA0 = 1; // set PORTA0 as input port Throttle TRISAbits.TRISA1 = 1; // set PORTA2 as input port DR TRISAbits.TRISA2 = 1; // set PORTA2 as input port Current TRISAbits.TRISA5 = 1; // set PORTA0 as input port Battery OSCCONbits.SCS1 = 0; // SCS<1:0>: System Clock Select bits 00 for PLL OSCCONbits.SCS0 = 0; // 1x = Internal oscillator block // 01 = Timer1 oscillator // 00 = Primary oscillator OSCTUNEbits.PLLEN = 0; // PLLEN: Frequency Multiplier PLL for INTOSC Enable bit(1) // 1 = PLL enabled for INTOSC (4 MHz and 8 MHz only) // 0 = PLL disabled //--------------------------------------------------------------------------------------------------------------// //Timer 0 high priority interrupt each 1,67 s = 0,6 Hz with writing timer new ajusted to 1 Hz T0CONbits.T0PS2 = 1; // T0PS<2:0>: Timer0 Prescaler Select bits T0CONbits.T0PS1 = 1; // 111 = 1:256 Prescale value T0CONbits.T0PS0 = 0; // 110 = 1:128 Prescale value // 101 = 1:64 Prescale value // 100 = 1:32 Prescale value // 011 = 1:16 Prescale value // 010 = 1:8 Prescale value // 001 = 1:4 Prescale value // 000 = 1:2 Prescale value T0CONbits.T0PS3 = 0; // PSA: Timer0 Prescaler Assignment bit .PSA laut Datenblatt geht nicht!! // 1 = TImer0 prescaler is not assigned. Timer0 clock input bypasses prescaler. if 1 = prescaler not working and 1:2 ratio // 0 = Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output. T0CONbits.T0SE = 1; // T0SE: Timer0 Source Edge Select bit // 1 = Increment on high-to-low transition on T0CKI pin // 0 = Increment on low-to-high transition on T0CKI pin T0CONbits.T0CS = 0; // T0CS: Timer0 Clock Source Select bit // 1 = Transition on T0CKI pin input edge // 0 = Internal clock (FOSC/4) T0CONbits.T08BIT = 0; // 0= 16bit Timer 1= 8bit Timer T0CONbits.TMR0ON = 1; // 1= enable Timer 0 INTCON2bits.TMR0IP = 1; //TMR0 Overflow Interrupt Priority bit //1 = High priority //0 = Low priority INTCONbits.TMR0IE = 1; //TMR0 Overflow Interrupt Enable bit //1 = Enables the TMR0 overflow interrupt //--------------------------------------------------------------------------------------------------------------// //Timer1 @ low priority interrupt xxx Hz T1CONbits.RD16 = 1; //1 = Enables register read/write of Timer1 in one 16-bit operation //0 = Enables register read/write of Timer1 in two 8-bit operations T1CONbits.T1RUN = 0; //1 = Device clock is derived from Timer1 oscillator //0 = Device clock is derived from another source T1CONbits.T1CKPS1 = 1; //Prescale 1=8 1=4 0=1 T1CONbits.T1CKPS0 = 1; //Prescale 1=8 0=4 0=1 T1CONbits.T1OSCEN = 0; //1 = Timer1 oscillator is enabled //0 = Timer1 oscillator is shut off //T1CONbits.T1SYNC = 1; //Timer1 External Clock Input Synchronization Select bit //When TMR1CS = 1: //1 = Do not synchronize external clock input //0 = Synchronize external clock input //When TMR1CS = 0: //This bit is ignored. Timer1 uses the internal clock when TMR1CS = 0 T1CONbits.TMR1CS = 0; //Timer1 Clock Source Select bit //1 = External clock from pin RC0/T1OSO/T13CKI (on the rising edge) //0 = Internal clock (FOSC/4) T1CONbits.TMR1ON = 1; //Timer1 On bit //1 = Enables Timer1 //0 = Stops Timer1 //-----------------------------------------------------------------------------------------------------------------// PIE1bits.TMR1IE = 1; //TMR1 Overflow Interrupt Enable bit //1 = Enables the TMR1 overflow interrupt PIE1bits.TMR2IE = 1; //1 = Enables the TMR2 to PR2 match interrupt //0 = Disables the TMR2 to PR2 match interrupt IPR1bits.TMR1IP = 1; //TMR1 Overflow Interrupt Priority bit //1 = High priority //0 = Low priority IPR1bits.TMR2IP = 1; //TMR2 Overflow Interrupt Priority bit //1 = High priority //0 = Low priority //Timer2 Einstellungen //-----------------------------------------------------------------------------------------------------------------// T2CONbits.T2OUTPS3 = 0; //00 = Prescaler is 1 T2CONbits.T2OUTPS2 = 0; //00 = Prescaler is 1 T2CONbits.T2OUTPS1 = 0; //00 = Prescaler is 1 T2CONbits.T2OUTPS0 = 0; //00 = Prescaler is 1 T2CONbits.TMR2ON = 1; //1= Timer2 is on T2CONbits.T2CKPS1 = 0; //01 = Prescaler is 4 T2CONbits.T2CKPS0 = 1; //01 = Prescaler is 4 //-----------------------------------------------------------------------------------------------------------------// RCONbits.IPEN = 1; //IPEN: Interrupt Priority Enable bit //1 = Enable priority levels on interrupts //0 = Disable priority levels on interrupts INTCONbits.GIEH = 1; //When IPEN = 1: //1 = Enables all high-priority interrupts //0 = Disables all high-priority interrupts INTCONbits.GIEL = 0; //When IPEN = 1: //1 = Enables all low-priority peripheral interrupts //0 = Disables all low-priority peripheral interrupts INTCONbits.INT0IE = 1; //INT0 External Interrupt Enable bit //1 = Enables the INT0 external interrupt //0 = Disables the INT0 external interrupt INTCONbits.RBIE = 1; //RB Port 4 to 7 Change Interrupt Enable bit //1 = Enables the RB port change interrupt //0 = Disables the RB port change interrupt //-----------------------------------------------------------------------------------------------------------------// //PWM Settings PR2 = 249; CCP1CONbits.CCP1M3 = 1; //11xx = PWM mode CCP1CONbits.CCP1M2 = 1; //11xx = PWM mode SetDCPWM1(DC_act); //-----------------------------------------------------------------------------------------------------------------// //ADC Einstellungen //Configure analog pins, voltage reference and digital I/O (ADCON1)// ADCON1bits.PCFG3 = 1; //1110 (AN10) D D D D D D A A A A A (AN0) ADCON1bits.PCFG2 = 0; //1110 (AN10) D D D D D D A A A A A (AN0) ADCON1bits.PCFG1 = 1; //1110 (AN10) D D D D D D A A A A A (AN0) ADCON1bits.PCFG0 = 0; //1110 (AN10) D D D D D D A A A A A (AN0) ADCON1bits.VCFG1 = 0; //0 = AVSS (AN2) Voltage Reference Configuration bit (VREF- source) //1 = VREF- (AN2) ADCON1bits.VCFG0 = 1; //0 = AVDD (AN3) Voltage Reference Configuration bit (VREF+ source) //1 = VREF+ (AN3) 5,00 V //Select A/D acquisition time (ADCON2) // ADCON2bits.ACQT2 = 1; //111 = 20 TAD ADCON2bits.ACQT1 = 1; //111 = 20 TAD ADCON2bits.ACQT0 = 1; //111 = 20 TAD //Select A/D conversion clock (ADCON2)// ADCON2bits.ADCS2 = 1; //110 = FOSC/64 ADCON2bits.ADCS1 = 1; //110 = FOSC/64 ADCON2bits.ADCS0 = 0; //110 = FOSC/64 ADCON2bits.ADFM = 1; //1 = Right justified //Turn on A/D module (ADCON0)// ADCON0bits.ADON = 1; //1 = A/D Converter module is enabled //Turns on AD module //-----------------------------------------------------------------------------------------------------------------// INTCON2bits.RBPU = 1; //PORTB Pull-up Enable bit //1 = All PORTB pull-ups are disabled //0 = PORTB pull-ups are enabled by individual port latch values INTCON2bits.INTEDG0 = 1; //External Interrupt 0 Edge Select bit //1 = Interrupt on rising edge //0 = Interrupt on falling edge INTCON2bits.INTEDG1 = 0; //External Interrupt 1 Edge Select bit Magnet in front of the sensor = 0V //1 = Interrupt on rising edge //0 = Interrupt on falling edge //INTCON2bits.INTEDG2 = 1; //External Interrupt 2 Edge Select bit //1 = Interrupt on rising edge //0 = Interrupt on falling edge INTCON2bits.RBIP = 1; //RB Port Change Interrupt Priority bit //1 = High priority //0 = Low priority //CONFIG4Lbits.DEBUG =1; //Background Debugger Enable bit //1 = Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins //0 = Background debugger enabled, RB6 and RB7 are dedicated to In-Circuit Debug //-----------------------------------------------------------------------------------------------------------------// INTCON3bits.INT2IP = 1; //INT2 External Interrupt Priority bit //1 = High priority //0 = Low priority INTCON3bits.INT1IP = 1; //INT1 External Interrupt Priority bit //1 = High priority //0 = Low priority /* INT0 it´s always a high-priority interrupt source*/ INTCON3bits.INT2IE = 1; //INT2 External Interrupt Enable bit //1 = Enables the INT2 external interrupt //0 = Disables the INT2 external interrupt INTCON3bits.INT1IE = 1; //INT1 External Interrupt Enable bit //1 = Enables the INT1 external interrupt //0 = Disables the INT1 external interrupt //-----------------------------------------------------------------------------------------------------------------// //-----------------------------------------------------------------------------------------------------------------// LCD_ON = 1; Delay10KTCYx(100); // 0,2 s delay very important and needed OpenXLCD(FOUR_BIT & LINES_5X7 ); while( BusyXLCD() ) { } SetDDRamAddr((unsigned char) 0); // 1. row in display putrsXLCD(( char*)"Willkommen NIC"); SetDDRamAddr((unsigned char) 40); // 2. row in display putrsXLCD(( char*)"E-Kart Version 1"); Delay10KTCYx(250); // 0,5 s delay Delay10KTCYx(250); // 0,5 s delay Delay10KTCYx(250); // 0,5 s delay Delay10KTCYx(250); // 0,5 s delay START= 1; while (1) { ClrWdt(); //--------------------------------------------------------------------------------------------------------// if(driving_direction == 1 && Speed < 40 && START ==1 ) { // backwards active/change only, if speed is below 4 km/h Gas = 0; // reset gas one time T1=0; T4=0; Delay10KTCYx(50); // 0,1 s delay T2=1; T3=1; driving_direction =3; // to run one time only thru this instruction } if(driving_direction == 0 && Speed < 40 && START ==1) { // forward active/change only, if speed is below 4 km/h Gas = 0; // reset gas one time T3=0; T2=0; Delay10KTCYx(50); // 0,1 s delay T1=1; T4=1; driving_direction =3; // to run one time only thru this instruction } //--------------------------------------------------------------------------------------------------------// AN0 = getADC(ADC_CH0); //Throttle if(AN0 > AN0_offset) { // (180 > 200) Throttle pressed ERG = AN0_DC * (AN0 - AN0_offset); // Throttle pressed } else { ERG = 0; // Throttle not pressed } //--------------------------------------------------------------------------------------------------------// AN1 = getADC(ADC_CH1); // LDR if (AN1<500) { // If darkness, then turn ON the light Light_ON=1; // use some hysteresis } else if (AN1>700) { Light_ON=0; } //--------------------------------------------------------------------------------------------------------// AN4 = getADC(ADC_CH4); // here max. 140µs // BAT_WERT = (float) AN4 * 0.004883 * 6.2457 * 10 ; // Festkommaarithmetik // 0.004883 * 6.2457 * 10 = 0,304977531 ~ 312 / 1024 BAT_WERT = ((unsigned long)AN4 * 312) >> 10 ; //--------------------------------------------------------------------------------------------------------// if(T1 && T4) { // driving forward / motor current calculation from ADC in ISR AN2 = (int) 512 -((AN2_falling + AN2_raising)/ 2) ; // forward mean value } else { AN2 = (int) 1023-((AN2_falling + AN2_raising)/ 2); // backward mean value } // MOTOR_CURRENT = (float) AN2 * 0.148 *10 ; // 0,071 bei 68 Ohm // Festkommaarithmetik // 0.148 *10 = 1,48 ~ 189 / 128 MOTOR_CURRENT = ((unsigned int)AN2 * 128)>>7 ; //--------------------------------------------------------------------------------------------------------// if(RPM ==0) { // Speed calculation Speed = 0; } else { // Speed = (float) 0.82 /((RPM *0.2)/1000)*36 ; // 36 insted of 3.6 m/s x 10 // Festkommaarithmetik // 0,82 * 36 / (RPM * 0,2 / 1000) = 0,82 * 36 * 1000 * 5 / RPM = 147600 / RPM Speed = 147600/RPM; } //--------------------------------------------------------------------------------------------------------// if(B4_counter >=5000) { //B4 longer than 1 s pushed for page 1 B4_count = 0; B4_counter= 0; display_page = 1; } if(B5_counter >=5000) { //B5 longer than 1 s pushed for page 1 B5_count = 0; B5_counter= 0; display_page = 0; } if(B6_counter >=5000) { //B6 longer than 1 s pushed for backwards B6_count = 0; B6_counter= 0; driving_direction = 1; } if(B7_counter >=5000) { //B7 longer than 1 s pushed for forward B7_count = 0; B7_counter= 0; driving_direction = 0; } //--------------------------------------------------------------------------------------------------------// sprintf(LCDdata1, "%4dkm/h %4dkm", speed, (int)(cm/100000)); //--------------------------------------------------------------------------------------------------------// sprintf(LCDdata2, "%2d.%1dV %4d %4d%%", BAT_WERT/10, BAT_WERT%10, MOTOR_CURRENT, DC_act); if (T1 && T4) { // visualisation driving direction at any time // forward LCDdata2[18] = '-'; LCDdata2[19] = '>'; } if(T2 && T3 ) { LCDdata2[18] = '<'; LCDdata2[19] = '-'; } sprintf(LCDdata3, "%4d %4d %4d", (int)(cm/100000), AN2, MOTOR_CURRENT); if (Display_update == 1) { //refreh display if(display_page) { SetDDRamAddr((unsigned char) 0); // 1. row in display putsXLCD(LCDdata3); SetDDRamAddr((unsigned char) 40); // 2. row in display putrsXLCD(( char*)"Das ist seite 2 unte"); } else { SetDDRamAddr((unsigned char) 0); // 1. row in display putsXLCD(LCDdata1); SetDDRamAddr((unsigned char) 40); // 2. row in display putsXLCD( LCDdata2); } Display_update = 0; } } } //--------------------------------------------------------------------------------------------------------// // High priority interrupt vector #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh //jump to interrupt routine _endasm } //--------------------------------------------------------------------------------------------------------// // High priority interrupt routine 1 Hz #pragma code #pragma interrupt InterruptHandlerHigh void InterruptHandlerHigh () { if (INTCONbits.TMR0IF) { // Timer 0 WriteTimer0(26475); //was 80 , @ 3 h it was 2 sek to fast INTCONbits.TMR0IF = 0; //clear interrupt flag } if (PIR1bits.TMR1IF) { //clear interrupt flag Timer 1 PIR1bits.TMR1IF = 0; } if (INTCON3bits.INT1IF) { cm += 82; // milage counter if (RPM_count <= 7000) { // if RPM signal is more than 1.4 s than -> no (very low) speed RPM = RPM_count; RPM_count =0; } Go=1; INTCON3bits.INT1IF = 0; //clear interrupt 1 flag RPM signal } if (PIR1bits.TMR2IF) { //Timer 2 Interrupt 5 kHz each 0,2 ms (200µs) SW_Z++; Display_refresh++; //--------------------------------------------------------------------------------------------------------// if (SW_Z == 6 ) { //Trigger for raising edge and ADC current measurement INTCON2bits.INTEDG2 = 1; //1 = Interrupt on rising edge } if(SW_Z == 14 ) { //Trigger for raising edge and ADC current measurement INTCON2bits.INTEDG2 = 0; //0 = Interrupt on falling edge } //--------------------------------------------------------------------------------------------------------// if (Brake) { break_blinking++; //break has been pushed if (break_blinking >= 300) { // toggle after xxx ms (2500 x 0.2 s) // If brake, then turn ON the brake light and blink Brake_ON = !Brake_ON; break_blinking = 0; } } else { Brake_ON =0; break_blinking = 0; } //--------------------------------------------------------------------------------------------------------// if (B4_count==1) B4_counter++; // B4 measure duration of pushed button if (B5_count==1) B5_counter++; // B5 measure duration of pushed button if (B6_count==1) B6_counter++; // B6 measure duration of pushed button if (B7_count==1) B7_counter++; // B7 measure duration of pushed button //--------------------------------------------------------------------------------------------------------// if (Display_refresh >= 500) { // refresh after 100 ms (2500 x 0.2 s) Display_update = 1; Display_refresh = 0; } if (Go==1) { RPM_count ++; } if (RPM_count > 7000) { RPM_count =0; RPM = RPM_count; Go=0; } if (SW_Z >= SW_Intervall) { SW_Z = 0; // reset counter if (ERG == 0) { // ERG = 0 if AN0 <=200 DC_act = 0; Gas =0; } if (ERG > 1 && Brake == 0 && START ==1) { // if AN0 >= 201 Throttle pressed LED =1; if ( Gas == 0) { DC_act = 10; Gas =1; } else { DC_alt = DC_act; DC_act = (int) DC_alt + DC_speed; if (DC_act >= DC_max ) { DC_act = DC_max; } } if (ERG < DC_act) { // if throttle value is lower than before, then set PWM to lower value DC_act = ERG; } } LED =0; SetDCPWM1(DC_act); } PIR1bits.TMR2IF = 0; //clear interrupt flag } if (INTCONbits.INT0IF) { // Brake pedal is pushed DC_act = 0; // set PWM = 0% SetDCPWM1(DC_act); INTCONbits.INT0IF = 0; // clear interrupt 0 flag } if (INTCON3bits.INT2IF) { // current measurement raising and falling edge PWM if (SW_Z == 7) { // AN2_raising = getADC(ADC_CH2); } if (SW_Z == 15) { // Motor current falling edge AN2_falling = getADC(ADC_CH2); } INTCON3bits.INT2IF = 0; // clear interrupt 2 flag } if (INTCONbits.RBIF) { LastKnownPORTB = PORTB; // clear the mismatch to enable RBIF to be cleared. INTCONbits.RBIF = 0; // clear interrupt flag LastKnownPORTB = PORTB; // read and save the new state of PORTB if (B4) { B4_count = 1; } else { B4_count = 0; B4_counter = 0; } if(B5) { B5_count = 1; } else { B5_count = 0; B5_counter = 0; } if(B6) { B6_count = 1; } else { B6_count = 0; B6_counter = 0; } if(B7) { B7_count = 1; } else { B7_count = 0; B7_counter = 0; } } } //--------------------------------------------------------------------------------------------------------// // Low priority interrupt vector #pragma code InterruptVectorLow = 0x18 void InterruptVectorLow (void) { _asm goto InterruptHandlerLow //jump to interrupt routine _endasm } //--------------------------------------------------------------------------------------------------------// // Low priority interrupt routine #pragma code #pragma interrupt InterruptHandlerLow void InterruptHandlerLow () { }