Как сохранить статус контакта MCU-GPIO (значение) в массиве из 10 чисел в Embedded C?

Я хочу прочитать статус вывода MCU GPIO и повторно сохранить его в массиве из 10 номеров. Когда массив заполнен, он должен сдвинуть значение влево и сохранить новое значение в [9]-й позиции нижнего индекса и продолжить.

Как я могу реализовать это как код в Embedded C?


person Emlinux    schedule 11.08.2015    source источник
comment
Вместо того, чтобы каждый раз перемещать данные, как насчет использования кольцевого буфера?   -  person Steve Melnikoff    schedule 11.08.2015
comment
Нет языка Embedded C!   -  person too honest for this site    schedule 11.08.2015
comment
Звучит как неправильный подход, чтобы делать неправильные вещи. Но без дополнительной информации вряд ли возможен хороший ответ. Например. один контакт/бит, параллельный порт? Что вы имеете в виду под цифрами? C не знает чисел.   -  person too honest for this site    schedule 11.08.2015


Ответы (3)


Учитывая, что вы каждый раз сохраняете только 1 бит, массив не является единственным решением:

static uint16_t buffer = 0;

void gpio_add(bool pin_value)
{
    buffer >>= 1;
    if(pin_value) {buffer |= 0x0200;}
}

bool gpio_get_entry(uint8_t index)
{
    return !!(buffer & (1 << index));
}

Обратите внимание, что если вы используете этот подход, вы также можете хранить 8 или 16 значений.

Если цель этого состоит в том, чтобы реализовать простой дебаунсер (т. е. определить, оставался ли уровень вывода стабильным какое-то время), то мы можем просто увидеть, равен ли buffer нулю или 0x3FF.

person Steve Melnikoff    schedule 11.08.2015
comment
Этот подход также можно использовать при разработке быстродействующих медианных фильтров для удаления пиков/всплесков шума. Вы можете использовать различные возможные комбинации переменной результата в качестве индекса для таблицы поиска, где каждый элемент является истинным или ложным. Или вы можете отсортировать биты/подсчитать количество единиц. - person Lundin; 13.08.2015
comment
Привет @Steve Melnikoff, спасибо за ваш ответ. да, мне нужно это, чтобы сохранить и проверить button_pin_status для устранения дребезга. Пожалуйста, предложите мне процесс. Спасибо. - person Emlinux; 24.08.2015

Если я правильно понял, это должно выглядеть примерно так:

void insert(int* arr, int size, int value){
    int i = 0;
    for(int i=0; i < size-1; i++){
        arr[i] = arr[i+1];
    }
    arr[size-1] = value;
}

С размером размер вашего массива (10 для вас). Вы должны инициализировать свой массив с 0 или -1, чтобы быть уверенным. Однако я не знаю разницы между ansi C и встроенным C. Возможно, «for (int i = ;...)» не работает, и вам придется создать переменную i непосредственно перед этим. Не уверен, что ты этого хотел.

person Asoub    schedule 11.08.2015
comment
Привет Asoub, спасибо за ваш ответ. Я уже получаю какое-то значение на выводе GPIO микроконтроллера [input = gpio_pin_read] и хочу сохранить его в виде массива из 10 чисел. каждый раз, когда я читаю значение вывода, он должен сохранять его в массив...... что-то вроде [0]......a[1]....a[2]...... ...минимум 10 значений. мой главный вопрос в том, как сохранить его в массиве... - person Emlinux; 11.08.2015
comment
Используете ли вы часы или события для каждого чтения? или что-то другое ? Как вы читаете эти значения? - person Asoub; 11.08.2015
comment
Вы захотите использовать циклический буфер вместо того, чтобы каждый раз перемещать все данные. Кроме того, это не касается того, как спроектировать фактическое чтение порта, что является сложной частью вопроса. - person Lundin; 13.08.2015
comment
Я не думаю, что перемещение десяти значений — это дорого, но циклический буфер может быть более гибким. Я не знаю, была ли проблема в том, как спроектировать его, чтобы события заполняли буфер и извлекали значения более глобальным образом. - person Asoub; 13.08.2015

Не уверен, что именно вы имеете в виду под «встроенным C», но я пишу C для встроенных систем, и я бы использовал что-то вроде следующего. (Функция GpioPrint() действительно предназначена только для (моей) отладки.)

#include <stdio.h>
#include <string.h>

// Returns the size of a[].
#define ARRAY_SZ(a) (sizeof a / sizeof a[0])

// Holds MCU-GPIO pin values.
typedef struct
{
    unsigned a[10]; // replace unsigned with your 'pin value' type
    unsigned n;     // values are in a[0..n-1]
} Gpio_t;

// Initialise the pin value store.
static void GpioInit(Gpio_t *gpio)
{
    gpio->n = 0;
}

// Add the new value to the pin store, removing the oldest if the store
// is full.
static void GpioAdd(Gpio_t *gpio, unsigned newVal)
{
    if (gpio->n < ARRAY_SZ(gpio->a))
    {
        gpio->a[gpio->n++] = newVal;
    }
    else
    {
        memmove(&gpio->a[0], &gpio->a[1], (gpio->n - 1) * sizeof gpio->a[0]);

        gpio->a[gpio->n - 1] = newVal;
    }
}

// Output the pin store contents.
static void GpioPrint(const Gpio_t *gpio)
{
    unsigned i;

    for (i = 0; i < gpio->n; i++)
    {
        printf("%2u: %10u\n", i, gpio->a[i]);
    }
}

// Test the functions.
int main(void)
{
    Gpio_t   gpio;
    unsigned newVal;

    GpioInit(&gpio);

    // Add 20 values to the pin store, checking the contents after each
    // addition.
    for (newVal = 0; newVal < 20; newVal++)
    {
        printf("add %u:\n", newVal);

        GpioAdd(&gpio, newVal);
        GpioPrint(&gpio);
    }

    return 0;
}
person matth1j    schedule 11.08.2015