Снова подниму тему глобальных переменых... Прочитал я в этой теме, что это зло, но от него не могу отказаться. Тут один проектик разросся до того, что стал трудно "сопровождаемым" и я решил его побить по модулям. Вот с одной проблемой не знаю как справиться. Выделил в отдельный модуль обработчик клавиш - всё вроде внятно, но есть одна переменная у неё kbddelay - таймер задержки, которая декрементируется в таймерном прерывании. Пока оно было в одном файле - проблем не было. А теперь обработчик прерываний находится в главном файле проекта, а обработчик кнопок в другом. Где эту переменную объявить, описать итд.
Есть еще одна - буфер "видеоозу". Используется в главном модуле и в модуле конфигурации. Конечно, я могу в каждом модуле выделить свой буфер - на функционал не влияет, но прамяти жалко. Пока объявил в main.c а в configure.c написал как extern.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
есть, как говорится, два способа: правильный и удобный удобный - это плевать на то, как говорят, делать так, чтобы работало. но тут следует помнить, что удобно одному, другому будет неудобно. да и собственные привычки могут поменяться с годами...
а правильный способ - это изолировать сущности друг от друга. с видеоозу, по правильному, не должны работать модули напрямую, как с массивом - только через предназначенные для этого функции. в этом случае и видеоозу, и функции для работы с ним будут в одном модуле, а для других модулей видеоозу существовать не будет - только функции, которые чтото там выводят/рисуют.
с обработчиками прерываний все похуже, т.к. у них особый статус "невидимок для всех". поэтому, с моей точки зрения, идеальным был бы вариант, когда прерывание для работы с клавиатурой определено в модуле работы с клавиатурой. но если одно прерывание занимается обслуживанием интересов нескольких модулей - так не выйдет. и тут городить излишние "изолирующие прокладки" в виде промежуточных модулей, не очень хорошая идея: попрёт оверхед памяти, снизится производительность... тут нужно искать компромиссы, например, по типу, как у вас
uldemir писал(а):
объявил в main.c а в configure.c написал как extern
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
есть одна переменная у неё kbddelay - таймер задержки, которая декрементируется в таймерном прерывании. Пока оно было в одном файле - проблем не было. А теперь обработчик прерываний находится в главном файле проекта, а обработчик кнопок в другом. Где эту переменную объявить, описать итд.
объявлять там, где непосредственно используется. Так же иметь в "модуле" функцию, декрементирующую сию переменную, и дергать ее из прерывания или откуда угодно еще.
Есть еще одна - буфер "видеоозу". Используется в главном модуле и в модуле конфигурации. Конечно, я могу в каждом модуле выделить свой буфер - на функционал не влияет, но прамяти жалко
храните и используйте указатели на буфер, заносите в них актуальный адрес при инициализации.
с видеоозу, по правильному, не должны работать модули напрямую, как с массивом - только через предназначенные для этого функции. в этом случае и видеоозу, и функции для работы с ним будут в одном модуле, а для других модулей видеоозу существовать не будет - только функции, которые чтото там выводят/рисуют
это даже на "больших" компах далеко не всегда проканывает. Зачастую вывод чего-нибудь графического начинается с обращения к вышележащей софтине (драйверу/интерфейсу/части тулкита) типа "дай мне буфер для непосредственных манипуляций".
Всем привет! Пытаюсь написать алгоритм работы с SPI EEPROM, но из-за недостатка опыта сомневаюсь в правильности алгоритмов, потому требуется помощь. Контроллер STM32F103C8 (Reference manual) Память M95M01 (pdf) В общем, начал с низкоуровневых функций. Настройка SPI2, поднятие преываний на прием и окончание передачи. Как я понимаю передача и приём идет одновременно. В интернете полно примеров, но там используются всякие костыли типа
SpiEepromStatus ui8EepromSendByte(uint8_t byte) { SpiEepromStatus Status = SPI_EEPROM_STATUS_BSY;
if (SPI2->SR & SPI_SR_TXE) { SPI2->DR = byte; Status = SPI_EEPROM_STATUS_RDY; } else Status = SPI_EEPROM_STATUS_BSY;
return Status; }
Смысл такой, что если циклически вызывать
Код:
ui8EepromSendByte
и чекать что вернула функция, то можно рулить тем, что бы данные отправлялись тогда, когда предыдущие гарантированно уйдут. Такая конструкция приемлема или есть более интересная реализация?
В целом, цель поднять FAT на SPI EEPROM и определить её как USB, потому в этом контексте, подобная реализация низкоуровневых функций норм? Или же мне отправляемые/принимаемые данные через кольцевой буфер гонять? Или исходящий поток нет смысла через кольцевой буфер гнать? Вообще, общение с EEPROM постраничное? т.е. прежде чем изменить байт (-ты), я должен прочитать всю страницу, изменить нужную информацию и записать вновь?
и чекать что вернула функция, то можно рулить тем, что бы данные отправлялись тогда, когда предыдущие гарантированно уйдут. Такая конструкция приемлема или есть более интересная реализация?
каноничный подход - сначала дождаться взведения флага TXE, потом чего-то пытаться отправить
Вопрос то не по Сям. Надо было здесь топик создавать, сразу бы про DMA разговор бы пошел .
Точно. Виноват. Подумал что алгоритмические вопросы тоже сюда )) Наверное передислацируюсь туда. Если есть возможноть, то удалите, пожалуйста, мой пост, что бы не захламлять.
В старой реализации SPI, как у F1, достаточно было выбрать 8-ми битный формат в CR1 и тогда при записи байта в DR байт и оправлялся, а в новом SPI все иначе, там чтобы ушел байт нужно привести 16-ти битный DR к указателю на байт, иначе отправятся сразу два байта.
Зарегистрирован: Пт фев 14, 2014 20:45:33 Сообщений: 94 Откуда: Северный Кавказ
Рейтинг сообщения:0
Пытаюсь изучить работу таймера и прерываний. MK AT89C2051, кварц 4 МГц. Компилятор языка Си ICC8051. По задумке таймер должен перезагружаться каждые 0,05 с (предустановка таймера 0xBEE5 - 48869). Для визуализации на портах P3.7 и P1.3 подвешены светодиоды. По поему (вероятно ошибочному мнению) HG2 на P3.7 должен одну сек. гореть, одну сек. быть потушенным. А HG1 на P1.3 мигать с частотой около 20 Гц. Но что-то пошло не так... Не могу разобраться сам в чём косяк.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 35
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения