/*Traffic_Light.ino 17 SEP 2015 Arduining.com
Implementing the traffic light controller using Finite State Machines modeling.
Using Direct Port Manipulation in the Arduino UNO.
Creating a Data Structure in C.
Port B pins 0 and 1 as inputs (Arduino pins 8 and 9):
Pin 8 = North Switch
Pin 9 = East Switch
Port D pins 2 to 7 as outputs (Arduino pins 2 to 7):
Pin 2 = North Red light
Pin 3 = North Yellow light
Pin 4 = North Green light
Pin 5 = East Red light
Pin 6 = East Yellow light
Pin 7 = East Green light
Based in: Finite State MachinesFrom:http://users.ece.utexas.edu/~valvano/Volume1/E-Book/
*/
#define SENSORS PINB // define the ATmega328 Port to read the switches
#define LIGHTS PORTD // define the ATmega328 Port to drive the lights
// Linked data structure
struct State {
int Out;
int Time;
int Next[4];};
typedef const struct State STyp;//将 STyp 指代为名为 state 的恒定的结构体变量
#define goS 0
#define waitS 1
#define goW 2
#define waitW 3
STyp FSM[4]={
{0x21,3000,{goS,waitS,goS,waitS}}, //State 0 (goS) go South.
{0x22, 500,{goW,goW,goW,goW}}, //State 1 (waitS) wait South.
{0x0C,3000,{goW,goW,waitW,waitW}}, //State 2 (goW) go West.
{0x14, 500,{goS,goS,goS,goS}}}; //State 3 (waitW) wait West.
//0x21 = 00100001 ,取后六位为灯控状态
int State; // index to the current state
int Input;
void setup(){
DDRB &= B11111100; // Port B pins 0 and 1 as inputs (Arduino pins 8 and 9)
DDRD |= B11111100; // Port D pins 2 to 7 as outputs (Arduino pins 2 to 7)
//DDRB 控制 Port B 的引脚方向。每个位(bit)代表一个引脚,当位被设置为 1 时,对应的引脚为输出模式;
//当位被设置为 0 时,对应的引脚为输入模式。
//DDRD 控制 Port D 的引脚方向。同样,每个位代表一个引脚,设置方式与 DDRB 相同。
//DDRB &= B11111100; 将Port B的引脚0和1设置为输入模式,即设置为0,其他引脚保持不变。
//这里使用了位操作 &=,以及二进制数 B11111100 来设置引脚的方向。
//这样做的目的是将Arduino的引脚8和9(对应Port B的引脚0和1)设置为输入模式,用作传感器的输入。
}
void loop(){
LIGHTS = (FSM[State].Out)<<2; // set lights
delay(FSM[State].Time);
Input = SENSORS & B00000011; //这行代码的作用是只保留端口 B 上的两个最低位,忽略其他位的状态,然后将这个结果存储到 Input 变量中。
State = FSM[State].Next[Input];
}