1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #define F_CPU 2000000
|
4 | #include <util/delay.h>
|
5 | #include <inttypes.h>
|
6 | #include <stdint.h>
|
7 |
|
8 | // Anchlussbelegung:
|
9 | #define KTEMP_DDR DDRD //Temperatur Input vom Kältebad
|
10 | #define WTEMP_DDR DDRC //Temperatur Input vom Wärmebad
|
11 | #define PTEMP_DDR DDRA //Temperatur Input von Probe
|
12 |
|
13 | #define MOTOR_DDR DDRB //Datenrichtung zum Motor-Steuer-Atmega festlegen
|
14 | #define MOTOR_OUT PORTB //Ausgänge zum Motor-Steuer-Atmega
|
15 | #define MOTOR_IN PINB
|
16 | //cw = clockwise = im Uhrzeigersinn; ccw = counter clockwise = entgegen dem Uhrzeigersinn
|
17 | #define CW PB0 //Motor cw Richtung Kältebad drehen lassen
|
18 | #define CCW PB1 //Motor ccw Richtung Wärmebad drehen lassen
|
19 | #define KB PB2 //Endanschlagstaster Kältebad abfragen
|
20 | #define WB PB3 //Endanschlagstaster Wärmebad abfragen
|
21 |
|
22 | enum { RESET, CW_AN, CCW_AN, BREAK, IM_WAERMEBAD, IM_KAELTEBAD };
|
23 |
|
24 |
|
25 | //Funktion für die Tastenentprellung aufrufen über >>entprellung( &PINB, (1<<PINB2) );<<
|
26 | void entprellung( volatile uint8_t *port, uint8_t maske ) {
|
27 | uint8_t port_puffer;
|
28 | uint8_t entprellungs_puffer;
|
29 |
|
30 | for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {
|
31 | entprellungs_puffer<<=1;
|
32 | port_puffer = *port;
|
33 | _delay_us(150);
|
34 | if( (*port & maske) == (port_puffer & maske) )
|
35 | entprellungs_puffer |= 0x01;
|
36 | }
|
37 | }
|
38 |
|
39 | //Temperatur Abholen
|
40 | uint8_t bcd2bin( uint8_t val )
|
41 | {
|
42 | return (val & 0x0F) + (val >> 4) * 10;
|
43 | }
|
44 |
|
45 | int main(void)
|
46 | {
|
47 | uint8_t w_temp = 0; //Variable zum speichern der Zustände vom Wärmebad
|
48 | uint8_t k_temp = 0; //Variable zum speichern der Zustände vom Kältebad
|
49 | uint8_t p_temp = 0; //Variable zum speichern der Zustände von der Probe
|
50 | uint8_t state = RESET;
|
51 |
|
52 | KTEMP_DDR = 0x00; //Eing?nge D
|
53 | WTEMP_DDR = 0x00; //Eing?nge C
|
54 | PTEMP_DDR = 0x00; //Eing?nge A
|
55 | MOTOR_DDR = (1 << DDB0) | (1 << DDB1); //B0 un B1 als Ausgänge, B2 und B3 als Eingänge:
|
56 |
|
57 | PORTB &= ~ (1<<CCW); //Motor aus
|
58 | PORTB &= ~ (1<<CW); //Motor aus
|
59 |
|
60 | for(int a=0; a<2; a++){_delay_ms( 1000 );}
|
61 |
|
62 | for(;;){ // Main-Loop
|
63 |
|
64 | k_temp = bcd2bin( PIND ); //k_temp Einlesen
|
65 | p_temp = bcd2bin( PINA ); //p_temp Einlesen
|
66 | w_temp = bcd2bin( PINC ); //w_temp Einlesen
|
67 |
|
68 | p_temp = ~p_temp; //Temperatur konvertieren
|
69 | w_temp = ~w_temp; //Temperatur konvertieren
|
70 | k_temp = ~k_temp; //Temperatur konvertieren
|
71 |
|
72 | switch( state ){ //State Maschine
|
73 | case IM_KAELTEBAD:
|
74 | // Motor anhalten
|
75 | PORTB &= ~(1<<CW);
|
76 | PORTB &= ~(1<<CCW);
|
77 | // Temp abfragen
|
78 | if((p_temp <= k_temp) )
|
79 | state = CCW_AN;
|
80 | break;
|
81 | case CCW_AN:
|
82 | //Richtung Wärmebad fahren
|
83 | PORTB &= ~(1<<CW);
|
84 | PORTB |= (1<<CCW);
|
85 | if((PINB & (1<<WB)) && !(PINB & (1<<KB)))
|
86 | state = IM_WAERMEBAD;
|
87 | break;
|
88 | case IM_WAERMEBAD:
|
89 | // Motor anhalten
|
90 | PORTB &= ~(1<<CCW);
|
91 | PORTB &= ~(1<<CW);
|
92 | // Temp abfragen
|
93 | if((p_temp >= w_temp) )
|
94 | state = CW_AN;
|
95 | break;
|
96 | case CW_AN:
|
97 | //Richtung Kältebad fahren
|
98 | PORTB &= ~(1<<CCW);
|
99 | PORTB |= (1<<CW);
|
100 | if((PINB & (1<<KB)) && !(PINB & (1<<WB)))
|
101 | state = IM_KAELTEBAD;
|
102 | break;
|
103 | case RESET:
|
104 | if(!(PINB & (1<<KB)))
|
105 | // Wenn nicht im Kältebad, dann fahre dort hin
|
106 | state = CW_AN;
|
107 | else
|
108 | // Endschalter schon gedrückt, also bleibe an dieser Stelle
|
109 | state = IM_KAELTEBAD;
|
110 | break;
|
111 | default:
|
112 | if((PINB & (1<<WB)) && !(PINB & (1<<KB)))
|
113 | state = CW_AN;
|
114 | if((PINB & (1<<KB)) && !(PINB & (1<<WB)))
|
115 | state = CCW_AN;
|
116 | break;
|
117 | }//Ende Switch-Case
|
118 | }//Ende Main-Loop
|
119 | } //ENDE main
|