Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 12:56:42

Не совсем в тему, но
PORTD &= ~(1 << PD6)&&~(1 << PD7);


эквивалентно
Код:
PORTD &= 1;
Пока Вы не замечаете, но когда начнут использоваться другие ножки PORTD, будете долго искать.

Немного ближе к теме. Я так понимаю, что TCNT0 переполняется. Это так? Если да, то
Код:
(a-b) < 20
не совсем корректно.

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 13:32:11

viiv писал(а):Не совсем в тему,
в тему! сюда я не заглядывал (принял как проверенную команду останова мотора)
viiv писал(а):TCNT0 переполняется?
переполняется, но это не мешает вычитанию (если переменные правильные - unsigned char и результат такойже)

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 13:48:50

тогда хотябы так:
Код:
ISR (TIMER2_OVF_vect)
{
takt++;
if (takt==40) {b=TCNT0;}
if (takt==50)
  {
  a=TCNT0;
  if (a-b<20) {PORTD &= ~(1 << PD6)&&~(1 << PD7);}
  b=a;
  takt=40;
  }
}

ждет 40 тактов, берёт первую пробу, ещё через 10 берет вторую и сравнивает, следующее сравнение будет через 10 тактов
при запуске двигателя не забудь скинуть takt=0; чтобы обеспечить твои обязательные 2 секунды работы двигателя.

Добавлено after 7 minutes 11 seconds:
по приблизительным подсчетам при тактовой 8 МГц при рабочих оборотах переполнение Т0 может произойти уже на 3х тактах (а при меньшей тактовой частоте и раньше), поэтому вместо (takt==50) надо писать (takt==42)


Ты написал то же, что и я только "перефразировав". Я уже писал, что так не работает. Переполнение таймера ТО, при частоте 8MHz будет через 8000000\1024\256=30 тактов.
Вот проект в Proteus с твоим примером, может так нагляднее будет (так же в вложении библиотека для драйвера упр. мотором).
Вложения
BrizMega8.rar
(26.57 KiB) Скачиваний: 210

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 13:57:53

это переполнение т2 будет с частотой 30 Гц
теперь посчитаем что будет в т0 через 1/30с (возьмем 3500об/мин и 50 имп/оборот)
3500*50/60/30=97. Т0 досчитает до 97 за одно переполнение Т2.... за 3 переполнения будет 291, а это уже залёт.
проект скачаю, но вникнуть сегодня уже не успею...

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 14:00:29

это переполнение т2 будет с частотой 30 Гц
теперь посчитаем что будет в т0 через 1/30с (возьмем 3500об/мин и 50 имп/оборот)
3500*50/60/30=97. Т0 досчитает до 97 за одно переполнение Т2.... за 3 переполнения будет 291, а это уже залёт.
проект скачаю, но вникнуть сегодня уже не успею...


Ок. Спасибо!

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 14:00:54

чегото наверно версия не та... какой из файлов протеусом открывать?

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 14:09:59

чегото наверно версия не та... какой из файлов протеусом открывать?

BrizMega8.pdsprj
Proteus8

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 14:11:37

сюда я не заглядывал

Так я и не Вам отвечал :-)


переполняется, но это не мешает вычитанию (если переменные правильные - unsigned char и результат такойже)

1) вижу, что а и b объявлены как int
2) тогда и надо результат операции (a-b) приводить к unsigned char - этого не вижу в коде

Код:
        unsigned char b = 255;
        unsigned char a = b + 21;       /* сделан 21 шаг */

        if (a-b<20)
                printf ("Less (Ok)\n");
        else    printf ("fail\n");


Что выдаст? По Вашей логике, должно "fail".

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 14:18:53

про правильность типов я уже тоже писал и, надеюсь :) был услышан

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 15:03:58

сюда я не заглядывал

Так я и не Вам отвечал :-)


переполняется, но это не мешает вычитанию (если переменные правильные - unsigned char и результат такойже)

1) вижу, что а и b объявлены как int
2) тогда и надо результат операции (a-b) приводить к unsigned char - этого не вижу в коде

Код:
        unsigned char b = 255;
        unsigned char a = b + 21;       /* сделан 21 шаг */

        if (a-b<20)
                printf ("Less (Ok)\n");
        else    printf ("fail\n");


Что выдаст? По Вашей логике, должно "fail".


Я не совсем понял ваш код. Логику я описал. unsigned char, на сколько я понимаю, это целые числа от 0 до 255. Каким образом это влияет на выражение a-b<20 ? И как применить ваш пример относительно моего проекта?

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 15:30:17

dds7sdd, пожалуйста, не цитируйте посты целиком (темболее предшествующие непосредственно).
по поводу условия - возьми свободный порт и копируй результат вычитания в него, подавай на вход разную частоту и смотри результат.
у меня протеуса 8 нет, потому не знаю есть такой порт или придётся сделать тестовую плату - но результат сразу будет наглядный.

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 16:11:40

Ivanoff-iv Хорошо не буду. Не совсем понял последний совет...

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 17:19:18

ну вот смотри при вычитании должно получиться число 8бит беззнаковое и порт можно настроить 8бит беззнаковым числом вот и посмотри если есть свободный (или временно освободи занятый, заремив к нему обращения и отцепив провода) и вместо условия напиши PORTX=a-b; где х - твой порт, затем прицепи ко входу генератор импульсов, который можно в процессе симуляции настраивать (в протеусе 7 он есть) и регулируя его смотри что будет на порту (понятно что его надо настроить на выход)...там в двоичном коде (красными и синими квадратиками) должно отображаться число, пропорциональное скорости импульсов - так и работу проверишь и частоту выстроишь.

Добавлено after 1 minute 18 seconds:
я, когда начинал, часто к таким приёмам прибегал, сейчас больше умозрительно косяки нахожу.

Добавлено after 13 minutes 8 seconds:
зато досихпор оцениваю загрузку процессора МК - в начале всег прерываний (которые будят контроллер) поднимаю определённую ногу, а перед асм"слип" сбрасываю её в 0, а потом к ноге цепляю осциллограф

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 17:41:15

Ivanoff-iv Спасибо за разъяснения. Принцип понял, но не понял, что это мне даст... В режиме отладки кода Watch в Протеусе, я и так вижу все пошагово и какие значения принимают переменные, и т. д.

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 18:22:09

Я не совсем понял ваш код. Логику я описал. unsigned char, на сколько я понимаю, это целые числа от 0 до 255. Каким образом это влияет на выражение a-b<20 ? И как применить ваш пример относительно моего проекта?


Я просто привел пример, что код может неправильно работать, если между двумя чтениями TCNT0 было его (TCNT0) переполнение.
a - текущее значение TCNT0
b - значение TCNT0 5 тиков TIMER2 назад

Лень искать стадарты, а потом их пересказывать их.

Вот четыре функции. Можете, сказать в каких из них, условие будет истинно? т.е. выполнится присвоение PORTD = 0;

Спойлер
Код:
#include <avr/io.h>
void x1 (void)
{
        unsigned char b = 255;
        unsigned char a = b + 21;       /* сделан 21 шаг енкодера */

        if (a-b<20) {
                // можете с уверенностью сказать, зайдем сюда или не зайдем?
                PORTD = 0;
        }
}

void x2 (void)
{
        unsigned char b = 255;
        unsigned char a = b + 15;       /* сделано 15 шагов енкодера */

        if (a-b<20) {
                // можете с уверенностью сказать, зайдем сюда или не зайдем?
                PORTD = 0;
        }
}

void f1 (void)
{
        unsigned char b = 255;
        unsigned char a = b + 21;       /* сделан 21 шаг енкодера */

        if ((unsigned char)(a-b) < 20) {
                // можете с уверенностью сказать, зайдем сюда или не зайдем?
                PORTD = 0;
        }
}

void f2 (void)
{
        unsigned char b = 255;
        unsigned char a = b + 15;       /* сделано 15 шагов енкодера */

        if ((unsigned char)(a-b) < 20) {
                // можете с уверенностью сказать, зайдем сюда или не зайдем?
                PORTD = 0;
        }
}


А если в proteus-е прошагать?

Если лень - то вместо if (a-b<20) пишите if ((unsigned char)(a-b) < 20).

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 19:55:00

viiv, я сразу понял к чему вы клоните, но посчитал это излишним, т.к. по идее код должен разложиться примерно так темп=а; темп-=б; (темп<20)? врядли под 8бит переменную компилятор задействует 16бит регистров. Но вы так уверенно настаиваете, что я засомневался, завтра посмотрю. ну, ещё можно так сделать: а-=b; if(а<20) {...}; b+=а;
по протеусу, завтра посмотрю как ему в душу заглянуть, а то мне он только на паузе содержимое показывает... наверно придётся на 8й переходить.

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 20:28:21

Ivanoff-iv, viiv, Господа! Мне даже стыдно что либо написать, ибо мой "француСИшный" - равен нулю... С этого момента я вообще перестал что либо понимать... Но если будет решение - постараюсь обязательно разобраться. Спасибо за помощь!

Re: Простое управление коллекторным двигателем с помощью МК

Чт мар 29, 2018 21:48:53

да, нет тут ничего сложного, просто для компилятора (и впоследствии для МК) один и тот же набор бит может означать разное число, для того ытобы этой путаницы не возникло - применяют приведение типов, просто я считаю что тип здесь сбиться не может, а viiv считает что лучше перебдеть и заставить компилятор воспринимать результат вычитания именно как беззнаковый 8битный. я в ответ предложил сохранять разность в одну из исходных переменных т.к. она имеет нужный тип.

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 10:18:13

проверил -
if ((unsigned char)(a-b) < 20) - работает
a-=b; if(a<20) {...}; b+=a; - работает
if (a-b<20) - неработает там под эти вычисления не 2, а аж 4 байта (регистра) выделяется - по 2 на каждую переменную...

Добавлено after 53 seconds:
так, что я был неправ, или не совсем прав в этом вопросе :oops:

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 11:45:23

Ivanoff-iv Я правильно понял, нужно записать так?

unsigned char b;
unsigned char a;
unsigned char takt = 0;

ISR (TIMER2_OVF_vect)
{
a=TCNT0;
takt++;
if (takt==25) {b=TCNT0;}
if (takt==30) {if ((unsigned char)(a-b) < 20){PORTD &= 1;} takt=0;}
}

Но так все равно не работает...
Вы можете привести рабочий пример?
Ответить