Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Importance of volatile variable

Status
Not open for further replies.

swapan

Full Member level 4
Joined
Feb 20, 2009
Messages
199
Helped
27
Reputation
54
Reaction score
23
Trophy points
1,298
Location
Kolkata
Activity points
2,806
Hi guys,

Somewhere I have seen that 'variable shared between ISR and main code should be declared volatile'. Accordingly, I took up the following code to make a practical test. But it is noticed that control passes to 2nd loop without performing the task of 1st loop. After trying it various ways and failing every time, I changed the declaration of "duty" from Unsigned Volatile short int to Unsigned int. Interestingly it is seen that the code works well as desired.

Please see the code and offer your valued comments on importance and use of Volatile declaration of variable.


Code:
sbit blink_led at RC4_bit;
sbit led at RC5_bit;
sbit rly at RB3_bit;
unsigned int  count, blink_cnt;
volatile short int  duty, blink_flag,  count_flag;

void interrupt ()
{
if (INTF_bit == 1)  {
PR2 = duty;
count++;
if (count > 5) {
count_flag = 1;
count = 0;
blink_cnt++;
                }

if (blink_cnt > 10)
              {
blink_flag =1;
blink_cnt = 0;
              }
TMR2IF_bit = 0;
TMR2IE_bit =1;
INTF_bit = 0;
INTE_bit = 0;
TMR2ON_bit = 1;
                     }


if (TMR2IF_bit == 1) {
blink_led =1;
delay_MS(1000);
blink_led=0;
TMR2ON_bit = 0;
INTE_bit = 1;
TMR2IE_bit =0;
TMR2IF_bit = 0;
                      }
}


 void main() {
GIE_bit = 1;
PEIE_bit = 1;
INTEDG_bit = 1;
INTE_bit = 1;
duty = 250;
T2CON = 0x3E;
count_flag = 0;

do  {

if (count_flag == 1) {
duty --;
count_flag = 0;
                     }
if (blink_flag==1)
                    {
led = ~led;
blink_flag = 0;
                     }
}while  ( duty >=50);          //    LOOP No.1

led = 1;
do  {

if (count_flag == 1)
count_flag = 0;


if (blink_flag == 1)  {
rly = ~rly;
blink_flag = 0;
                      }
    }  while (1);               //    LOOP No.2
}
 

it seems a variation of PIC, which one? (pic16? pic18?)

which compiler is this? it doesn't seem like XC8...

so, in your compiler what's the difference between

'int' and 'short int'?

did you tried changing from 'volatile unsigned short int' to 'volatile unsigned int'?? did something happened??



...

'volatile' can be understood as 'plz don't optimize this variable and always read it before using it'

while it's true and very important to use 'volatile' in variables that changes inside an ISR (because any compiler can't predict when the ISR is called and thus assume it's never called, and thus tries to optimize the use of variables that apparently don't change in the main program flow), I assume your problem is in the int-short.int range...

maybe your optimization is OFF so it works without the volatile, or, as you change some of those variables in the main program loop, you are lucky enough so you don't need volatile in this example...

as you are testing, try implementing a counter in the ISR (exactly use your 'count' variable) and try reading it in the main loop (like printing 'count' in a terminal or lcd) but don't change 'count' in the main loop, only in the ISR, in this example if you omit the 'volatile' it shouldn't work if the compiler is fully optimized... (but also maybe your compiler is intelligent enough? who knows?)
 

Hi,

whenever a variable will be modified by external events like interrupt, ports etc, "volatile" will be used. Once the variable is declared as a volatile, its an indication to compiler to not do any optimization for that variable.
 

Hi Kurenai_ryu ,
Thanks for your explicit note. This is PIC 16F72 and mikroC Pro compiler (free version). I have noticed that compiler reserves single byte for 'short int' variables and two bytes for 'int' variables. Since the variable 'duty' will never be more that one byte, I have declared it as 'volatile short int' with a view not to load the RAM unnecessarily.

I have not tried by changing 'volatile unsigned short int' to 'volatile unsigned int'. However I shall try it tonight.

while it's true and very important to use 'volatile' in variables that changes inside an ISR

In this connection please state if a variable is changed in main code ( as in my above code - 'duty' changes in main code) and polled in ISR, is it required to declare the variable 'volaile'?
 

It's a good idea to declare all variables shared between interrupt and main code as volatile, but strictly spoken, a problem arises only for variables that are modified in the interrupt code which isn't the case for variable duty. So your problem is of a different kind.

Presuming mikroC is following ANSI C (I'm not using it), and short is understood as 8-bit entity, 250 is a negative number and (duty < 50) initially false. So you'll want to declare it unsigned.
 

Hi Kurenai_ryu ,
Thanks for your explicit note. This is PIC 16F72 and mikroC Pro compiler (free version). I have noticed that compiler reserves single byte for 'short int' variables and two bytes for 'int' variables.
are you sure - the C standard specifies that the minimum for short int is 16bits
check your limits.h?
https://www.cplusplus.com/reference/climits/
 

Presuming mikroC is following ANSI C (I'm not using it), and short is understood as 8-bit entity, 250 is a negative number and (duty < 50) initially false. So you'll want to declare it unsigned.

I shall try as per your advice and appraise you the result.


are you sure - the C standard specifies that the minimum for short int is 16bits
check your limits.h?

I am not sure, but one of various options of compiler shows size of variable used in code. When a variable is declared 'unsigned short int', the size is shown as 1 byte and when the same variable is declared 'unsigned int' the size becomes 2 bytes. That's why I have written in above post.
 

the C standard specifies that the minimum for short int is 16bits
Yeah, at least in this regard mikroC is not ANSI compliant.
 

Presuming mikroC is following ANSI C (I'm not using it), and short is understood as 8-bit entity, 250 is a negative number and (duty < 50) initially false.

Thaaaaaaaanks FvM.

Your detection is absolutely right. Changing the variable 'duty' from volatile short int to volatile unsigned short int I have tested the hardware and it is working well as per the algorithm.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top