# Attiny85 Manchester Encoding Timing Problem

#### Obreezy

Joined Aug 9, 2014
11
Hello, I've been having trouble getting this little timer routine to work correctly. I started out with a little program that switches the output of a pin every 240µs which turned out to work as expected:

C:
// This program switches the output of PB3 every 240µs.

#include <avr/interrupt.h>
#include <avr/io.h>

ISR(TIMER0_COMPA_vect)
{
PORTB ^= _BV(PB3);
}

int main()
{
DDRB |= _BV(PB3);
TCCR0A = _BV(WGM01);
TCCR0B = _BV(CS00);
TIMSK = _BV(OCIE0A);
OCR0A = 240;
sei();

while(1);
}

Then I started on the manchester encoding program building on the first program.
C:
// This program shifts out one byte on PB3 manchester encoded.
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>

#define set(X) PORTB |= _BV(X)
#define clr(X) PORTB &= ~_BV(X)
#define tgl(X) PORTB ^= _BV(X)

volatile bool waiting;

ISR(TIMER0_COMPA_vect)
{
waiting = 0;
}

void delay(uint8_t t)
{
waiting = 1;

TCCR0A = _BV(WGM01);
TCCR0B = _BV(CS00);
TIMSK = _BV(OCIE0A);
OCR0A = t;
sei();

while(waiting);

cli();
TCCR0B = 0; // stop timer
TCNT0 = 0; // reset timer counter

return;
}

int main()
{
DDRB |= _BV(PB3);
set(PB3); // 1. Begin with the output signal high.

uint8_t byte = 0X55;

int i;
for(i = 0; i < 8; i++) // 2. check if all bits have been sent
{       // 3. 4. 5.
if(byte & 1)
{       // ManchesterOne
clr(PB3);
delay(200);
set(PB3);
delay(200);
}
else
{       // ManchesterZero
set(PB3);
delay(200);
clr(PB3);
delay(200);
}
byte >>= 1;

set(PB3); // 7. Set output signal high and return.

while(1);
}
The output was really unexpected, I put in mid-bit time(T) of 200µs so it would be easy to see if it was working right with the oscilloscope grid at 200µs per div (I zoomed out to 400µs/div when I saw it), it ended up looking like this:

Realizing something was wrong with the timing, I took the new delay function and put it in its own program to try to figure out where I messed up. I noticed that it seems to take a long time to access certain registers, when I change TCCR0B to turn the timer on and off from inside the delay function, it adds a lot of extra delay in the function.

C:
// This program is a simple delay routine from 1 to 255 µs.
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdbool.h>
#include <stdint.h>

#define set(X) PORTB |= _BV(X)
#define clr(X) PORTB &= ~_BV(X)
#define tgl(X) PORTB ^= _BV(X)

volatile bool waiting;

ISR(TIMER0_COMPA_vect)
{
waiting = 0;
}

void delay(uint8_t t)
{
waiting = 1;
TCNT0 = 0;
OCR0A = t;
sei();

while(waiting);

cli();

return;
}

int main()
{
DDRB |= _BV(PB3);

TCCR0A = _BV(WGM01);
TCCR0B = _BV(CS00);
TIMSK = _BV(OCIE0A);

set(PB3); // 1. Begin with the output signal high.

while(1)
{
delay(200);
tgl(PB3);
}

}

The call to the function calls it with the value 200, so I would have liked to see 200µs between toggles on the scope. But it's actually toggling it at around 235µs. I know it's a software issue because the first basic timer program worked just fine. I'm just not seeing where I messed up in making the software. Also if I made some mistakes in the manchester encoding part please let me know, I haven't really gotten that far yet. I used this guide by atmel to put together the manchester encoding part.

Last edited:

#### Raymond Genovese

Joined Mar 5, 2016
1,658
What happens to the timing in the last program if you remove line 31, the return; in
void delay(uint8_t t) ?

#### Obreezy

Joined Aug 9, 2014
11
What happens to the timing in the last program if you remove line 31, the return; in
void delay(uint8_t t) ?
nothing, looks like it behaves the same.

#### Obreezy

Joined Aug 9, 2014
11
Nice I got it working after moving some stuff around. Turns out resetting the counter was the problem. so this one works now.

C:
// This program is a simple delay routine from 1 to 255 µs.
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>

#define set(X) PORTB |= _BV(X)
#define clr(X) PORTB &= ~_BV(X)
#define tgl(X) PORTB ^= _BV(X)

volatile bool waiting;

ISR(TIMER0_COMPA_vect)
{
waiting = 0;
}

void delay(uint8_t t)
{
waiting = 1;
OCR0A = t;
sei();

while(waiting);

cli();

return;
}

int main()
{
DDRB |= _BV(PB3);

TCCR0A = _BV(WGM01);
TCCR0B = _BV(CS00);
TIMSK = _BV(OCIE0A);

set(PB3); // 1. Begin with the output signal high.

while(1)
{
delay(200);
tgl(PB3);
}

}

#### Raymond Genovese

Joined Mar 5, 2016
1,658
Good deal that you got it working.

Since you are not returning a value in void delay(uint8_t t), and the return (in line 31) is the last statement in the function, it seems unnecessary. I just thought off the top of my head that it might be adding some overhead, but it clearly does not..