Попытка сжать код при сохранении модульности с помощью побитового оператора - PullRequest
0 голосов
/ 18 сентября 2018

Я работаю над проектом встраиваемых систем и читаю несколько переключателей, а затем делаю что-то в зависимости от результата.Я пытаюсь сохранить это модульным и абстрагированным, чтобы каждая из моих функций не видела ни одного из низкоуровневых номеров выводов или функций чтения выводов.

Может быть несколько выключателей одновременно, поэтому яЯ сохраняю числа с помощью побитового или |, а затем с помощью побитового сравнения.В настоящее время я просто избыточно преобразовываю считываемый вывод в значения моего переключателя, которые можно сравнить с побитовыми операторами.

Является ли более эффективный или лучший способ сделать это?

// physical pins on microcontroller
#define pin_sw_green 5
#define pin_sw_yellow 6
#define pin_sw_blue 7
#define pin_sw_red 8


// switch numbers, allowing bitwise operators to work
#define switch_green 0x01 
#define switch_yellow 0x02 
#define switch_blue 0x04 
#define switch_red 0x08 


// store switch press to val
uint8_t button_pressed()
{
  uint8_t data;
  if (pin_read(pin_sw_red))
    data |= switch_red;
  //...
  if (pin_read(pin_sw_green))
    data |= switch_green;    
  return data;
}

 //...

uint8_t button_data = button_pressed();
if (button_data & switch_red)
{
// do things..

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Вы можете прочитать их за один раз, если они являются выводами одного и того же отображенного в памяти регистра портов. Затем вы можете просто создать новую маску:

#define SWITCH_ALL (switch_green | switch_yellow | switch_blue | switch_red)

Или труднее читать, но в остальном эквивалентно:

#define SWITCH_ALL 0x0F

Затем, при условии, что вы можете избавиться от, казалось бы, лишней pin_read функции:

uint8_t button_pressed (void)
{
  return  (uint8_t) (PORTX & SWITCH_ALL);
}

где PORTX - имя регистра данных порта.

Помимо того, что он быстрее, он также имеет преимущество в том, что все ваши выводы будут считываться синхронно, в одно и то же время.

Однако, , вам, естественно, нужно будет добавить где-нибудь отскок кнопки, иначе показания будут ненадежными.

0 голосов
/ 18 сентября 2018

Скрытие доступа к порту внутри функции - это лишь небольшая и слабая форма абстракции.Вы сталкиваетесь с общей проблемой во встроенном программировании, которая заключается в объединении различных и четко реагирующих источников данных.Одним из способов является создание множества отдельных имен (в вашем случае, функций) на уровне языка - это имеет естественный предел до тех пор, пока обслуживание и тестирование не станут кошмаром.Такие системы имеют тенденцию умирать, когда создатель покидает их, по крайней мере, они становятся необслуживаемыми.

Вместо этого попытайтесь определить природу ваших входных данных на стороне бизнес-логики - в вашем случае, особенно если они являются уровнем или переходом - и создайте способ, который позволит вам получить к ним доступ с помощью адреса времени выполнения (некоторыеформа индекса) вместо адреса времени компиляции (== имя функции).Вы всегда можете организовать доступ таким образом, чтобы оптимизировать код до одинаково быстрого кода, когда параметры известны во время компиляции и при этом все еще остаются открытыми индексированный / запрограммированный способ.Затем напишите сопоставление между вашим реальным оборудованием и этими идеализированными входами, где вы можете иметь дело с такими вещами, как дебасинг, инвертированные логические уровни и т. Д.

0 голосов
/ 18 сентября 2018

Используйте struct для организации этой информации.

typedef struct{
    uint8_t green:1;
    uint8_t yellow:1;
    uint8_t blue:1;
    uint8_t red:1;
    uint8_t :4; //unused
}switch_t;

switch_t s = {0};

// store switch press to val
void button_pressed(switch_t * s)
{
    s->red = pin_read(pin_sw_red);
    //...
    s->green = pin_read(pin_sw_green);
}

button_pressed(&s);
if(s.red){
    //do stuff
}
//...
if(s.green){
    //do stuff
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...