|
C++ и макросы имени Аскольда Волкова., Хочу скрестить:) |
|
|
|
Jul 31 2009, 08:06
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(sergeeff @ Jul 31 2009, 12:48)  Вы внимательно пересмотрите свой топик. Пересмотрел. Не увидел, в чём я неправ. Я лишь симметрично отвечал. Цитата Не можете поддерживать в спокойном тоне дискуссию - не мои проблемы. Могу. Пока кто-то не выведет дискуссию из спокойного русла. Цитата Не можете ясно излагать свои идеи - тоже не ко мне. Могу. Я излагаю свои идеи на форуме разработчиков электроники. Это подразумевает определённый уровень участников. Если кто-то не понимает - не мои проблемы. Цитата Напоследок хочу пожелать быть более уравновешенным и уважительным. Я это и раньше замечал в других ваших сообщениях. Ах, вот оно что. Вы решили меня повоспитывать? Спасибо, не надо. Цитата Если я вас чем-то обидел - прощу прощения и на том закончим. Ок.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Aug 19 2009, 05:09
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Подниму тему. У меня сейчас мысль не про макросы, а вот про это изящное решение с шаблонизацией регистров: Цитата(Сергей Борщ @ Jul 29 2009, 16:50)  Я делал так. это не совсем по теме, но...: Код enum usci_module_t { USCI0, USCI1 }; template <usci_module_t const module> class uscia_t { public: class usca_ctl0_t /* USCI Ax Control Register 0 */ { public: uint8_t operator=(uint8_t value) { module ? UCA1CTL0 = value : UCA0CTL0 = value; return value; } void operator|=(uint8_t value) { module ? UCA1CTL0 |= value : UCA0CTL0 |= value; } void operator&=(uint8_t value) { module ? UCA1CTL0 &= value : UCA0CTL0 &= value; } operator uint8_t() { return module ? UCA1CTL0 : UCA0CTL0; } } static CTL0; ... // pins class txd_bit { public: operator uint8_t() { return module ? (1 << 6) : (1 << 4); } } static TXD_BIT; ... }; template <usci_module_t module> class uart_t { typedef uscia_t<module> UCA; public: static INLINE inline void init(uint32_t const divider); .... }; template <usci_module_t module> void uart_t<module>::init(uint32_t const divider) { UCA::CTL1 |= (1 * UCSWRST); UCA::CTL1 = 0 ... } Здесь ведь можно сделать ещё красивее, если унаследовать uart_t от uscia_t: Код template <usci_module_t module> class uart_t: public uscia_t<module> { public: static INLINE inline void init(uint32_t const divider); .... }; Тогда не потребуется указывать UCA:: при обращении к регистрам: Код template <usci_module_t module> void uart_t<module>::init(uint32_t const divider) { CTL1 |= (1 * UCSWRST); CTL1 = 0 ... }
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Aug 28 2009, 16:54
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Сергей Борщ @ Aug 19 2009, 15:07)  А это мысль! Нет предела совершнству! Оказывается, есть... Эта красота не работает в более свежих gcc. Ругается, что мембер из базового класса "was not declared in this scope" в классе-потомке. Я покопался в интернете, оказывается, что стандарт на этот счёт гласит: 14.6.2/3 In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
И даже есть специальный баг, из-за которого, возможно, это работает в msp-gcc  Я опечален
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 5 2009, 21:44
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Короче, вот что получилось в итоге:
pin_h_stm32.rar ( 1.39 килобайт )
Кол-во скачиваний: 381От общего виртуального предка я отказался, всё-таки оказалось накладно. Придумал другой способ передачи ножек в объект - через параметр шаблона. Например, библиотечный файл adc.h: Код template <typename cs_pin>class adc_t { private: spi_t& spi; cs_pin CS; void select() { CS.On(); } void deselect() { CS.Off(); } public: adc_t(spi_t& spi_ref): spi(spi_ref) { CS.Mode(OUTPUT); deselect(); } } А в приложении: Код typedef Pin<'A', 2, 'L'> adc_cs_t; typedef adc_t<adc_cs_t> adc1_t; и, наконец, Код adc1_t adc(spi2); Как-то так  Конструктивная критика и предложения по улучшению - приветствуются  ЗЫ. Есть ещё такая-же, но для MSP, на днях выложу.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 3 2010, 16:10
|

Местный
  
Группа: Свой
Сообщений: 268
Регистрация: 4-11-05
Пользователь №: 10 470

|
На днях опять пришлось иметь дело с проектом, где с разными ножками контроллера поочередно выполняются одинаковые действия. Снова вернулся к проблеме обращения к ногам через ссылки в массиве. И хотя главную проблему так и не решил (неоправданное разрастание кода при использовании виртуальных функций в шаблонных классах), однако получилось написать класс, который понимает Аскольдовские объявления ножек, а также имеется возможность создать порты на разные контроллеры. В данном случае выкладываю порт на ADuc702x, который можно переделать например под AVR переписав небольшой класс BaseIO, или еще лучше добавить условную компиляцию... Код #define Req1 1, 0, L #define Req2 1, 1, L //... #define ChipSel1 1, 7, L #define ChipSel2 0, 5, L //... #include "ascold.h" #include "pin.hpp" Pin<ChipSel1> CS1; Pin<ChipSel2> CS2;
Pin<Req1> RQ1; Pin<Req2,OUTPUT_OK> RQ2;
int main() { on(ChipSel1); // макрос Аскольда Волкова CS1.On(); // гибрид на С++ }
Прикрепленные файлы
pin.zip ( 2.14 килобайт )
Кол-во скачиваний: 77
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|