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 - портит.