Markus Müller
/
StateMachine_02
StateMachine
main.cpp@0:965e1122fba3, 2014-10-28 (annotated)
- Committer:
- p0ckin3d
- Date:
- Tue Oct 28 17:52:40 2014 +0000
- Revision:
- 0:965e1122fba3
StateMachine
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
p0ckin3d | 0:965e1122fba3 | 1 | #include "mbed.h" |
p0ckin3d | 0:965e1122fba3 | 2 | |
p0ckin3d | 0:965e1122fba3 | 3 | /* Modulname: SM_FahrradLeuchte1.c Version:1.0 */ |
p0ckin3d | 0:965e1122fba3 | 4 | /* Funktion: State-Machine-Programm */ |
p0ckin3d | 0:965e1122fba3 | 5 | /* Erstellt von: p0ckin3d am: 2014-10-28 */ |
p0ckin3d | 0:965e1122fba3 | 6 | /* Beschreibung: */ |
p0ckin3d | 0:965e1122fba3 | 7 | // Fahrradrückleuchte mit 4 roten LEDs am PORTC |
p0ckin3d | 0:965e1122fba3 | 8 | // ----------------------------------- |
p0ckin3d | 0:965e1122fba3 | 9 | // Zum Schalten: 1 Taster PINA PA0 |
p0ckin3d | 0:965e1122fba3 | 10 | // 1. Funktion |
p0ckin3d | 0:965e1122fba3 | 11 | // Start-Taste 1x betätigen: |
p0ckin3d | 0:965e1122fba3 | 12 | // Dauerlicht aller 4 LEDs |
p0ckin3d | 0:965e1122fba3 | 13 | // 2. Funktion |
p0ckin3d | 0:965e1122fba3 | 14 | // Start-Taste ein 2.mal betätigen: |
p0ckin3d | 0:965e1122fba3 | 15 | // LEDs blinken im ca. 400 Millisekunden-Takt; 200 msec Ein, 200 msec Aus |
p0ckin3d | 0:965e1122fba3 | 16 | // Ausschalten des Rücklichts |
p0ckin3d | 0:965e1122fba3 | 17 | // Die Start-Taste ein 3.mal betätigen: |
p0ckin3d | 0:965e1122fba3 | 18 | // Alle LEDs aus. |
p0ckin3d | 0:965e1122fba3 | 19 | |
p0ckin3d | 0:965e1122fba3 | 20 | |
p0ckin3d | 0:965e1122fba3 | 21 | //volatile uint8_t count; |
p0ckin3d | 0:965e1122fba3 | 22 | volatile unsigned int count; |
p0ckin3d | 0:965e1122fba3 | 23 | volatile unsigned int newEvent =0; |
p0ckin3d | 0:965e1122fba3 | 24 | volatile unsigned int event=0, state=0; |
p0ckin3d | 0:965e1122fba3 | 25 | |
p0ckin3d | 0:965e1122fba3 | 26 | Ticker timer0; |
p0ckin3d | 0:965e1122fba3 | 27 | BusOut myleds(LED1, LED2, LED3, LED4); |
p0ckin3d | 0:965e1122fba3 | 28 | DigitalIn center(p14); |
p0ckin3d | 0:965e1122fba3 | 29 | |
p0ckin3d | 0:965e1122fba3 | 30 | /* Prototypen der Funktionen */ |
p0ckin3d | 0:965e1122fba3 | 31 | int no_fu(); |
p0ckin3d | 0:965e1122fba3 | 32 | int ledsEin(); |
p0ckin3d | 0:965e1122fba3 | 33 | int msec300TimerOn(); |
p0ckin3d | 0:965e1122fba3 | 34 | int ledsAusTimerOff(); |
p0ckin3d | 0:965e1122fba3 | 35 | int ledsTogglen(); |
p0ckin3d | 0:965e1122fba3 | 36 | int nightRiderTest(); |
p0ckin3d | 0:965e1122fba3 | 37 | int nightRider(); |
p0ckin3d | 0:965e1122fba3 | 38 | |
p0ckin3d | 0:965e1122fba3 | 39 | bool doNightRider = false; |
p0ckin3d | 0:965e1122fba3 | 40 | bool upwards = true; |
p0ckin3d | 0:965e1122fba3 | 41 | int ledCounter = 1; |
p0ckin3d | 0:965e1122fba3 | 42 | |
p0ckin3d | 0:965e1122fba3 | 43 | /****************************************************/ |
p0ckin3d | 0:965e1122fba3 | 44 | /* Tabelle fuer die naechsten Zustaende bei Eingabe */ |
p0ckin3d | 0:965e1122fba3 | 45 | /****************************************************/ |
p0ckin3d | 0:965e1122fba3 | 46 | unsigned char nextstate_tab[3][4]= |
p0ckin3d | 0:965e1122fba3 | 47 | //present state 0 1 2 3 |
p0ckin3d | 0:965e1122fba3 | 48 | //------------------------ |
p0ckin3d | 0:965e1122fba3 | 49 | /* event 0 */{{ 1, 2, 3, 0 }, // next |
p0ckin3d | 0:965e1122fba3 | 50 | /* event 1 */ { 0, 1, 2, 3 }, // state |
p0ckin3d | 0:965e1122fba3 | 51 | /* event 2 */ { 0, 1, 2, 3 }}; // state |
p0ckin3d | 0:965e1122fba3 | 52 | // state=nextstate_tab[event][state]; // gehe auf naechsten Zustand |
p0ckin3d | 0:965e1122fba3 | 53 | |
p0ckin3d | 0:965e1122fba3 | 54 | /*************************************************************/ |
p0ckin3d | 0:965e1122fba3 | 55 | /* Tabelle fuer Aktionsroutinen fuer die Zustaende bei Input */ |
p0ckin3d | 0:965e1122fba3 | 56 | /*************************************************************/ |
p0ckin3d | 0:965e1122fba3 | 57 | // p r e s e n t s t a t e |
p0ckin3d | 0:965e1122fba3 | 58 | int(*action[3][4])()= // 0 1 2 3 |
p0ckin3d | 0:965e1122fba3 | 59 | /* event 0 */ {{ ledsEin, msec300TimerOn, nightRiderTest, ledsAusTimerOff }, |
p0ckin3d | 0:965e1122fba3 | 60 | /* event 1 */ { no_fu, no_fu, ledsTogglen, no_fu }, |
p0ckin3d | 0:965e1122fba3 | 61 | /* event 2 */ { no_fu, no_fu, no_fu, nightRider }}; |
p0ckin3d | 0:965e1122fba3 | 62 | // (*action[event][state])(); // suche in Tabelle nach Funktion |
p0ckin3d | 0:965e1122fba3 | 63 | |
p0ckin3d | 0:965e1122fba3 | 64 | |
p0ckin3d | 0:965e1122fba3 | 65 | /* Aktionsroutinen, functions */ |
p0ckin3d | 0:965e1122fba3 | 66 | int no_fu() // keine function - tue nichts |
p0ckin3d | 0:965e1122fba3 | 67 | { |
p0ckin3d | 0:965e1122fba3 | 68 | return(0); |
p0ckin3d | 0:965e1122fba3 | 69 | } |
p0ckin3d | 0:965e1122fba3 | 70 | |
p0ckin3d | 0:965e1122fba3 | 71 | int nightRiderTest() |
p0ckin3d | 0:965e1122fba3 | 72 | { |
p0ckin3d | 0:965e1122fba3 | 73 | doNightRider = true; |
p0ckin3d | 0:965e1122fba3 | 74 | return(2); |
p0ckin3d | 0:965e1122fba3 | 75 | } |
p0ckin3d | 0:965e1122fba3 | 76 | |
p0ckin3d | 0:965e1122fba3 | 77 | int nightRider() |
p0ckin3d | 0:965e1122fba3 | 78 | { |
p0ckin3d | 0:965e1122fba3 | 79 | myleds = ledCounter; |
p0ckin3d | 0:965e1122fba3 | 80 | |
p0ckin3d | 0:965e1122fba3 | 81 | if(ledCounter == 8) |
p0ckin3d | 0:965e1122fba3 | 82 | upwards = false; |
p0ckin3d | 0:965e1122fba3 | 83 | else if(ledCounter == 1) |
p0ckin3d | 0:965e1122fba3 | 84 | upwards = true; |
p0ckin3d | 0:965e1122fba3 | 85 | |
p0ckin3d | 0:965e1122fba3 | 86 | if(upwards) |
p0ckin3d | 0:965e1122fba3 | 87 | ledCounter*=2; |
p0ckin3d | 0:965e1122fba3 | 88 | else |
p0ckin3d | 0:965e1122fba3 | 89 | ledCounter/=2; |
p0ckin3d | 0:965e1122fba3 | 90 | |
p0ckin3d | 0:965e1122fba3 | 91 | return 4; |
p0ckin3d | 0:965e1122fba3 | 92 | } |
p0ckin3d | 0:965e1122fba3 | 93 | |
p0ckin3d | 0:965e1122fba3 | 94 | // interrupt SR |
p0ckin3d | 0:965e1122fba3 | 95 | void timer0_int() |
p0ckin3d | 0:965e1122fba3 | 96 | { |
p0ckin3d | 0:965e1122fba3 | 97 | //Increment our variable |
p0ckin3d | 0:965e1122fba3 | 98 | count++; |
p0ckin3d | 0:965e1122fba3 | 99 | if(count==10) |
p0ckin3d | 0:965e1122fba3 | 100 | { |
p0ckin3d | 0:965e1122fba3 | 101 | count=0; |
p0ckin3d | 0:965e1122fba3 | 102 | |
p0ckin3d | 0:965e1122fba3 | 103 | if(doNightRider) |
p0ckin3d | 0:965e1122fba3 | 104 | event=2; |
p0ckin3d | 0:965e1122fba3 | 105 | else |
p0ckin3d | 0:965e1122fba3 | 106 | event=1; |
p0ckin3d | 0:965e1122fba3 | 107 | |
p0ckin3d | 0:965e1122fba3 | 108 | newEvent = 1; |
p0ckin3d | 0:965e1122fba3 | 109 | } |
p0ckin3d | 0:965e1122fba3 | 110 | } |
p0ckin3d | 0:965e1122fba3 | 111 | |
p0ckin3d | 0:965e1122fba3 | 112 | int msec300TimerOn() |
p0ckin3d | 0:965e1122fba3 | 113 | { |
p0ckin3d | 0:965e1122fba3 | 114 | timer0.attach(&timer0_int, 0.032); |
p0ckin3d | 0:965e1122fba3 | 115 | doNightRider = false; |
p0ckin3d | 0:965e1122fba3 | 116 | return(1); |
p0ckin3d | 0:965e1122fba3 | 117 | } |
p0ckin3d | 0:965e1122fba3 | 118 | |
p0ckin3d | 0:965e1122fba3 | 119 | int ledsAusTimerOff() |
p0ckin3d | 0:965e1122fba3 | 120 | { |
p0ckin3d | 0:965e1122fba3 | 121 | timer0.detach(); |
p0ckin3d | 0:965e1122fba3 | 122 | myleds = 0; |
p0ckin3d | 0:965e1122fba3 | 123 | doNightRider = false; |
p0ckin3d | 0:965e1122fba3 | 124 | return(3); |
p0ckin3d | 0:965e1122fba3 | 125 | } |
p0ckin3d | 0:965e1122fba3 | 126 | |
p0ckin3d | 0:965e1122fba3 | 127 | int ledsTogglen() |
p0ckin3d | 0:965e1122fba3 | 128 | { |
p0ckin3d | 0:965e1122fba3 | 129 | myleds = ~myleds; |
p0ckin3d | 0:965e1122fba3 | 130 | return(3); |
p0ckin3d | 0:965e1122fba3 | 131 | } |
p0ckin3d | 0:965e1122fba3 | 132 | |
p0ckin3d | 0:965e1122fba3 | 133 | int ledsEin() |
p0ckin3d | 0:965e1122fba3 | 134 | { |
p0ckin3d | 0:965e1122fba3 | 135 | myleds = 0x0F; |
p0ckin3d | 0:965e1122fba3 | 136 | return(4); |
p0ckin3d | 0:965e1122fba3 | 137 | } |
p0ckin3d | 0:965e1122fba3 | 138 | |
p0ckin3d | 0:965e1122fba3 | 139 | // functions |
p0ckin3d | 0:965e1122fba3 | 140 | void initTimer0() |
p0ckin3d | 0:965e1122fba3 | 141 | { |
p0ckin3d | 0:965e1122fba3 | 142 | count=0; |
p0ckin3d | 0:965e1122fba3 | 143 | } |
p0ckin3d | 0:965e1122fba3 | 144 | |
p0ckin3d | 0:965e1122fba3 | 145 | // Diese Funktion ist zum Entprellen von Tastern geeignet: |
p0ckin3d | 0:965e1122fba3 | 146 | // Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1,5-4ms |
p0ckin3d | 0:965e1122fba3 | 147 | // (mindestens 8*150us = 1,2ms) erreicht werden. |
p0ckin3d | 0:965e1122fba3 | 148 | // Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. |
p0ckin3d | 0:965e1122fba3 | 149 | // Wenn die/der Pegel 8 Mal konstant war, wird die Schleife verlassen. |
p0ckin3d | 0:965e1122fba3 | 150 | // Diese Funktion kann sehr gut eingesetzt werden, um in einer Endlosschleife Taster anzufragen, |
p0ckin3d | 0:965e1122fba3 | 151 | // da sie, wie erwähnt, eine kurze Wartezeit hat. |
p0ckin3d | 0:965e1122fba3 | 152 | unsigned char debounce(PinName name, unsigned char samples) |
p0ckin3d | 0:965e1122fba3 | 153 | { |
p0ckin3d | 0:965e1122fba3 | 154 | DigitalIn joystick(name); |
p0ckin3d | 0:965e1122fba3 | 155 | |
p0ckin3d | 0:965e1122fba3 | 156 | unsigned char i = 0; |
p0ckin3d | 0:965e1122fba3 | 157 | |
p0ckin3d | 0:965e1122fba3 | 158 | for(unsigned char j=0; j < samples; j++) |
p0ckin3d | 0:965e1122fba3 | 159 | { |
p0ckin3d | 0:965e1122fba3 | 160 | if(joystick == 1) |
p0ckin3d | 0:965e1122fba3 | 161 | j++; |
p0ckin3d | 0:965e1122fba3 | 162 | else |
p0ckin3d | 0:965e1122fba3 | 163 | { |
p0ckin3d | 0:965e1122fba3 | 164 | j = 0; |
p0ckin3d | 0:965e1122fba3 | 165 | i++; |
p0ckin3d | 0:965e1122fba3 | 166 | } |
p0ckin3d | 0:965e1122fba3 | 167 | |
p0ckin3d | 0:965e1122fba3 | 168 | if(j == samples) |
p0ckin3d | 0:965e1122fba3 | 169 | break; |
p0ckin3d | 0:965e1122fba3 | 170 | |
p0ckin3d | 0:965e1122fba3 | 171 | if(i == samples) |
p0ckin3d | 0:965e1122fba3 | 172 | break; |
p0ckin3d | 0:965e1122fba3 | 173 | |
p0ckin3d | 0:965e1122fba3 | 174 | wait(0.001); |
p0ckin3d | 0:965e1122fba3 | 175 | } |
p0ckin3d | 0:965e1122fba3 | 176 | return joystick; |
p0ckin3d | 0:965e1122fba3 | 177 | } |
p0ckin3d | 0:965e1122fba3 | 178 | |
p0ckin3d | 0:965e1122fba3 | 179 | |
p0ckin3d | 0:965e1122fba3 | 180 | int main() |
p0ckin3d | 0:965e1122fba3 | 181 | { |
p0ckin3d | 0:965e1122fba3 | 182 | unsigned char released = 0; |
p0ckin3d | 0:965e1122fba3 | 183 | |
p0ckin3d | 0:965e1122fba3 | 184 | myleds = 0; |
p0ckin3d | 0:965e1122fba3 | 185 | initTimer0(); |
p0ckin3d | 0:965e1122fba3 | 186 | |
p0ckin3d | 0:965e1122fba3 | 187 | newEvent = 0; |
p0ckin3d | 0:965e1122fba3 | 188 | state=0; |
p0ckin3d | 0:965e1122fba3 | 189 | event=0; |
p0ckin3d | 0:965e1122fba3 | 190 | |
p0ckin3d | 0:965e1122fba3 | 191 | while(1) |
p0ckin3d | 0:965e1122fba3 | 192 | { |
p0ckin3d | 0:965e1122fba3 | 193 | //debounce(p14, 6); |
p0ckin3d | 0:965e1122fba3 | 194 | if(debounce(P0_10, 6)) // jetzt stabilen Wert einlesen |
p0ckin3d | 0:965e1122fba3 | 195 | { |
p0ckin3d | 0:965e1122fba3 | 196 | if (released == 1) |
p0ckin3d | 0:965e1122fba3 | 197 | { |
p0ckin3d | 0:965e1122fba3 | 198 | event =0; |
p0ckin3d | 0:965e1122fba3 | 199 | newEvent =1; |
p0ckin3d | 0:965e1122fba3 | 200 | released =0; |
p0ckin3d | 0:965e1122fba3 | 201 | } |
p0ckin3d | 0:965e1122fba3 | 202 | } |
p0ckin3d | 0:965e1122fba3 | 203 | else |
p0ckin3d | 0:965e1122fba3 | 204 | { |
p0ckin3d | 0:965e1122fba3 | 205 | released =1; |
p0ckin3d | 0:965e1122fba3 | 206 | } |
p0ckin3d | 0:965e1122fba3 | 207 | |
p0ckin3d | 0:965e1122fba3 | 208 | if (newEvent) |
p0ckin3d | 0:965e1122fba3 | 209 | { |
p0ckin3d | 0:965e1122fba3 | 210 | timer0.detach(); |
p0ckin3d | 0:965e1122fba3 | 211 | newEvent =0; |
p0ckin3d | 0:965e1122fba3 | 212 | (*action[event][state])(); // suche in Tabelle nach Funktion |
p0ckin3d | 0:965e1122fba3 | 213 | state=nextstate_tab[event][state]; // gehe auf naechsten Zustand |
p0ckin3d | 0:965e1122fba3 | 214 | timer0.attach(&timer0_int, 0.032); |
p0ckin3d | 0:965e1122fba3 | 215 | } |
p0ckin3d | 0:965e1122fba3 | 216 | } |
p0ckin3d | 0:965e1122fba3 | 217 | } |
p0ckin3d | 0:965e1122fba3 | 218 |