3
Dependencies: 411_lcdi2c1_latche TextLCD
main.cpp
- Committer:
- serg1958
- Date:
- 2021-03-17
- Revision:
- 0:e1947a05c2a2
- Child:
- 1:78d19167c0f7
File content as of revision 0:e1947a05c2a2:
/* 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