• Mark
• Christoph
• Hendrik
• Robert

# Code

## 1. Abend

### LED - Blinken

Aufgabe: Eine LED soll zum blinken gebracht werden.
Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * Aufgabe: Eine LED soll zum blinken gebracht werden. // * Lösung: Alle LEDs werden zum blinken gebracht // * //****************************************************************************

1. include <avr/io.h>
2. include <util/delay.h>

int main(void) { unsigned int i;

/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */ DDRC = (1<<DDC4); DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD3); /* Setze Ports PC4, PD3, PD6 und PD7 auf high */ PORTC = (1<<PC4); PORTD = (1<<PD7)|(1<<PD6)|(1<<PD3);

while(1) { for (i=0;i<50;i++) _delay_loop_2(0);

```PORTC ^= _BV(PC4);
PORTD ^= _BV(PD7)|_BV(PD6)|_BV(PD3);
```

} return 0; }

</source>

### LED - Einschalten

Aufgabe: Eine LED soll zum leuchten gebracht werden.
Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * Aufgabe: Eine LED soll zum leuchten gebracht werden. // * //****************************************************************************

1. include <avr/io.h>

int main(void) {

``` /* PC4 auf Ausgang */
DDRC = &b10000;  /* Alternativ Hex: 0xF oder Dezimal: 16 */
/* 7 6 5 4 3 2 1 0 */
/* 0 0 0 1 0 0 0 0 */
```
``` /* PC4 einschalten */
PORTD = &b10000;
```
``` /* Endlosschleife */
while(1)
{
}
```

}

</source>

### LED - Lauflicht

Code:

<source lang ="c"> //**************************************************************************** // * // * Von Gruppe 1 // * //****************************************************************************

1. include <avr/io.h>
2. include <util/delay.h>

int main(void) { unsigned int i;

/* Setze Ports PC4, PD3, PD6 und PD7 als Ausgang */ DDRC = (1<<DDC4); DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD3); /* Setze Ports PC4, PD3, PD6 und PD7 auf low */ PORTC = (0<<PC4); PORTD = (0<<PD7)|(0<<PD6)|(0<<PD3);

while(1) {

```PORTC ^= _BV(PC4);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTC ^= _BV(PC4);
PORTD ^= _BV(PD3);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD3);
PORTD ^= _BV(PD6);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD6);
PORTD ^= _BV(PD7);
for (i=0;i<50;i++) _delay_loop_2(0);
PORTD ^= _BV(PD7);
```

} return 0; } </source>

### Blinksequenz aufzeichnen und später abspielen

<source lang="c">#include <avr/io.h>

1. include <util/delay.h>
1. define SEQS 100

typedef struct { uint8_t bstate; uint32_t dur; } seq_t;

seq_t seq[SEQS]; uint8_t count = 0;

void wait(uint32_t ms); void record(void); void play(void);

void wait(uint32_t ms) {

```  uint32_t i;
```

for (i = 0; i < ms; i++) { _delay_ms(1); } }

void record(void) {

uint32_t dur = 0; uint8_t bstate_prev = 0x00; // prev button state uint8_t bstate = 0x00; // current button state

while (1) { bstate = 0x00;

// S1 if (~PINC & _BV(PC0)) { bstate |= 1 << 1; }

// S2 if (~PINC & _BV(PC1)) { bstate |= 1 << 2; }

// S3 if (~PINC & _BV(PC2)) { bstate |= 1 << 3; }

// S4 if (~PINC & _BV(PC3)) { bstate |= 1 << 4; }

// omit first state if (count == 0 && bstate == 0x0) { continue; }

if (count >= SEQS) { // overflow error => all LEDs on while (1) { PORTC |= _BV(PC4); PORTD |= _BV(PD3) | _BV(PD6) | _BV(PD7); } }

if (bstate_prev == bstate) { if (dur + 50 > dur) { dur += 50; }

if (bstate == 0x0 && count > 0 && dur >= 2000) { // no button was pressed for 2s return; } } else { // save state seq[count].bstate = bstate_prev; seq[count].dur = dur; count++;

// prepare for next state dur = 0; bstate_prev = bstate; }

wait(50); } }

void play(void) { uint8_t i;

while (1) { // PORTD |= _BV(PD7);

for (i = 0; i < count; i++) { // LED1 if (seq[i].bstate & 1 << 1) { PORTC |= _BV(PC4); } else { PORTC &= ~_BV(PC4); }

// LED2 if (seq[i].bstate & 1 << 2) { PORTD |= _BV(PD3); } else { PORTD &= ~_BV(PD3); }

// LED3 if (seq[i].bstate & 1 << 3) { PORTD |= _BV(PD6); } else { PORTD &= ~_BV(PD6); }

// LED4 if (seq[i].bstate & 1 << 4) { PORTD |= _BV(PD7); } else { PORTD &= ~_BV(PD7); }

wait(seq[i].dur); }

PORTC &= ~_BV(PC4); PORTD &= ~_BV(PD3) & ~_BV(PD6) & ~_BV(PD7); wait(300);

} }

int main(void) { DDRC |= _BV(PC4); DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7); // all LEDs are output

DDRC &= ~_BV(PC0) & ~_BV(PC1) & ~_BV(PC2) & ~_BV(PC3); // S[1..4] are input PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3); // use pullup for S[1..4]

// wait for pullops to "settle down" wait(1000);

while (1) { record(); play(); } }</source>

## 2. Abend

Änderungen des IR-Signals werden aufgezeichnet, und auch zeitlich ausgewertet. Messung ist jedoch relativ ungenau. Implementation von Timer / Counter fehlt.

<source lang ="c"> /* ################################### */ /* # IR-Empfang # */ /* # Von Gruppe 1 # */ /* ################################### */ /* # Done: IR-Signale chronologisch # */ /* # aufzeichnen # */ /* ################################### */ /* # Todo: Counter / Timer einbauen # */ /* ################################### */

1. include <avr/io.h>
2. include <string.h>
3. include <stdio.h>
4. include <avr/pgmspace.h>
5. include <util/delay.h>
6. include "uart.h"

int main(void) { int status = 0; int counter = 0;

```   /* initialize serial uart */
uart_init();
```
```   /* configure irrx as input */
DDRC &= ~_BV(PC3);
```
```   /* init led pin as output */
DDRD |= _BV(PD3);
```
```   while(1) {
counter++;
for (int i = 0; i<10; i++)
{
_delay_us(10);
```

}

```       /* if ir rx is high, turn off led */
if (PINC & _BV(PC3)) {
// Kein IR
PORTD &= ~_BV(PD3);
if (status == 1)
{
uart_printf("Ir jetzt aus %u\n",counter);
counter = 0;
}
status = 0;

} else {
PORTD |= _BV(PD3);
if (status == 0)
{
uart_printf("Ir jetzt an %u\n",counter);
counter = 0;
}
status = 1;
}
}
```

} </source>

## 3. Abend

### IR-Jammer

Sendet, sobald er IR empfängt, für 1000ms und wartet dann 5ms, damit er das ausgesandte Signal nicht wieder empfängt.

<source lang="c">

1. include <avr/io.h>
2. include <avr/interrupt.h>
3. include <util/delay.h>
4. include "uart.h"

/* constants */

1. define MAX 160

/* 38khz: freq = F_CPU/(2*prescaler*frequency)

```* 20mhz/(2*8*38khz) = ~33
* real frequency: 20mhz/(2*8*33) = ~37878Hz */
```
1. define PWM_FREQ 33

/* global variables */

/* allocate 160*2 = 320 byte memory for storing a code,

```* this means we can store 80 on/off sequence timings */
```

volatile uint16_t code[MAX]; /* current index in code[] (default: 0) */ volatile uint8_t pos = 0; /* current pin state (default: high == idle) */ volatile uint8_t state = 1; /* signal for the main application that a code has been received

```* (default: 0) */
```

volatile uint8_t done = 0; /* signal button presses from interrupt to main */ volatile uint8_t button_press; /* current system mode */ enum {

```   MODE_OFF = 0,
MODE_DISPLAY = 1,
MODE_JAM = 2,
MODE_RECORD = 3,
```

} mode = MODE_DISPLAY; /* current viewmode */ enum {

```   VIEW_VALUE_AND_TIME = 0,
VIEW_VALUE = 1,
VIEW_TIME = 2,
```

} view = VIEW_VALUE_AND_TIME;

/* call every 10 ms, for buttons at pins PC0-PC3 */ static uint8_t button_sample(void) {

```   /* initialize state, buttons are active low! */
static uint8_t btn_state = 15; //0b1111;
/* initialize old sample */
static uint8_t last_sample = 15; //0b1111;
/* read inputs */
uint8_t new_sample = PINC & 15; //0b1111;
```
```   /* mark bits which are sampled with the same value */
uint8_t same_sample = (last_sample ^ ~new_sample);
/* all bits set in same_sample now have been sampled with the same value
* at least two times, which means the button has settled */
```
```   /* compare the current button state with the most recent sampled value,
* but only for those bits which have stayed the same */
uint8_t state_different = btn_state ^ (new_sample & same_sample);
/* all bits set in state_different have been sampled at least two times
* with the same value, and this value is different from the current
* button state */
```
```   /* if a bit is set in state (means: button is not pressed) AND bit is set
* in state_different (means: input has settled and value is different
* from state) together means: button has been pressed recently */
uint8_t btn_press = btn_state & state_different;
```
```   /* toggle all bits for inputs which switched state */
btn_state ^= state_different;
```
```   /* store current sample for next time */
last_sample = new_sample;
```
```   /* if bit is set in btn_press, a button has been pressed
* (not released yet) */
return btn_press;
```

}

void wait(uint32_t s) { uint32_t i; for (i = 0; i < s; i++) { _delay_ms(1); } }

/* set up timer 0 to generate a carrier using pwm at freq on pin OC0B (PD5) */ static void ir_enable(uint8_t freq) {

```   /* timer 0: fast pwm mode, clear OC0B on match, prescaler 8 */
TCCR0A = _BV(WGM00) | _BV(COM0B1);
TCCR0B = _BV(CS01) | _BV(WGM02);
```
```   /* set frequency */
OCR0A = freq;
```
```   /* set duty-cycle to 50% */
OCR0B = freq/2;
```

}

/* disable timer 0 and pwm generation */ static void ir_disable(void) {

```   TCCR0A = 0;
TCCR0B = 0;
```

}

/* pin change interrupt 1 service function */ ISR(PCINT1_vect) {

```   /* do nothing if we are just processing a code in the main loop,
* or no more space is available for a timer value */
if (done || pos == MAX)
return;
```
```   /* if this would be the first timing value ever recorded, and the
* state before was high (=idle), do not record the timing value
* and just reset the timer */
if (state && pos == 0) {
TCNT1 = 0;
/* else record the timing value */
} else {
/* store current timer value in code[]
* and reset the timer */
code[pos++] = TCNT1;
TCNT1 = 0;
}
```
```   /* toggle second led */
PORTD ^= _BV(PD3);
```
```   /* toggle state */
state = !state;
```

}

/* timer 1 compare A interrupt service function */ ISR(TIMER1_COMPA_vect) {

```   /* do nothing if we are just processing a code in the main loop */
if (done)
return;
```
```   /* if some code has been received */
if (pos > 0) {
/* if pos is odd, one last 'off'-timing is missing, fill with zero */
if (pos % 2 == 1)
code[pos++] = 0;
```
```       /* signal main */
done = 1;
```
```       /* turn on third led */
PORTD |= _BV(PD6);
}
```

}

/* timer 2 compare A interrupt service function */ ISR(TIMER2_COMPA_vect) {

```   /* sample buttons every 10ms */
button_press |= button_sample();
```

}

int main(void) {

```   /* initialize uart */
uart_init();
uart_printf("rumpus ir analyzer\n");
```
```   /* configure led pins as outputs and turn leds off */
DDRC |= _BV(PC4);
DDRD |= _BV(PD3) | _BV(PD6) | _BV(PD7);
PORTC &= ~_BV(PC4);
PORTD &= ~(_BV(PD3) | _BV(PD6) | _BV(PD7));
```
```   /* configure ir input pin, with pullup */
DDRC &= ~_BV(PC3);
PORTC |= _BV(PC3);
```
```   /* configure button input pins, with pullup */
DDRC &= ~(_BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3));
PORTC |= _BV(PC0) | _BV(PC1) | _BV(PC2) | _BV(PC3);
```
```   /* configure ir send pin as output, set low */
DDRD |= _BV(PD5);
PORTD &= ~_BV(PD5);
```
```   /* wait until pin is high (no ir carrier is detected) */
while(!(PINC & _BV(PC3)));
```
```   /* enable pin change interrupt 1 for ir input pin (PC3/PCINT11) */
PCMSK1 |= _BV(PCINT11);
PCICR |= _BV(PCIE1);
```
```   /* configure timer1 with prescaler 64 and CTC for measuring ir timings */
TCCR1B = _BV(CS11) | _BV(CS10) | _BV(WGM12);
/* configure timer action after 200ms: 20mhz/64/5 */
OCR1A = F_CPU/5/64;
/* enable OCR1A interrupt */
TIMSK1 = _BV(OCIE1A);
```
```   /* configure timer 2 with prescaler 1024 and CTC
* for button sampling */
TCCR2A = _BV(WGM21);
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
/* configure compare event a to occur after 10ms and enable interrupt */
OCR2A = F_CPU/1024/100;
TIMSK2 = _BV(OCIE2A);
```
```   /* signal user availability by turning on led 1 */
PORTC |= _BV(PC4);
```
```   /* enable interrupts */
sei();
```
```   /* signal the user that the analyzer part has started by turning led 1 on */
PORTC |= _BV(PC3);
```
```   while(1) {
/* if a code has been received */
if (mode == MODE_DISPLAY && done) {
```
```           /* print code to serial uart */
uart_printf("complete code received, %u on-off-timings:\n", pos/2);
for (uint8_t i = 0; i < pos; i += 2) {
```
```               if (view == VIEW_VALUE_AND_TIME) {
uint32_t on, off;
```
```                   /* compute timing in microseconds */
on = ((uint32_t)code[i]) * 64 / 20;
off = ((uint32_t)code[i+1]) * 64 / 20;
```
```                   uart_printf("  %5lu us (%5u) on, %5lu us (%5u) off\n",
on, code[i],
off, code[i+1]);
} else if (view == VIEW_VALUE) {
uart_printf("  %5u on, %5u off\n",
code[i], code[i+1]);
} else if (view == VIEW_TIME) {
uint32_t on, off;
```
```                   /* compute timing in microseconds */
on = ((uint32_t)code[i]) * 64 / 20;
off = ((uint32_t)code[i+1]) * 64 / 20;
```
```                   uart_printf("  %5lu us on, %5lu us off\n",
on, off);
}
}
```

```           /* turn off second and third led */
PORTD &= ~(_BV(PD3) | _BV(PD6));
```
```           /* wait until pin is high (no ir carrier is detected) */
while(!(PINC & _BV(PC3)));
```
```           /* reset all global variables */
pos = 0;
state = 1;
done = 0;
}
```

if (mode == MODE_JAM) { // hier wird gejammt!

if (!state) { DDRC |= _BV(PC3); // ir empfang aus

ir_enable(PWM_FREQ); wait(1000); ir_disable();

wait(5); // damit wir unser eben gesendetes signal nicht empfangen DDRC &= ~_BV(PC3); // ir empfang an

done = 0; pos = 0; } }

```       if (button_press) {
/* first button toggles system mode */
if (button_press & 1) {
mode++;
if (mode > MODE_RECORD)
mode = MODE_OFF;
```
```               if (mode == MODE_OFF) {
uart_printf("ir analyzer switched off\n");
```
```                   /* disable timer1 and pin change interrupts */
TIMSK1 &= ~_BV(OCIE1A);
PCMSK1 &= ~_BV(PCINT11);
```
```                   /* turn off led1 */
PORTC &= ~_BV(PC4);
```
```               } else if (mode == MODE_DISPLAY) {
uart_printf("scan and display codes\n");
```
```                   /* clear interrupt flags, enable timer1 and pin change interrupts */
TIFR1 = _BV(OCIE1A);
TIMSK1 |= _BV(OCIE1A);
PCMSK1 |= _BV(PCINT11);
```
```                   /* turn on led1 */
PORTC |= _BV(PC4);
} else if (mode == MODE_JAM) {
/* clear interrupt flags, enable timer1 and pin change interrupts */
TIFR1 = _BV(OCIE1A);
TIMSK1 |= _BV(OCIE1A);
PCMSK1 |= _BV(PCINT11);
```
```                   uart_printf("jamming mode active\n");
} else if (mode == MODE_RECORD) {
uart_printf("record and replay a code\n");
}
}
```

```           /* second button toggles view mode */
if (button_press & 2) {
view++;
if (view > VIEW_TIME)
view = VIEW_VALUE_AND_TIME;
```
```               if (view == VIEW_VALUE_AND_TIME)
uart_printf("display timer value and time (in us)\n");
else if (view == VIEW_VALUE)
uart_printf("display timer value\n");
else if (view == VIEW_TIME)
uart_printf("display time (in us)\n");
}
```
```           if (button_press & 4) {
static uint8_t pwm = 0;
```
```               if (!pwm) {
ir_enable(PWM_FREQ);
uart_printf("pwm on\n");
} else {
ir_disable();
uart_printf("pwm off\n");
}
pwm = !pwm;
}
```
```           button_press = 0;
}
}
```

}</source>