Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

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

Вт июн 15, 2021 07:55:17

technik-1017 писал(а):Использование static заставляет компилятор оптимизировать данный код (скорее всего он выкидывает часть)
использование static заставляет компилятор сделать загрузку 2 байт в структуру при входе в функцию и сохранение этих 2 байт при выходе, только и всего, никакой другой оптимизации он не делает. не должен делать, во всяком случае.

главное: я не понимаю, что я делаю не так! не первый год это делаю, но в данном случае результат не соответствует ожиданиям! как так-то?!

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

Вт июн 15, 2021 09:59:45

Ассемблерный код все таки наверно придётся смотреть, что бы понять что происходит.

На самом деле у меня было несколько вопросов:
1) переменная entry определена как static, но где тогда происходит первая инициализация. Впервые встречается в условии if и уже сама себя увеличивает (увеличивает мусор?)
2) переменная pos, аналогично пункту 1.
3) переменная regs вроде должна быть (задумано) как static ну и также не инициализирована.
4) переменная two_ms вроде как глобальная, тогда зачем было часть переменных делать глобальными, а часть как static.

Желание избавиться от глобальных переменных? Но по факту они остаются глобальными.
Может пойти классическим путём: в прерывании использовать глобальные переменные с volatile?

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

То что иногда работает, уже говорили: скорее всего используется память которая ранее была освобождена, и содержала корректные данные от предыдущих действий программы.

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

Вт июн 15, 2021 10:53:55

а вы посмотрите внимательно:
regs.word &= 0xf800;
regs.word |= digs[scr->symbol[entry >= scr->bright]];

младшие 11 бит в каждом прерывании меняются, а старшие 5 - только каждое 62 прерывание.
Я это видел, об этом и писал.
А что значит "со static не работает"? В чём это выражается "не работает"?
Неработать может от того, что кроме этого у вас там есть ещё баги. И их комбинация даёт причудливый результат - когда-то что-то работает, когда-то - нет. Одни баги могут компенсировать/нивелировать действие других.
Например - когда делаете static, то в другом месте другой код, у вас эту область памяти портит. Потому и не работает. Как вариант.
И вообще - как можно о чём-то судить если половину кода не привели и листинга не привели? Только гадать....
Например - что такое static pos_t *scr = screen; и зачем ему (static-переменной scr) на каждом входе в функцию присваивается (переменная/константа/etc.(?)) screen? Какой тут смысл делать статик если по использованию тут нужна обычная автоматическая переменная?

Добавлено after 6 minutes 19 seconds:
1) переменная entry определена как static, но где тогда происходит первая инициализация. Впервые встречается в условии if и уже сама себя увеличивает (увеличивает мусор?)
Не имеющие явной инициализации глобальные/статические переменные, инициализируются 0. Это поведение по умолчанию для си/си++ (может быть измененено соответствующими ключевыми словами компилятора).
Но для самокомментируемости кода, полезно делать явную инициализацию 0-м, чтобы показать для каких переменных это критично. Но не обязательно.

2) переменная pos, аналогично пункту 1.
3) переменная regs вроде должна быть (задумано) как static ну и также не инициализирована.
Хотя бы для начала изучите си. :dont_know:

Может пойти классическим путём: в прерывании использовать глобальные переменные с volatile?
Зачем? (volatile)

Добавлено after 14 minutes 32 seconds:
вам известны более красивые способы отправки двух байт с последующей дрыгоножной выдачей строба на классическом AVR? посоветуйте, я всегда готов учиться хорошему. а грубить я умею и сам.
Сразу, навскидку, что бросается в глаза - ожидания делать не после записей, а перед. А строб перенести в начало ISR. Это сразу уменьшает ожидание внутри ISR на эти самые 16 тактов.

PS: Чисто теоретически я бы выбрал другой МК: с DMA (для SPI) или с FIFO (в SPI). И эти проблемы бы сами собой отпали. Например STM8Lxx.

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

Вт июн 15, 2021 11:57:12

jcxz писал(а):А что значит "со static не работает"? В чём это выражается "не работает"?
как минимум в том, что в обычном случае добавление static к любой локальной переменной никаких побочных эффектов, кроме увеличения статически выделенной памяти, давать не должно, т.е. что со static, что без, поведение программы должно быть неизменным. в моём случае это не так.
jcxz писал(а):Например - когда делаете static, то в другом месте другой код, у вас эту область памяти портит. Потому и не работает. Как вариант.
невероятный вариант: локальная переменная потому и локальная, что более нигде не используется, хоть со static, хоть без. а всякие "опасные" действия (с указателями) у меня отсутствуют в коде.
jcxz писал(а):Например - что такое static pos_t *scr = screen; и зачем ему (static-переменной scr) на каждом входе в функцию присваивается (переменная/константа/etc.(?)) screen? Какой тут смысл делать статик если по использованию тут нужна обычная автоматическая переменная?
для локальной static-переенной это присваивание делается один раз, по идее вы не должны были спрашивать это, это ведь азы Си. для первого входа в обработчик надо, чтобы указатель указывал на начало массива, а в ходе обработки (см. код) этот указатель сдвигается.
jcxz писал(а):ожидания делать не после записей, а перед. А строб перенести в начало ISR. Это сразу уменьшает ожидание внутри ISR на эти самые 16 тактов.
ну, это, наверное, сделать можно, хотя фактически получится, что состояние индикаторов будет отставать от того, что делает обработчик :) но вряд ли это критично... 16 тактов, я имею ввиду.
jcxz писал(а):я бы выбрал другой МК
выбирайте, я не запрещаю.
technik-1017 писал(а):переменная regs вроде должна быть (задумано) как static ну и также не инициализирована
так о том и речь: когда эта переменная БЕЗ static, т.е. содержит мусор на входе в функцию, все работает, а когда я делаю её static, т.е. она на первом входе уже инициализирована нулями - работать перестаёт...

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

Вт июн 15, 2021 13:12:39

когда эта переменная БЕЗ static, т.е. содержит мусор на входе в функцию, все работает, а когда я делаю её static, т.е. она на первом входе уже инициализирована нулями - работать перестаёт...

==
Когда переменная находится в одной области памяти, все работает, а когда переносится в другую область памяти - работать перестаёт?
Возможно, что-то портит ту область, где static переменные. Может стек туда наезжает. Для проверки можно сделать переменную глобальной, и объявить её выше / ниже по отношению к другим переменным, так, чтобы можно было менять её адрес расположения в памяти. Если окажется, что при таком перемещении переменной всё заработало - вывод очевиден.

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

Вт июн 15, 2021 13:31:18

Кстати, вот это
Код:
   static pos_t *scr = screen;
действительно опаснее, чем выглядит. Хотя, если screen - тоже static и представляет собой массив pos_t, то всё вроде выглядит ОК - один раз оно получит своё значение, а дальше уже будет итерироваться/сбрасываться.

Хотя я бы, наверное, вообще убрал эту переменную, а просто обращался бы к screen[pos].symbol[n], так как scr и pos фактически друг друга дублируют

Если идти последовательно:

При старте программы все static переменные получают свои значения (не важно, локальные они или нет):
entry = 0;
pos = 0;
scr = screen;

Далее, при первом входе в прерывание:
regs = ???; // не определено значение

Условие "считаем входы" не выполняется, поэтому regs так и остаётся неопределённым. Поэтому далее в regs.word состояние 5 старших битов так и остаётся непонятным в течение как минимум IND_RPT раз. И только 1 раз из IND_RPT у нас значение старших 5 байтов regs определено. Остальные - просто "везёт" из-за попадания в ту же ячейку памяти на стеке.

А вот почему код, если regs сделать static, ломается - действительно странно. Потому как после IND_RPT вхождений в прерывание индикация должна бы наладиться

Добавлено after 1 minute 34 seconds:
Может, и правда ОЗУ уже не хватает и стек наезжает на область статических переменных...

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

Вт июн 15, 2021 13:37:33

Скорее всего static в Си не может использоваться со структурами (так как мы этого хотим в данном примере) и конечно их не инициализирует (инициализировать структуру нужно принудительно).
static используется только для ограничения видимости. Попробуйте сделать структуру глобальной переменной.

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

Вт июн 15, 2021 13:45:21

jcxz писал(а):А что значит "со static не работает"? В чём это выражается "не работает"?
как минимум в том
Вы не поняли вопрос. Перечитайте ещё раз.

ARV писал(а):
jcxz писал(а):Например - когда делаете static, то в другом месте другой код, у вас эту область памяти портит. Потому и не работает. Как вариант.
невероятный вариант: локальная переменная потому и локальная, что более нигде не используется, хоть со static, хоть без.
И что что "не используется"? Она в памяти присутствует? Рядом с ней другие переменные (static или глобальные) присутствуют? А раз присутствуют, значит любая неправильная операция с памятью может её порушить.

ARV писал(а):а всякие "опасные" действия (с указателями) у меня отсутствуют в коде.
Ну да, а ещё вы пишете абсолютно безглючный код, который никогда не глючит. :))) Зачем тогда вопрос задали раз у вас ничего не глючит?

ARV писал(а):для локальной static-переенной это присваивание делается один раз, по идее вы не должны были спрашивать это, это ведь азы Си.
А вам по идее с этого места надо взять учебник по си и начать изучать азы. Ибо смотрим в листинг (IAR):
Код:
inline void CpuUseTimeTick()
{
  _Z14CpuUseTimeTickv: (+1)
  ...
 //static u16 t = cpuUseCalc;
 0x4821             LDR.N    R0,??CpuUseTimeTick_0+0x8
 0x78C0             LDRB     R0,[R0, #+3]
 0x8020             STRH     R0,[R4, #+0]
...

Как видим - нормально так static переменной t присваивается значение переменной cpuUseCalc на каждом входе в функцию CpuUseTimeTick().
Или думаете это IAR не знает азов си? 8) Или всё-таки вы их не знаете? :)))

PS: Складывается ощущение, что это не у вас эти баги, а у меня. К советам вы не прислушиваетесь, ещё и спорите.... Зачем тогда вообще вопрос задали?
Баги эти вроде не у меня. И мне абсолютно на них насрать. Не нужно вам найти решение - воля ваша. Зачем тогда было спрашивать? :dont_know:

Добавлено after 1 minute 2 seconds:
Возможно, что-то портит ту область, где static переменные.
Я уже это советовал автору. Но не принимает никаких советов.... :dont_know:

Добавлено after 2 minutes 35 seconds:
Кстати, вот это
Код:
   static pos_t *scr = screen;
действительно опаснее, чем выглядит. Хотя, если screen - тоже static и представляет собой массив pos_t
Я ещё в самом начале советовал автору привести определения всех объектов и типов, фигурирующих в примере кода. Чтобы не играть в угадайку. Но он проигнорировал. Видимо ищет здесь гадалок....

Добавлено after 2 minutes 10 seconds:
А вот почему код, если regs сделать static, ломается - действительно странно.
Очень просто - наверняка там ещё табун других багов рядом пасётся. :))) которые иногда проявляются, иногда - нет. Как карты лягут....

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

Вт июн 15, 2021 14:18:01

Только что проверил в IAR AVR
- если объявить структуру как static (не инициализированную), то компилятор просто выкидывает кусок кода, где используется структура
- если объявить структуру без static, то код не выбрасывается, но переменная локальная
- если объявить структуру volatile static, то код не выбрасывается, но куда указывает, не успел проверить (пора домой, дома позже могу проверить)

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

Вт июн 15, 2021 15:31:53

Код:
inline void CpuUseTimeTick()
{
  _Z14CpuUseTimeTickv: (+1)
  ...
 //static u16 t = cpuUseCalc;
 0x4821             LDR.N    R0,??CpuUseTimeTick_0+0x8
 0x78C0             LDRB     R0,[R0, #+3]
 0x8020             STRH     R0,[R4, #+0]
...

Как видим - нормально так static переменной t присваивается значение переменной cpuUseCalc на каждом входе в функцию CpuUseTimeTick().

Это не более чем результат оптимизации, если после использования переменной t присвоить новое значение, то компилятор может добавить флаг говорящий о том нужно ли загружать в переменную значение cpuUseCalc, а может он перезапишет значение самой cpuUseCalc, если она больше нигде не используется, тогда одна загрузка и останется.

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

Вт июн 15, 2021 16:05:02

WiseLord писал(а):действительно опаснее, чем выглядит
почему? screen - это массив, он не static, но адрес-то его неизменен, и присваивание его указателю, по-моему, совершенно безопасно.
WiseLord писал(а):ОЗУ уже не хватает и стек наезжает на область статических переменных..
у меня atmega328 и в коде статически задействовано 63 байта ОЗУ - там еще немеряно памяти! никаких наездов нет и быть не может.
jcxz писал(а):Перечитайте ещё раз
я не могу сказать точнее, чем сформулировал ранее: добавление static к локальной переменной ломать код не должно по определению. поэтому "не работает" выражается в том, что работа кода ломается. а эффекты от этого могут быть разные - от нарушения индикации (одновременное свечение соседних разрядов) до полной абракадабры индикации (хаотические мерцания, скакания цифр и их яркости).
jcxz писал(а):А раз присутствуют, значит любая неправильная операция с памятью может её порушить.
теоретически - да, но на практике - откуда взяться неправильной операции с памятью?! memcpy и strcpy я не использую, как не использую и аналогичных "самописных" функций, заполняющих/изменяющих области памяти по указателю... других способов разрушить "соседние" переменные (не считая переполнения стека) я не знаю... а стек не переполняется - см. выше
jcxz писал(а):вы пишете абсолютно безглючный код, который никогда не глючит
сам по себе код не глючит, это я где-то что-то сделал не так. только я не могу понять, что именно не так.
поскольку остальная часть кода работает (как минимум - визуально) надежно, грешу только на этот обработчик прерывания.
jcxz писал(а):Или думаете это IAR не знает азов си? Или всё-таки вы их не знаете?
может быть, я и не знаю... но вот предыдущие 10 лет программирования как-то static-ом для локальных переменных пользовался, и ни разу проблем не испытывал, а тут вот оно чо... азы поменялись? а что делает IAR - я не в курсе, мне сейчас больше интересно, что avr-gcc делает. по листингам он делает все правильно, т.е. static-и сохраняет/загружает, auto-переменные не инициализирует никак... и, как ранее было сказано, для не-static варианта на 64-ю итерацию прерывания все устаканивается, а со static - нет. вот в чем вопрос.
jcxz писал(а):Я ещё в самом начале советовал автору привести определения всех объектов и типов, фигурирующих в примере кода. Чтобы не играть в угадайку.
это можно, хотя поможет навряд ли.
Код:
static const __flash uint16_t digs[CHAR_CNT] = {
   CHAR_0, CHAR_1, CHAR_2, CHAR_3, CHAR_4,
   CHAR_5, CHAR_6, CHAR_7, CHAR_8, CHAR_9,
   CHAR_PU, CHAR_PD, CHAR_PB, CHAR_SP
};

/// структура знакоместа
typedef struct {
   volatile uint8_t   bright;   //!< заданная яркость
   volatile char_t      symbol[2]; //!< коды знака
} pos_t;

// структура для управления индикаторами через регистры 74HC595
typedef union {
   struct {
      uint16_t   symbol : 11;      // код символа
      uint8_t      anode : POS_CNT;   // бит разряда
   };
   uint8_t         bytes[2];         // 2 байта для выдачи в регистры
   uint16_t      word;
} regs_t;

pos_t   screen[POS_CNT];

///*
ISR(TIMER1_OVF_vect){
   static uint8_t entry;
   static uint8_t anode = 0x08;
   uint16_t word;
   static pos_t *scr = screen;

   word = digs[scr->symbol[entry >= scr->bright]];
   if(entry < 50)
      word |= anode << 8;

   if(++entry >= IND_RPT){
      entry = 0;
      two_ms++;
      scr++;
      anode <<= 1;
      if(anode == 0){
         anode = 0x08;
         scr = screen;
      }
   }

   SPDR = word >> 8;
   while(bit_is_clear(SPSR, SPIF));
   SPDR = word;
   while(bit_is_clear(SPSR, SPIF));
   // строб для защелкивания данных
   PORTB |= LOAD_PIN;
   PORTB &= ~LOAD_PIN;
}
теперь все ясно по типам данных?

Добавлено after 3 minutes 32 seconds:
да, я привел уже немного модифицированный код, поскольку постоянно пытаюсь разобраться с ним. он хоть и отличается от предыдущего мной показанного, но проблему сохраняет: сейчас вместо regs используется тупо uint16_t word - и тем не менее эффект прежний: эта переменная, будучи автоматической, обеспечивает работу кода, а будучи static - портит.

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

Вт июн 15, 2021 16:38:20

А можно ещё уточнить по значениям POS_CNT, IND_RPT. А то без этого логика не до конца ясна (особенно проверка entry < 50)

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

Вт июн 15, 2021 16:52:07

откуда взяться неправильной операции с памятью?! memcpy и strcpy я не использую, как не использую и аналогичных "самописных" функций, заполняющих/изменяющих области памяти по указателю... других способов разрушить "соседние" переменные (не считая переполнения стека)
Вы используете указатели. Одного этого достаточно чтобы порушить память.

Добавлено after 6 minutes 58 seconds:
А можно ещё уточнить по значениям POS_CNT, IND_RPT. А то без этого логика не до конца ясна (особенно проверка entry < 50)
Как партизан на допросе... под пытками выдаёт по капле инфу... хотя вроде же ему нужны советы... :dont_know:

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

Вт июн 15, 2021 16:58:50

Ещё момент... word = digs[blablabla] - тут не возникнет переполнения?
Значение CHAR_CNT нам неизвестно (как и CHAR_0 сотоварищи), поэтому есть ли гарантия, что где-то в scr->symbol[0] или scr->symbol[1] не лежит число большее либо равное этому CHAR_CNT?

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

Вт июн 15, 2021 17:01:26

IND_RPT = 63;
POS_CNT = 5;

проверка entry<50 - это от безнадеги...

смысл вот в чем: entry считает входы. поле bright в структуре pos_t определяет значение, до которого выводится bytes[0], а свыше - bytes[1] этой структуры. таким образом от 0-го входа до bright светится первый символ, а от bright до 63-го входа - второй. сравнение с 50 делал для того, чтобы укоротить свечение второго, принудительно отключив анод индикатора - думал, вдруг оптрон долго запирается, что и дает эффекты одновременного свечения разрядов... по документам 10 мкс время выключения оптрона - прилично, по МК-шным меркам.

в контексте моих проблем на это сравнение можно не обращать внимание

WiseLord писал(а):CHAR_CNT неизвестна, но есть ли гарантия, что где-то в scr->symbol[0] или scr->symbol[1] не лежит число большее либо равно этому?
гарантия есть: всего 10 символов для цифр, 3 варианта для точек и 1 "пустой" символ - итого 14.

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

Вт июн 15, 2021 17:02:56

А сами символы? Что именно такое CHAR_0?

Я почему спрашиваю... Вот идёт код
Код:
word = digs[scr->symbol[entry >= scr->bright]];

В зависимости от яркости и entry, это может быть одно из двух:
Код:
word = digs[scr->symbol[0]];
word = digs[scr->symbol[1]];

scr->symbol[i] - это какая-то 11-битная переменная, например, 0x0482 = 1154
Вопрос, насколько правомерно тогда digs[1154] ?

Хотя.. я, видимо, не туда глянул, и там всё же не 11-битная symbol из regs_t, а char из pos_t. Тогда это будет скорее не код знака, а его индекс в массиве, меньший CHAR_CNT

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

Вт июн 15, 2021 17:12:18

WiseLord писал(а):scr->symbol[i] - это какая-то 11-битная переменная, например, 0x0482 = .1154
Вопрос, насколько правомерно тогда digs[1154] ?
переменная scr->symbol[i] 8-битная, см. структуру pos_t. содержит эта переменная код символов от 0 до 13. коды эти получаются самописной функцией, аналогичной itoa по смыслу. а вот digs[] - это уже массив 11-битных переменных

здесь не может быть проблем

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

Вт июн 15, 2021 17:18:26

Да, я уже "проэмулировал" на компьютере:
Спойлер
Код:
#include <stdio.h>

#include <stdint.h>

#define CHAR_CNT    14
#define POS_CNT     5
#define IND_RPT     63

#define CHAR_0      0x000
#define CHAR_1      0x111
#define CHAR_2      0x222
#define CHAR_3      0x333
#define CHAR_4      0x444
#define CHAR_5      0x555
#define CHAR_6      0x666
#define CHAR_7      0x777
#define CHAR_8      0x888
#define CHAR_9      0x999
#define CHAR_PU     0xaaa
#define CHAR_PD     0xbbb
#define CHAR_PB     0xccc
#define CHAR_SP     0xddd

static const uint16_t digs[CHAR_CNT] = {
   CHAR_0, CHAR_1, CHAR_2, CHAR_3, CHAR_4,
   CHAR_5, CHAR_6, CHAR_7, CHAR_8, CHAR_9,
   CHAR_PU, CHAR_PD, CHAR_PB, CHAR_SP
};

/// структура знакоместа
typedef struct {
   volatile uint8_t   bright;   //!< заданная яркость
   volatile char      symbol[2]; //!< коды знака
} pos_t;

// структура для управления индикаторами через регистры 74HC595
typedef union {
   struct {
      uint16_t   symbol : 11;      // код символа
      uint8_t      anode : POS_CNT;   // бит разряда
   };
   uint8_t         bytes[2];         // 2 байта для выдачи в регистры
   uint16_t      word;
} regs_t;

pos_t screen[POS_CNT];

void ISR(){
   static uint8_t entry;
   static uint8_t anode = 0x08;
   uint16_t word;
   static pos_t *scr = screen;

   word = digs[scr->symbol[entry >= scr->bright]];
   if(entry < 50)
      word |= anode << 8;

   if(++entry >= IND_RPT){
      entry = 0;
      scr++;
      anode <<= 1;
      if(anode == 0){
         anode = 0x08;
         scr = screen;
      }
   }

   printf("entry=%2d: word=%04x\n", entry, word);
}


int main()
{
    screen[0].symbol[0] = 1;
    screen[0].symbol[1] = 2;
    screen[0].bright = 4;
    screen[1].symbol[0] = 3;
    screen[1].symbol[1] = 4;
    screen[1].bright = 3;
    screen[2].symbol[0] = 5;
    screen[2].symbol[1] = 6;
    screen[2].bright = 2;
    screen[3].symbol[0] = 7;
    screen[3].symbol[1] = 8;
    screen[3].bright = 1;
    screen[4].symbol[0] = 9;
    screen[4].symbol[1] = 10;
    screen[4].bright = 2;


    for (int i = 0; i < 1000; i++) {
        ISR();
    }

    return 0;
}
Выхлоп:
Спойлер
Код:
entry= 1: word=0911
entry= 2: word=0911
entry= 3: word=0911
entry= 4: word=0911
entry= 5: word=0a22
entry= 6: word=0a22
entry= 7: word=0a22
entry= 8: word=0a22
entry= 9: word=0a22
entry=10: word=0a22
entry=11: word=0a22
entry=12: word=0a22
entry=13: word=0a22
entry=14: word=0a22
entry=15: word=0a22
entry=16: word=0a22
entry=17: word=0a22
entry=18: word=0a22
entry=19: word=0a22
entry=20: word=0a22
entry=21: word=0a22
entry=22: word=0a22
entry=23: word=0a22
entry=24: word=0a22
entry=25: word=0a22
entry=26: word=0a22
entry=27: word=0a22
entry=28: word=0a22
entry=29: word=0a22
entry=30: word=0a22
entry=31: word=0a22
entry=32: word=0a22
entry=33: word=0a22
entry=34: word=0a22
entry=35: word=0a22
entry=36: word=0a22
entry=37: word=0a22
entry=38: word=0a22
entry=39: word=0a22
entry=40: word=0a22
entry=41: word=0a22
entry=42: word=0a22
entry=43: word=0a22
entry=44: word=0a22
entry=45: word=0a22
entry=46: word=0a22
entry=47: word=0a22
entry=48: word=0a22
entry=49: word=0a22
entry=50: word=0a22
entry=51: word=0222
entry=52: word=0222
entry=53: word=0222
entry=54: word=0222
entry=55: word=0222
entry=56: word=0222
entry=57: word=0222
entry=58: word=0222
entry=59: word=0222
entry=60: word=0222
entry=61: word=0222
entry=62: word=0222
entry= 0: word=0222
entry= 1: word=1333
entry= 2: word=1333
entry= 3: word=1333
entry= 4: word=1444
entry= 5: word=1444
entry= 6: word=1444
entry= 7: word=1444
entry= 8: word=1444
entry= 9: word=1444
entry=10: word=1444
entry=11: word=1444
entry=12: word=1444
entry=13: word=1444
entry=14: word=1444
entry=15: word=1444
entry=16: word=1444
entry=17: word=1444
entry=18: word=1444
entry=19: word=1444
entry=20: word=1444
entry=21: word=1444
entry=22: word=1444
entry=23: word=1444
entry=24: word=1444
entry=25: word=1444
entry=26: word=1444
entry=27: word=1444
entry=28: word=1444
entry=29: word=1444
entry=30: word=1444
entry=31: word=1444
entry=32: word=1444
entry=33: word=1444
entry=34: word=1444
entry=35: word=1444
entry=36: word=1444
entry=37: word=1444
entry=38: word=1444
entry=39: word=1444
entry=40: word=1444
entry=41: word=1444
entry=42: word=1444
entry=43: word=1444
entry=44: word=1444
entry=45: word=1444
entry=46: word=1444
entry=47: word=1444
entry=48: word=1444
entry=49: word=1444
entry=50: word=1444
entry=51: word=0444
entry=52: word=0444
entry=53: word=0444
entry=54: word=0444
entry=55: word=0444
entry=56: word=0444
entry=57: word=0444
entry=58: word=0444
entry=59: word=0444
entry=60: word=0444
entry=61: word=0444
entry=62: word=0444
entry= 0: word=0444
entry= 1: word=2555
entry= 2: word=2555
entry= 3: word=2666
entry= 4: word=2666
entry= 5: word=2666
entry= 6: word=2666
entry= 7: word=2666
entry= 8: word=2666
entry= 9: word=2666
entry=10: word=2666
entry=11: word=2666
entry=12: word=2666
entry=13: word=2666
entry=14: word=2666
entry=15: word=2666
entry=16: word=2666
entry=17: word=2666
entry=18: word=2666
entry=19: word=2666
entry=20: word=2666
entry=21: word=2666
entry=22: word=2666
entry=23: word=2666
entry=24: word=2666
entry=25: word=2666
entry=26: word=2666
entry=27: word=2666
entry=28: word=2666
entry=29: word=2666
entry=30: word=2666
entry=31: word=2666
entry=32: word=2666
entry=33: word=2666
entry=34: word=2666
entry=35: word=2666
entry=36: word=2666
entry=37: word=2666
entry=38: word=2666
entry=39: word=2666
entry=40: word=2666
entry=41: word=2666
entry=42: word=2666
entry=43: word=2666
entry=44: word=2666
entry=45: word=2666
entry=46: word=2666
entry=47: word=2666
entry=48: word=2666
entry=49: word=2666
entry=50: word=2666
entry=51: word=0666
entry=52: word=0666
entry=53: word=0666
entry=54: word=0666
entry=55: word=0666
entry=56: word=0666
entry=57: word=0666
entry=58: word=0666
entry=59: word=0666
entry=60: word=0666
entry=61: word=0666
entry=62: word=0666
entry= 0: word=0666
entry= 1: word=4777
entry= 2: word=4888
entry= 3: word=4888
entry= 4: word=4888
entry= 5: word=4888
entry= 6: word=4888
entry= 7: word=4888
entry= 8: word=4888
entry= 9: word=4888
entry=10: word=4888
entry=11: word=4888
entry=12: word=4888
entry=13: word=4888
entry=14: word=4888
entry=15: word=4888
entry=16: word=4888
entry=17: word=4888
entry=18: word=4888
entry=19: word=4888
entry=20: word=4888
entry=21: word=4888
entry=22: word=4888
entry=23: word=4888
entry=24: word=4888
entry=25: word=4888
entry=26: word=4888
entry=27: word=4888
entry=28: word=4888
entry=29: word=4888
entry=30: word=4888
entry=31: word=4888
entry=32: word=4888
entry=33: word=4888
entry=34: word=4888
entry=35: word=4888
entry=36: word=4888
entry=37: word=4888
entry=38: word=4888
entry=39: word=4888
entry=40: word=4888
entry=41: word=4888
entry=42: word=4888
entry=43: word=4888
entry=44: word=4888
entry=45: word=4888
entry=46: word=4888
entry=47: word=4888
entry=48: word=4888
entry=49: word=4888
entry=50: word=4888
entry=51: word=0888
entry=52: word=0888
entry=53: word=0888
entry=54: word=0888
entry=55: word=0888
entry=56: word=0888
entry=57: word=0888
entry=58: word=0888
entry=59: word=0888
entry=60: word=0888
entry=61: word=0888
entry=62: word=0888
entry= 0: word=0888
entry= 1: word=8999
entry= 2: word=8999
entry= 3: word=8aaa
entry= 4: word=8aaa
entry= 5: word=8aaa
entry= 6: word=8aaa
entry= 7: word=8aaa
entry= 8: word=8aaa
entry= 9: word=8aaa
entry=10: word=8aaa
entry=11: word=8aaa
entry=12: word=8aaa
entry=13: word=8aaa
entry=14: word=8aaa
entry=15: word=8aaa
entry=16: word=8aaa
entry=17: word=8aaa
entry=18: word=8aaa
entry=19: word=8aaa
entry=20: word=8aaa
entry=21: word=8aaa
entry=22: word=8aaa
entry=23: word=8aaa
entry=24: word=8aaa
entry=25: word=8aaa
entry=26: word=8aaa
entry=27: word=8aaa
entry=28: word=8aaa
entry=29: word=8aaa
entry=30: word=8aaa
entry=31: word=8aaa
entry=32: word=8aaa
entry=33: word=8aaa
entry=34: word=8aaa
entry=35: word=8aaa
entry=36: word=8aaa
entry=37: word=8aaa
entry=38: word=8aaa
entry=39: word=8aaa
entry=40: word=8aaa
entry=41: word=8aaa
entry=42: word=8aaa
entry=43: word=8aaa
entry=44: word=8aaa
entry=45: word=8aaa
entry=46: word=8aaa
entry=47: word=8aaa
entry=48: word=8aaa
entry=49: word=8aaa
entry=50: word=8aaa
entry=51: word=0aaa
entry=52: word=0aaa
entry=53: word=0aaa
entry=54: word=0aaa
entry=55: word=0aaa
entry=56: word=0aaa
entry=57: word=0aaa
entry=58: word=0aaa
entry=59: word=0aaa
entry=60: word=0aaa
entry=61: word=0aaa
entry=62: word=0aaa
entry= 0: word=0aaa
entry= 1: word=0911
entry= 2: word=0911
entry= 3: word=0911
entry= 4: word=0911
entry= 5: word=0a22
entry= 6: word=0a22
entry= 7: word=0a22
entry= 8: word=0a22
entry= 9: word=0a22
entry=10: word=0a22
entry=11: word=0a22


Вроде бы всё как задумывалось, и от static не зависит.

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

Вт июн 15, 2021 17:21:49

scr->symbol[i] - это какая-то 11-битная переменная, например, 0x0482 = 1154
symbol не может быть 11-битным, так как это char, а char в AVR думаю 8-битный скорей всего.
Другое дело если в symbol будут лежать отрицательные значения, а тип char - знаковый (если это так в компиляторе автора - не знаю), тогда будут проблемы с выходом за диапазон индексов массива.

И ещё я бы проверил операцию entry >= scr->bright. Возможно оптимизатор для неё не обязательно генерит результат в диапазоне [0,1]. Возможно оптимизатор более вольно трактует.
Вообще не вижу смысла так делать. Лучше уж: ((entry >= scr->bright) ? 1: 0) для надёжности.

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

Вт авг 17, 2021 08:39:00

Расскажите, как делать округление знакового числа при делении в целочисленной математике?
С беззнаковыми я обычно делал A + (B/2) / B и тогда результат получается уже округлённым. Но если A отрицательное число? делать if или есть более изящные способы?
Ответить