Bit Shift Operations help & Understanding "Disabling Arduino Standard Interrupt"

Hello All,

I'm using this snippet of code as follows for reference;

// enable Timer 1 interrupt
TIMSK1 = 0;
TIMSK1 |= _BV(TOIE1);
// disable arduino standard timer interrupt
TIMSK0 &= ~_BV(TOIE1);

I don't understand what that last line of code is doing. I know "~" is a "not" operator and "&=" is a "compound and" operator, but what does that achieve? When I tried writing the results by hand all I got was 000. Also, does anyone have an idea to what the author means by "disable arduino standard timer interrupt"? Any ideas what they mean by "standard" interrupt?

Here's the link to my attempt at writing it out.

Thanks!

&= ~ is standard form for clearing a bit, or turning a bit off.

If X is defined as 0b11000011 and Y is defined as 0b00000010 and we’re looking at X &= ~Y

Then ~Y is 0b11111101

0b11000011
& 0b11111101
= 0b11000001

For use older guys :confused:

  0b11000011
& 0b11111101
= 0b11000001

Thanks, I didn't know how to make it look like that.

Ok cool it's good to know that "&=~" is the standard form for clearing something, and that example was very helpful but I'm still a little confused. In section 19.9.3 of the the Atmel 328p datasheet, TOIE is just a single byte. So when doing the operation I originally posted, wouldn't the net effect still be 0 essentially? Why not just set "TIMSK0 = 0"?

Do you guys know what "disable arduino standard timer interrupt" might mean or do?

Here's the whole chunk of code I'm using as an example if it makes more sense in context. I'm trying to set up the three timers for an arduino 328p chip on a brushless gimbal board.

//timer setup for 31.250KHZ phase correct PWM
TCCR0A = 0;
TCCR0B = 0;
TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00); // non-inverting mode, clear OC0B on compare match, phase correct PWM mode
TCCR0B = _BV(CS00); // No Prescaling
TCCR1A = 0;
TCCR1B = 0;
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10); // phase correct PWM 8-bit
TCCR1B = _BV(CS10); //
TCCR2A = 0;
TCCR2B = 0;
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);

// enable Timer 1 interrupt
TIMSK1 = 0;
TIMSK1 |= _BV(TOIE1);
// disable arduino standard timer interrupt
TIMSK0 &= ~_BV(TOIE1);

ShayS:
I know "~" is a "not" operator

No, it's NOT a "not" operator. It does an inversion of all bits. Exclamation mark is the "not" operator.

void setup()
{
  byte val = 0xA5;

  
  Serial.begin(250000);
  Serial.println("Ready");

  Serial.print("! -> 0x"); Serial.println(!val, HEX);
  Serial.print("~ -> 0x"); Serial.println((byte)~val, HEX);
}

The cast to byte in the last print is needed to suppress leading F.
Output:

Ready
! -> 0x0
~ -> 0x5A

Our posts crossed. The &= prevents the other bits in TIMSK0 from being modified. If you would set it to 0, all bits will be cleared, not only the interrupt enable bit.

void setup()
{
  byte reg = 0xFF;
  byte val = _BV(TOIE1);
  
  Serial.begin(250000);
  Serial.println("Ready");

  Serial.print("val: 0x"); Serial.println(val, HEX);
  Serial.print("reg: 0x"); Serial.println(reg, HEX);
  Serial.print("! -> 0x"); Serial.println(reg & !val, HEX);
  Serial.print("~ -> 0x"); Serial.println((byte)reg & ~val, HEX);
}

Output

Ready
val: 0x1
reg: 0xFF
! -> 0x0
~ -> 0xFE

Thanks for the verification between ! and ~, that's good to know.

Your next post makes sense. Is that just considered good coding ettiquette if TIMSK0 has never been modified in the code before up until this point?

Also any idea why we would want to disable this timer 0 like this? Why not just leave it out and keep the use of millis() and delay() if we wanted?

Because by setting Timer0 prescaler to 1 you break the millis() functionality anyway (it will count much faster) and the interrupt will come very often, every 256 CK eating a lot of processor time.

Also any idea why we would want to disable this timer 0 like this? Why not just leave it out and keep the use of millis() and delay() if we wanted?

The execution of the Timer0 overflow interrupt, used for millis(). can create timing jitter in the other outputs and its often disabled when precise timing is required..

However the code snippet that you posted is enabling a Timer1 overflow interrupt. What is it being used for?

It's being used for an inverted pendulum (self balancing) robot, which is my eventual end goal. The code is supposed to set up the timers, and then to my understanding so far, it uses those timers to create PWM wave(s?) to run a couple of brushless gimbal motors.

Here's the whole function

void Bl_Setup()
{
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);

digitalWrite(LEDPIN, HIGH);

cli();//stop interrupts

//timer setup for 31.250KHZ phase correct PWM
TCCR0A = 0;
TCCR0B = 0;
TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00); // non-inverting mode, clear OC0B on compare match, phase correct PWM mode
TCCR0B = _BV(CS00); // No Prescaling
TCCR1A = 0;
TCCR1B = 0;
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10); // ?, ?, phase correct PWM 8-bit
TCCR1B = _BV(CS10); //
TCCR2A = 0;
TCCR2B = 0;
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);

// enable Timer 1 interrupt
TIMSK1 = 0;
TIMSK1 |= _BV(TOIE1);
// disable arduino standard timer interrupt
TIMSK0 &= ~_BV(TOIE1);

sei(); // Start Interrupt

//turn off all PWM signals
OCR2A = 0; //11 APIN
OCR2B = 0; //D3
OCR1A = 0; //D9 CPIN
OCR1B = 0; //D10 BPIN
OCR0A = 0; //D6
OCR0B = 0; //D5

// switch off PWM Power
motorPowerOff();
}

to my understanding so far, it uses those timers to create PWM wave(s?)

Yes. But with using the hardware output pins, that can be done without any interrupts. It seems strange to be clearing the Timer0 overflow interrupt, and then setting one up on Timer1.

Yea I don't know.... I'll keep in there for now, but at least I learned something. Later on when everything's working I can try to take it out and see what happens.

Thanks for the help!

cattledog:
Yes. But with using the hardware output pins, that can be done without any interrupts. It seems strange to be clearing the Timer0 overflow interrupt, and then setting one up on Timer1.

I guess the Timer1 overflow ISR is used for something else than counting time. Such as read change of position and update PWM duty to fix it. This way you get nearly constant time between updates and your main loop does not have to care about this (i.e. the robot won't topple if you run into long something in main loop).