Stop timer every period

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello!

I continue to study the process of signal synchronization.

I have external PWM signal -  400 Hz.

This signal is connected to the INT0 pin on Atmega2560. The rising edge of INT0 generates an interrupt request ISR(INT0_vect). In this interrupt I enable the internal 400Hz PWM.

The main task is synchronize the rising edge of external and internal 400 Hz PWM. 

The idea in as follows:

Interrupt triggers the internal PWM. When the couner reaches the value near 90% of the maximum - timer turns off. 

Maybe you thing that this is unclear option, but it suints my task well.

The problem is:

I'm trying to compare TCNT1 value with 39000, but this condition is not working. 

my code:


#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned int t_1=0;
volatile unsigned int t_2=0;
uint16_t period=0;
unsigned long frequency =0;

//capture Flag
volatile uint8_t flag;
int TOP=40000;	//Задаем период в битах.

void ExternalInterruptIni(void)
{
	EICRA|=(1<<ISC01)|(1<<ISC00);
	EIMSK|=(1<<INT0);
}


void Timer_400Hz_ini(void)
{
	ICR1=TOP;
	OCR1A=20000;
	TCCR1A|=(1<<COM1A1)|(1<<WGM11);
	TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS10);
}


void UART0_Init(void) {
	UBRR0L = 103;
	UBRR0H = 0;
	UCSR0B=(1<<RXEN0)|(1<<TXEN0);
	UCSR0C=(1<<UPM01)|(1<<UPM00)|(1<<UCSZ01)|(1<<UCSZ00);//(1<<UPM01)|
}
//Функция отправки на терминал
void uart0_tr(char value)
{
	while(!(UCSR0A & (1 << UDRE0))); // Ожидаем когда очистится буфер передачи
	UDR0 = value;
	
}

// print both bytes of a 16 bit hex number
void UART_puthex16(uint16_t n) {
	uart0_tr(n >> 8);
	uart0_tr(n & 0xFF);
}

int main(void)
{
	DDRB|=(1<<PB5);
	UART0_Init();
	// initialize timer
	ExternalInterruptIni();
	sei();
	while (1)
	{
		if (TCNT1>=39000)
		{
			TCCR1A=0;
		}
				
		
	}
}
ISR(INT0_vect)
{
	Timer_400Hz_ini();
	
}

 

This topic has a solution.
Last Edited: Fri. May 27, 2022 - 03:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What happens in the simulator (or in the 2560 if you observe it visa JTAG) ?

 

Also if you insist in breaking the time initialization stuff out into Timer_400Hz_ini() then make it "static inline" so it gets inlined in the body of the ISR. For obvious reasons you don't want it to be an actual CALL !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The main task is synchronize the rising edge of external and internal 400 Hz PWM. 

I'm not sure I understand your approach, although that wasn't the question asked.

 

The external signal's leading edge will occur once every 2.5 mSec.

So when the ISR fires you know "exactly", (+/- a couple of clock cycles), when the next PWM pulse will appear, and therefore when you should start the internal PWM.

The jitter in the approach is due to one not knowing how many clock cycles the current instruction is executing when the initial ISR fires.

 

So with a 16 MHz uC you should be able to synchronize the two signals to within < 200 nSec, or so.

 

If that isn't close enough, then one could use a faster uC, or use an analog approach, although it seems that your goal is learning how to do this in SW, without an actual HW project requirement at the moment.

 

JC 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello!

clawson wrote:

What happens in the simulator (or in the 2560 if you observe it visa JTAG) ?

 

Also if you insist in breaking the time initialization stuff out into Timer_400Hz_ini() then make it "static inline" so it gets inlined in the body of the ISR. For obvious reasons you don't want it to be an actual CALL !

clawson, what do you mean by the static inline?

The only one task that I have - synchtonize signals. I found out just one solution: 


#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>

volatile unsigned int t_1=0;
volatile unsigned int t_2=0;
uint16_t period=0;
unsigned long frequency =0;

uint16_t counter=0;
bool TimerStatus=false;

//capture Flag
volatile uint8_t flag;
int TOP=40000;	//Задаем период в битах.


void ExternalInterruptIni(void)
{
	EICRA|=(1<<ISC01)|(1<<ISC00);
	EIMSK|=(1<<INT0);
}

/*
void timer_ini(void)
{
	TCCR4B=(1<<WGM42)|(1<<CS40);
	OCR4A=79;	//меняем период таймера 1
	TIMSK4=(1<<OCIE4A);
}
*/
void Timer_400Hz_ini(void)
{
	ICR1=TOP;
	OCR1A=20000;
	TCCR1A|=(1<<COM1A1)|(1<<WGM11);
	TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS10);

}


void Timer_1MHz_ini(void)
{
	ICR1=15;
	OCR1A=7;
	TCCR1A|=(1<<COM1A1)|(1<<WGM11);
	TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS10);

}


void UART0_Init(void) {
	UBRR0L = 103;
	UBRR0H = 0;
	UCSR0B=(1<<RXEN0)|(1<<TXEN0);
	UCSR0C=(1<<UPM01)|(1<<UPM00)|(1<<UCSZ01)|(1<<UCSZ00);//(1<<UPM01)|
}
//Функция отправки на терминал
void uart0_tr(char value)
{
	while(!(UCSR0A & (1 << UDRE0))); // Ожидаем когда очистится буфер передачи
	UDR0 = value;
	
}

// print both bytes of a 16 bit hex number
void UART_puthex16(uint16_t n) {
	uart0_tr(n >> 8);
	uart0_tr(n & 0xFF);
}

int main(void)
{
	DDRB|=(1<<PB5)|(1<<PB6);
	UART0_Init();
	// initialize timer
	ExternalInterruptIni();
	uart0_tr(0xf1);

	



	sei();
	while (1)
	{
		

		
			
	}
}
ISR(INT0_vect)
{
PORTB|=(1<<PB5);


_delay_us(10);
PORTB&=~(1<<PB5);	
	
}

But this is the way of timer rejection. This is noncense for my device. 

Unfortunately, I don't have JTAG or Proteus. I always use Oscilloscope to signal control.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:

I'm not sure I understand your approach, although that wasn't the question asked.

 

The external signal's leading edge will occur once every 2.5 mSec.

So when the ISR fires you know "exactly", (+/- a couple of clock cycles), when the next PWM pulse will appear, and therefore when you should start the internal PWM.

The jitter in the approach is due to one not knowing how many clock cycles the current instruction is executing when the initial ISR fires.

 

So with a 16 MHz uC you should be able to synchronize the two signals to within < 200 nSec, or so.

 

If that isn't close enough, then one could use a faster uC, or use an analog approach, although it seems that your goal is learning how to do this in SW, without an actual HW project requirement at the moment. 

 

Hello DocJC

200 nSec is enouth. 

One more time about the problem. 

I have external 400Hz signal on the INT0 pin.  I use external interrupt in the mode of rising edge detecting. 

void ExternalInterruptIni(void)
{
	EICRA|=(1<<ISC01)|(1<<ISC00);
	EIMSK|=(1<<INT0);
}

This interrupt is working, i checked it by pin toggling.  

In the body of ISR(INT0_vect) I'm initialaze the Timer_400Hz_ini.  After some time (for example 2.4 mSec) I need to stop my timer. And start it againg in ISR(INT0_vect). In another word - I would like to make single shot PWM. 

unfortunately, if I add in my code TCCR1B=0 (to stop the timer) it stop internal PWM completely.

I tried to stop timer by checking TCNT1 or using a _delay_us or using another timer interrupt to generate delay before timer stop. I cannot to find any solution. 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Iaz5 wrote:
clawson, what do you mean by the static inline?
OK here is a really contrived example. First I implement pretty much what you have but for the purposes of illustration I absolutely guarantee the compiler won't accidentally choose to inline the called function anyway. I use __attribute__((noinline)) to guarantee this.

 

 

Now look at what was generated for the ISR(INT0_vect) code:

 

 

What has happened here is that as the compiler was compiling the one line ISR(INT0_vect) code which is the call to the timer init function it's said to itself "I don't know what he might be using in that timer_init() function so just to be on the safe side I will PUSH almost every important register just in case it happens to use any of these". It does not help that the code of timer_init() is in the same file or even that it is above the ISR() (so the compiler has already "seen" it). It just assumes that any called function could touch any register so it PUSHs and POPs all of them.

 

Now this is what happens when I do everything in my power to ensure that the function is just generated "inside" the INT0_vect handler:

 

 

Now the code for the ISR looks like:

 

 

Sure there are still some PUSH/POPs but not nearly as many. The middle bit of the function uses R24, R25, R30, R31 and those are now the only main registers being preserved/restored (some of the other stuff above/below is always there - for a different reason)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A lot of new, I have to digest information

Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Questions questions questions...

 

1) How much jitter can you stand from the incoming edge to your generated edge?

2) What else is this timer going to be doing?

3) Why can't you just use one micro?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

1) How much jitter can you stand from the incoming edge to your generated edge?

2) What else is this timer going to be doing?

3) Why can't you just use one micro?

Hello!

1. approximately - 2 mkSec;

2. Timer1 must generate 3 PWM with different duty cycle

3. Because i have external trigger (400Hz, not a micro. external device) and should synchronyze the signal

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please give a clear explanation of what you actually want to do.

e.g. create a single 1250us pulse which starts on rising edge of INT0.

e.g. how much latency is allowed.

 

You can run the program in the AS7.0 Simulator.   You can see exactly how many cycles or how many microseconds latency.

 

If you simply want to synchronise with an existing 2.5ms PWM from an external MCU,  just use the incoming PWM.

Obviously this requires the same duty cycle is acceptable for both PWM.

 

David.

Last Edited: Thu. May 26, 2022 - 02:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Iaz5 wrote:

2. Timer1 must generate 3 PWM with different duty cycle

 

What AVR are you using?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

Iaz5 wrote:

 

2. Timer1 must generate 3 PWM with different duty cycle

 

What AVR are you using?

Atmega2560

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Run both MCUs off the same clock.   Perfect synchronisation.

 

PWM generally means generating an average voltage from the duty cycle.   The actual synch is seldom important.

 

Obviously things like complementary drive signals need to be perfect as well as having dead-time.

You would never risk this from two independent MCUs.

 

Your code in #1 turns off TCCR1A.  This does not stop TCNT1.  It turns off COM#2 mode and changes WGM#14 into WGM#12.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Please give a clear explanation of what you actually want to do.

Sorry, my English is very bad, that is why my previous explanasion does not clear.

 

I have external Master device which generate 400 Hz signal. Duty cycle does not matter. Just frequency is matter. 

Also I have Atmega2560 - Slave. External 400 Hz signal is connected to the INT0. Why INT0? The serial number of ISR (INT0_vect) is 2 - after RESET.  Best response speed.

 

As soon as possible after rising edge of external signal I should start TIMER1 (it is possible to use any 16-bit timer) in FAST PWM Mode where TOP is ICR1. Why this mode? Because I should generate 3 internal 400 Hz signal. Signals are inverting and non-inverting( COM1A1 and COM1A0).

In my example above I generate just OCR1A, because if I can synchonize  one PWM of them,another - is not problem any more.

 

For internal signal duty cycle is extremly important. Frequency is controlling by the external 400 Hz signal. That is why in my first example I have tried to stop internal timer when the  counter (TCNT1) reaches the value near 90% of the maximum. It allows to prevent situation when the frequency of internal signal more, for example 401 Hz. The new period of internal signal have to start just after rising edge of external signal.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Your code in #1 turns off TCCR1A.  This does not stop TCNT1.  It turns off COM#2 mode and changes WGM#14 into WGM#12.

Yes, you are right. I found this mistake some time ago. To stop timer I use this one: TCCR1B=0; Divisor zeroing

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

Run both MCUs off the same clock.   Perfect synchronisation.

 

PWM generally means generating an average voltage from the duty cycle.   The actual synch is seldom important.

 

Obviously things like complementary drive signals need to be perfect as well as having dead-time.

You would never risk this from two independent MCUs.

 

Your code in #1 turns off TCCR1A.  This does not stop TCNT1.  It turns off COM#2 mode and changes WGM#14 into WGM#12.

 

David.

Unfortunately it is not possible. the only one signal that my Atmega 2560 has is external 400 Hz signal.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sure there's a flaw in this idea but...

why not simply reset TCNT to zero when you get the INT0 ISR? Run the timer in Mode 12 with ICR as TOP. In the ISR set your outputs and clear then on match.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Thu. May 26, 2022 - 03:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

I'm sure there's a flaw in this idea but...

why not simply reset TCNT to zero when you get the INT0 ISR? Run the timer in Mode 12 with ICR as TOP. In the ISR set your outputs and clear then on match.

In theory this is possible if the frequency of internal signal less than the frequency of external signal. for example 399 Hz. I will check it tomorrow on the oscilloscope

Last Edited: Fri. May 27, 2022 - 03:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So the timer free-runs, at a rate determined by ICRn which is set so that without an external signal the frequency is lower than 400Hz.

 

In the INT0 ISR TCNTn gets reset to zero. This will cause the timer to restart from zero before it reaches ICRn.

 

You now set the OC pins high in the ISR and let them clear on OCRn match.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Iaz5 wrote:

In theory this is possible if the frequency of internal signal more than the frequency of external signal. for example 401 Hz. I will check it tomorrow on the oscilloscope

 

But that's under your control by setting ICR to a suitable value. You'll need to play with prescaler values as that will determine your step size for the PWM. Depending on the longest output pulse width you can afford to run quite a bit faster than 400Hz (I think). 

 

[E2A]

You're OK, you can run wit a prescale of 1. 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Thu. May 26, 2022 - 03:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Iaz5 wrote:

Brian Fairchild wrote:

I'm sure there's a flaw in this idea but...

why not simply reset TCNT to zero when you get the INT0 ISR? Run the timer in Mode 12 with ICR as TOP. In the ISR set your outputs and clear then on match.

In theory this is possible if the frequency of internal signal more than the frequency of external signal. for example 401 Hz. I will check it tomorrow on the oscilloscope

 

Yes, in such a sync-trigger situation, you usually set some free-run period that is a bit longer than the tolerance on the trigger.

eg if you expect 2.5ms triggers +/- 50us, you could set a free-run period to 2.6ms, then you will always sync to trigger, but also run OK if that is missing  for any reason.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Who-me wrote:

Iaz5 wrote:

 

 

Brian Fairchild wrote:

 

I'm sure there's a flaw in this idea but...

why not simply reset TCNT to zero when you get the INT0 ISR? Run the timer in Mode 12 with ICR as TOP. In the ISR set your outputs and clear then on match.

In theory this is possible if the frequency of internal signal more than the frequency of external signal. for example 401 Hz. I will check it tomorrow on the oscilloscope

 

Yes, in such a sync-trigger situation, you usually set some free-run period that is a bit longer than the tolerance on the trigger.

eg if you expect 2.5ms triggers +/- 50us, you could set a free-run period to 2.6ms, then you will always sync to trigger, but also run OK if that is missing  for any reason.

 

Hello! Well, I have try this solution, something wrong. If I reset the TCNT1 in the body of ISR (INT0_vect) - timer just stopping.  Why this is so? I cannot to understand.

I have attached the picture from oscilloscope. Yellow - external trigger, blue - internal signal.

Also the code:


#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <stdbool.h>

volatile unsigned int t_1=0;
volatile unsigned int t_2=0;
uint16_t period=0;
unsigned long frequency =0;
uint16_t counter=0;
bool TimerStatus=false;
//capture Flag
volatile uint8_t flag;



void ExternalInterruptIni(void)
{
	EICRA|=(1<<ISC01)|(1<<ISC00);
	EIMSK|=(1<<INT0);
}


//__attribute__ ((always_inline)) 
void Timer_300Hz_ini(void)
{
	ICR1=53332;//300Hz
	OCR1A=20000;
	TCCR1A|=(1<<COM1A1)|(1<<WGM11);
	TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS10);

}

void UART0_Init(void) {
	UBRR0L = 103;
	UBRR0H = 0;
	UCSR0B=(1<<RXEN0)|(1<<TXEN0);
	UCSR0C=(1<<UPM01)|(1<<UPM00)|(1<<UCSZ01)|(1<<UCSZ00);//(1<<UPM01)|
}
//Функция отправки на терминал
void uart0_tr(char value)
{
	while(!(UCSR0A & (1 << UDRE0))); // Ожидаем когда очистится буфер передачи
	UDR0 = value;
	
}

// print both bytes of a 16 bit hex number
void UART_puthex16(uint16_t n) {
	uart0_tr(n >> 8);
	uart0_tr(n & 0xFF);
}

int main(void)
{
	DDRB|=(1<<PB5)|(1<<PB6);
	UART0_Init();
	
	// initialize timer
	ExternalInterruptIni();
	Timer_300Hz_ini();
	
	sei();
	while (1)
	{
							
	}
}
ISR(INT0_vect)
{
	TCNT1=0;
	//Timer_300Hz_ini();
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

I'm sure there's a flaw in this idea but...

why not simply reset TCNT to zero when you get the INT0 ISR? Run the timer in Mode 12 with ICR as TOP. In the ISR set your outputs and clear then on match.

I have checked, this is not work by some reason. You can see the post above

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did it!!!!

When the TCNT equals to zero - this is not work. I have changed it to 53300 and now in works!!!

Working code againg:


#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/cpufunc.h>
#include <util/delay.h>
#include <stdbool.h>

volatile unsigned int t_1=0;
volatile unsigned int t_2=0;
uint16_t period=0;
unsigned long frequency =0;
uint16_t counter=0;
bool TimerStatus=false;
//capture Flag
volatile uint8_t flag;



void ExternalInterruptIni(void)
{
	EICRA|=(1<<ISC01)|(1<<ISC00);
	EIMSK|=(1<<INT0);
}


//__attribute__ ((always_inline)) 
void Timer_400Hz_ini(void)
{
	ICR1=53332;
	OCR1A=20000;
	TCCR1A|=(1<<COM1A1)|(1<<WGM11);
	TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS10);

}

void UART0_Init(void) {
	UBRR0L = 103;
	UBRR0H = 0;
	UCSR0B=(1<<RXEN0)|(1<<TXEN0);
	UCSR0C=(1<<UPM01)|(1<<UPM00)|(1<<UCSZ01)|(1<<UCSZ00);//(1<<UPM01)|
}
//Функция отправки на терминал
void uart0_tr(char value)
{
	while(!(UCSR0A & (1 << UDRE0))); // Ожидаем когда очистится буфер передачи
	UDR0 = value;
	
}

// print both bytes of a 16 bit hex number
void UART_puthex16(uint16_t n) {
	uart0_tr(n >> 8);
	uart0_tr(n & 0xFF);
}

int main(void)
{
	DDRB|=(1<<PB5)|(1<<PB6);
	UART0_Init();
	
	// initialize timer
	ExternalInterruptIni();
	Timer_400Hz_ini();
	
	sei();
	while (1)
	{
							
	}
}
ISR(INT0_vect)
{
	TCNT1=53300;
	//Timer_400Hz_ini();
}

 

Thanks everyone, you helped me a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This seems to work using Fast PWM mode...

 

// I/O Registers definitions
#include <mega328p.h>

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
	TCNT1H=0x8f;
	TCNT1L=0xff;
}

void main(void)
{

	// Crystal Oscillator division factor: 1
	#pragma optsize-
	CLKPR=(1<<CLKPCE);
	CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
	#ifdef _OPTIMIZE_SIZE_
	#pragma optsize+
	#endif

	// Input/Output Ports initialization
	// Port B initialization
	// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=Out
	DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
	// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=0 Bit1=0 Bit0=0
	PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

	// Timer/Counter 1 initialization
	// Clock source: System Clock
	// Clock value: 16000.000 kHz
	// Mode: Fast PWM top=ICR1
	// OC1A output: Clear on compare match, set at BOTTOM
	// OC1B output: Clear on compare match, set at BOTTOM
	// Noise Canceler: Off
	// Input Capture on Falling Edge
	// Timer Period: 2.3041 ms
	// Output Pulse(s):
	// OC1A Period: 2.3041 ms
	// OC1B Period: 2.3041 ms
	// Timer1 Overflow Interrupt: Off
	// Input Capture Interrupt: Off
	// Compare A Match Interrupt: Off
	// Compare B Match Interrupt: Off
	TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (0<<WGM10);
	TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
	TCNT1H=0x00;
	TCNT1L=0x00;
	ICR1H=0x90;
	ICR1L=0x00;
	OCR1AH=0x30;
	OCR1AL=0x00;
	OCR1BH=0x60;
	OCR1BL=0x00;

	// Timer/Counter 1 Interrupt(s) initialization
	TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

	// External Interrupt(s) initialization
	// INT0: On
	// INT0 Mode: Rising Edge
	// INT1: Off
	// Interrupt on any change on pins PCINT0-7: Off
	// Interrupt on any change on pins PCINT8-14: Off
	// Interrupt on any change on pins PCINT16-23: Off
	EICRA=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (1<<ISC00);
	EIMSK=(0<<INT1) | (1<<INT0);
	EIFR=(0<<INTF1) | (1<<INTF0);
	PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);

	// Globally enable interrupts
	#asm("sei")

	while (1){
		;
	}
}

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."