mas123 писал(а):Небрежность в опытах ой как скажется на результатах опыта.
да пока всё пучком. тут главное найти золотую середину.чтобы не погрязнуть в догмах.
mas123 писал(а):А тогда вообще зачем был нужен этот опыт?
о каком опыте идёт речь?
mas123 писал(а):Я и так скажу - ёмкости зарядятся за время, куда меньшее чем 1 минуту. Поэтому, этим значением можно пренебречь!
я думаю вы просто не знаете как работает устройство и зачем нужны конденсаторы. а нужны они чтобы когда скорость ниже полтора оборота в секунду они чтобы включались и сглаживали прямоугольные импульсы которые идут на обмотки мотора. и переменная n конечно немного гуляет но в пределах 5 процентов от точки включения конденсаторов, поэтому всё нормально отрабатывает. устройство то реально работает.
mas123 писал(а):Я тоже писал код в таком безобразном стиле. И мне так же говорили о недопустимости такого.
Прозрение пришло (как и у всех) - когда я попытался разобраться в собственном коде спустя полгода после его написания. Я высказал всё о том идиоте, который так и такое написал.
а мне трудно читать код написанный так называемыми "программистами" есть конечно правила которые действительно помогают при написании и чтения кода - их я постараюсь перенять, но остальные сектанские заморочки меня не интересуют.
поэтому код
Код: Выделить всё
if (PINC.5==0) {dir=1;} else dir=2; //читаем направление
я думаю так оставить, а
Код: Выделить всё
if (PINC.4==0) {temp_step=0;} //читем шаг
else if (temp_step==0) {
вернул обратно к виду
Код: Выделить всё
if (PINC.4==0) {temp_step=0;} //читем шаг
if (PINC.4==1 & temp_step==0) {
так как конструкции else ухудшают читабельность и понимание кода. а так чётко видно, что условие срабатывает когда PINC.4==1. - то есть когда пришол фронт импульса на ногу.
ну а реальный источник глюков оказался совершенно в другом месте. оказалось что на высокой скорости глючит из за того что конфиг программы LinuxCNC настроен так чтобы высокую скорость не сразу давать а постепенно(и это правильно) увеличивая,и когда я в программе пропускал шаги в начале движения чтобы скорректировать пропуски, то пропускались как раз шаги разгона и потом резко на высокой скорости шли импульсы и кручение мотора срывалось.
исправил я это следующим образом. с помощью переменной cd я узнаю если скорость низкая
Код: Выделить всё
if (n>50) cd=1; else cd=0; // смотрим если скорость маленькая тогда раздрешаем корректировку
и тогда пропускаю корректировочные шаги
Код: Выделить всё
if (correct<=0 || cd==0) { // шаг в другую сторону если нет коррекции
if (dir==2) {step--;ob=ob-1;
if (step==0) step=8;
}
}
if(dir==2 & correct>0 & cd==1) correct--; //если шаг умышлено пропустили для коректировки то счётчик коррекции уменьшаем
ну и весь код
Спойлер
Код: Выделить всё
#include <io.h> // Хотим использовать порты ввода/вывода
#include <delay.h> // Хотим использовать функции задержек
#include <math.h>
#include <string.h>
#include <stdlib.h>
int ob,corr_count,mig_count,correct;
unsigned int n,k,n2,k2,nfp,nfp2,temp_mig_count;
unsigned char a[9];
unsigned char temp2,temp_save2,temp,temp_save,i,temp_step,temp_step2,step=1,step2=1,dir,dir2,go_step,go_step2,c0,ob_temp,cd;
unsigned int n_prev;
eeprom unsigned int n_eprom,n_eprom2,ob_eprom;
void mig(int v) {
for (i=0; i < v; i++) { //моргаем
PORTB.2=0; delay_us(100000);PORTB.2=1;delay_us(100000);PORTB.2=0;
}}
void main()
{
DDRA=(0<<DDA7) | (0<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
a[1]=1;a[2]=3;a[3]=2;a[4]=6;a[5]=4;a[6]=12;a[7]=8;a[8]=9;
nfp=93; //вручную задаём момент включения кандёров
while (1)
{
if (mig_count>0) temp_mig_count=temp_mig_count+1;
if (temp_mig_count==2500) {PORTB.1=0;} //моргаем число пропусков
if (temp_mig_count==5000) {PORTB.1=1;mig_count=mig_count-1;temp_mig_count=0;}
if (PINB.3==1){ob_temp=0;}
if (PINB.3==0 & ob_temp==0 & ob>150 & dir==1){
if (c0==1){
corr_count=ob-400; // узнаём если пропущены шаги и сколько
if (corr_count!=0) {correct=correct+corr_count;mig_count=abs(correct);} //PORTB.1=1;mig_count=mig_count+abs(abs(corr_count)/2);
}
ob_temp=1; // флаг прихода импульса - чтобы один раз исполнился код до прихода следующего импульса
ob=0; //сбрасываем счётчик шагов на ноль при каждом срабатывании датчика
c0=1; //начинаем фиксировать пропущенные шаги со второго срабатывания датчика.первое срабатывание - установка на ноль
}
if (n>50) cd=1; else cd=0; // смотрим если скорость маленькая тогда раздрешаем корректировку
/*
if (PINB.0==1 & temp_save==0) {n_eprom=n;nfp=n;temp_save=1;mig(2);} // записываем в память значение включения конденсаторов
if (PINB.0==0) {temp_save=0;} // nfp - значение с которого включаются кандёры X
if (PINB.4==1 & temp_save2==0) {n_eprom2=n2;nfp2=n2;temp_save2=1;mig(2);} // записываем в память значение включения конденсаторов для Y
if (PINB.4==0) {temp_save2=0;} // nfp2 - для Y
*/
/////////////////////////////////////////////// канал Х ....
if (PINC.5==0) {dir=1;} else dir=2; //читаем направление
if (PINC.4==0) {temp_step=0;} //читем шаг
if (PINC.4==1 & temp_step==0) {
if (nfp>k+3) {
PORTD.0=0; //индицируем выключение кандёров
PORTD.2=0; //выключаем кандёры
}
PORTB.2=0; //индицируем отключение простоя
//go_step=1; // пойдём делать шаг
temp_step=1; // цикл крутится один раз по фронту импульса
n=k;k=0; // обнуляем счётчик и узнаём время между импульсами n
if (correct>=0 || cd==0) { // шаг в одну сторону если нет коррекции
if (dir==1) {step++;ob=ob+1;
if (step==9) {step=1;}
}
}
if(dir==1 & correct<0 & cd==1) correct++; //если шаг умышлено пропустили для коректировки то счётчик коррекции увеличиваем
if (correct<=0 || cd==0) { // шаг в другую сторону если нет коррекции
if (dir==2) {step--;ob=ob-1;
if (step==0) step=8;
}
}
if(dir==2 & correct>0 & cd==1) correct--; //если шаг умышлено пропустили для коректировки то счётчик коррекции уменьшаем
temp=0;
if (ob==-400) ob=0;
PORTC=a[step]; //выводим на мотор
}
if ( nfp<n-3 ) {
PORTD.0=1; //индицируем включение кандёров
PORTD.2=1; //включаем кандёры
}
if (k>5000) //режим простоя
{
PORTB.2=1; //индицируем режим простоя
PORTC=0; //отключаем обмотки
}
if (k<30000) k=k+1;
if (k2<30000) k2=k2+1;
}
}
скорость выполнения кода увеличилось примерно в 3 раза после всех модификаций, при самой большой скорости мотора, между соседними импульсами цикл успевает прокрутиться примерно 15 раз, что достаточно для нормальной работы программы.
Глупый не задает вопросы. Глупый и так все знает.