Имеется программный ШИМ:
Код
typedef struct
{
uint8_t counter;
uint8_t top;
uint8_t compare_val;
uint8_t pin;
uint8_t enabled;
volatile uint8_t *port;
} pwm_channel;
static pwm_channel channels[PWM_MAXCHANNELS];
ISR(TIMER1_COMPA_vect)
{
uint8_t i;
for ( i = 0; i < chnls_cnt; i++ )
{
if ( ! channels[i].enabled )
continue;
channels[i].counter++;
if ( channels[i].counter == channels[i].compare_val )
{
*channels[i].port |= 1 << channels[i].pin;
}
else
{
if ( channels[i].counter >= channels[i].top )
{
channels[i].counter = 0;
*channels[i].port &= ~(1 << channels[i].pin);
}
}
}
}
При этом channels[i].enabled, channels[i].top и channels[i].compare_val меняются посредством вызова функции spwm_configchannel(), нужно ли делать их volatile и почему всё работает и без этого?
Верно ли утверждение, что все глобальные переменные, доступ к которым осуществляется как в прерывании, так и в основном цикле нужно обязательно объявлять с volatile?
Я в принципе так всегда и делал, но вот тут вдруг всё работает даже с -O3
P.S. скурил
Nine ways to break your systems code using volatile.. страшно. Щас ещё баръеры памяти расставлять побегу )
The truth is out there...