я сделал 2 хидера: в одном определил все константы, касающиеся протокола (тайминги различных этапов тайм-слотов, стандартные команды, коды устройств и т.п.), а во втором - функции для поиска девайсов, передачи байтов, приема байтов, вычисления CRC и т.п.
ну а модуль, соответственно, один.
функции, которые зависят от тактовой (прием-передача бита) я сделал статическими в модуле, чтобы даже соблазна не было с ними работать и компилятор хорошо их инлайнил при необходимости.
т.к. от тактовой по-настоящему зависят только прием-передача бита, то в этих функциях в нужных местах использовал ATOMIC_BLOCK(RESTORE_STATE), чтобы задержки (стандартные из delay.h) не плавали от таковой. собственно, вот и все...
чтобы меньше зависеть от портов и пинов, сделал все через маски, поэтому появилась возможность иметь 8 независимых линий 1-wire на одном порту, что очень удобно для нескольких термодатчиков DS18x20: задал маску 0xFF и подаешь одновременно во все 8 линий сброс, команду старта измерения, потом в нужный момент так же точно сброс, команду чтения результата и опа-на! меняешь маску на 0x01 и считываешь температуру только с 1 датчика, потом сменил маску 0x02 и считал второй... огромный плюс - не надо абсолютно заморачиваться с адресами, т.к. каждый датчик только один на линии! для конечного пользователя намного удобнее, чем меню и инструкция, как датчики приручить
как-то так в общем...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
меняешь маску на 0x01 и считываешь температуру только с 1 датчика
Круче было бы одновременно и считывать с 8-ми датчиков
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19716 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
А интересная задачка получается. Каждый из 8 портов принял по 8 байт...
ARV писал(а):
разбирать параллельно принятые данные в 8 последовательных цепочек - тот еще гемор...
Я думаю, это довольно легко решается за 8*64=512 сдвигов через перенос и дополнительных 64 байт ОЗУ. Т.е. взяли 1-й "параллельный" байт, его первый бит сдвигом через переноС засунули в первый "последовательный" байт первого канала, взяли тот же 1-й "параллельный" байт, его второй бит сдвигом через переноС засунули в первый "последовательный" байт второго канала, ... взяли 64-й "параллельный" байт, его восьмой бит сдвигом через переноС засунули в восьмой "последовательный" байт восьмого канала.
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4565 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Gudd-Head писал(а):
Круче было бы одновременно и считывать с 8-ми датчиков
А что в этом крутого ? Не думаю, что при работе с какими-нибудь, например, датчиками температуры, нужна такая спешка. Ибо остальные процессы слишком медленны (например - преобразование температуры).
я не сказал, что это неразрешимая задача. просто я не сторонник ставить себе задачи, в решении которых нет никакого смысла. я уверен почти на 100%, что геморрой с разбором будет не быстрее и не меньше по объему, чем циклическое вычитывание 8 раз из датчиков.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Если кому то реально нужно параллельно читать 8 датчиков, могу заморочится... мне нравится решать подобные задачки ...
Если все датчики висят на одном порту, то маской задать нужные биты, далее набираем массив считанных параллельно битов, а потом два цикла (один в другом) чтобы перевести в нормальные байты. Вопрос только в конкретной реализации. Не знаю как с разбросом временных характеристик у датчиков. Это, пожалуй, единственное с чем могут возникнуть заморочки.
_________________ Когда уже ничего не помогает - прочтите, наконец, инструкцию. Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII) Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Инженеры ночами не спали, думали - как бы создать протокол и устройства , которые могли бы работать все одновременно на одном проводе - а тут приходят программисты, и давай вешать по датчику на каждую линию 8-битной шины.
Инженеры ночами не спали, думали - как бы создать протокол и устройства , которые могли бы работать все одновременно на одном проводе - а тут приходят программисты, и давай вешать по датчику на каждую линию 8-битной шины.
Чет тон вашего сообщения как то, по моему, не очень правильный... Во первых - вы ж не запретите программисту программировать просто для удовольствия, то, что может потом и не пригодится... тем более что все программисты тоже проходят этот этап... Во вторых - данный протокол хоть и рассчитан на параллельное использование датчиков, тем не менее никто не запрещал вешать их на разные линии, тем более если есть хороший запас по ножкам... Во третьих - не всегда оправдано вешать кучу датчиков на одну линию... например при подключении к разным линиям, отпадает трудность с определением позиций и нумерации конкретных датчиков... а при параллельном подключении нужно как то реализовать привязку датчиков к нумерации.
Че-то там фигня какая-то понаписана. Не претендую на истину, с чистым Си, да и вообще, мало дело имел, но все-таки: 1. Глобальные переменные достаточно определить в .h файле и незачем их определять в .с, а потом ссылать на них в .h использую extern. 2. Локальные переменные модуля достаточно определить в .с и слово static для этого не требуется. 3. А вот локальные функции модуля надо определить в .с файле со словом static, тогда они будут недоступны из других файлов.
Че-то там фигня какая-то понаписана. Не претендую на истину, с чистым Си, да и вообще, мало дело имел, но все-таки: 1. Глобальные переменные достаточно определить в .h файле и незачем их определять в .с, а потом ссылать на них в .h использую extern. 2. Локальные переменные модуля достаточно определить в .с и слово static для этого не требуется. 3. А вот локальные функции модуля надо определить в .с файле со словом static, тогда они будут недоступны из других файлов.
ту фигню не читал, а ваш ответ прокомментирую: 1. вы путаете "определение" и "описание". в хидерах все должно ОПИСЫВАТЬСЯ, а ОПРЕДЕЛЯТЬСЯ уже в конкретном модуле. то есть по-хорошему в хидерах не может быть переменных без extern, а в модулях, соответственно, не должно быть переменных с extern. 2. нет, при отсутствии static переменные все равно будут "видимы" из других модулей. 3. вопросов нет.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19716 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Gudd-Head писал(а):
Я думаю, это довольно легко решается за 8*64=512 сдвигов через перенос и дополнительных 64 байт ОЗУ.
Не, не так. Заполняем 64 байта ОЗУ "паралельными" данными и выделяем 8+1 временных регистров. Далее считываем из ОЗУ первый "параллельный" байт и раскидываем его побитно сдвигом через перенос по 8 регистрам. После такого раскидывания первых 8 "параллельных" байт в регистрах у нас будут первые 8 "последовательных" байт, сохраняем их в ОЗУ на место этих самых 8 "параллельных" и проделываем то же самое с байтами 9-16, ..., 56-64. Наверняка кода и времени это займёт немного.
Кстати, слот чтения "0" в 1-Wire не менее 60 мкс, а "1" — 15 мкс. Кто как делает в своих поделках — одинаковое время на чтение "0" и "1", или "1" побыстрее???
И вот ещё один вопрос: где почитать про АСМовские вставки? Как, например, узнать по какому адресу находится та или иная переменная? Как убрать лишнее в конечном коде? И т.п.
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4565 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Тайм-слот и для "0" и для "1" одинаков по времени, а 60 мкс. - это минимальное его время. Что касается 15-ти мкс. , это время, за которое слейв гарантированно сделает выборку. Т.е. если ты передаёшь "0" и опускаешь линию, то обязан её продержать в этом состоянии минимум 15 мкс, а дальше можешь делать с ней что хочешь. Ну а следующий тайм-слот ты должен начинать только по истечению 60-ти мкс.
По адресам переменных. А для чего знать их адреса ? С переменной можно делать что угодно и не зная её месторасположения.
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19716 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Аlex писал(а):
Т.е. если ты передаёшь "0" и опускаешь линию, то обязан её продержать в этом состоянии минимум 15 мкс, а дальше можешь делать с ней что хочешь. Ну а следующий тайм-слот ты должен начинать только по истечению 60-ти мкс.
Та не. При чтении от слэйва. Т.е. через 15 мкс слэйв выдал "1" — и сразу запускать следующий слот, не ждя ещё 45 мкс.
Аlex писал(а):
А для чего знать их адреса ?
Чтобы поизвращаться с ней в АСМовских вставках.
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
И вот ещё один вопрос: где почитать про АСМовские вставки? Как, например, узнать по какому адресу находится та или иная переменная? Как убрать лишнее в конечном коде? И т.п.
1. вы путаете "определение" и "описание". в хидерах все должно ОПИСЫВАТЬСЯ, а ОПРЕДЕЛЯТЬСЯ уже в конкретном модуле. то есть по-хорошему в хидерах не может быть переменных без extern, а в модулях, соответственно, не должно быть переменных с extern. 2. нет, при отсутствии static переменные все равно будут "видимы" из других модулей.
Сперва по второму пункту Пусть есть файл program.c, в нем ссылка #include "module.h" В module.c объявлена переменная int var=0; Я утверждаю, что она будет локальной для модуля и не видна из program.c и чтобы её увидеть надо в program.c использовать extern int var; Вы утверждаете, что ее и так будет видно из program.c?
А по первому, я просто считаю, что объявление переменной это и есть её определение или описание, можно называть как угодно, дважды её объявлять незачем. Но спорить не буду, тем более по терминам.
Карма: 16
Рейтинг сообщений: 196
Зарегистрирован: Вс дек 02, 2012 16:58:33 Сообщений: 919 Откуда: от туда
Рейтинг сообщения:0
ks0 писал(а):
ARV писал(а):
1. вы путаете "определение" и "описание".
Пусть есть файл program.c, в нем ссылка #include "module.h" В module.c объявлена переменная int var=0;
Здесь одновременно и объявление, и определение переменной.
ks0 писал(а):
А по первому, я просто считаю, что объявление переменной это и есть её определение или описание, можно называть как угодно, дважды её объявлять незачем. Но спорить не буду, тем более по терминам.
Объявление = указание типа переменной, из него компилятор принимает размер и условия применения переменной: int s; char v; Определение - выделение конкретного места хранения переменной, присвоение ей адреса в памяти. s = 10; v = 'h'; Можно совместить полезное в приятным: int s = 11; Для внешних переменных не нужно выделять память, достаточно знать их объявления. Но переменную нужно где-то определить. И *.h файл для этого не место. Иначе везде, где будет включён этот файл, создадутся дубликаты переменной с одним и тем же именем.
Но переменную нужно где-то определить. И *.h файл для этого не место. Иначе везде, где будет включён этот файл, создадутся дубликаты переменной с одним и тем же именем.
А в исходном тексте, на который ссылались на страницу выше, было прописано так:
В module.c // Глобальные char GlobalVar1;
А в module.h // Секция определения глобальных переменных extern char GlobalVar1;
Все с ног на голову. В .с объявили, в .h че сделали? Переобъявили, чтобы её было видно из файлов, которые включают этот .h? Из .с объявление выкинуть, а из .h выкинуть extern.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения