подскажите пожл. как мне конвертировать HEX 0x08e6 в DEC 2278.
пробывал всякие bcd2dec bin2dec, результат не тот а вообще я радио мучу там формула такая
Код:
ra=0x08e6;//dec-2278 temp=ra; temp=temp*50;//dec-113900 temp=(temp-10700);//dec-103200-103,2 fm
все работает, ток вот на дисплей нормально инфу ввывести не могу
например, так:
Код:
printf("%d",ra);
вы не путайте присваивание значения в шестнадцатеричном формате с самим числом...
Как раз число мне и нужно, чтоб я его умножил, отнял, и получил, нужное значение волны.
Все решил проблему с помошью первой главы книги!! просто когда делал умножение переменнная(unsigned long int) переполнялась и число было другим, зделал(uint32_t) все сразу заработало
Товарищи, хелп! Кончилась память в контроллере, пришло время оптимизировать код Начать решил с того, что сразу в глаза бросается неадекватным размером и кривостью:
Код:
#define RX_BIN_BUFSIZE 40 //..... volatile unsigned char rxBinBuffer [RX_BIN_BUFSIZE]; //Имеется буфер для приема данных из UART //..... volatile signed long int time; //Имеется 32-битная переменная //В буфер принимаются данные с компа, и в позициях rxBinBuffer[3]...rxBinBuffer[6] //старшим байтом "кверху" лежит 32-битное число, которое хотелось бы присвоить переменной. //Компилятор переменные long int располагает в памяти данных старшим байтом "вниз". //В общем, мой код: time = ((long int) rxBinBuffer[3] << 24) + ((long int) rxBinBuffer[4] << 16) + ((int) rxBinBuffer[5] << 8 ) + rxBinBuffer[6] ;
Компилируется это естественно в черт знает что, где-то на 100 инструкций размером. Научите, как правильно сделать без ассемблерных вставок (этот козырь я пока решил поберечь ). Не стреляйте в программиста, он пишет как умеет
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
2stas00n, например, через UNION структуру код должен уменьшиться. Смотреть надо компиленный asm. А вообще то, компилятор на volatile действия в одну строку должен был ругнуться.
Код:
#define RX_BIN_BUFSIZE 40 volatile unsigned char rxBinBuffer [RX_BIN_BUFSIZE]; //Имеется буфер для приема данных из UART
На ту, где в длинном выражении идёт считывание нескольких volatile-переменных.
Зависит от "тщательности" компилятора и выбранного урованя _предупреждений_ (ошибки там нет). По стандарту компилятор имеет право зачитывать переменные из памяти в произвольном порядке, но для volatile он обязан соблюдвать заданный порядок. А тут порядок никак не определён и он ворчит, что результат может зависеть от порядка чтения. Он же не знает, влияет ли чтение buf[7] на содержимое buf[5] с volatile может происходить что угодно
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
...На какую именно строчку должен ругаться? У меня не ругается, может надо настроить варнинги?. Компилятор hi-tech PICC.
Любое предупреждение компилятора я считаю руганью. Рекомендую включить все предупреждения.
---
Не соглашусь с avreal в высказывании (ошибки там нет). Нет синтаксической ошибки. Да. Согласен. Но! Есть очень гадкая логическая ошибка!
Попытаюсь обосновать: 8-и битный компилятор (это тот, который за "такт/раз" умеет считывать только один байт) используя много байтовые глобальные переменные может считать и обработать на следующем "такте/разе" уже искажённые данные. Т.е., на момент считывания одного из байтов много байтовой переменной другие байты этой переменной, из-за ключевого слова volatile, могут быть легко изменены. А так как, volatile, используется в основном в прерываниях, то, прервав вычисления, это прерывание может такую свинью подложить, что не передать словами… ) Уфф... )))
Выхода два. Считать во временную переменную или запретить все прерывания на момент обработки.
И да. Не сочтите за пиар. Компилятор IAR делает в таких местах предупреждение.
А так как, volatile, используется в основном в прерываниях, то, прервав вычисления, это прерывание может такую свинью подложить, что не передать словами… ) Уфф... )))
Упс, как-то я этот момент упустил. У меня time_t инкрементируется каждую секунду в прерывании от TMR1, а когда девайс подключен к компу, время синхронизируется с компьютерными часами через UART по нажатию кнопки в программе на ПК. Если "удачно" подловить момент для синхронизации, действительно глюк можно словить. Запрещу-ка я прерывание на время работы с time_t... asteroid7, avreal спасибо за науку, буду внимательней теперь.
Не соглашусь с avreal в высказывании (ошибки там нет). ... И да. Не сочтите за пиар. Компилятор IAR делает в таких местах предупреждение.
GCC тоже предупреждение, именно это я и имел ввиду, когда говорил, что ошибки там нет. Компилятор не знает, есть ли зависимость от порядка чтения этих переменных, как, например, для половинок таймера TCNT1H/TCNT1L. volatile говорит ему только о том, что он а) обязан зачитать, даже если "только что" читал, б) не должен менять порядок обращений. И тут он предупрежадет о том, что не знает, какой порядок должен быть, скомпилировал как пришлось, а программист пусть разбирается. Может, порядок и не важен. Точка.
asteroid7 писал(а):
Нет синтаксической ошибки. Да. Согласен. Но! Есть очень гадкая логическая ошибка!
Попытаюсь обосновать: 8-и битный компилятор (это тот, который за "такт/раз" умеет считывать только один байт) используя много байтовые глобальные переменные может считать и обработать на следующем "такте/разе" уже искажённые данные. ... Выхода два. Считать во временную переменную или запретить все прерывания на момент обработки
Выход один - запретить прерывания. На время обработки или на время считывания во временную переменную — не важно. Второе время меньше, значит, вероятность глюка при незапрещённых прерываниях меньше, значит, глюк не будет отловлен на столе и будет заработана беда на задницу после установки изделия на объект. Логические ошибки программиста компилятор вылавливать не обязан. Это раз. Два — описываемая Вами проблема будет и при обращении к одной переменной (а не к нескольким, как для обсуждаемого предупреждения). И компилятор даже предупреждения не выдаст. Компилятор не знает — запрещены ли прерывания (например, ещё в функции уровнем выше) вообще, запрещено ли именно то прерывание, которое может помешать и т.д. и т.п. И вообще он не знает, что данный volatile зависит именно от прерывания. Может, то аппаратный регистр. Вон для упомянутых выше половинок TCNT аппаратура обеспечивает защёлкивание двухбайтовой переменной, нужно только в правильном порядке читать (там для не-xmega опять может вылезть беда, если прерывание обращается к другому словному регистру AVR, но это, опять-таки, компилятору не ведомо). Проблема считывания/записи "многобайтных" переменных (проблема критических секций) это нечто параллельное и независимое. И не специфически-8-битное, так как и у 32-битного процессора бывают 64-битные переменные, и вообще нужным значением может быть структура из нескольких полей, когерентность которых важна. Описываемая бяка будет и с uint8_t;
Код:
volatile uint8_t a; volatile uint8_t b;
void wait_ab() { while( a != b ) ; }
будет то же самое предупреждение о порядке считывание volatile-переменных. Уйти от него можно при помощи
Критические секции, ATOMIC_BLOCKS() и тому подобное - это само собой, volatile не спасает от проблем многоциклового доступа. Для типов, которые не читаются/не пишутся за один раз, атомарность надо обеспечивать вручную. Кстати, поэтому во многих компиляторах в signal.h определён тип sig_atomic_t, это максимальный размер целого, для которого гарантируется атомарное обращение.
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
P.S. "не сочтите за пиар" - у avr-gcc есть очень хороший atomic.h, полный аналог которому, насколько я знаю, мало для какого компилятора (если рассматривать только С, без С++) можно написать.
Код:
ATOMIC_BLOCK(тип_блока) { все операторы тут будут выполняться при нужном состоянии прерываний запрещены -- потом разрешены либо сохранено состояние, запрещены, потом восстановлено из блока можно выходить по return, по goto -- всё равно отработает правильно }
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
компилятор IAR AVR. Подозреваю проблема связана с stdio библиотекой, но вроде ее хеадер я подключил в начале проекта...
PS Хочу использовать эту фичу для контроля значений основных объявленных констант (они у меня пересчитываются препроцессором, поэтому было бы очень удобно) Если нет ответа, тогда подскажите, как можно реализовать что-нибудь подобное?
GCC тоже предупреждение, именно это я и имел ввиду, когда говорил, что ошибки там нет.
Согласитесь, что в выше случае компилятор делает предупреждение о возможной логической ошибке. Ещё пример, где нет ошибки, но есть предупреждение:
Код:
char c; if ( c = 2 ) { ... }
Я в предыдущем посте не точно указал про два варианта. Правильнее, при считывании во временную переменную необходимо тоже запретить прерывания на момент считывания, а потом спокойно с ней работать. И второй - на все вычисления запретить. Спасибо, что поправили.
---
Будет свободное время посмотрю atomic.h для GCC. В IAR-e видел похожее на критические секции сделанные через классы, но применять не довелось. Для AVR обходился простым
U8 sreg = SREG; cli(); // без этого никакого смысла нет в критической секции //крит. секция ... SREG = sreg;
но проблемы начнутся, если в критической секции есть return или критическая секция в цикле и в ней есть break - тогда ваш способ обрастает всякими проверками для правильного восстановления SREG в нужный момент и т.д. - кайф пропадает. а в atomic.h макрос ATOMIC_BLOCK позволяет об этом не думать - SREG всегда будет верно восстановлен, и при этом практически не будет избыточного кода.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
но проблемы начнутся, если в критической секции есть return или критическая секция в цикле и в ней есть break ...
Обычно, код критической секции линейный. Простые чтение/запись Eeprom-a, по SPI чё нить оправить/принять, volatile переменные обработать. С ветвлениями в таких местах программы не сталкивался.
ARV писал(а):
макрос ATOMIC_BLOCK позволяет об этом не думать - SREG всегда будет верно восстановлен, и при этом практически не будет избыточного кода.
Теперь точно найду время на изучение хидеров GCC )
Согласитесь, что в выше случае компилятор делает предупреждение о возможной логической ошибке. Ещё пример, где нет ошибки, но есть предупреждение:
Код:
char c; if ( c = 2 ) { ... }
Это как раз специально-для-забывчивых введённое предупреждение. Компилятор эту строку инетрпретирует однозначно, но надстройка переспрашивает. Зачатки искусственного интелекта, когда-то компилятор, может, и начнет компилировать то, что программист хотел написать, а не то, что он дейстивтельно написал. Вот счастье-то будет для не читающих документацию на язык и на контроллер... А обсуждаемое предупреждение — о том, что компилятор не может понять однозначно. Это совершенно по сути разные предупреждения. Если бы у компилятора было разделение на «critical warning» и «informative warning», то обсуждаемое предупреждение было бы critical, а про if( c = 2) — informative. В обсуждаемом случае компилятору стандарт сказал, что он не должен менять порядок обращений к volatile, а программист порядок не задал. Когнитивный диссонанс. А вот пример, где логическая ошибка может быть для _любой_ архитектуры (хоть 128-битной), а предупреждения нет.
Код:
volatile char a; volatile char b; bool foo() { char ta = a; return ta == b; }
asteroid7 писал(а):
Будет свободное время посмотрю atomic.h для GCC. В IAR-e видел похожее на критические секции сделанные через классы, но применять не довелось.
Ну так я же сразу сказал, если оставаться в рамках С. Для С++ — без проблем.
#include <util/atomic.h> volatile uint8_t a, b, c; void foo() { ATOMIC_BLOCK(ATOMIC_RESTORSTATE) { if( ++a < 20) return; // а ещё тут можно было написать break для выхода из этого блока a = 0; if( ++b < 20) return; b = 0; if( ++c < 20) return; c = 0; } }
и в большинстве случаев компилируется в тождественный код. И это не удивительно, так как atomic.h использует gcc-шные аттрибуты переменной, которые эквивалентны конструкторам/деструкторам для конкретно этой переменной. По поводу невыхода из середины критической секции — да, можно написать
но мне это кажется более корявым. Когда идёт связанный доступ к нескольким volatile-переменным (например, указатели/индексы головы и хвоста кольцевого буфера и сам буфер), часто код становится гораздо читабельнее, если сделать выход в удобной точке, а не городить каскадные if ради единственного выхода из функции.
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19672 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
lix писал(а):
просттите за глупый вопрос. если прерывание должно возникнуть, когда они запрещены, то после их разрешения оно сгенерируется?
На мой взгляд, к СИ это не относится, но всё же... Да, после разрешения прерываний оно возникнет. Если, конечно, программно не сброшен флаг произошедшего прерывания.
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
Сейчас этот форум просматривают: kotneko и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения