Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

О программировании AVR на C++

Непрочитано 21.03.2010, 19:58  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Разработка классов на основе стратегий.

Приведённый пример про шаговик конечно-же не свободен от недостатков. Некоторые из них любезно указал многоуважаемый kison. Он по этому поводу даже вспомнил баян «про один байт».
Главный из них – это если все пины находятся в одном порту, то код получается не оптимальным, особенно если это злополучный порт F, до которого не достают побитовые команды работы с портами и приходится использовать команды работы с памятью.

Как можно избавится от этого недостатка?
Нужно ввести ещё один уровень абстракции, чтобы отделить логику работы нашего шаговика от низкоуровневых деталей ввода-вывода. Не надо только говорить, что в этом примере логики-то почти нет. Это только наглядный пример, чтоб показать идею. Если пример будет слишком сложным – идею за ним можно и не заметить .

Напишем два класса, которые позволят нам абстрагироваться от вывода в порты. Один для вывода в один порт разом, естественно с ограничением, что все пины в одном порту. И второй, дёргающий пины индивидуально (как и было раньше). Такие классы сейчас модно называть стратегиями (policy).
Код:
template‹class PORT, uint8_t IN1, uint8_t IN2, uint8_t IN3, uint8_t IN4›
class StepperPerPortOutput
{
	enum {PORT_MASK = (1‹‹IN1) | (1‹‹IN2) | (1‹‹IN3) | (1‹‹IN4)};
	enum {PH1 = (1‹‹IN1) | (0‹‹IN2) | (0‹‹IN3) | (0‹‹IN4)};
	enum {PH2 = (0‹‹IN1) | (0‹‹IN2) | (1‹‹IN3) | (0‹‹IN4)};
	enum {PH3 = (0‹‹IN1) | (1‹‹IN2) | (0‹‹IN3) | (0‹‹IN4)};
	enum {PH4 = (0‹‹IN1) | (0‹‹IN2) | (0‹‹IN3) | (1‹‹IN4)};
public:
	static void OutputEnable()
	{
		PORT::dir() |= PORT_MASK;
	}
	static void Write(uint8_t phase)
	{
		uint8_t value;
		switch(phase)
		{
			case 0:
				value = PH1;
			break;
			case 1:
				value = PH2;
			break;
			case 2:
				value = PH3;
			break;
			case 3:
				value = PH4;
			break;
		}
		PORT::data() = (PORT::data() & (uint8_t)~PORT_MASK) | value;
	}
};

template‹class IN1, class IN2, class IN3, class IN4›
class StepperPerPinOutput
{
	public:
	static void OutputEnable()
	{
		IN1::SetDirWrite();
		IN2::SetDirWrite();
		IN3::SetDirWrite();
		IN4::SetDirWrite();
	}
	static void Write(uint8_t phase)
	{
		switch(phase)
		{
			case 0:
				IN1::Set(); IN2::Clear(); IN3::Clear(); IN4::Clear();
			break;
			case 1:
				IN1::Clear(); IN2::Clear(); IN3::Set(); IN4::Clear();
			break;
			case 2:
				IN1::Clear(); IN2::Set(); IN3::Clear(); IN4::Clear();
			break;
			case 3:
				IN1::Clear(); IN2::Clear(); IN3::Clear(); IN4::Set();
			break;
		}
	}
};
А класс SimpleStepper перепишется следующим образом:
Код:
template‹class OUTPUTS, class E1, class E2›
class SimpleStepper //L293 driver, for example
{
public:
	static void HalfStepFwd()
	{
		StepFwd();//TODO implement
	}
	static void HalfStepBack()
	{
		StepBack();//TODO implement
	}
	static void StepBack()
	{
		_phase = (_phase - 1) & 0x3;
		SetOutput();
	}
	static void StepFwd()
	{
		_phase = (_phase + 1) & 0x3;
		SetOutput();
	}
	static void Enable()
	{
		E1::SetDirWrite();
		E2::SetDirWrite();
		OUTPUTS::OutputEnable();
		E1::Set();
		E2::Set();
	}
	static void Disable()
	{
		E1::Clear();
		E2::Clear();
	}
protected:
	static void SetOutput()
	{
		OUTPUTS::Write(_phase);
	}
	static uint8_t _phase;
};
template‹class OUTPUTS, class E1, class E2›
	uint8_t SimpleStepper‹OUTPUTS, E1, E2›::_phase=0;
Как видно часть логики, в лице switch-а по фазе, пришлось перенести в классы стратегий в целях компактности и скорости кода. Иначе те сдвиги, что спрятаны в enum-ы PH1..PH4 переползли бы из compile time в runtime. But it’s a small price to pay. Как говорят наши англоязычные коллеги. К тому же, если ввести ещё ограничение, что все пины в порту идут по порядку, то сдвиг будет только один.

А использовать класс со стратегиями можно так:
Код:
#if USE_PER_PIN_OUTPUT
SimpleStepper
‹
	StepperPerPinOutput
	‹
		TPin‹Portc, 4›,	//in1
		TPin‹Portc, 5›,	//in2
		TPin‹Portc, 6›,	//in3
		TPin‹Portc, 7›	//in4
	›,
	TPin‹Portd, 7›,	//e1
	TPin‹Portd, 6›	//e2
› stepper;

#else //Per port output

SimpleStepper
‹
	StepperPerPortOutput
	‹
		Portc, 
		4,	//in1
		5,	//in2
		6,	//in3
		7	//in4
	›,
	TPin‹Portd, 7›,	//e1
	TPin‹Portd, 6›	//e2
› stepper;

#endif
В принципе, уже можно думать о том, чтобы абстрагировать N произвольных пинов, и полностью изолировать логику работы с внешними устройствами от ввода/вывода. И уже не так важно к каким именно портам/пинам подключено внешнее устройство, может вообще через SPI или что-то другое. При этом можно выбрать оптимальную стратегию для каждого конкретного случая. А поскольку стратегия выбирается и всё связывание происходит на этапе компиляции, то никаких дополнительных издержек не возникает.
Также упрощается переход на другую архитектуру. Достаточно реализовать нижний уровень абстракции для целевой архитектуры.

На счет файла определения ног. Это безусловно удобно. Можно вынести все определения объектов классов, параметризованных конкретными стратегиями также в отдельный заголовок. И получается уже не «файл определения ног», а «файл описания проекта», с описанием подключения всех внешних устройств.

Что читать:
- Александреску Андрей. Современное проектирование на С++.
- Мейерс С. Эффективное использование С++.
- Седжвик Роберт. Фундаментальные алгоритмы на С++.

Для эмдеддеров читать эти книги от корки до корки большого смысла нет, поскольку многие описанные вещи не применимы для встроенных систем, но с основными идеями ознакомится бывает очень полезно.
Реклама:
neiver вне форума  
Сказали "Спасибо" neiver
alexgap (22.03.2010)
Непрочитано 21.03.2010, 20:45  
kison
Почётный гражданин KAZUS.RUN
 
Регистрация: 13.12.2004
Сообщений: 3,168
Сказал спасибо: 11
Сказали Спасибо 691 раз(а) в 503 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от neiver Посмотреть сообщение
Приведённый пример про шаговик конечно-же не свободен от недостатков. Некоторые из них любезно указал многоуважаемый kison. Он по этому поводу даже вспомнил баян «про один байт».
Главный из них – это если все пины находятся в одном порту, то код получается не оптимальным, особенно если это злополучный порт F, до которого не достают побитовые команды работы с портами и приходится использовать команды работы с памятью.
Баян, не баян, но это вполне возможная жизненная ситуация. А так и про произведения Шекспира можно сказать - баян
И не цепляйтесь Вы к этому порту F, он всего лишь был примером того, что регистры портов не всегда идут по порядку. А портов, до которых не дотягиваются sbi/out полно. В М128 еще есть порт G, в более новых кристаллах их вообще много - L,K,J,H и т.д
Но продолжайте. Ваши примеры реально впечатляют. Заменить 4-х строчный дефайн таким монстрообразным образом не каждый сможет
kison вне форума  
Непрочитано 22.03.2010, 01:26  
SasaVitebsk
Гражданин KAZUS.RUN
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от kison Посмотреть сообщение
Но продолжайте. Ваши примеры реально впечатляют. Заменить 4-х строчный дефайн таким монстрообразным образом не каждый сможет
Да ладно вам. Дайте человеку выссказаться. Мне например очень интересно. Я например, в одном проекте управлял 6 ШД на м8. Разбросаны были по портам абы как. Так я просто банально для каждого ШД на каждую фазу потратил 3 байта. То есть сразу 3 порта и засветил. Проект не менялся. Только массивы переписывались. Например для смены направления - переписал задом наперёд. Правда проект на ассемблере был. А управление - пять строк.

Но всё равно. Очень интересно. Давайте послушаем. Человек разъясняет. Даже крупица новых знаний - тоже очень приятно. Вдруг что-нибудь полезное почерпнём и заимствуем. А вы отбиваете желание у автора продолжать.


Вот было обсуждение и интересная ссылка. Почитаете, тогда поймёте где монстообразно.


http://electronix.ru/forum/index.php?showtopic=73917
SasaVitebsk вне форума  
Непрочитано 22.03.2010, 03:02  
kison
Почётный гражданин KAZUS.RUN
 
Регистрация: 13.12.2004
Сообщений: 3,168
Сказал спасибо: 11
Сказали Спасибо 691 раз(а) в 503 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от SasaVitebsk Посмотреть сообщение
Но всё равно. Очень интересно. Давайте послушаем. Человек разъясняет. Даже крупица новых знаний - тоже очень приятно. Вдруг что-нибудь полезное почерпнём и заимствуем. А вы отбиваете желание у автора продолжать.
Я не мешаю А здоровая критика помогает взглянуть на свое творение под другим углом, что нередко может вызвать переосмысливание всей концепции. Или изменить что то в деталях реализациии. Я на то, на что пошел автор темы просто не способен - я для этого слишком ленив
А в обсуждении с элетроникса понравилась фраза:
Цитата:
IMHO главная проблема писателей подобных систем - чрезмерная универсальность, превышающая реальные потребности решаемых с помощью подобных инструментов задач.
Мне кажется эта фраза и сюда подойдет
kison вне форума  
Непрочитано 22.03.2010, 14:13  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от kison Посмотреть сообщение
Заменить 4-х строчный дефайн таким монстрообразным образом не каждый сможет
Согласен, можно и четырьмя дефайнами обойтись, если шаговик один и PORTx и DDRx захардкодить. А можно и вообще без дефайнов

У меня есть итороия про перепутанные дефайны и сложности сопровождения чужого кода - не менее эпическая, чем "Про один байт". Но рассказывать не буду, очень длинная.
neiver вне форума  
Непрочитано 22.03.2010, 15:04  
alexgap
Гражданин KAZUS.RUN
 
Аватар для alexgap
 
Регистрация: 08.07.2006
Сообщений: 883
Сказал спасибо: 119
Сказали Спасибо 1,108 раз(а) в 175 сообщении(ях)
alexgap на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

neiver, я изучил ваш последний пример. Конечно же, этим путем можно добиться оптимальности кода.

Но универсальность уже страдает. Ваш пример универсальный "в статике", так как настраивается параметрами шаблона. Но частенько универсальность бывает нужна именно в разрезе экземпляра, а не статики. Я к тому, что параметр шаблона - это статический параметр, известный на этапе компиляции. А что если нужно во время выполнения сменить порт/пин? Как это будет возможно с шаблонным классом, который принимает параметры только на этапе компиляции? Думаю что никак. Разве что использовать статические переменные, что опять же убивает универсальность.

Вообщем мой вывод таков: нужен более совершенный алгоритм оптимизации в самом компиляторе. Уровень оптимизации должен быть настолько глубоким, чтобы, к примеру, в нужных местах делались подстановки обращений к портам вместо вызовов виртуальных методов тогда, когда это возможно и когда это приносит выигрыш по скорости/размеру программы. Чтобы обращения к портам автоматически группировались, когда последовательно производятся обращения к смежным пинам в пределах одного порта. И т.д. Вот тогда это будет универсальность, когда написав один раз код, его можно будет склеить с любым железом без потери оптимальности.

Нынешние компиляторы оптимизируют исключительно в пределах одной функции. Максимум, на что они способны - это заинлайнить функцию при соответствующих предпосылках, таких как размер функции и количество обращений к ней. Нынешние компиляторы даже не делают функцию статической при отсутствии обращений к членам класса в ней! О чем дальше можно говорить... Дальше peephole-подобных оптимизаций компиляторы слабо продвинулись. Они хорошо оптимизируют линейные алгоритмы в пределах одной функции, но абсолютно беспомощны в плане логической оптимизации с использованием информации об объектной модели компилируемой программы.

Так произошло, потому что железо очень быстро эволюционировало в 80 - 90-х годах. А ООП стал массово применяться только с середины 90-х. Тогда массовое железо было уже настолько мощным, чтобы отбить у производителей компиляторов веское желание совершенствовать математику оптимизаций, поэтому она "застыла" на линейно-алгоритмическом уровне. Все потуги, которые были после - это в основном поделки одиночек, и ни у кого не хватило усидчивости "подвинуть" существующую математику вперед. Да что там говорить, приличный оптимизирующий Си компилятор для Z80/ZX Spectrum до сих пор не написан! Даже на уровне хорошо известных линейно-алгоритмических техник оптимизации.

А все потому, что это ниша. Ровно как и встраиваемые устройства. Это такая же ниша, пусть более широкая, но пока не нашлось желающих подвинуть математику вперед ради нее. А для массовых более мощных машин типа PC смысла особого подвигать и нет - всё приемлимо работает и так.

Спасибо за ваши идеи и примеры, с нетерпением ожидаю ваших новых сообщений.
__________________
.

В мире всего два типа людей: те у кого был ZX Spectrum, и те у кого его не было.

Последний раз редактировалось alexgap; 22.03.2010 в 15:28.
alexgap вне форума  
Непрочитано 22.03.2010, 16:26  
SasaVitebsk
Гражданин KAZUS.RUN
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: О программировании AVR на C++.


Вот видите kison, для некоторых это недостаточно универсально. Человек хочет чтобы компилятор соптимизировал программу, которая неизвестна на этапе компиляции. Очень свежо.

Кстати пожелание "Чтобы обращения к портам автоматически группировались, когда последовательно производятся обращения к смежным пинам в пределах одного порта." для IAR работает давно и нормально.
Точнее для порта это не позволяет сделать volatile. И вы бы первый орали если бы компилятор это делал. Сами подумайте. Что если вам сначала надо махнуть ножкой PB2, а потом ножкой PB3. А умный компилятор махнёт сразу обоими? Но если вы напишете конструкцию типа bit0=bit1=bit2=bit5=0; , то компилятор вместо 4 cbi сделает in-andi-out. То же произойдёт если вы будете работать с битовыми полями.


Пример по портам - очень нагляден. Возражения, что привёл kison неубедительны. Так как легко обходятся в рамках конструкции. И оверхэда при этом не будет. И сам kison это знает. Другое дело, что сам подход меня не устраивает. Приведу пример простой.

Есть проект. В нём есть светодиод, скажем PWR, который подключён по старой привычке "нога-резюк-питание". Соответственно я зажигаю его 0. Ввожу define типа LED_PWR_SHOW, LED_PWR_HIDE, LED_PWR_BLINK. После переработке проекта (аппаратно) светодиод вешается на 24V и ставится транзистор. Я ввожу новую плату в моём файле local.c. И меняю 3 дефайна. Проект не трогаю! При компиляции выбираю версию платы, для которой будет произведена компиляция. То есть прога общая, для всех реинкарнаций. Как для этих целей подойдёт первый пример?

Приведу второй пример (всё из жизни). Потребовалось ввести светодиод AVAR. Ног и места на плате не хватает и мы вместо старого светодиода (порт D5-R-VD-+5V) применяем конструкцию (порт D5-R-VD-порт D6) и ставим двухцветный светодиод.
Я переписываю 3 define + добавляю ещё 3 define и, в прогу, добавляю работу со светодиодом AVAR. При этом (внимание) программа будет работать аналогично как для старой платы, так и для новой. Только в старой не будет соответствующей индикации.
SasaVitebsk вне форума  
Непрочитано 22.03.2010, 17:35  
kison
Почётный гражданин KAZUS.RUN
 
Регистрация: 13.12.2004
Сообщений: 3,168
Сказал спасибо: 11
Сказали Спасибо 691 раз(а) в 503 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от SasaVitebsk Посмотреть сообщение
Вот видите kison, для некоторых это недостаточно универсально. Человек хочет чтобы компилятор соптимизировал программу, которая неизвестна на этапе компиляции. Очень свежо.
Я ничего такого не хотел. Возможности инструмента не безграничны. А такая оптимизация вообще посильна только для мозга человека.

Сообщение от SasaVitebsk Посмотреть сообщение
Точнее для порта это не позволяет сделать volatile. И вы бы первый орали если бы компилятор это делал.
Мне то это зачем рассказываете? Я и так знаю


Сообщение от SasaVitebsk Посмотреть сообщение
Возражения, что привёл kison неубедительны. Так как легко обходятся в рамках конструкции. И оверхэда при этом не будет. И сам kison это знает. Другое дело, что сам подход меня не устраивает. Приведу пример простой.
Тут мои возражения относятся к очень разным подходам топикстартера. О неэффективности я писал для первых вариантов. В последнем примере топикстартер избавился от оверхедов и подтормаживаний. Правда по пути и универсальность тоже потерял Последний пример с ШД по эффективности не уступит дефайнам. Ну и универсальность имеет ту же.
На самом деле шаблоны в С++ очень сильная вещь. И при работе с портами именно на АВР они могут дать некоторое удобство. Но до этого пока не дошло. А мне это как то продемонстрировал Real на электрониксе. Я то же потом для себя пробовал сделать так же через дефайн, но получилось некрасиво и не всегда работоспособно.
Но то, что приводится в этой ветке выигрыша перед традиционным подходом не имеет. Только писанины куда больше требует.
kison вне форума  
Непрочитано 22.03.2010, 17:36  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от alexgap Посмотреть сообщение
Нынешние компиляторы оптимизируют исключительно в пределах одной функции. Максимум, на что они способны - это заинлайнить функцию при соответствующих предпосылках, таких как размер функции и количество обращений к ней. Нынешние компиляторы даже не делают функцию статической при отсутствии обращений к членам класса в ней! О чем дальше можно говорить... Дальше peephole-подобных оптимизаций компиляторы слабо продвинулись. Они хорошо оптимизируют линейные алгоритмы в пределах одной функции, но абсолютно беспомощны в плане логической оптимизации с использованием информации об объектной модели компилируемой программы.
Да, абсолютно с вами согласен. Для императивных языков программирования, коими являются и Паскаль и Бейсик и все Си-подобные языки, и многие другие, это абсолютно справедливо. От этих недостатков свободны функциональные языки. В них программист формулирует результат, который хочет получить, а последовательность генерирует компилятр. Полностью избавляя от деталей реализации. Однако эти функциональные языки ещё далеки от совершенства. И маленьких для встроенных систем не применимы.
Для АВР есть вроде компилятор Лиспа, Pico Lisp. если не ошибаюсь, но ему не меньше Меги128 надо

Механизм шаблонов в С++ является своего рода примитивным статическим функциональным языком, по которому компилярор генерируют код. Его статичность это и приемущество и недостаток. Приемущество - он позволяет генерировать очень эффективный стачически сконфигурированный код. Недостаток - для динамического поведения нужно использовать другие механихмы. Собственно, никто не запрещает комбинировать шаблоны и, например виртуальные функции - статический и динамический полиморфизм. При этом где можно соптимизировать в статике, компилятор соптимизирует, где нельзя - получите столько виртуальности сколько надо.

Могу привести примерчик, если интересно.
neiver вне форума  
Непрочитано 22.03.2010, 18:04  
alexgap
Гражданин KAZUS.RUN
 
Аватар для alexgap
 
Регистрация: 08.07.2006
Сообщений: 883
Сказал спасибо: 119
Сказали Спасибо 1,108 раз(а) в 175 сообщении(ях)
alexgap на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

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

Зная "рамки" каждой инструкции программы компилятору следует самому принять решение - перевести обращение к порту в статику, или использовать полиморфизм для дергания абстрактным пином.

Это нужно, чтобы не держать две реализации одной и той же функциональности. Сейчас универсальность + оптимальность недостижима. Точнее достижима, если держать две реализации: одну на шаблонах/дефайнах для оптимальности, а другую на интерфейсах/абстрактных классах для универсальности. Это два разных файла с кодом. А в идеале, файл должен быть один.

У neiver'a получалось в одном из примеров получать хорошо оптимизированный код, когда объект пина был локальной переменной, потому что компилятор использовал специальный оптимизирующий алгоритм для этого случая. А когда переменная стала глобальной (статической), то всё, оптимизация перестала работать, потому что компилятор уже не смотрит на что либо, выходящее за рамки функции. И именно здесь, в компиляторе, эту проблему нужно решать и шаг за шагом улучшать алгоритмы оптимизации.

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

В мире компьютеров побольше это время давно прошло, так как размеры библиотек давно перевалили за 1000 строк. Не перепишешь всего, жизни не хватит. Там уже не кичаться дефайнами, а стараются все сделать универсальнее, чтобы потом сопровождать и использовать в разных проектах было легче. Как пример, это библиотеки STL и Boost для С++, которыми пользуется пол мира.
__________________
.

В мире всего два типа людей: те у кого был ZX Spectrum, и те у кого его не было.

Последний раз редактировалось alexgap; 22.03.2010 в 18:29.
alexgap вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
AVR JTAGICE MKII - проблемы firmware... Luxurious AVR 25 20.10.2014 10:50
Ищу книги по AVR rocky7 Микроконтроллеры, АЦП, память и т.д 9 17.03.2010 12:43
AVR. Как правильно совместить LCD и ISP на PORTB? Serg3621 Микроконтроллеры, АЦП, память и т.д 8 04.02.2010 14:03


Часовой пояс GMT +4, время: 02:26.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.