/* filename FSM12.C Complicated Moore FSM PortJ bits 7-0 are inputs, PortH bits 7-0 are outputs Each state can have up to 4 next state arrows The input to cause a state change is a sequence of 8 1,0,X E.g., 1X0XX1XX means Bit7=1, Bit5=0 and Bit2=1 This pattern is encoded with AndMask=0xA4 and EquMask=0x84 */ // Last modified 1/16/02 by Jonathan W. Valvano // Copyright 2002 by Jonathan W. Valvano, valvano@uts.cc.utexas.edu // You may use, edit, run or distribute this file // as long as the above copyright notice remains #include "HC12.h" // Nonvolatile structure placed in EEPROM const struct State{ unsigned char Out; /* Output to Port B */ unsigned int Wait; /* Time (E cycles) to wait in this state */ unsigned char AndMask[4]; unsigned char EquMask[4]; const struct State *Next[4];}; /* Next state if input=matches */ typedef const struct State StateType; typedef StateType * StatePtr; #define stop &fsm[0] #define turn &fsm[1] #define bend &fsm[2] StateType fsm[3]={ {0x34, 2000, // stop 1 ms {0xFF, 0xF0, 0x27, 0x00}, {0x51, 0xA0, 0x07, 0x00}, {turn, stop, turn, bend}}, {0xB3,5000, // turn 2.5 ms {0x80, 0xF0, 0x00, 0x00}, {0x00, 0x90, 0x00, 0x00}, {bend, stop, turn, turn}}, {0x75,4000, // bend 2 ms {0xFF, 0x0F, 0x01, 0x00}, {0x12, 0x05, 0x00, 0x00}, {stop, stop, turn, stop}}}; void Init(void){ COPCTL = 0x00; // disable COP DDRT |= 0x40; // PortT bit 6 is output to LED TSCR = 0x80; // TEN(enable) } void main(void){ StatePtr Pt; unsigned char Input; int Endt; unsigned int i; Init(); // disable COP, enable Port T DDRH = 0xFF; // PortH bits 7-0 are outputs DDRJ = 0x00; // PortJ bits 7-0 are inputs PUPSJ = 0xFF; // Pullups J7-J0 PULEJ = 0xFF; // Enable pull up/down PortJ Pt = &fsm[0]; // Initial State while(1){ PORTT ^= 0x40; // toggle LED (debug) PORTH = Pt->Out; // 1) output Endt = TCNT+Pt->Wait; // Time (cycles) to wait in this state while(Endt-(int)TCNT>0); // 2) wait Input = PORTJ; // 3) input for(i=0;i<4;i++){ if((Input&Pt->AndMask[i])==Pt->EquMask[i]){ Pt = Pt->Next[i]; // 4) next depends on input i = 4; } } } } extern void _start(); #pragma abs_address:0xfffe void (*reset_vector[])() = { _start }; #pragma end_abs_address