Перейти к содержанию
    

xemul

Свой
  • Постов

    1 922
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о xemul

  • Звание

    Профессионал

Контакты

  • Сайт
    Array
  • ICQ
    Array

Retained

  • Звание
    Array

Посетители профиля

4 581 просмотр профиля
  1. if((tmp ^ (tmp>>1)) & 1) { if((StepDir >> (tmp | (EncState << 2))) & 1) должно быть ещё короче. Не могу найти старый проект. 4 энкодера (без счётчиков) вписались с антидребезгом в 4 байта ОЗУ. В #define's были EncXChY и таблица истинности для состояний энкодера. Остальные magic numbers считались препроцессором.
  2. Дык у меня кроме склероза ещё и способности к устному счёту пониженные. const uint16_t StepDir 0x2442;
  3. Если EncInput - какой-нить volatile прямо из порта, то ... И с ридабилитью сложно.
  4. switch() весьма неудобен в реализации и весьма компиляторозависим (особенно, в плане оптимизации). То же, что Вы написали, но чуть другими словами: tmp = (EncState ^ EncInput) & 0b11; if(tmp == 0b11) Error++; else if(tmp == 0b01)) StepD++; else if(tmp == 0b10)) StepD--; EncState = tmp; UPD прошу пардонов, писал по склерозу const uint16_t StepDir 0x1442; tmp = (EncState ^ EncInput) & 0b11; if((tmp == 0b01) || (tmp == 0b10)) { if(StepDir & (1<<(tmp | (EncState << 2)))) StepD++; else StepD--; } EncState ^= tmp;
  5. Всё может быть (кроме смысла в обсуждении очередного сферического коня). Я говорил про необязательность самостоятельной полировки древка грабель. (у мну коробочки с потреблением в статике ~0.1 мкА просыпаются по прерыванию от кнопок; другие коробочки, где есть часовой кварц, и можно позволить 2-3-.. мкА, просыпаются по прерыванию от RTC; были коробочки, которые пинала внешняя сторожевая собака. При этом основная масса поделий для входов с динамикой +- как от кнопок благополучно обходится опросом по софтовому таймеру с периодом 2^-7 с. А общего у всех коробочек - алгоритм антидребезга.)
  6. Выше уже поминали дребезг кнопок. Вы знаете, как с ним бороться? (чтобы сэкономить Вам немного времени: типичное время дребезга мелких тактовых кнопок 5..20 мс, больших не-тактовых - легко до 100 мс, - на это точно нужны EXTI?. На "изначально были условия: ... обязательный опрос кнопок по прерываниям" можно ответить опросом кнопок по прерыванию таймера. Потратьте сэкономленное время на разбор вариантов антидребезга.)
  7. Т.к. предыдущий пример был громоздким, савиршеннонипанятным и просто fooooo, попробую ещё раз с картинками, арфистками и домино. К тому же спич пошёл про "write code that is guaranteed to work". /* boo.h */ #ifndef _BOO_H #define _BOO_H extern int flag; #endif /* main.c */ #include <stdio.h> #ifdef WITH_EXTERN_IN_MAIN #include "boo.h" #endif extern void boo(void); void main(void); void bingo(int); int flag; void main(void) { int cnt; flag = 0; for(cnt = 0; flag != 1; cnt++) { if(flag == 1) bingo(cnt); else puts("Считаем..."); boo(); } while(1) continue; } void bingo(int prize) { if(prize == 1) puts("Получилось: один!!!111"); } /* boo.c */ #include "boo.h" void boo(void) { if((int)(2.0 * 2.0) == (int)(pow(2.0, 2.0) + 0.5)) /* типа somewhat_happened для multi-file compilation */ flag = 1; } Невооружённым глазом видно, что с -DWITH_EXTERN_IN_MAIN после любого вменяемого компилятора (полагаю, даже pre-C89) с любой оптимизацией в выхлопе будет Без -DWITH_EXTERN_IN_MAIN имеем случай ТС. Без оптимизации выхлоп будет идентичным. Но с любой оптимизацией... Не, ну понятно, volatile от оптимизации спасёт, и "code is guaranteed to work". (вот уж не помню, в этой же конфе лет дцать тому чел по совету уверовал во всемогущий volatile? "Пони бегают по кругу")
  8. ЗдОрово, и я о том же. Необходимость квалификатора volatile по содержанию исходного поста никак не просматривается. (Прилетел пакет, где-то его распарсили. Непосредственно в прерывании? Это точно про "старайтесь делать хорошо"?) У ТС (была?) явная ошибка в описании внешней переменной. Я всего лишь показал, как это исправить.
  9. Я буквально следовал условиям ТС. Про прерывания, multi-file compilation и IAR у него нет ни слова. Если Вам будет не лень поэкспериментировать про volatile и "ровно ту же самую проблему", и выложить здесь .map'ы с флагами компиляции для прояснения, то ... ЗЫЖ есть проблема - у мну нет и не будет IAR.
  10. foo.h #ifndef _FOO_H #define _FOO_H extern int flag; #endif foo.c #include "foo.h" int flag; void foo(void) { flag = 0; while(!flag) boo(); } boo.c #include "foo.h" void boo(void) { if(somewhat_happened) flag = 1; } Есть предположение, что flag не будет соптимизирован и без volatile.
  11. Если за период опроса энкодер не успевает нащёлкать 2^16, то всё ещё проще uint32_t getEncoder() { static uint16_t oldCnt = 0; // предыдущее значение счётчика таймера static uint32_t encoder = 0; // а это наш 32-битный энкодер int16_t delta = TIM3->CNT - oldCnt; // дельта счётчика, если он считал oldCnt += delta; return encoder += delta; } Если память не жмёт, а энкодеров несколько, то можно придумать каку-нить typedef struct { uint16_t * ptimcnt; int32_t enccnt; int16_t delta; } encoder_t; void update_encoder(encoder_t *penc) { ... }; // по периоду опроса энкодеров int32_t get_encoder(encoder_t *penc) {return penc->enccnt}; // по мере необходимости
  12. 1 LSB RTC_SSR при таком RTC_PRER действительно будет соответствовать 1/LSE_CLK*2. А если в PREDIV_A вписать 0, то 1 LSB RTC_SSR вообще получится 1/LSE_CLK. Но точность этой 1 будет определяться только точностью LSE_CLK. (на всякий случай) И лучше сразу придумать какой-нить выход по таймауту из цикла ожидания готовности LSE. По исходному вопросу у меня только одно предположение: т.к. RTC_SSR обнуляется только в трёх случаях, то за ~ 0.33 с до вызова RTC_TEST() приключался один из этих случаев.
  13. Если бы Вы показали инициализацию RTC, гадать было бы проще. У мну почему-то получается (для дефолтного RTC_PRER), что RTC у Вас тактируется от ~ 50 кГц.
×
×
  • Создать...