001: /* FMradio.c from ChatGPT */
002: #include <stdio.h>
003: // 状態定義
004: typedef enum
005: {
006:     STATE_OFF,
007:     STATE_HIGH,
008:     STATE_SCANNING,
009:     STATE_LOCKED
010: } RadioState;
011: 
012: // * イベント定義
013: typedef enum
014: {
015:     EVENT_ON,
016:     EVENT_OFF,
017:     EVENT_SCAN,
018:     EVENT_RESET,
019:     EVENT_LOCK,
020:     EVENT_END
021: } RadioEvent;
022: 
023: // 状態名文字列
024: const char* state_name(RadioState s)
025: {
026:     switch(s)
027:     {
028:         case STATE_OFF:
029:             return "OFF";
030:         case STATE_HIGH:
031:             return "HIGH";
032:         case STATE_SCANNING:
033:             return "SCANNING";
034:         case STATE_LOCKED:
035:             return "LOCKED";
036:         default:
037:             return "UNKNOWN";
038:     }
039: }
040: 
041: // イベント名文字列
042: const char* event_name(RadioEvent e)
043: {
044:     switch(e)
045:     {
046:         case EVENT_ON:
047:             return "ON";
048:         case EVENT_OFF:
049:             return "OFF";
050:         case EVENT_SCAN:
051:             return "SCAN";
052:         case EVENT_RESET:
053:             return "RESET";
054:         case EVENT_LOCK:
055:             return "LOCK";
056:         case EVENT_END:
057:             return "END";
058:         default:
059:             return "UNKNOWN";
060:     }
061: }
062: 
063: // 状態遷移関数
064: RadioState radio_transition(
065:     RadioState current,
066:     RadioEvent event)
067: {
068:     switch(current)
069:     {
070:         // OFF
071:         case STATE_OFF:
072: 
073:             switch(event)
074:             {
075:                 case EVENT_ON:
076:                     return STATE_HIGH;
077: 
078:                 default:
079:                     return STATE_OFF;
080:             }
081: 
082:         // HIGH
083:         case STATE_HIGH:
084:             switch(event)
085:             {
086:                 case EVENT_SCAN:
087:                     return STATE_SCANNING;
088:                 case EVENT_RESET:
089:                     return STATE_HIGH;
090:                 case EVENT_OFF:
091:                     return STATE_OFF;
092:                 default:
093:                     return STATE_HIGH;
094:             }
095: 
096:         // SCANNING
097:         case STATE_SCANNING:
098:             switch(event)
099:             {
100:                 case EVENT_LOCK:
101:                     return STATE_LOCKED;
102:                 case EVENT_END:
103:                     return STATE_HIGH;
104:                 case EVENT_RESET:
105:                     return STATE_HIGH;
106:                 case EVENT_OFF:
107:                     return STATE_OFF;
108:                 default:
109:                     return STATE_SCANNING;
110:             }
111: 
112:         // LOCKED
113:          case STATE_LOCKED:
114:             switch(event)
115:             {
116:                 case EVENT_SCAN:
117:                     return STATE_SCANNING;
118:                 case EVENT_RESET:
119:                     return STATE_HIGH;
120:                 case EVENT_OFF:
121:                     return STATE_OFF;
122:                 default:
123:                     return STATE_LOCKED;
124:             }
125:         default:
126:             return STATE_OFF;
127:     }
128: }
129: 
130: // イベント実行
131: void execute_event(
132:     RadioState* state,
133:     RadioEvent event)
134: {
135:     RadioState next;
136:     printf(
137:         "[EVENT] %s\n",
138:         event_name(event));
139:     next = radio_transition(*state, event);
140:     printf(
141:         "  %s -> %s\n",
142:         state_name(*state),
143:         state_name(next));
144:     *state = next;
145: }
146: 
147: // メイン
148: int main(void)
149: {
150:     RadioState state = STATE_OFF;
151:     printf("FM Radio STM Demo\n\n");
152:     printf(
153:         "Initial State: %s\n\n",
154:         state_name(state));
155:     execute_event(&state, EVENT_ON);
156:     execute_event(&state, EVENT_SCAN);
157:     execute_event(&state, EVENT_LOCK);
158:     execute_event(&state, EVENT_SCAN);
159:     execute_event(&state, EVENT_END);
160:     execute_event(&state, EVENT_OFF);
161:     return 0;
162: }
