Die ATtiny461A-TPS         

von Christian Hottum                        
Elektronik-Labor  Projekte   TPS



Das Projekt ist an der Hochschule RheinMain,University of Applied Sciences,Wiesbaden Rüsselsheim im Fachbereich Ingenieurwissenschaften,
Studienbereich Informationstechnologie und Elektrotechnik im Labor für Informationstechnik und Telekommunikation entstanden. 
 
Entdeckt hat die TPS ein Professor mit dem ich oft zusammen arbeite. Wir waren auf der Suche nach einer Möglichkeit jemandem einen Mikrocontroller in kurzer Zeit näher zu bringen. Nach der Entdeckung haben wir uns erst mal zwei Franzis Lernpackete besorgt und uns mit dem System vertraut gemacht. Nach kurzer Zeit war uns klar, dass es genau das ist was wir gesucht haben. Nun bestand die Aufgabe darin die TPS auf unsere Anfoderungen anzupassen und das ganze mit einen Atmel IC umzusetzten. Diese Aufgabe fiel dann hauptsächlich in mein Gebiet.

Aktuell benutzen wir die TPS in Schülerpraktika als Lötprojekt, mit abschließenden Programmierübungen, und im nächsten Semester soll die TPS das erste Mal in einem Planspiel benutzt werden. Die TPS dient hierbei als Controller für einen Roboter und soll dafür sorgen das der Roboter an einer Linie entlang fährt.





Die TPS Firmware für den ATtiny 461A-PUwurde mit dem Atmel Studio in C neu programmiert.  Durch den größeren Speicherplatz und die größere Anzahl Pins habe ich die Programmgröße (256 Zeilen) erweitert und  einen zweiten PWM Ausgang hinzugefügt. Außerdem befindet sich in der Software ein Testprogramm um alle Ein- und Ausgänge zu testen.

Wenn man beim Einschalten oder bei einem Reset S1 gedrückt hält, verzweigt das Programm in den Testmodus. Dieser dient zum Testen der vorhandenen Hardware. In diesem sind die folgenden Funktionen, durch betätigen der entsprechenden Schalter, abrufbar.

S1:    Einschalten der Ausgänge (A1 – A4) mit einem Delay von 200ms zwischen dem Einschalten.
S2:    Ausschalten der Ausgänge (A1 – A4) mit einem Delay von 200ms zwischen dem Ausschalten.
E1:    Ansteuern der PWM-Ausgänge (PWM1, PWM2) auf 50 und 100 mit einem delay von 200ms zwischen den einzelnen Stufen.
E2:    Ansteuern der PWM-Ausgänge (PWM1, PWM2) auf 150, 200 und 250 mit einem delay von 200ms zwischen den einzelnen Stufen.
E3:    Einlesen von ADC1 und Ausgabe des Werts auf PWM1
E4:    Einlesen von ADC2 und Ausgabe des Werts auf PWM2

Außerdem enthält das Board im Unterschied zum Original einen weiteren PWM-Ausgang und einen erweiterten Speicherbereich. Aus diesem Grund wurde die Befehlstabelle um die Befehle 5A (PWM2=A) und 88 bis 8F erweitert.

Erweiterungsplatinen



Die TPS-Variante klein


Die Software

Download C-Projekt und Hexfile: TPStiny461.zip


/***************************************************************************************
Titel: ATtiny TPS
Author: Christian Hottum
File: ATtiny461A_TPS.c
Version: 0.1
Datum: 09.01.2015
Software: AVR-GCC 4.3.3
Target: ATtiny461A

DESCRIPTION
Firmware für einen Tasten Programierbare Steuerung auf Basis einen ATtiny461A
mit 3 Tasten (S1(PB0), S2(PB2) und reset(PB7)), 4 digitale Eingängen (PA0 - PA3),
2 ADC Eingänge (PB4 - PB5), 4 digitale Ausgänge (PA4 - PA7),
2 PWM Ausgänge (PB1, PB3), Freie Pins (PB6), 8 MHZ System Takt

***************************************************************************************/

// CPU Frequenz

#define F_CPU 8000000UL /* Quarz mit 8 Mhz */


// Include Dateien

#include <math.h>
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <util/delay.h>
#include "TPS_UP.h"
#include <avr/eeprom.h>

// Variablen

// I/O vorbereiten

int main(void)
{
_delay_ms(200);


// Ausgänge
PORTA &= ~(1<<A1) | (1<<A2) | (1<<A3) | (1<<A4); // alle Ausgänge aus
DDRA |= (1<<A1) | (1<<A2) | (1<<A3) | (1<<A4); // als Ausgänge setzen


// Tasten
PORTB |= (1<<S1) | (1<<S2) | (1<<PINB6); // Pull up Widerstände an
DDRB &= ~(1<<S1) | (1<<S2) | (1<<PINB6); // als Eingänge setzen


// Eingänge
PORTA |= (1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // Pull up Widerstände an
DDRA &= ~(1<<E1) | (1<<E2) | (1<<E3) | (1<<E4); // als Eingänge setzen


// ADC's
ADCSRA |= (1<<ADEN); // ADC aktivieren
ADMUX |= (1<<ADLAR); // ADC Ausgabe left adjusted
ADCSRA |= (1<<ADPS2) | (1<<ADPS0); // ADC-Frequenz Clock/32 (verkürzt die Abfrage)


// PWM's
PORTB &= ~(1<<PB1) | (1<<PB3); // alle Ausgänge aus
DDRB |= (1<<PB1) | (1<<PB3); // als Ausgänge setzen
TCCR1B |= (1<<CS10); // PWM-Mode setzen
TCCR1D |= (1<<WGM10);
TCCR1D &= ~(1<<WGM11);
TCCR1A |= (1<<PWM1A) | (1<<PWM1B) | (1<<COM1A1) | (1<<COM1B1);


// Hauptprogrammschleife

while(1)
{

if (!(PINB & (1<<S2))) // wenn S2 beim einschalten gedrückt ist
{ // gehe in den Programmier-Modus
PROG();
}
if (!(PINB & (1<<S1))) // wenn S1 beim einschalten gedrückt ist
{ // gehe in den Test-Modus
TEST();
}

AUSF(); // ansonsten gehe in den Ausführen-Modus

}

return 0;

}







/***************************************************************************************
Titel: ATtiny TPS Unterprogramme
Author: Christian Hottum
File: TPS_UP.h
Version: 0.1
Datum: 09.01.2015
Software: AVR-GCC 4.3.3
Target: ATtiny461A

DESCRIPTION
Variablen und Unterprogramme der TPS

***************************************************************************************/

// CPU Frequenz

#define F_CPU 8000000UL /* Quarz mit 8 Mhz */

// Include Dateien

#include <math.h>
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/eeprom.h>

// Tasten
#define S1 PINB0
#define S2 PINB2

// Eingänge
#define E1 PINA0
#define E2 PINA1
#define E3 PINA2
#define E4 PINA3

// Ausgänge
#define A1 PINA4
#define A2 PINA5
#define A3 PINA6
#define A4 PINA7

//PWM's
#define PWM1 OCR1A
#define PWM2 OCR1B


//Variablen
uint8_t eebyte[256] EEMEM; //Programmspeicher
uint8_t byte = 0; //Zwischenspeicher Programmbytes
uint8_t addr = 0; //Addresse Programmspeicher
uint8_t dat = 0; //Daten Programmspeicher
uint8_t kom = 0; //Befehl Programmspeicher
uint8_t adrlo = 0; //Adresse Low - unteres Nibble
uint8_t adrhi = 0; //Adresse High - oberes Nibble
uint8_t adrret = 0; //Rücksprungadresse
uint8_t prog = 0; //Programmierschritt
uint8_t puffer = 0; //ADC Puffer für ersten Wert
uint16_t ff = 0; //Rücksetzt Zähler
uint16_t ms = 0; //Zählvariable langes Delay

uint8_t A = 0; //Speicher A
uint8_t B = 0; //Speicher B
uint8_t C = 0; //Speicher C
uint8_t D = 0; //Speicher D


// Unterprogramme

// ADC 1 auslesen
uint8_t ADC1(void)
{
loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird
ADMUX = 39; // setze den Mux auf ADC 7
ADCSRA |= (1<<ADSC); // starte die Wandlung
loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird
return ADCH; // gib den zweiten ADC-Wert zurück
}

// ADC 2 auslesen
uint8_t ADC2(void)
{
loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird
ADMUX = 40; // setze den Mux auf ADC 8
ADCSRA |= (1<<ADSC); // starte die Wandlung
loop_until_bit_is_clear (ADCSRA, ADSC); // warte bis das Bit ADSC gelöscht wird
return ADCH; // gib den zweiten ADC-Wert zurück
}

// Größere Delays
void long_delay(uint16_t ms)
{
for(; ms>0; ms--) _delay_ms(1);
}


// Programm ausführen
void AUSF()
{
addr = 0;
do
{
byte = eeprom_read_byte (&eebyte [addr]); // lese das eebyte-Array an der stelle addr aus
dat = byte & 15; // schreibe das unter Nibble in dat und
kom = byte / 16; // das obere Nibble in kom
addr = addr + 1; // addiere 1 zu addr

if (kom == 1) // 1: Direkte Portausgabe
{
PORTA = dat * 16 & 0xF0;
}

if (kom == 2) // 2: Wartezeit
{
if (dat == 0) _delay_ms(1);
if (dat == 1) _delay_ms(2);
if (dat == 2) _delay_ms(5);
if (dat == 3) _delay_ms(10);
if (dat == 4) _delay_ms(20);
if (dat == 5) _delay_ms(50);
if (dat == 6) _delay_ms(100);
if (dat == 7) _delay_ms(200);
if (dat == 8) _delay_ms(500);
if (dat == 9) _delay_ms(1000);
if (dat == 10) _delay_ms(2000);
if (dat == 11) _delay_ms(5000);
if (dat == 12) long_delay(10000);
if (dat == 13) long_delay(20000);
if (dat == 14) long_delay(30000);
if (dat == 15) long_delay(60000);
}

if (kom == 3) // 3: Sprung - relativ
{
addr = addr - 1;
addr = addr - dat;
}

if (kom == 4) // 4: A = ...
{
A = dat;
}

if (kom == 5) // 5: ... = A
{
if (dat == 1) B = A; // Variablen
if (dat == 2) C = A;
if (dat == 3) D = A;
if (dat == 4) PORTA = A * 16 & 0xF0; // Port
if (dat == 5) // Portbits
{
if (A == 0) PORTA &= ~(1<<A1);
else PORTA |= (1<<A1);
}
if (dat == 6)
{
if (A == 0) PORTA &= ~(1<<A2);
else PORTA |= (1<<A2);
}
if (dat == 7)
{
if (A == 0) PORTA &= ~(1<<A3);
else PORTA |= (1<<A3);
}
if (dat == 8)
{
if (A == 0) PORTA &= ~(1<<A4);
else PORTA |= (1<<A4);
}
if (dat == 9) PWM1 = A * 16; // PWM
if (dat == 10) PWM2 = A * 16;
}

if (kom == 6) // 6: A = ...
{
if (dat == 1) A = B; // Variablen
if (dat == 2) A = C;
if (dat == 3) A = D;
if (dat == 4) A = PINA & 15; // Port
if (dat == 5) // Portbits
{
if (!(PINA & (1<<E1))) A = 0;
else A = 1;
}
if (dat == 6)
{
if (!(PINA & (1<<E2))) A = 0;
else A = 1;
}
if (dat == 7)
{
if (!(PINA & (1<<E3))) A = 0;
else A = 1;
}
if (dat == 8)
{
if (!(PINA & (1<<E4))) A = 0;
else A = 1;
}
if (dat == 9) A = ADC1() / 16; // ADC
if (dat == 10) A = ADC2() / 16;
}

if (kom == 7) // 7: A = ...
{
if (dat == 1) A = A + 1;
if (dat == 2) A = A - 1;
if (dat == 3) A = A + B;
if (dat == 4) A = A - B;
if (dat == 5) A = A * B;
if (dat == 6) A = A / B;
if (dat == 7) A = A & B;
if (dat == 8) A = A | B;
if (dat == 9) A = A ^ B;
if (dat == 10) A = ~A;
}

if (kom == 8) adrhi = dat; // 8: Oberes Nibble der Adresse

if (kom == 9) // 9: Spring absolut 0...255
{
addr = adrhi * 16;
addr = addr + dat;
}

if (kom == 10) // 10: C * Spring absolut 0...255
{
if (C > 0)
{
C = C - 1;
C = C & 15;
addr = adrhi * 16;
addr = addr + dat;
}
}

if (kom == 11) // 11: D * Spring absolut 0...255
{
if (C > 0)
{
D = D - 1;
D = D & 15;
addr = adrhi * 16;
addr = addr + dat;
}
}

if (kom == 12) // 12: Skip if ...
{
if (dat == 1)
{
if (A > B) addr = addr + 1;
}
if (dat == 2)
{
if (A < B) addr = addr + 1;
}
if (dat == 3)
{
if (A == B) addr = addr + 1;
}
if (dat == 4)
{
if (PINA & (1<<E1)) addr = addr + 1;
}
if (dat == 5)
{
if (PINA & (1<<E2)) addr = addr + 1;
}
if (dat == 6)
{
if (PINA & (1<<E3)) addr = addr + 1;
}
if (dat == 7)
{
if (PINA & (1<<E4)) addr = addr + 1;
}
if (dat == 8)
{
if (!(PINA & (1<<E1))) addr = addr + 1;
}
if (dat == 9)
{
if (!(PINA & (1<<E2))) addr = addr + 1;
}
if (dat == 10)
{
if (!(PINA & (1<<E3))) addr = addr + 1;
}
if (dat == 11)
{
if (!(PINA & (1<<E4))) addr = addr + 1;
}
if (dat == 12)
{
if (!(PINB & (1<<S1))) addr = addr + 1;
}
if (dat == 13)
{
if (!(PINB & (1<<S2))) addr = addr + 1;
}
if (dat == 14)
{
if (PINB & (1<<S1)) addr = addr + 1;
}
if (dat == 15)
{
if (PINB & (1<<S2)) addr = addr + 1;
}
}

if (kom == 13) // 13: Call Unterprogramm absolut 0...255
{
adrret = addr;
addr = adrhi * 16;
addr = addr + dat;
}

if (kom == 14) // 14: Return
{
addr = adrret;
}

if (kom == 15 ) // 15: EEProm neu schreiben
{
if ((dat == 15) && (addr < 3))
{
ff++;
if (ff == 2)
{
eeprom_write_byte (&eebyte [0], 0x64);
eeprom_write_byte (&eebyte [1], 0x51);
eeprom_write_byte (&eebyte [2], 0x4E);
eeprom_write_byte (&eebyte [3], 0x80);
eeprom_write_byte (&eebyte [4], 0xC3);
eeprom_write_byte (&eebyte [5], 0x98);
eeprom_write_byte (&eebyte [6], 0x82);
eeprom_write_byte (&eebyte [7], 0x95);
eeprom_write_byte (&eebyte [8], 0x4D);
eeprom_write_byte (&eebyte [9], 0x80);
eeprom_write_byte (&eebyte [10], 0xC3);
eeprom_write_byte (&eebyte [11], 0x9E);
eeprom_write_byte (&eebyte [12], 0x82);
eeprom_write_byte (&eebyte [13], 0x9A);
eeprom_write_byte (&eebyte [14], 0x4B);
eeprom_write_byte (&eebyte [15], 0x81);
eeprom_write_byte (&eebyte [16], 0xC3);
eeprom_write_byte (&eebyte [17], 0x94);
eeprom_write_byte (&eebyte [18], 0x83);
eeprom_write_byte (&eebyte [19], 0x90);
eeprom_write_byte (&eebyte [20], 0x47);
eeprom_write_byte (&eebyte [21], 0x81);
eeprom_write_byte (&eebyte [22], 0xC3);
eeprom_write_byte (&eebyte [23], 0x9A);
eeprom_write_byte (&eebyte [24], 0x83);
eeprom_write_byte (&eebyte [25], 0x94);
eeprom_write_byte (&eebyte [26], 0x43);
eeprom_write_byte (&eebyte [27], 0x82);
eeprom_write_byte (&eebyte [28], 0xC3);
eeprom_write_byte (&eebyte [29], 0x90);
eeprom_write_byte (&eebyte [30], 0x84);
eeprom_write_byte (&eebyte [31], 0x90);
eeprom_write_byte (&eebyte [32], 0x11);
eeprom_write_byte (&eebyte [33], 0x28);
eeprom_write_byte (&eebyte [34], 0x18);
eeprom_write_byte (&eebyte [35], 0x28);
eeprom_write_byte (&eebyte [36], 0x34);
eeprom_write_byte (&eebyte [37], 0x71);
eeprom_write_byte (&eebyte [38], 0x54);
eeprom_write_byte (&eebyte [39], 0x59);
eeprom_write_byte (&eebyte [40], 0x26);
eeprom_write_byte (&eebyte [41], 0x34);
eeprom_write_byte (&eebyte [42], 0x69);
eeprom_write_byte (&eebyte [43], 0x54);
eeprom_write_byte (&eebyte [44], 0x59);
eeprom_write_byte (&eebyte [45], 0x26);
eeprom_write_byte (&eebyte [46], 0x34);
eeprom_write_byte (&eebyte [47], 0xFF);
eeprom_write_byte (&eebyte [48], 0x54);
eeprom_write_byte (&eebyte [49], 0xCE);
eeprom_write_byte (&eebyte [50], 0x71);
eeprom_write_byte (&eebyte [51], 0x33);
eeprom_write_byte (&eebyte [52], 0x22);
eeprom_write_byte (&eebyte [53], 0xCC);
eeprom_write_byte (&eebyte [54], 0x32);
eeprom_write_byte (&eebyte [55], 0x40);
eeprom_write_byte (&eebyte [56], 0x22);
eeprom_write_byte (&eebyte [57], 0x71);
eeprom_write_byte (&eebyte [58], 0x54);
eeprom_write_byte (&eebyte [59], 0xCE);
eeprom_write_byte (&eebyte [60], 0x34);
eeprom_write_byte (&eebyte [61], 0x39);
eeprom_write_byte (&eebyte [62], 0xFF);
eeprom_write_byte (&eebyte [63], 0xFF);
eeprom_write_byte (&eebyte [64], 0x86);
eeprom_write_byte (&eebyte [65], 0xD0);
eeprom_write_byte (&eebyte [66], 0x40);
eeprom_write_byte (&eebyte [67], 0x71);
eeprom_write_byte (&eebyte [68], 0x54);
eeprom_write_byte (&eebyte [69], 0x23);
eeprom_write_byte (&eebyte [70], 0xCD);
eeprom_write_byte (&eebyte [71], 0x34);
eeprom_write_byte (&eebyte [72], 0xD8);
eeprom_write_byte (&eebyte [73], 0x40);
eeprom_write_byte (&eebyte [74], 0x54);
eeprom_write_byte (&eebyte [75], 0x3B);
eeprom_write_byte (&eebyte [76], 0xFF);
eeprom_write_byte (&eebyte [77], 0xFF);
eeprom_write_byte (&eebyte [78], 0xFF);
eeprom_write_byte (&eebyte [79], 0xFF);
eeprom_write_byte (&eebyte [80], 0x4F);
eeprom_write_byte (&eebyte [81], 0x93);
eeprom_write_byte (&eebyte [82], 0x45);
eeprom_write_byte (&eebyte [83], 0x53);
eeprom_write_byte (&eebyte [84], 0x19);
eeprom_write_byte (&eebyte [85], 0x11);
eeprom_write_byte (&eebyte [86], 0x21);
eeprom_write_byte (&eebyte [87], 0x19);
eeprom_write_byte (&eebyte [88], 0x11);
eeprom_write_byte (&eebyte [89], 0x21);
eeprom_write_byte (&eebyte [90], 0x19);
eeprom_write_byte (&eebyte [91], 0x11);
eeprom_write_byte (&eebyte [92], 0x20);
eeprom_write_byte (&eebyte [93], 0xB4);
eeprom_write_byte (&eebyte [94], 0x10);
eeprom_write_byte (&eebyte [95], 0xE0);
eeprom_write_byte (&eebyte [96], 0x23);
eeprom_write_byte (&eebyte [97], 0xCE);
eeprom_write_byte (&eebyte [98], 0x32);
eeprom_write_byte (&eebyte [99], 0x23);
eeprom_write_byte (&eebyte [100], 0xCC);
eeprom_write_byte (&eebyte [101], 0x31);
eeprom_write_byte (&eebyte [102], 0xE0);
eeprom_write_byte (&eebyte [103], 0xFF);
eeprom_write_byte (&eebyte [104], 0x23);
eeprom_write_byte (&eebyte [105], 0xCF);
eeprom_write_byte (&eebyte [106], 0x32);
eeprom_write_byte (&eebyte [107], 0x23);
eeprom_write_byte (&eebyte [108], 0xCD);
eeprom_write_byte (&eebyte [109], 0x31);
eeprom_write_byte (&eebyte [110], 0xE0);
eeprom_write_byte (&eebyte [111], 0xFF);
eeprom_write_byte (&eebyte [112], 0xCC);
eeprom_write_byte (&eebyte [113], 0x31);
eeprom_write_byte (&eebyte [114], 0x40);
eeprom_write_byte (&eebyte [115], 0x54);
eeprom_write_byte (&eebyte [116], 0x23);
eeprom_write_byte (&eebyte [117], 0xCE);
eeprom_write_byte (&eebyte [118], 0x32);
eeprom_write_byte (&eebyte [119], 0xCF);
eeprom_write_byte (&eebyte [120], 0xE0);
eeprom_write_byte (&eebyte [121], 0xCC);
eeprom_write_byte (&eebyte [122], 0x33);
eeprom_write_byte (&eebyte [123], 0x71);
eeprom_write_byte (&eebyte [124], 0x23);
eeprom_write_byte (&eebyte [125], 0xCC);
eeprom_write_byte (&eebyte [126], 0x31);
eeprom_write_byte (&eebyte [127], 0x3C);

ff = 0;
}
}
}
}
while (!0);
}



// Programmieren
void PROG()
{
addr = 0; // setze addr und prog auf 0
prog = 0;
do // Hauptschleife
{ // Adresse anzeigen
adrlo = addr & 15; // lade das untere Nibble der Adresse in adrlo
PORTA = adrlo * 16 & 0xF0; // gib das untere Nibble aus und warte 500 ms
_delay_ms(300);
PORTA = 0 & 0xF0; // schalte die Anzeige für 250 ms aus
_delay_ms(200);
byte = eeprom_read_byte (&eebyte [addr]); // lese das eebyte-Array an der stelle addr aus
dat = byte & 15; // schreibe das unter Nibble in dat und
kom = byte / 16; // das obere Nibble in kom
PORTA = kom * 16 & 0xF0; // Befehl anzeigen - gib kom aus
loop_until_bit_is_set (PINB, S2); // warte bis die Taste S2 nicht mehr gedrückt wird
_delay_ms(40); // Taste entprellen
prog = 1; // setze prog = 1
do
{
if (!(PINB & (1<<S1))) // wenn Taste S1 gedrückt wird, verzweige nach hier
{
if (prog == 1) // Phase 1: Befehl anzeigen
{ // wenn prog = 1 dann setzte prog = 2 und kom = 15
prog = 2;
kom = 15;
}
if (prog == 2) // Phase 2: Befehl verändern
{ // wenn prog = 2 dann addier 1 zu kom und verknüpfe
kom = kom + 1; // kom & 15, gib kom aus
kom = kom & 15;
PORTA = kom * 16 & 0xF0;
}
if (prog == 3) // Phase 3: Befehl unverändert, Daten ändern
{ // wenn prog = 3 dann setzte prog = 5 und dat = 15
prog = 5;
dat = 15;
}
if (prog == 4) // Phase 4: Befehl und Daten geändert
{ // wenn prog = 4 dann setzte prog = 5 und dat = 15
prog = 5;
dat = 15;
}
if (prog == 5) // Phase 5: Daten verändern
{ // wenn prog = 5 dann addier 1 zu dat und verknüpfe
dat = dat + 1; // dat & 15, gib dat aus
dat = dat & 15;
PORTA = dat * 16 & 0xF0;
}
_delay_ms(40); // Taste entprellen
loop_until_bit_is_set (PINB, S1); // Warte bis die Taste S1 nicht mehr gedrückt wird
_delay_ms(40); // Taste entprellen
}
if (!(PINB & (1<<S2))) // wenn Taste S2 gedrückt wird verzweige hier
{
if (prog == 3) // nur angezeigt nicht verändert
{ // wenn prog = 3 dann setzte prog = 7
prog = 7;
}
if (prog == 1) // wenn prog = 1 dann zeige dat an und setze prog = 3
{
PORTA = dat * 16 & 0xF0;
prog = 3;
}
if (prog == 4) // wenn prog = 4 dann zeige dat an u. setze prog = 6
{
PORTA = dat * 16 & 0xF0;
prog = 6;
}
if (prog == 2) // wenn prog = 2 dann zeige dat an u. setzte prog = 4
{
PORTA = dat * 16 & 0xF0;
prog = 4;
}
if (prog == 6) // nur Befehl wurde verändert
{ // verknüpfe dat & 15 und nehme kom * 16
dat = dat & 15; // schreibe beides in byte und schreibe das ins eeprom
byte = kom * 16; // an die stelle addr ins eebyte-Array
byte = byte + dat;
eeprom_write_byte (&eebyte [addr], byte);
PORTA = 0 & 0xF0; // schalte die Anzeige für 600 ms aus
_delay_ms(600);
addr = addr + 1; // addiere 1 zu addr und setzte prog = 0
prog = 0;
}
if (prog == 5) // Daten wurden verändert
{ // verknüpfe dat & 15 und nehme kom * 16
dat = dat & 15; // schreibe beides in byte und schreibe das ins eeprom
byte = kom * 16; // an die stelle addr ins eebyte-Array
byte = byte + dat;
eeprom_write_byte (&eebyte [addr], byte);
PORTA = 0 & 0xF0; // schalte die Anzeige für 600 ms aus
_delay_ms(600);
addr = addr + 1; // addiere 1 zu addr und setzte prog = 0
prog = 0;
}
if (prog == 7) // wenn prog = 7 dann addiere 1 zu addr u. setze prog = 0
{
addr = addr + 1;
prog = 0;
}
_delay_ms(40); // Taste entprellen
loop_until_bit_is_set (PINB, S2); // Warte bis die Taste S2 nicht mehr gedrückt wird
_delay_ms(40); // Taste entprellen
}
}
while(!prog == 0);
}
while (!0);
}



// Testprogramm
void TEST()
{
do
{
if (!(PINB & (1<<S1))) // Wenn S1 geschaltet ist dann
{ // schalte A1 bis A4 an.
PORTA |= (1<<A1);
_delay_ms(200);
PORTA |= (1<<A2);
_delay_ms(200);
PORTA |= (1<<A3);
_delay_ms(200);
PORTA |= (1<<A4);
_delay_ms(200);
}

if (!(PINB & (1<<S2))) // Wenn S2 geschaltet ist dann
{ // schalte A1 bis A4 aus.
PORTA &= ~(1<<A1);
_delay_ms(200);
PORTA &= ~(1<<A2);
_delay_ms(200);
PORTA &= ~(1<<A3);
_delay_ms(200);
PORTA &= ~(1<<A4);
_delay_ms(200);
}

if (!(PINA & (1<<E1))) // Wenn E1 geschaltet ist dann
{ // dann schalte PWM1 und PWM2
_delay_ms(200); // auf 50 und dann auf 100
PWM1 = 50;
_delay_ms(200);
PWM2 = 50;
_delay_ms(200);
PWM1 = 100;
_delay_ms(200);
PWM2 = 100;
}

if (!(PINA & (1<<E2))) // Wenn E2 geschaltet ist dann
{ // dann schalte PWM1 und PWM2
_delay_ms(200); // auf 150, 200 und dann auf 250
PWM1 = 150;
_delay_ms(200);
PWM2 = 150;
_delay_ms(200);
PWM1 = 200;
_delay_ms(200);
PWM2 = 200;
_delay_ms(200);
PWM1 = 250;
_delay_ms(200);
PWM2 = 250;
}

if (!(PINA & (1<<E3))) // Wenn E3 geschaltet ist dann
{ // dann frage ADC1 ab und setzte PWM1
PWM1 = ADC1();
}

if (!(PINA & (1<<E4))) // Wenn E4 geschaltet ist dann
{ // dann frage ADC2 ab und setzte PWM2
PWM2 = ADC2();
}
}
while (!0);
}




Elektronik-Labor  Projekte   TPS