Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

В основном цикле у меня несколько формул, которые из набора переменных вычисляют одно значение. Это значение должно быть максимально точным в каждый конкретные момент времени. Некоторые переменные изменяются в прерывании по событию. Нужно чтобы при изменении любой переменной расчет происходил с самого начала основного цикла (и если прерывание произошло в середине основного цикла, то после выхода из прерывания необходимо вернуться в начало основного цикла и произвести расчет с уже измененными переменными).
И еще вопрос созрел. Есть у меня набор значений как положительных, так и отрицательных. Как высчитать разрыв между двумя конкретными значениями? К примеру имеем два значения 1 и 1, разрыв между ними = 0. Теперь другие, 0 и 1, разрыв между ними = 1. А теперь самое интересное, значения -1 и 1, разрыв между ними = 2. Как такое на СИ реализовать не пойму... :dont_know:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Я бы посоветовал в прерывании просто устанавливать какой-нибудь флаг, а в начале главного цикла его сбрасывать. Результат вычислений не принимать, если флаг установлен. Для более быстрого перехода в начало цикла (если вычисления сложные и длительные) расставить проверки типа if (flag) continue; внутри цикла:
Спойлер

Код: Выделить всё

volatile uint8_t isrFlag;

ISR () {
  isrFlag = 1;
}

int main() {
  ...
  while (1) {
    isrFlag = 0;
    formula1();
    if (isrFlag)
      continue;
    formula2();
    if (isrFlag)
      continue;
    formula3();
    if (isrFlag)
      continue;
    processResult();
  }
}
Как такое на СИ реализовать не пойму
Вычесть одно из другого, очевидно.
Последний раз редактировалось WiseLord Вт авг 04, 2015 23:08:51, всего редактировалось 1 раз.
Контактная информация:
Реклама
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Если Вам нужно выполнять вычисления только по обновлению переменных, то сделайте процессы синхронизированными, по тем же флагам. В прерывании переменную обновили, взвели флаг. В майне проверяете флаг и выполняете вычисления.
По второму вопросу. Это же обычное вычитание :)

ЗЫ: Упс, опоздал. Слишком медленно печатаю :))
Последний раз редактировалось Аlex Вт авг 04, 2015 23:09:56, всего редактировалось 1 раз.
Причина: -
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Аlex писал(а):По второму вопросу. Это же обычное вычитание
Да, но вот только иногда получаются отрицательные значения, и приходится добавлять еще if и менять знак в этом случае. Думал может по-проще алгоритм есть, но похоже нет :) .
WiseLord писал(а):Я бы посоветовал в прерывании просто устанавливать какой-нибудь флаг,
Напрямую получается никак нельзя сделать? Тогда попробуем флаг...
Спасибо за ответы :)
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

isx писал(а): Да, но вот только иногда получаются отрицательные значения,
Нужно вычитать из большего меньшее, тогда отрицательных значений никогда не получится.
Что-то типа:

Код: Выделить всё

int diff(int a, int b){
  return a>b ? a-b : b-a;
}
Реклама
isx
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Сообщение isx »

Точно... Так можно выбросить умножение на -1. Еще раз благодарю :) .
Реклама
Грызет канифоль
Сообщения: 289
Зарегистрирован: Пт мар 20, 2009 12:25:47
Откуда: Ivanovo

Сообщение spongebob »

а подскажите ещё по записи/чтению структур в/из eeprom
на этот раз уже большая структура

Код: Выделить всё

struct _state {
   unsigned char temp[5];
   unsigned char time[9];
} state;
14 байт.
функции записи/чтения работают с одним байтом
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Перебирайте все байты по одному в цикле и пишите их по-очереди в еепром.
Не вижу проблем... :dont_know:

Как пример - http://forum.chipmk.ru/index.php/topic/ ... -с-eeprom/
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Для avr-gcc в avr-libc есть функции eeprom_read_block() и eeprom_write_block() (а также eeprom_update_block() и eeprom_update_block()), позволяющие читать/писать большое количество байтов.
Поэтому всё будет достаточно просто. Например, для записи этой структуры по адресу 0xA0 вызвать её как-то так:

Код: Выделить всё

eeprom_update_block(&state, (void*)(0xA0), sizeof(state));
Контактная информация:
Грызет канифоль
Сообщения: 289
Зарегистрирован: Пт мар 20, 2009 12:25:47
Откуда: Ivanovo

Сообщение spongebob »

Аlex писал(а):Как пример - http://forum.chipmk.ru/index.php/topic/ ... -с-eeprom/
взял вариант без прерываний
сначала пихал ему указатель, не то
потом просто писал ee_write(0,state) и ee_read(0,state)
получаю предупреждения "illegal conversion between pointer types", но считывает/записывает правильно
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Замените

Код: Выделить всё

#define ee_write(adr,p_d) _ee_write(adr,&p_d,sizeof(p_d))
#define ee_read(adr,p_d) _ee_read(adr,&p_d,sizeof(p_d))
на

Код: Выделить всё

#define ee_write(adr,p_d) _ee_write(adr,(char *)&p_d,sizeof(p_d))
#define ee_read(adr,p_d) _ee_read(adr,(char *)&p_d,sizeof(p_d))
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

внезапно я :tea:
вчера ковырял одно гавно на пхп и столкнулся с интерфейсами
пхп давно учил и забил, а тут какая-то новая херня
быдлокниги не читал, посмотрел ролик какого-то какляцкого школьника

правильно ли я понял, что интерфейсы это просто перечень методов, которые потом будут реализованы в разных классах и будут делать какие-то штуки, но в основном коде надо использовать готовое название метода, которое есть интерфейс?
или например я сам могу переопределить этот метод в своем приложении

интерфейсы используются в фабриках, насколько я понял из видоса про фабрики
тематические ответы только в форуме, в приват не пишите
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

Тоже не читал книги, и пхп немного знал когда он был еще простой как три копейки. Ну а так интерфейсы это в объекто-ориентированных си-подобных языках, т.к. множественное наследование запрещено, а если хочется, то один класс предок с наследованием реализации, и сколько угодно интерфейсов с наследованием объявлений методов, которые потом надо будет реализовать. Тогда кто-то со стороны уже будет заранее, зная тот-же интерфейс, и знать как обратиться к этому новому классу.
Друг Кота
Сообщения: 13796
Зарегистрирован: Чт сен 20, 2007 14:08:00

Сообщение kalobyte »

в с++ интерфейсов не было, там были абстгактные методы
я тогда понял, что можно использовать один метод display в моем быдловузном проекте, но сделать несколько абстгактных методов и реализаций
потому что в реальности у меня могло подключаться 2 или 3 разных индикатора с разными протоколами управления, а в главном файле не должно было быть 100500 разных методов управления индикаторами, потому что главный файл писал другой человек, который в железе нихера не понимает

в пхп для этого решили запилить интерфейсы
все оказалось довольно просто
тематические ответы только в форуме, в приват не пишите
Мучитель микросхем
Аватара пользователя
Сообщения: 485
Зарегистрирован: Пн авг 20, 2007 21:35:45
Откуда: Мытищи, Московская область

Сообщение Gordon Shumway »

Доброго дня, уважаемые знатоки !

Помогите чайнику ! Всегда программировал на Баскоме, а тут попался очень заковыристый дисплей, упоминания о нем и тестовые подключалки нашел только на немецких сайтах, да и то всего две штуки.
Там прилагались архивы, как я понял - на Си. Тестовые программы. А вот как их скомпилировать в Хекс - так и не въехал.
Оба архива приложены, вроде как под мегу8 авторы компилировали. Сделайте пару хексов, пожалуйста !

PS Дисплей от телефонного аппарата Siemens Optipoint, интерфейс - SPI. 24х2.

Спасибо заранее !
Вложения
spi_lcd.zip
(4.04 КБ) 164 скачивания
myLoS-spi-0.2.tar.gz
(13.42 КБ) 257 скачиваний
С уважением,
Алексей.
Контактная информация:
Держит паяльник хвостом
Сообщения: 963
Зарегистрирован: Чт апр 03, 2014 23:16:55
Откуда: Россия

Сообщение Rtmip »

Пожалуйста :)
Надеюсь "файл.eep" сами "перегоните" в нужный формат для заливки в еепром атмеги8?
Оба хекса под 8 МГц.
В проекте, где есть энкодер и уарт не разбирался, что и куда подключается, какая скорость и тд,
думаю это неважно для проверки дисплея.
Вложения
spi__lcd.rar
(984 байт) 121 скачивание
myLoS.rar
(1.27 КБ) 134 скачивания
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Да, всё что понадобилось для второго архива (myLoS-spi) - зайти в каталог с Makefile и сделать make. Можно было бы и не спрашивать.
Для первого тоже, наверное, простенького Makefile было бы достаточно, но лениво.
Контактная информация:
Мучитель микросхем
Аватара пользователя
Сообщения: 485
Зарегистрирован: Пн авг 20, 2007 21:35:45
Откуда: Мытищи, Московская область

Сообщение Gordon Shumway »

Rtmip писал(а): Надеюсь "файл.eep" сами "перегоните" в нужный формат для заливки в еепром атмеги8?
Конечно ! Огромное спасибо, все протестилось, все показывает ! :)))
Обнаружил три модификации дисплея одного и того же телефонного аппарата. Два из них отлично завелись, третий (самый свежий, 2010 года) ни в какую !
Причем первые два - взаимозаменяемы (проверил на аппаратах и тестовой плате), третий - меняется только на такой же. Вот интересно...
С уважением,
Алексей.
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Вт апр 28, 2015 09:06:12

Сообщение Victor94 »

Приветствую, есть задача, что-то вроде "интерпретации" кода.
Есть массив int, который пока заполняю руками:
массив[элемент 0] = тут я определяю, что это будет за действие.(Деление/Умножение/Сложение/Вычитание)
массив[элемент 1] и массив[элемент 2] = целая часть числа.
массив[элемент 3] и массив[элемент 4] = часть после "точки".
Не знаю как правильно из 1,2,3,4 элементов вынуть float число.
->AVG-GCC
->Archlinux
->Wine -> Proteus
->Mono -> Avrdudes
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

float f;
f = массив[1] + 256*массив[2] + 1E-5*(массив[3] + 256*массив[4]);

как-то так... правда, массив в этом примере байтовый, а не int. т.е. char - int-ы отводить для этих целей бессмысленно
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»