Чиним ПДУ для МОБДа.

Пациент при поступлении...

Пациент при поступлении...

Пульт дистанционного управления для МОБД, как уже говорилось, представляет собой несложную плату, упакованную в металлический каркас и установленную в кабине водителя.

Основных функциий у ПДУ две — выводить информацию о состоянии дизельных установок и электросистемы в целом, обеспечивать необходимый минимум функций управления и контроля. А… еще, в случае чего, сообщать, что враги ворвались в отсек 🙂

Все это обеспечивается набором диодов, сегментных индикаторов и тремя кнопками. Ну и, конечно же, прошивкой микроконтроллера платы.

Недавно от Заказчика поступила просьба о некоторой доработке функционала ПДУ, заодно решили разобраться с багой, до которой раньше руки никак не доходили.

...на операционном столе...

...на операционном столе...

Нормальный режим работы работы ПДУ — постоянное получение информации по последовательному интерфейсу. На основе этой информации гасятся или зажигаются определенным цветом диоды, выводится текст на сегментах, разрешается или запрещается дистанционное управление системой. То есть, обмен информацией идет довольно интенсивный.
И вот, время от времени неправильно срабатывают диоды — либо загораются выключенные, либо включенные срабатывают не тем цветом. Процесс носит характер кратковременного промаргивания, но глазу это заметно. Особенно в полутьме завода. При предварительном тестировании в лаборатории перед отгрузкой подобного эффекта не наблюдалось.
Естественно, такие проколы оставлять нельзя — а то вместо деликатного намека, что так быть не должно, можно в неудачный момент получить официальную бумагу-претензию. Ваша, мол, штука плохо работает… Хотя реально на функциональность этот глюк не влиял.

Запустили боевую программу, которая реально ставится на ПМУ, зациклили простенький тест — заполнить все диоды то одним цветом, то другим. И действительно — бежит фронт зеленого цвета, вдруг перед ним зажигается красная полоса и тут же гаснет.

...и перед выпиской

...и перед выпиской

Стали разбираться.
Изначально мысль была одна — где-то портится буфер. Осталось только найти где и как — просто в программе или из-за неправильного распределения памяти.
Однако, поиски результата не дали. Оно и не удивительно — реально причина оказалась оказалась в другом.

Диоды, из-за их большого количества (48 шт), подключены через сдвиговые регистры, а вывод осуществляется по spi. Обновление — по таймеру на спи отправляется массив, хранящий состояние всех диодов. Т.е. время от времени срабатывает функция вида:

void sendbyte( unsigned char x ) {
	unsigned char i;
    for ( i = 0; i < 8; i++ ) {
        // здесь забиваем в спи порт все 8 бит отправляемого байта
    }
}

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

void sendbyte( unsigned char x ) {
	unsigned char i;
__disable_interrupt();
    for ( i = 0; i < 8; i++ ) {
        // здесь забиваем в спи порт все 8 бит отправляемого байта
    }
__enable_interrupt();
}

Похожий бред:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Protected by WP Anti Spam