sigmaN 0 8 января, 2015 Опубликовано 8 января, 2015 · Жалоба Всем привет! Я тут на праздниках немного поковырять что-то новое решил... Этим новым стало применене С++ в микроконтроллерном программировании. Началось всё с прочтения статьи шамана(уж извините) под ником Neiver. http://easyelectronics.ru/rabota-s-portami...erov-na-si.html С помощью не детских заклинаний, кажется, ему удаётся творить настоящие чудеса, о которых простым смертным Сишникам даже мечтать в голову не приходит ) Идеей шаблонной магии я здорово проникся и принялся за изучение главного пособия чёрных магов метапрограммирования - книги Современное проектирование на C++, за авторством Андрея Александреску. http://rutracker.org/forum/viewtopic.php?t=1434859 На данном этапе мне доступны лишь заклинания первого уровня, пользуясь которыми я реализовал довольно портабельный драйвер семисегментного индикатора с выводом значения на дисплей вызовом вида Display.DysplayStr("1234"); С поддержкой разных алфавитов символов, разными методами(полярность) засветки сегментов и отвязкой от реализации портов ввода/вывода, которая реализована благодаря библиотеке IO от Neiver. Ознакомиться с исходником можно тут http://pastebin.com/YMM96qz5 Вся эта красота и удобство скомпилилось в ~180байт кода и для дисплея с 2мя цифрами требуется 3 байта оперативки ) Драйвер поддерживает от 1 до 6 цифр. Используется драйвер очень просто: #include <avr/io.h> #include "iopins.h" #include "pinlist.h" #include "7seg.h" using namespace IO; //тут пины к которым подключен 7сегментник. //любое сочетание доступных пинов(не обязательно по порядку как тут) typedef PinList<Pc0, Pc1, Pb0, Pb1, Pb2, Pb3, Pb4, Pb5, Pb6, Pb7 > MyPins; //объевляем дисплей с 2мя цифрами, с методом засветки 0 на сегмент, 1 на цифру и алфавитом из цифр. SevenSeg<MyPins, 2, LOW, HIGH, DIGITSONLY> disp; int main(void) { disp.DysplayStr("18"); while(1) { //по идее это вызывается в прерывании таймера disp.Sync(); } } Как думаете, это действительно так круто как кажется? Нам всем надо радоваться, что технологии зашли так далеко, что теперь даже 8ми битную АВРку я могу программировать используя очень высокоуровневые конструкции или всё это от лукавого? Потому что я тут еще и библиотеку, реализующую механизм делегатов подтянул www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible и она даже работает! Уже хотя-бы на той-же XMEGA можно создавать почти "книжные" архитектуры и паттерны с учетом всех заветов Стива Макконнелла, наставляющего нас посредством своей легендарной книги Совершенный Код(http://cafe-aristokrat.nethouse.ru/static/doc/0000/0000/0102/102807.m0nldixuku.pdf) Не знаю как кто, а я в восторге! Потому что в принципе до сего дня я считал, что С++ это неуместная роскошь, доступная и оправданная как минимум на STM F4 :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 8 января, 2015 Опубликовано 8 января, 2015 · Жалоба Этим новым стало применене С++ в микроконтроллерном программировании. ... Как думаете, это действительно так круто как кажется? Так ведь МК бывают разные. Одно дело - высокопроизводительный ARM с кучей ОЗУ и ПЗУ, и совсем другое - PIC или AVR. Для восьмибитных МК, ИМХО, обычного Си хватает с головой. Хотя, если вам нравится ... Почему бы и нет ? Вы довольны ? И заказчик доволен ? Тогда зачем вам чьи-то мнения ? P.S. Вспоминаю, как я лет 10 назад открыл для себя Си. Первые же проекты показали, что на нем можно за день сделать то, что на ассемблере делается за неделю или даже две. Вот это было открытие :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 8 января, 2015 Опубликовано 8 января, 2015 · Жалоба Не знаю как кто, а я в восторге! А ведь есть ещё и ось на плюсах. Это уже будет восторг в квадрате:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 8 января, 2015 Опубликовано 8 января, 2015 · Жалоба ну а чем это лучше struct pin { int* port; int num; ... }; void pin_set(struct pin* pin, bool val){ ... } ... // дисплей один, поэтому все статическое static struct pin dist_pins[]={ { .port=..., .pin=... }, // a ... // f } void disp_print(char* str){ ... } void disp_update(){ ... } ? Насколько понимаю, в вашем коде шаблоны используются как макросы? Инициализация производится в конструкторах объектов? пмсм, не очень удобно. Использования каких-то особенностей C++, принципиально не реализуемых на C (перегрузки операторов, наследования и т.п.), в приведенном коде не наблюдается. Кстати, Александреску подался в D ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба Шаблоны, переносимость, повторное использование мне не нужны. А ООП, инкапсуляция, структурное программирование - назрела необходимость. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба ну а чем это лучше struct pin { int* port; int num; ... }; void pin_set(struct pin* pin, bool val){ ... } ... // дисплей один, поэтому все статическое static struct pin dist_pins[]={ { .port=..., .pin=... }, // a ... // f } void disp_print(char* str){ ... } void disp_update(){ ... } В статье http://electronix.ru/redirect.php?http://e...erov-na-si.html рассмотрены основные проблемы передачи по указателю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
smalcom 0 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба https://github.com/KonstantinChizhov/AvrPro...mcucpp/iopins.h https://github.com/KonstantinChizhov/AvrPro...tCppIo/main.cpp и http://electronix.ru/forum/index.php?showt...st&p=808044 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба Да да, когда-то я тоже говорил что си наше все и плюсов нам не надо) Кстати посмотрю как нибудь исходники scmRTOS... Интересно же) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба Поверю в эффективность предложенного, когда увижу управление, например, таймером STM32 с помощью шаблонов. Предполагаю, что не увижу никогда. А так - нет. Баловство для развлечения. Для обучения неплохо, въехать в C++. А портом дрыгать я и так умею виртуозно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба В статье http://electronix.ru/redirect.php?http://e...erov-na-si.html рассмотрены основные проблемы передачи по указателю. Статья интересная. В принципе, практически все то же самое можно было сделать руками и на С. Например, как-то так: #include <stdbool.h> enum { PORT_A=0, PORT_B=1 }; static void portA_set(int pin_num, bool val){ ... } static void portA_dir(int pin_num, bool val){ ... } static void portB_set(int pin_num, bool val){ } static void portB_dir(int pin_num, bool val){ } struct port_handler { void (*set)(int, bool); void (*dir)(int, bool); }; static struct port_handler handlers[]={ { .set=portA_set, .dir= portA_dir }, { .set=portB_set, .dir= portB_dir } }; void port_set(int port_num, int pin_num, bool val){ struct port_handler* p=&handlers[port_num]; p->set(pin_num, val); } void port_dir(int port_num, int pin_num, bool val){ struct port_handler* p=&handlers[port_num]; p->dir(pin_num, val); } #define EN_ 9 int main(){ port_set(PORT_A, EN_, true); ... } В случае C++ компилятор сам развернет portX_set, portX_dir по шаблону. Но статья интересная. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Леонид Иванович 0 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба А портом дрыгать я и так умею виртуозно. Как раз в STM32 портом дрыгать намного красивей получается на C++ с использованием шаблонов. Настройка аппаратных таймеров - там монстроидальный шаблонный класс получится, ну его. А вот программные таймеры в виде экземпляров соответствующего класса - это красота. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба Настройка аппаратных таймеров - там монстроидальный шаблонный класс получится, ну его. Из этого следует: C++ с шаблонами не подходит для инициализации аппаратуры чуть посложнее порта ввода-вывода? Так может, ну его... не C++, а шаблон? :rolleyes: Шаблоны хороши для чего-то унифицированного, GUI всякие, кнопки... Насчет красоты - меня восхищают собственные макрофункции для инициализации и работы с портами. И таймеры я настраиваю столькими (или чуть больше) командами, сколько регистров есть в управляющей аппаратной структуре. Что правильнее - пять команд засылки в регистры или монстроидальный шаблонный класс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба или монстроидальный шаблонный класс?Который скомпилится в те же пять команд записи, но в исходнике будет занимать всего одну строчку. Конечно шаблонный класс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 9 января, 2015 Опубликовано 9 января, 2015 · Жалоба Который скомпилится в те же пять команд записи, но в исходнике будет занимать всего одну строчку. Конечно шаблонный класс. Это вы не посчитали строчки в исходнике шаблонного класса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 10 января, 2015 Опубликовано 10 января, 2015 · Жалоба Это вы не посчитали строчки в исходнике шаблонного класса. А вы строчки исходников своих макросов посчитали? Ну больше гибкости дают шаблоны, больше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться