Страница 353 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 07:55:17
ARV
technik-1017 писал(а):Использование static заставляет компилятор оптимизировать данный код (скорее всего он выкидывает часть)
использование static заставляет компилятор сделать загрузку 2 байт в структуру при входе в функцию и сохранение этих 2 байт при выходе, только и всего, никакой другой оптимизации он не делает. не должен делать, во всяком случае.
главное: я не понимаю, что я делаю не так! не первый год это делаю, но в данном случае результат не соответствует ожиданиям! как так-то?!
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 09:59:45
technik-1017
Ассемблерный код все таки наверно придётся смотреть, что бы понять что происходит.
На самом деле у меня было несколько вопросов:
1) переменная entry определена как static, но где тогда происходит первая инициализация. Впервые встречается в условии if и уже сама себя увеличивает (увеличивает мусор?)
2) переменная pos, аналогично пункту 1.
3) переменная regs вроде должна быть (задумано) как static ну и также не инициализирована.
4) переменная two_ms вроде как глобальная, тогда зачем было часть переменных делать глобальными, а часть как static.
Желание избавиться от глобальных переменных? Но по факту они остаются глобальными.
Может пойти классическим путём: в прерывании использовать глобальные переменные с volatile?
По поводу оптимизации static:
в обычных функциях компилятор может понять, что значит переменная static и правильно выполнить оптимизацию. А вот с прерыванием такой фокус может не пройти, т.к. в коде программы прерывание нигде не вызывается как обычная функция и использование static в прерывании для компилятора может выглядеть странно.
То что иногда работает, уже говорили: скорее всего используется память которая ранее была освобождена, и содержала корректные данные от предыдущих действий программы.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 10:53:55
jcxz
[uquote="ARV",url="/forum/viewtopic.php?p=4047298#p4047298"]а вы посмотрите внимательно:
regs.word &= 0xf800;
regs.word |= digs[scr->symbol[entry >= scr->bright]];
младшие 11 бит в каждом прерывании меняются, а старшие 5 - только каждое 62 прерывание.[/uquote]Я это видел, об этом и писал.
А что значит "со static не работает"? В чём это выражается "не работает"?
Неработать может от того, что кроме этого у вас там есть ещё баги. И их комбинация даёт причудливый результат - когда-то что-то работает, когда-то - нет. Одни баги могут компенсировать/нивелировать действие других.
Например - когда делаете static, то в другом месте другой код, у вас эту область памяти портит. Потому и не работает. Как вариант.
И вообще - как можно о чём-то судить если половину кода не привели и листинга не привели? Только гадать....
Например - что такое
static pos_t *scr = screen; и зачем ему (static-переменной scr) на каждом входе в функцию присваивается (переменная/константа/etc.(?)) screen? Какой тут смысл делать
статик если по использованию тут нужна обычная автоматическая переменная?
Добавлено after 6 minutes 19 seconds:
[uquote="technik-1017",url="/forum/viewtopic.php?p=4047576#p4047576"]1) переменная entry определена как static, но где тогда происходит первая инициализация. Впервые встречается в условии if и уже сама себя увеличивает (увеличивает мусор?)[/uquote]Не имеющие явной инициализации глобальные/статические переменные, инициализируются 0. Это
поведение по умолчанию для си/си++ (может быть измененено соответствующими ключевыми словами компилятора).
Но для
самокомментируемости кода, полезно делать явную инициализацию 0-м, чтобы показать для каких переменных это критично. Но не обязательно.
[uquote="technik-1017",url="/forum/viewtopic.php?p=4047576#p4047576"]2) переменная pos, аналогично пункту 1.
3) переменная regs вроде должна быть (задумано) как static ну и также не инициализирована.[/uquote]Хотя бы для начала изучите си.
[uquote="technik-1017",url="/forum/viewtopic.php?p=4047576#p4047576"]Может пойти классическим путём: в прерывании использовать глобальные переменные с volatile?[/uquote]Зачем? (volatile)
Добавлено after 14 minutes 32 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=4047298#p4047298"]вам известны более красивые способы отправки двух байт с последующей дрыгоножной выдачей строба на классическом AVR? посоветуйте, я всегда готов учиться хорошему. а грубить я умею и сам.[/uquote]Сразу, навскидку, что бросается в глаза - ожидания делать не после записей, а перед. А строб перенести в начало ISR. Это сразу уменьшает ожидание внутри ISR на эти самые 16 тактов.
PS: Чисто теоретически я бы выбрал другой МК: с DMA (для SPI) или с FIFO (в SPI). И эти проблемы бы сами собой отпали. Например STM8Lxx.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 11:57:12
ARV
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
mont-oriol
[uquote="ARV",url="/forum/viewtopic.php?p=4047638#p4047638"]когда эта переменная БЕЗ static, т.е. содержит мусор на входе в функцию, все работает, а когда я делаю её static, т.е. она на первом входе уже инициализирована нулями - работать перестаёт...[/uquote]
==
Когда переменная находится в одной области памяти, все работает, а когда переносится в другую область памяти - работать перестаёт?
Возможно, что-то портит ту область, где static переменные. Может стек туда наезжает. Для проверки можно сделать переменную глобальной, и объявить её выше / ниже по отношению к другим переменным, так, чтобы можно было менять её адрес расположения в памяти. Если окажется, что при таком перемещении переменной всё заработало - вывод очевиден.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 13:31:18
WiseLord
Кстати, вот это
действительно опаснее, чем выглядит. Хотя, если 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
technik-1017
Скорее всего static в Си не может использоваться со структурами (так как мы этого хотим в данном примере) и конечно их не инициализирует (инициализировать структуру нужно принудительно).
static используется только для ограничения видимости. Попробуйте сделать структуру глобальной переменной.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 13:45:21
jcxz
[uquote="ARV",url="/forum/viewtopic.php?p=4047638#p4047638"]
jcxz писал(а):А что значит "со static не работает"? В чём это выражается "не работает"?
как минимум в том[/uquote]Вы не поняли вопрос. Перечитайте ещё раз.
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 не знает азов си?

Или всё-таки вы их не знаете?
PS: Складывается ощущение, что это не у вас эти баги, а у меня. К советам вы не прислушиваетесь, ещё и спорите.... Зачем тогда вообще вопрос задали?
Баги эти вроде не у меня. И мне абсолютно на них насрать. Не нужно вам найти решение - воля ваша. Зачем тогда было спрашивать?
Добавлено after 1 minute 2 seconds:
[uquote="mont-oriol",url="/forum/viewtopic.php?p=4047681#p4047681"]Возможно, что-то портит ту область, где static переменные.[/uquote]Я уже это советовал автору. Но не принимает никаких советов....
Добавлено after 2 minutes 35 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=4047688#p4047688"]Кстати, вот это
действительно опаснее, чем выглядит. Хотя, если screen - тоже static и представляет собой массив pos_t[/uquote]Я ещё в самом начале советовал автору привести определения
всех объектов и типов, фигурирующих в примере кода. Чтобы не играть в угадайку. Но он проигнорировал. Видимо ищет здесь гадалок....
Добавлено after 2 minutes 10 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=4047688#p4047688"]А вот почему код, если regs сделать static, ломается - действительно странно.[/uquote]Очень просто - наверняка там ещё табун других багов рядом пасётся.

которые иногда проявляются, иногда - нет. Как карты лягут....
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 14:18:01
technik-1017
Только что проверил в IAR AVR
- если объявить структуру как static (не инициализированную), то компилятор просто выкидывает кусок кода, где используется структура
- если объявить структуру без static, то код не выбрасывается, но переменная локальная
- если объявить структуру volatile static, то код не выбрасывается, но куда указывает, не успел проверить (пора домой, дома позже могу проверить)
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 15:31:53
Reflector
[uquote="jcxz",url="/forum/viewtopic.php?p=4047691#p4047691"]
Код: Выделить всё
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().[/uquote]
Это не более чем результат оптимизации, если после использования переменной t присвоить новое значение, то компилятор может добавить флаг говорящий о том нужно ли загружать в переменную значение cpuUseCalc, а может он перезапишет значение самой cpuUseCalc, если она больше нигде не используется, тогда одна загрузка и останется.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 16:05:02
ARV
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
WiseLord
А можно ещё уточнить по значениям POS_CNT, IND_RPT. А то без этого логика не до конца ясна (особенно проверка entry < 50)
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 16:52:07
jcxz
[uquote="ARV",url="/forum/viewtopic.php?p=4047763#p4047763"]откуда взяться неправильной операции с памятью?! memcpy и strcpy я не использую, как не использую и аналогичных "самописных" функций, заполняющих/изменяющих области памяти по указателю... других способов разрушить "соседние" переменные (не считая переполнения стека)[/uquote]Вы используете
указатели. Одного этого достаточно чтобы порушить память.
Добавлено after 6 minutes 58 seconds:
[uquote="WiseLord",url="/forum/viewtopic.php?p=4047784#p4047784"]А можно ещё уточнить по значениям POS_CNT, IND_RPT. А то без этого логика не до конца ясна (особенно проверка entry < 50)[/uquote]Как партизан на допросе... под пытками выдаёт по капле инфу... хотя вроде же ему нужны советы...

Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 16:58:50
WiseLord
Ещё момент... word = digs[blablabla] - тут не возникнет переполнения?
Значение CHAR_CNT нам неизвестно (как и CHAR_0 сотоварищи), поэтому есть ли гарантия, что где-то в scr->symbol[0] или scr->symbol[1] не лежит число большее либо равное этому CHAR_CNT?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 17:01:26
ARV
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
WiseLord
А сами символы? Что именно такое CHAR_0?
Я почему спрашиваю... Вот идёт код
Код: Выделить всё
word = digs[scr->symbol[entry >= scr->bright]];
В зависимости от яркости и entry, это может быть одно из двух:
Код: Выделить всё
word = digs[scr->symbol[0]];
word = digs[scr->symbol[1]];
scr->symbol
- это какая-то 11-битная переменная, например, 0x0482 = 1154
Вопрос, насколько правомерно тогда digs[1154] ?
Хотя.. я, видимо, не туда глянул, и там всё же не 11-битная symbol из regs_t, а char из pos_t. Тогда это будет скорее не код знака, а его индекс в массиве, меньший CHAR_CNT
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 17:12:18
ARV
WiseLord писал(а):scr->symbol - это какая-то 11-битная переменная, например, 0x0482 = .1154
Вопрос, насколько правомерно тогда digs[1154] ?
переменная scr->symbol 8-битная, см. структуру pos_t. содержит эта переменная код символов от 0 до 13. коды эти получаются самописной функцией, аналогичной itoa по смыслу. а вот digs[] - это уже массив 11-битных переменных
здесь не может быть проблем
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт июн 15, 2021 17:18:26
WiseLord
Да, я уже "проэмулировал" на компьютере:
Спойлер
Код: Выделить всё
#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
jcxz
[uquote="WiseLord",url="/forum/viewtopic.php?p=4047799#p4047799"]scr->symbol - это какая-то 11-битная переменная, например, 0x0482 = 1154[/uquote]symbol не может быть 11-битным, так как это char, а char в AVR думаю 8-битный скорей всего.
Другое дело если в symbol будут лежать отрицательные значения, а тип char - знаковый (если это так в компиляторе автора - не знаю), тогда будут проблемы с выходом за диапазон индексов массива.
И ещё я бы проверил операцию entry >= scr->bright. Возможно оптимизатор для неё не обязательно генерит результат в диапазоне [0,1]. Возможно оптимизатор более вольно трактует.
Вообще не вижу смысла так делать. Лучше уж: ((entry >= scr->bright) ? 1: 0) для надёжности.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 17, 2021 08:39:00
uldemir
Расскажите, как делать округление знакового числа при делении в целочисленной математике?
С беззнаковыми я обычно делал A + (B/2) / B и тогда результат получается уже округлённым. Но если A отрицательное число? делать if или есть более изящные способы?