/* * File: main.c * Author: Pekka Viljakainen *Band Saw Controller PIC 16F877A 20 MHz //-- Output pin for PWM signal = RC1 and RC2 //-- RA0,RA1,RA2 analog inputs (A_ACC, GYRO, STEER) //-- //--Timer 2: PWM //--Timer 0: Not used //--Timer 1: Not used * Created on 4. syyskuuta 2019, 15:18 */ #include #include #include #include #include #include "delay.h" //#include "rs232.h" #include "lcd.h" #pragma config WDTE = OFF // turn on watchdog timer #pragma config PWRTE = OFF #pragma config CP = OFF #pragma config BOREN = OFF #pragma config DEBUG = OFF #pragma config LVP = ON #pragma config CPD = OFF #pragma config WRT = HALF #pragma config FOSC = HS //bit st_risingedge;// start button rising edge memory bit int time2; // motor PWM update cycle time int sraw; //unsigned 16-bit integer 0...65535, speed raw setpoint int lmotor; //unsigned 16-bit integer 0...65535, motor pwm setpoint bit negative; // For negative number display //------ interrupts handling ------------------------------------- // //void interrupt tc_int(void) // { // // if(T0IF) // Timer0 interrupt // { // T0IF=0; // clear interrupt bit // if(time2>0) --time2; // } // } // ////---------------------------------------------------------------- void initialize(void); void Control (void); void UpdateMotors(void); void ReadAnalog(void); void Display (void); void Oplogic (void); // timer 0 interrupt, turnaround is 256* 1/20000000s = 51.2 us // 0,010s/51.2 us = 195 (appr) //control parameters //#define KP 0.05 // proportional //#define KD 0.04 // derivative //#define KS 0.15 // steering int main(int argc, char** argv) { initialize(); while(1) { //if (time2==5) UpdateMotors(); // Change Duty cycle setpoints every 5th cycle (time2) Control(); // Do control calcs every program cycle UpdateMotors(); if (time2==500)Display(); Oplogic (); } return (EXIT_SUCCESS); } void Oplogic() { if (RB1==0) RB2=1; //SD set to 1 =säätäjän vapautus päälle else RB2=0; //if ((st_risingedge==0) && (RB2==1)) // { // //ramp=5000; // st_risingedge=1; // rising edge of start button found // //motor=0; // } //if (RB2==0) // reset rising edge memory // st_risingedge=0; // //RB0=DMS // //RB2=STOP //if ((RB0=1)&&(RB2=1)) // { // RE0=0; //RE0=SD // RC3=1; // RB4=1; //monitor led // } // //else // { // RE0=1; //RE0=SD // RC3=0; // RB4=0; //monitor led // } //if ((angle_deg <2)&& (angle_deg > -2)&&(motor<40)&&(motor>-40)) //COND (RE2) OK? //if ((motor<40)&&(motor>-40)) //COND (RE2) OK? // { // RB5=1; // RE2=1; // } //else{ // RB5=0; // RE2=0; // } } void UpdateMotors() { CCPR1L=lmotor>>2; // set DUTY CYCLE motor 1 (On-time, 8 MSB's) CCP1X=(lmotor>>8 && 0x01); // 2 LSB's in CCP1CON vector CCP1CON(5:4) CCP1Y=(lmotor>>8 && 0x02)>>1; // 10 bits total //CCPR2L=rmotor>>2; // set DUTY CYCLE motor 2 (On-time, 8 MSB's) //CCP2X=(rmotor>>8 && 0x01); // 2 LSB's in CCP1CON vector CCP1CON(5:4) //CCP2Y=(rmotor>>8 && 0x02)>>1; // 10 bits total } void Control() { ReadAnalog(); // analog reading lmotor= 0.5*sraw+511; // forward direction only used if (lmotor>1018) //limit max lmotor=1018; if(time2<500) time2++; // increase counter else time2=1; // reset t2 } void ReadAnalog() { int z; // Delay loop variable /*/ADCS0=0; // select Fosc/32 ADCS1=1; // select Fosc/32 CHS0=0; // channel select 0 CHS1=0; CHS2=0; for(z=0;z<15;z++) // sampling C charges GO_DONE=1; // initiate conversion on the selected channel while(GO_DONE)continue; xraaka=((ADRESH<<8)+(ADRESL)); // X accelerometer voltage, float ADIF=0; ADCS0=0; ADCS1=1; CHS0=1; // channel select 1 CHS1=0; CHS2=0; for(z=0;z<15;z++) // sampling C charges GO_DONE=1; // initiate conversion on the selected channel while(GO_DONE)continue; graw=((ADRESH<<8)+(ADRESL)); // GYRO voltage, float */ ADIF=0; ADCS0=0; ADCS1=1; CHS0=0; // channel select 2 CHS1=1; CHS2=0; for(z=0;z<15;z++) // sampling C charges GO_DONE=1; // initiate conversion on the selected channel while(GO_DONE)continue; sraw=((ADRESH<<8)+(ADRESL)); // Steering voltage, unsigned int } void Display() { lcd_line1(); // lcd_cmd(0x01); //ylarivi 0x00-0x13 alarivi 0x40-0x53 lcd_string("nopeus = "); lcd_16number(lmotor); lcd_line2(); if(RB1==1) lcd_string("ohjaus = stop"); else lcd_string("ohjaus = run"); //lcd_16number(turn); //lcd_16number(ADRESL); //lcd_string("xraaka = "); //lcd_16number((int)xraaka); //lcd_goto (0x4E); //lcd_16number((int)graw); } void initialize() { ADCON1 = 0xB2; //ADCON1 = 0x83; // 10-bit, right justified A,VREF,A,A,A TRISA=0b00111; //RA0 & RA1 & RA2 = input muut output TRISB=0b11001011; // nRBPU=0; // Enable RB weak pull-up TRISD = 0b00000000; //D-portti outputeiksi TRISC = 0b10000000; PORTD=0x0; TRISE0=0; //RE0=output(SD),RE1=SPARE input, RE2=output(COND) TRISE1=0; TRISE2=0; //CVREN=0; //CMCON=7; ADON=1; // turn on the A2D conversion module lcd_init(); // Display module initialization delay(); RBIE=0; GIE=0; // enable global interrupts PEIE=0; // enable peripheral interrupts //INTCON=0x0; T0CS = 0; // Timer0 increments on instruction clock //TMR0IE = 1; // Enable interrupt on TMR0 overflow PSA=0; PS0=1; // Prescaler bits 1:64 PS1=0; PS2=1; T2CON= 0b00000100; //Timer 2 control register prescale 1:1(xxxxxx00);1:4(xxxxxx01), postscale 1:1 CCP1CON= 0b00001100; //set up for PWM and 2 LSB (CCP1CON(5:4), CCP1X, CCP1Y) CCP2CON= 0b00001100; PR2= 0b11111111; // Set up PERIOD, constant =255, with TMR2 Prescaler 1:4= 4.88 kHz (1:16 = 1.22 kHz) PWWM frequency RB2=0; //SD set to 0 =säätäjän vapautus pois//CCPR1L=0; // Set up Duty cycle initial value 8 MSB RB4=0; //LED out RB5=0; // LED out //T1CON= 0b00001001; //Timer 1 control register prescale 1:1, turn timer on //TMR1H=0x00; //TMR1L=0x00; //motor=0; //ramp=10000; // setpoint and ramp-up initial value }