![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
411ceu6
Dependencies: 411_lcdi2c1_latche TextLCD
Diff: main.cpp
- Revision:
- 0:e1947a05c2a2
- Child:
- 1:78d19167c0f7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Mar 17 18:13:51 2021 +0000 @@ -0,0 +1,987 @@ + +/* STM32F411CEU6 i2c LCD*/ +#include "mbed.h" +#include <math.h> /* cos */ +#include "TextLCD.h" +I2C i2c_lcd(PB_9,PB_8); // SDA, SCL (активировать если i2c LCD ) +TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD20x4); // I2C bus, PCF8574 Slaveaddress, LCD Type (активировать если i2c LCD) + +//TextLCD lcd(PA_15, PB_3, PB_4, PB_5, PB_6, PB_7);// rs, e, d4-d7 +//Serial pc(SERIAL_TX, SERIAL_RX); +//extern "C" void mbed_reset(); +#define pi 3.14159265 + +DigitalInOut GenOut (PB_4, PIN_OUTPUT, PullUp, 1); // GEN + + +//Step Motor +DigitalInOut STEPX (PB_12, PIN_OUTPUT, PullDown, 1); +DigitalInOut DIRX (PB_13, PIN_OUTPUT, PullDown, 1); //OpenDrain +DigitalInOut STEPZ (PB_15, PIN_OUTPUT, PullDown, 1); +DigitalInOut DIRZ (PA_8, PIN_OUTPUT, PullDown, 1); +DigitalInOut AMX (PB_14, PIN_INPUT, PullDown, 0); // Alarm step motor X +DigitalInOut AMZ (PA_9, PIN_INPUT, PullDown, 0); // Alarm step motor Z + +//Buton menu +DigitalInOut R_DZ (PB_0, PIN_INPUT, PullUp, 1); +DigitalInOut Up (PB_3, PIN_INPUT, PullUp, 1); +DigitalInOut Down (PA_15, PIN_INPUT, PullUp, 1); + +//External CPU +InterruptIn CStX (PA_0); +DigitalInOut CDirX (PC_14, PIN_INPUT, PullUp, 1); +InterruptIn CStZ (PA_1); +DigitalInOut CDirZ (PC_15, PIN_INPUT, PullUp, 1); +DigitalInOut EStop (PC_13, PIN_OUTPUT, PullDown, 1); + +//Joystik +DigitalInOut XJR (PA_10, PIN_INPUT, PullUp, 1); +DigitalInOut XJU (PA_11, PIN_INPUT, PullUp, 1); +DigitalInOut XJL (PA_12, PIN_INPUT, PullUp, 1); +DigitalInOut ZJR (PB_1, PIN_INPUT, PullUp, 1); +DigitalInOut ZJU (PB_2, PIN_INPUT, PullUp, 1); +DigitalInOut ZJL (PB_10, PIN_INPUT, PullUp, 1); + + +//Encoder & Tachometr +InterruptIn InTacho (PB_7); // +InterruptIn EncXA (PB_5); +InterruptIn EncXB (PB_6); +InterruptIn EncZA (PA_3); +InterruptIn EncZB (PA_2); + +volatile int y; +int k; +volatile int k1=0; +volatile int K=0; // номер режима (0-ручной, 1 ввод коорд., 2 -резьба, 3-CPU, 4-конус, 5-ввод скоростей)) +volatile long ind=0; +volatile int i=0; +volatile int j=0; +volatile int u; +volatile double time0=25000; +volatile double time1=25000; // время в мкс 1 оборота шпинделя + +volatile double time2; + +volatile int DX; // направление (куда нужно двигаться) DIRX +volatile int DX1; +volatile int EX; // флаг работы энкодера X +volatile int DZ; // направление (куда нужно двигаться) DIRZ +volatile int DZ1; +volatile int EZ; // флаг работы энкодера Z +volatile int DJX= 0; // флаг работы ддойстика X +volatile int DJX1= 0; // старый флаг работы ддойстика X +volatile int DJZ= 0; // флаг работы ддойстика Z +volatile int DJZ1= 0; // старый флаг работы ддойстика Z + +volatile double Dlrezby=-50.00; // длина резьбы в мм со знаком +unsigned long NDlrezby; // длина резьбы в Step X +volatile double Schag=1.00; // шаг резьбы в мм на 1 оборот шпинделя +unsigned long NSchag; // шаг резьбы в Step X +volatile double Hrez=-1.00; // глубина профиля резьбы со знаком в мм +int NHrezZ; // глубина профиля резьбы в Step Z +volatile double hrez=0.05; // глубина врезания резца за один проход резьбы в мм +unsigned long Nhrez; // глубина врезания резца за один проход резьбы в Step Z +volatile double Saw=2.00; // безопасное расстояние отвода резца в мм +unsigned int NSaw; // безопасное расстояние отвода резца в мм Step Z +volatile double Back=5.00; // расстояние отвода резца в мм после нарезания резьбы +unsigned int NBack; // расстояние отвода резца в Step Z после нарезания нарезания резьбы +unsigned int NhSZ; +volatile long NvarX; +volatile long NvarZ; +volatile long NSchagX; // кол. шагов X +volatile long NSchagZ; // кол. шагов Z +float chist; // глубина чистового прохода в мм. +int Nchist; // кол. шагов для чистового прохода + + +volatile int FlagZ; // флаг готовности введённых данных для резьбы Z +//volatile int FlagZold; // предыдущее значение флага готовности введённых данных для резьбы Z +volatile int FlagX; // флаг готовности введённых данных для резьбы X +//volatile int FlagXold; // предыдущее значение флага готовности введённых данных для резьбы X +int ProchodX=0; // кол-во оставшихся проходов резьбы по X +volatile int Strob=0; // Начало оборота шпинделя +volatile float frequencY1=600; // частота вращения шпинделя в об/мин. +volatile float frequencY2=600; + +volatile long NStX=0; // кол. StepX к выдаче +volatile long NStZ=0; // кол. StepZ к выдаче +volatile float bufX=0; // приёмный буфер X +float bufX1=0; // временный буфер X +float DISTX=400.00; // число для индикации положения оси X +volatile float bufZ=0; // приёмный буфер Z +float bufZ1=0; // временный буфер Z +float DISTZ=2000.00; // число для индикации положения оси Z + +volatile int STMMZ = 400.00; // кол. ипульсов/мм энкодера Z +volatile double STZ = 2000.00; // кол. шагов ШД по Z на 1мм.(ШД 1/5: 2000=(200(имп/об)/1(мм/об)*2*5), шаг винта =1 мм/об) +volatile int KSTZ=10; // коэф. редукции Z (2 (механика) * 5 деление шага = 10) +volatile int STMMX = 400.00; // кол. ипульсов/мм энкодера X +volatile double STX = 400.00; // кол. шагов по X на 1мм. (ШД 1/5: 400=(200(имп/об)/5(мм/об)*2 механика * 5 деление шага) шаг винта =5 мм/об) +volatile int KSTX=10; // коэф. редукции X (2 (механика) * 5 (деление шага) = 10) +volatile int KX4=0; // от джойстика Х попускаем 4 и на 5 обрабатываем + +volatile int N_T=1; // переключатель SpeedX1 и SpeedZ1 мм/мин или мм/оборот +volatile double SpeedX1 = 1.0; // скорость прохода X в мм/сек +volatile double SpeedX2 = 1500; // скорость быстрого перемещения X в мм/мин +volatile double SpeedZ1 = 1.0; // скорость прохода Z в мм/сек +volatile double SpeedZ2 = 400; // скорость быстрого перемещения Z в мм/мин + +volatile double TimeXMax=2500; // Максимальное значение времени между шагами ШД (минимальная скорость) +//volatile double TIMERx=250; // время для таймера х +volatile double TimeXold=250; // предыдущее значение таймера X +volatile double TimeX=500; // переменная +volatile double TimeX0=500; //время в мкс между шагами ШД по Х при нарезании резьбы +volatile double TimeX1 =60000000/frequencY1/SpeedX1/STX; // время между шагами прохода X +volatile double TimeX2 =60000000/SpeedX2/STX; // время между шагами ускоренного перемещения X +volatile double SpeedX0 = 60000000/(frequencY1*TimeX1*STX); + + +volatile double TimeZMax=500; // Максимальное значение времени между шагами ШД (минимальная скорость) +//volatile double TIMERz=150; // время для таймера z +volatile double TimeZold=100; // предыдущее значение таймера Z +volatile double TimeZ=100; +volatile double TimeZ0 =100; +volatile double TimeZ1 =60000000/frequencY1/SpeedZ1/STZ; // время между шагами прохода Z +volatile double TimeZ2 =60000000/SpeedZ2/STZ; // время в мкс между шагами ускоренного перемещения Z +volatile double accelX=1.05; // % ускороения/торможения X +volatile double accelZ=1.01; // % ускороения/торможения Z +volatile int a=1; // признак движения с ускоронием/торможением +unsigned int NShBZ; +float angle=45; // угол конуса от 0 до +/-90 градусов (+ правый, -левый конус). + +float Frec=600; // частота Gen1 в об/мин +float Gen1=7500000/Frec; // период генератора в мкс + +Timer timer_Tacho; +Timeout timerZ; +Timeout timerX; +Ticker timer_Gen; + +//---------------------------------------------- +void Gen() +{ + GenOut=!GenOut; + timer_Gen.attach_us(&Gen, (Gen1)); +} + +//---------------------------------------------- +// Подпрограмма прерывания по Tacho +void ITacho() + { + time2 = timer_Tacho.read_us(); + timer_Tacho.reset(); + //InTacho.fall(&ITacho); // + //timer_Tacho.start() ; + time0 += time2; + if (time2>4000) // если частота меньше 3600 об/мин. + { + TimeX0 = 4*time2/(STX * Schag)-20; // время в мксек. между шагами ШД по Х при нарезании резьбы-34мкс(длительность обработки прерываний) + if (j>=3) + { + time1=(time0+time1)/2; //время одного оборота шпинделя в мкс. + time0 = 0; j=0; Strob=1; // + } + else { ++j; Strob=0; } + } + //se {time0=0; time1=0;} + } +//---------------------------------------------- +// вывод частоты оборотов шпинделя + void OUTfrequencY () +{ + if ((timer_Tacho.read_us()-time1)>2000000) frequencY2=0; + else { frequencY2 = 60000000/time1;} // частота вращения шпинделя в о/мин + frequencY1=((frequencY2+frequencY1)/2); + lcd.locate(0, 3); + lcd.printf(" "); + lcd.locate(0, 3); + lcd.printf("%4.0f",frequencY1); + lcd.locate(4, 3); + lcd.printf(" n/m"); // выводим обороты шпинделя в об/мин +} + +//---------------------------------------------- + //Подпрограмма StepX + void TickX() +{ + //if (a==0) TimeXold=TimeX; + timerX.attach_us(&TickX, (TimeXold)); // Задать период в с + if (FlagX) + { + if (DX)++NStX; + else --NStX; + --NvarX; + if (NvarX==0) FlagX=0; + } + if ((DJX&&K==0)||(DJX&&K==1)||(DJX&&K==4)) { + if (DX)++NStX; + else --NStX;} + if (NStX!=0) + { + if (TimeXold>(TimeX+10)){ + if (TimeXold/accelX>(TimeX+10)) {TimeXold /= accelX;} // ускорение + else TimeXold=(TimeX+10);} + if (TimeXold<(TimeX+10)){ + if (TimeXold*accelX<(TimeX+10)) {TimeXold *= accelX;} // торможение + else TimeXold=(TimeX+10);} + + if (NStX>0) {DIRX=1; ++bufX; --NStX;} + if (NStX<0) {DIRX=0; --bufX; ++NStX;} + if (K!=1) + { + wait_us(2); //for (int q=20; q>0; ) { --q;++q;--q;} // 2 mks + STEPX=0; + wait_us(1); //for (int q=40; q>0; ) { --q;++q;--q;} //step - 3 mks + STEPX=1; + } + } + else {TimeXold=TimeXMax;} +} +//---------------------------------------------- + //Подпрограмма StepZ + void TickZ() +{ + //if (a==0) TimeZold=TimeZ; + timerZ.attach_us(&TickZ, (TimeZold)); // Задать период в мкс + if (FlagZ) + { + if (DZ)++NStZ; + else --NStZ; + --NvarZ; + if (NvarZ==0) FlagZ=0; + } + if ((DJZ&&K==0)||(DJZ&&K==1)||(DJZ&&K==4)) { + if (DZ)++NStZ; + else --NStZ;} + + if (NStZ!=0) + { + if (TimeZold>(TimeZ-8)){ + if (TimeZold/accelZ>(TimeZ-8)) {TimeZold /= accelZ;} // ускорение + else TimeZold=(TimeZ-8);} + if (TimeZold<(TimeZ-8)){ + if (TimeZold*accelZ<(TimeZ-8)) {TimeZold *= accelZ;} // торможение + else TimeZold=(TimeZ-8);} + + if (NStZ>0) {DIRZ=1; ++bufZ; --NStZ;} + if (NStZ<0) {DIRZ=0; --bufZ; ++NStZ;} + if (K!=1) + { + wait_us(2); //for (int q=20; q>0; ) { --q;++q;--q;} // 2 mks + STEPZ=0; + wait_us(1); //for (int q=30; q>0; ) { --q;++q;--q;} //step - 3 mks + STEPZ=1; + } + } + else {TimeZold=TimeZMax;} +} + +//---------------------------------------------- +// Подпрограмма вычисления по энкодеру Х + void EncX() +{ + if (K==2||K==5) // резьба или ввод скоростей + { + if (DX1) ind+=1; + else ind-=1; + if (K==2) + { // если резьба + if (ind>22) ind=0; + if (ind<0) ind=22; // кол-во вводимых параметров 0-5 + i=ind/4; + } + if (K==5) + { // если ввод скоростей + if (ind>14) ind=0; + if (ind<0) ind=14; // кол-во вводимых параметров 0-3 + i=ind/4; + } + } + if (K==0||K==1||K==4) + { + if (!NStX) DX=DX1; + if (!DJX) + { + if (DX)++NStX; + else --NStX; + TimeX=250; + } + } +} +//---------------------------------------------- +// Подпрограмма прерывания по энкодеру ХА + void IEncXA() +{ + if (EncXA==EncXB) DX1=1; + else DX1=0; + EncX(); +} +//---------------------------------------------- +// Подпрограмма прерывания по энкодеру ХВ + void IEncXB() + { + if (EncXA!=EncXB) DX1=1; + else DX1=0; + EncX(); +} +//---------------------------------------------- +void EncZ() +{ + if (K ==2) // резьба + { + if (!DZ1 &&(i==0)) {Dlrezby+=0.0025;} + if (!DZ1 &&(i==1)) {Schag+=0.0025;} + if (!DZ1 &&(i==2)) {Hrez+=0.0025;} + if (!DZ1 &&(i==3)) {hrez+=0.0025;} + if (!DZ1 &&(i==4)) {Saw+=0.0025;} + if (!DZ1 &&(i==5)) {Back+=0.0025;} + + if (DZ1 &&(i==0)) {Dlrezby-=0.0025;} + if (DZ1 &&(i==1)) {Schag-=0.0025;} + if (DZ1 &&(i==2)) {Hrez-=0.0025;} + if (DZ1 &&(i==3)) {hrez-=0.0025;} + if (DZ1 &&(i==4)) {Saw-=0.0025;} + if (DZ1 &&(i==5)) {Back-=0.0025;} + } + if (K==4) //конус + { + if (!DZ1) + { + angle+=0.125f; + if (angle>=90.0f) angle=90.0f; + } + if (DZ1) + { + angle-=0.125f; + if (angle<=-90.0f) angle=-90.0f; + } + } + + if (K==5) + { + if (!DZ1 &&(i==0)) { SpeedX1+=0.0025; + if (SpeedX1>5.00) SpeedX1=5.00; } + if (!DZ1 &&(i==1)) { SpeedX2+=0.25; + if (SpeedX2>1500) SpeedX2=1500; } + if (!DZ1 &&(i==2)) { SpeedZ1+=0.0025; + if (SpeedZ1>3.00) SpeedZ1=3.00; } + if (!DZ1 &&(i==3)) { SpeedZ2+=0.25; + if (SpeedZ2>400) SpeedZ2=400; } + + if (DZ1 &&(i==0)) { SpeedX1-=0.0025; + if (SpeedX1<0.01) SpeedX1=0.01; } + if (DZ1 &&(i==1)) { SpeedX2-=0.25; + if (SpeedX2<1.00) SpeedX2=1.00; } + if (DZ1 &&(i==2)) { SpeedZ1-=0.0025; + if (SpeedZ1<0.01) SpeedZ1=0.01; } + if (DZ1 &&(i==3)) { SpeedZ2-=0.25; + if (SpeedZ2<1.00) SpeedZ2=1.00; } + } + if (!NStZ) DZ=DZ1; + if (K==0||K==1) + { + if (!DJZ) + { + if (DZ) {NStZ+=5;} + else {NStZ-=5;} + TimeZ=100; + } + } +} +//---------------------------------------------- +// Подпрограмма прерывания по энкодеру ZА + void IEncZA() +{ + if (K!=3) // ручной режим или ввод координат и т.д. кроме CPU + { + if (EncZA==EncZB) DZ1=0; + else DZ1=1; + EncZ(); + } +} +//---------------------------------------------- +// Подпрограмма прерывания по энкодеру ZB + void IEncZB() +{ + if (K!=3) // ручной режим или ввод координат ит.д. кроме CPU + { + if (EncZA!=EncZB) DZ1=0; + else DZ1=1; + EncZ(); + } +} +//---------------------------------------------- +//Подпрограмма вывода в LCD +void OUTLCD() +{ + //if (!K || K==1) + //{ + DISTX = float ( bufX ); + lcd.locate(0,0); + lcd.printf("x=%+7.2f",DISTX/STX); + lcd.locate(5,2); + if (!R_DZ) + { + lcd.printf("dia"); + DISTZ = 2* float ( bufZ); // диаметр: значения координат * 2 + } + else + { + lcd.printf("rad"); + DISTZ = float ( bufZ); + } + lcd.locate(0,1); + lcd.printf("z=%+7.2f",DISTZ/STZ); + //} + bufZ1=bufZ; + bufX1=bufX; +} +//--------------------------- +// Подпрограмма прерывания от CPU X в режиме внешнего управления + void CPUX() + { + if (K==3) + { + if (CDirX) {++bufX; DIRX=1;} // вправо + else {--bufX; DIRX=0;} // влево + wait_us(2); + STEPZ=0; + for (int q=30; q>0; ) + { --q;++q;--q;} + STEPZ=1; //step - 4 mks + } + } +//---------------------------------------------- +// Подпрограмма прерывания от CPU Z в режиме внешнего управления + void CPUZ() + { + if (K==3) + { + if (CDirZ) {++bufZ; DIRZ=1;} // вправо + else {--bufX; DIRZ=0;} // влево + wait_us(2); + STEPZ=0; + for (int q=30; q>0; ) + { --q;++q;--q;} + STEPZ=1; //step - 4 mks + } + } +//---------------------------------------------- +void wanProch () +{ + int k=1; + if (k==1) // врезаемся по Z на hrez мм. + { + TimeXold=TimeX0; // предварительно для таймера Х + TimeZ=TimeZ2; // период между шагами + NvarZ=Nhrez; // кол-во шагов + lcd.locate(17, 3); lcd.printf("-hr"); + lcd.locate(10, 1); lcd.printf("vz=%7.2f",SpeedZ2); + FlagZ=1; // данные готовы + while(NvarZ>0){ + OUTLCD();OUTfrequencY(); // ждём пока таймер выдаст "NSvar" стробов + if (NvarZ==0) break;} + FlagZ=0; ++k; + } + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + //--------------------------- + if (k==2) // нарезание резьбы один проход + { + NvarX=NSchagX; // кол-во шагов + TimeX=(TimeX0); + //lcd.locate(10, 2); lcd.printf("Tx=%7.6f",TimeXold*1000.0); + lcd.locate(17, 3); lcd.printf("-LX"); + lcd.locate(10, 0); lcd.printf("vx=%7.2f",Schag); + while(Strob) {} + while(!Strob) {} + FlagX=1; // данные готовы + while (NvarX>0){ // ждём пока таймер выдаст "Nvar" стробов + TimeX=TimeX0; + if (NvarX==0) break;} + OUTLCD();OUTfrequencY(); + //lcd.locate(10, 2); lcd.printf("Tx=%7.6f",TimeXold); + FlagX=0; ++k; + } + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + //--------------------------- + if (k==3) // отводим резец по Z на hrez+swZ мм. + { + TimeZ=TimeZ2; //период между шагами + NvarZ=NhSZ; // кол-во шагов для отвода резца на безопасное расстояние + lcd.locate(17, 3); lcd.printf(" Sv"); + lcd.locate(10, 1); lcd.printf("vz=%7.2f",SpeedZ2); + DZ= !DZ; // смена направления движения по оси + FlagZ=1; // данные готовы + while (NvarZ>0){ + OUTLCD(); OUTfrequencY(); // ждём пока таймер выдаст "NSvar" стробов + if (NvarZ==0) break;} + FlagZ=0; ++k; + } + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + //--------------------------- + if (k==4) // отводим резец по Х к началу резьбы + { + TimeX=TimeX2; // период между шагами + NvarX=NSchagX; // кол-во шагов + lcd.locate(17, 3); lcd.printf(" LX"); + lcd.locate(10, 0); lcd.printf("vx=%7.2f",SpeedX2); + DX= !DX; // смена направления движения по оси + FlagX=1; // данные готовы + while (NvarX>0){ + OUTLCD(); OUTfrequencY(); // ждём пока таймер выдаст "NSvar" стробов + if (NvarX==0) break;} + FlagX=0; ++k; + DX= !DX; // смена направления движения по оси + } + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + //--------------------------- + if (k==5) // подводим резец по Z на hrez+swZ мм. + { + TimeZ=TimeZ2; // период между шагами + NvarZ=NhSZ; // кол-во шагов + lcd.locate(17, 3); lcd.printf("-Sv"); + lcd.locate(10, 1); lcd.printf("vz=%7.2f",SpeedZ2); + DZ= !DZ; // смена направления движения по оси + FlagZ=1; // данные готовы + while (NvarZ>0){ + OUTLCD(); OUTfrequencY(); // ждём пока таймер выдаст "NSvar" стробов + if (NvarZ==0) break;} + FlagZ=0; ++k; + } + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + --ProchodX; + } +//---------------------------------------------- +// в случае сигнала alarm от ШД + + void Alarm () +{ + __disable_irq(); + lcd.cls(); // Clear LCD + wait_ms(20); + if (AMX) { + lcd.locate(5,1); + lcd.printf("ALARM X!");} + if (AMZ) { + lcd.locate(5,2); + lcd.printf("ALARM Z!");} + EStop =0; // для внешнего сомпьютера + while (AMX||AMZ){ + if (!AMX&&!AMZ) break;} // ждем пока будет устранена авария + NVIC_SystemReset(); // рестарт системы +} +//---------------------------------------------- +void Enc_enable () +{ + EncXA.rise(&IEncXA); EncXA.fall(&IEncXA); // + EncXB.rise(&IEncXB); EncXB.fall(&IEncXB); // + EncZA.rise(&IEncZA); EncZA.fall(&IEncZA); // + EncZB.rise(&IEncZB); EncZB.fall(&IEncZB); // + +} + +//---------------------------------------------- +void Enc_disable () +{ + EncXA.rise(NULL); EncXA.fall(NULL); // запрещаем прерывания от энкодеров + EncXB.rise(NULL); EncXB.fall(NULL); // + EncZA.rise(NULL); EncZA.fall(NULL); // + EncZB.rise(NULL); EncZB.fall(NULL); +} +//---------------------------------------------- +void Jx () // джойстик X +{ + if (!XJR&& XJU) {DX=1; TimeX=TimeX1; DJX=1; } //если X вправо + if (!XJR&&!XJU) {DX=1; TimeX=TimeX2; DJX=2; } //если X быстро вправо + if (!XJL&& XJU) {DX=0; TimeX=TimeX1; DJX=1; } //если X влево + if (!XJL&&!XJU) {DX=0; TimeX=TimeX2; DJX=2; } //если X быстро влево +} +//---------------------------------------------- +void Jz () // джойстик Z +{ + if (!ZJR&& ZJU) {DZ=1; TimeZ=TimeZ1; DJZ=1; } //если Z вправо + if (!ZJR&&!ZJU) {DZ=1; TimeZ=TimeZ2; DJZ=2; } //если Z быстро вправо + if (!ZJL&& ZJU) {DZ=0; TimeZ=TimeZ1; DJZ=1; } //если Z влево + if (!ZJL&&!ZJU) {DZ=0; TimeZ=TimeZ2; DJZ=2; } //если Z быстро влево +} +//---------------------------------------------- +void SpX1Z1 () +{ // нормальная установка скоростей + if (N_T) + { + TimeX1 = 1000000/(STX*SpeedX1); // время в мкс между шагами ШДX если шпиндель не вращается + TimeZ1 = 1000000/(STZ*SpeedZ1); // время в мкс между шагами ШДZ если шпиндель не вращается + TimeX2 = 60000000/(SpeedX2*STX); // время в мкс между шагами ШДX при скорости Speed (мм/мин) + TimeZ2 = 60000000/(SpeedZ2*STZ); // время в мкс между шагами ШДZ при скорости Speed (мм/мин) + } + else + { + TimeX1 = 20*time1/(STX*SpeedX1); // время в мкс между шагами ШДX на 1 оборот шпинделя *20, а то очень быстро. + TimeZ1 = 20*time1/(STZ*SpeedZ1); // время в мкс между шагами ШДZ на 1 оборот шпинделя *20, а то очень быстро. + TimeX2 = 60000000/(SpeedX2*STX); // время в мкс между шагами ШДX при скорости Speed (мм/мин) + TimeZ2 = 60000000/(SpeedZ2*STZ); // время в мкс между шагами ШДZ при скорости Speed (мм/мин) + } +} +//---------------------------------------------- +//---------------------------------------------- +int main() +{ + InTacho.mode(PullUp); // + EncXA.mode(PullUp); + EncXB.mode(PullUp); + EncZA.mode(PullUp); + EncZB.mode(PullUp); + + InTacho.fall(&ITacho); // + timer_Tacho.start() ; // + Enc_enable (); + SpX1Z1 (); + timerX.attach_us(&TickX, (TimeXMax)); // + timerZ.attach_us(&TickZ, (TimeZMax)); // + timer_Gen.attach_us(&Gen, (Gen1)); + ZJU.write ( 1); + STEPX=1; + STEPZ=1; + EStop=0; + //__enable_irq(); + + lcd.cls(); // Clear LCD + lcd.locate(3,1); lcd.printf("Latche control"); + lcd.locate(4,3); lcd.printf("STM32F411ce"); + wait(2); + lcd.cls(); + + K=0; k1=0; +//---------------------------------------------- +//Основной цикл + + while(1) + { + if (!Up) + { + wait_ms(100); + if (!Up) + { + --K; + if (K<0) K=5; + lcd.cls(); + wait_ms(100); + } + } + if (!Down) + { + wait_ms(100); + if (!Down) + { + ++K; + if (K>5) K=0; + lcd.cls(); wait_ms(100); + } + } + if (AMZ||AMX) Alarm (); + + //-------------------------------------------- + if (K==0||K==1) // режим ручного управления и ввода координат + { + if (!XJR||!XJL) // джойстик X + { wait_ms (50); + if (!XJR&&XJU) { if (DJX!=1) Jx();} + if (!XJR&&!XJU) { if (DJX!=2) Jx();} + if (!XJL&&XJU) { if (DJX!=1) Jx();} + if (!XJL&&!XJU) { if (DJX!=2) Jx();} + } + else DJX=0; + //---------------- + if (!ZJR||!ZJL) // джойстик X + { wait_ms (50); + if (!ZJR&&ZJU) { if (DJZ!=1) Jz();} + if (!ZJR&&!ZJU) { if (DJZ!=2) Jz();} + if (!ZJL&&ZJU) { if (DJZ!=1) Jz();} + if (!ZJL&&!ZJU) { if (DJZ!=2) Jz();} + } + else DJZ=0; + + //---------------- + if (K==0) + { + if ((ZJR&&ZJL&&!ZJU)||(XJR&&XJL&&!XJU)) // ни влево, ни вправо, но нажата кнопка на любом + { // джойстике - можем выставить лимбы энкодеров + DJX=0; DJZ=0; + Enc_disable(); + while(!ZJU||!XJU) {if (ZJU&&XJU) { break;}} + Enc_enable(); + } + lcd.locate(10, 0); lcd.printf("vx=%7.2f",SpeedX1); + lcd.locate(10, 1); lcd.printf("vz=%7.2f",SpeedZ1); + lcd.locate(10, 2); lcd.printf("VX=%7.0f",(SpeedX2)); + lcd.locate(10, 3); lcd.printf("VZ=%7.0f",(SpeedZ2)); + /*lcd.locate(10, 0); lcd.printf(" "); + lcd.locate(10, 0); lcd.printf("Tx=%7.2f",TimeX); + lcd.locate(10, 1); lcd.printf(" "); + lcd.locate(10, 1); lcd.printf("Tz=%7.2f",TimeZ); + //lcd.locate(10, 2); lcd.printf("VX=%7.2f",TimeX2); */ + + lcd.locate(0, 2); lcd.printf("Man "); + k1=0; + } + if (K==1) // режим ввода значений X Z + { + lcd.locate(11, 3); + lcd.printf("Enter X,Z"); + if (!ZJU&&ZJR&&ZJL) bufZ=0; + if (!XJU&&XJR&&XJL) bufX=0; // обнуление координат X или Z + } + + OUTLCD(); + k1=0; + OUTfrequencY (); + + } //end K0 K1 +//---------------------------------------------- +// режим: нарезание резьбы + + if (K ==2) + { + if (!k1) + { + lcd.locate(0, 0); lcd.printf("Lx%7.2f",Dlrezby); + lcd.locate(10, 0); lcd.printf("st%6.2f",Schag); + lcd.locate(0, 1); lcd.printf("Hr%7.2f",Hrez); + lcd.locate(10, 1); lcd.printf("hr%6.2f",hrez); + lcd.locate(0, 2); lcd.printf("Sf%7.2f",Saw); + lcd.locate(10, 2); lcd.printf("Bk%6.2f",Back); + + if (i==0){ lcd.locate(18, 3); lcd.printf("Lx");} + if (i==1){ lcd.locate(18, 3); lcd.printf("st");} + if (i==2){ lcd.locate(18, 3); lcd.printf("Hr");} + if (i==3){ lcd.locate(18, 3); lcd.printf("hr");} + if (i==4){ lcd.locate(18, 3); lcd.printf("Sf");} + if (i==5){ lcd.locate(18, 3); lcd.printf("Bk");} + + + SpX1Z1 (); + ProchodX=100*abs(Hrez)/(100*hrez); + lcd.locate(11, 3); lcd.printf(" %d ",ProchodX); // кол-во проходов по Х + lcd.locate(14, 3); lcd.printf("thr"); + int Hrez1=100*abs(Hrez); + int hrez1 = 100*hrez; + int chist1 = Hrez1 % hrez1; // остаток в сотках на чистовой проход + chist = float(float(chist1)/100); // остаток в мм на чистовой проход + Nchist=int(chist*float(STZ)); // кол. шагов глубины чистового прохода + OUTfrequencY (); + if ( Dlrezby>0 ) DX=1; else DX= 0; // направление резьбы 1-левая, 0-правая резьба + if ( Hrez>0 ) DZ=1; else DZ= 0; // направление врезания 1-внутренняя, 0-наружная резьба + TimeX=TimeX0; // период между шагами по Х + NSchagX=abs(Dlrezby)*STX; // кол-во шагов по Х на всю длину резьбы + NSaw=Saw*STZ; + Nhrez= abs(hrez)*STZ; + NhSZ=NSaw+Nhrez; + NBack=Back*STZ+(abs(Hrez)*STZ); //отвод на Back мм + lcd.locate(11, 3); lcd.printf(" %d ",ProchodX); + } //end (!k1)--------------------------- + + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY (); + + if ((!XJU||!ZJU)&& (k1==0)) + { // begin (k1==0)) + while (!XJU||!ZJU) {wait_ms(20); if(XJU&&ZJU) break;} // ждём отпускания кнопки + ++k1; + //------------------------------------------------- + Enc_disable (); // запрещаем прерывания от энкодеров + lcd.cls(); OUTLCD(); OUTfrequencY (); + for(ProchodX; ProchodX>0; ) // цикл по кол-ву проходов + { + lcd.locate(11, 3); lcd.printf(" %d ",ProchodX); + wanProch (); + lcd.locate(11, 3); lcd.printf(" %d ",ProchodX); + //while (1){wait_ms(20); if(!XJU||!ZJU) break;} + } + + if (Nchist!=0) + { + lcd.locate(11, 3); lcd.printf("ch"); + Nhrez = Nchist; + ProchodX=1; + wanProch (); + } + if (!ProchodX) // отвод резца после окончания резьбы + { + TimeZ=TimeZ2; //период между шагами + NvarZ=NBack; // кол-во шагов + lcd.locate(17, 3); lcd.printf(" BK"); + lcd.locate(10, 1); lcd.printf("vz=%7.2f",SpeedZ2); + DZ= !DZ; // смена направления движения по оси + FlagZ=1; // данные готовы + while (NvarZ>0){ + OUTLCD(); OUTfrequencY (); + if (NvarZ==0) break;} // ждём пока таймер выдаст "NSvar" стробов + FlagZ=0; ++k; K=0; + Enc_enable (); // разрешаем прерывания от энкодеров + lcd.cls();k1=0; + } + } // end k1=0 + SpX1Z1 (); // установка скоростей по умолчанию + } // end (K ==2) +//------------------------------------------------- +// режим: управления от внешнего компьютера + + if (K==3) + { + if (k1==0) + { + lcd.locate(10, 3); lcd.printf(" CPU "); + OUTLCD(); OUTfrequencY (); + CStX.rise(&CPUX); CStZ.rise(&CPUZ); // разрешаем прерывания от CPU + timerX.attach_us(&TickX, (NULL)); // запрещаем прерывания от timerX + timerZ.attach_us(&TickZ, (NULL)); // запрещаем прерывания от timerZ + Enc_disable (); // запрещаем прерывания от энкодеров + ++k1; EStop =1; + } + if (AMZ||AMX) Alarm (); + if (k1==1) + { + if ((bufZ1!=bufZ) ||(bufX1!=bufX)) OUTLCD(); + OUTfrequencY(); + if (!Up||!Down) + { + wait_ms(100); + if (!Up) + { + --K; + while(!Up) {wait_ms(100);} + } + if (!Down) + { + ++K; + while(!Down) {wait_ms(100);} + } + wait_ms(100); + EStop =0; + ++k1; + } + } + if (k1==2) + { + CStX.rise(NULL); CStZ.rise(NULL); // запрещаем прерывания от CPU + timerX.attach_us(&TickX, (TimeX1)); // разрешаем прерывания от timerX + timerZ.attach_us(&TickZ, (TimeZ1)); // разрешаем прерывания от timerZ + Enc_enable (); // разрешаем прерывания от энкодеров + EStop =0; k1=0; wait_ms(100); + } + SpX1Z1 (); // утановка скоростей по умолчанию + } //end K3 + + +//------------------------------------------------- +// режим: конус + + if (K==4) + { + double xn; + double zn; + double TimeX3; + double TimeZ3; + SpX1Z1 (); + OUTLCD(); + OUTfrequencY (); + lcd.locate(10, 2); lcd.printf("angle %+3.0f",angle); + lcd.locate(10, 3); lcd.printf("cone deg"); + double anglerad = double(angle)*pi/180; + xn=double (sin(anglerad)); + zn=double (cos(anglerad)); + TimeX3 = 1000000/(STX*SpeedX1*(xn)); + TimeZ3 = 1000000/(STZ*SpeedZ1*(zn)); + float speedX= float (SpeedX1*float(xn)); + float speedZ= float (SpeedZ1*float(zn)); + if (angle==0) speedX=0; + //lcd.locate(10, 0); lcd.printf("%-+8.3f",TimeX3); + //lcd.locate(10, 1); lcd.printf("%-+8.3f",TimeZ3); + lcd.locate(10, 0); lcd.printf("vx %-+3.4f",speedX); + lcd.locate(10, 1); lcd.printf("vz %-+3.4f",speedZ); + + if (!XJR||!XJL) // джойстик X + { wait_ms (50); + if (!XJR&&XJU) { if (DJX!=1) Jx();} + if (!XJR&&!XJU) { if (DJX!=2) Jx();} + if (!XJL&&XJU) { if (DJX!=1) Jx();} + if (!XJL&&!XJU) { if (DJX!=2) Jx();} + while (!XJR||!XJL) {OUTLCD(); OUTfrequencY ();} + } + else DJX=0; + OUTLCD(); OUTfrequencY (); + if (!ZJR&&ZJU||!ZJL&&ZJU) //джойстик Z + { + if (!ZJR&&ZJU) //если Z вперёд (-Z) + { + DZ=1; // + if (xn>0) DX=0; //X в плюс + if (xn<0) DX=1; //X в минус + } + if (!ZJL&&ZJU) + { + DZ=0; //если Z назад + if (xn>0) DX=1; //X в минус + if (xn<0) DX=0; //X в плюс + } + if (angle==90) {DJZ=0;} + else + { + TimeZ = TimeZ3; + DJZ=1; + } + if (angle==0) {DJX=0;} //запрет движения по X + else + { + TimeX=abs(TimeX3); + DJX=1; + } + Enc_disable(); + while (!ZJR||!ZJL) {OUTLCD(); OUTfrequencY ();} + } + else + { + DJZ=0; DJX=0; + Enc_enable(); + SpX1Z1 (); // утановка скоростей по умолчанию + } + OUTLCD(); OUTfrequencY (); + } //end K4 +//------------------------------------------------- +// режим установки скоростей по X и Z + + if (K==5) + { + if (!XJU||!ZJU) N_T=!N_T; + SpX1Z1 (); // утановка скоростей по умолчанию + if (N_T) + { + lcd.locate(0, 0); lcd.printf(" mm/s "); + } + else + { + lcd.locate(0, 0); lcd.printf(" mm/n "); + } + lcd.locate(10, 0); lcd.printf(" mm/min "); + lcd.locate(0, 1); lcd.printf("vx=%6.2f",SpeedX1); + lcd.locate(10, 1); lcd.printf("Vx=%7.2f",SpeedX2); + lcd.locate(0, 2); lcd.printf("vz=%6.2f",SpeedZ1); + lcd.locate(10, 2); lcd.printf("Vz=%7.2f",SpeedZ2); + + if (i==0){ lcd.locate(12, 3); lcd.printf(" vx ");} + if (i==1){ lcd.locate(12, 3); lcd.printf(" Vx ");} + if (i==2){ lcd.locate(12, 3); lcd.printf(" vz ");} + if (i==3){ lcd.locate(12, 3); lcd.printf(" Vz ");} + OUTfrequencY(); + + } //end K5 +//------------------------------------------------- + //SpX1Z1 (); + } //end while(1) +} //end main \ No newline at end of file