dice.c51


1
/************************************************************************/
2
/*                  */
3
/*    Dice with manual controlled random number    */
4
/*                  */
5
/*    Author: Peter Dannegger          */
6
/*                  */
7
/************************************************************************/
8
9
#pragma cd pl(9999) rom(small)
10
11
#include"reg51.h"
12
#include"types.h"
13
14
#define  XTAL  8.8e6
15
16
#define DICE_TIMER  241    // roll dice (invisible)
17
#define DISPLAY_TIMER  251    // roll display (visible)
18
#define DISPLAY_SPEED  ((uint)(XTAL / 12.0 / DISPLAY_TIMER / 10 + 0.5))
19
          // 10Hz
20
21
#define BUTTON  INT1
22
23
#define  _A  BIN8(0,0,1,0,0,0,0,0)  //  Dice LEDs:
24
#define  _B  BIN8(0,0,0,0,1,0,0,0)
25
#define  _C  BIN8(0,1,0,0,0,0,0,0)  //  A    B
26
#define  _D  BIN8(0,0,0,1,0,0,0,0)
27
#define  _E  BIN8(0,0,0,0,0,1,0,0)  //  C  D  E
28
#define  _F  BIN8(1,0,0,0,0,0,0,0)
29
#define  _G  BIN8(0,0,0,0,0,0,1,0)  //  F    G
30
31
32
#define  PRESS_BUTTON  0  // roll dice
33
#define ROLL_OUT  1  // roll out
34
#define  STOP    2  // stop dice
35
#define WAIT    3  // minimum delay until next dice
36
#define NEXT_DICE  4  // wait for next press
37
38
#define T_POWER_OFF  250  // power off time
39
#define T_ROLL_OUT  3  // minimum roll out count
40
#define T_WAIT    10  // minimum delay time
41
42
43
uchar dice_new;      // new value, if key released
44
45
46
void main( void )
47
{
48
  uchar code DICE[] = {  0xFE -                _D,
49
      0xFE - _A -                          _G,
50
      0xFE -      _B -      _D -      _F,
51
      0xFE - _A - _B -                _F - _G,
52
      0xFE - _A - _B -      _D -      _F - _G,
53
      0xFE - _A - _B - _C -      _E - _F - _G };
54
55
  uchar  dice_view;      // visible rolls every 100ms
56
  uchar  dice_state;      // dice state machine
57
  uchar  timeout;
58
  uint  timer_100ms;      // 100ms time base
59
60
  timer_100ms = 1;
61
  TMOD = T0_M1_ + T1_M1_;    // T0, T1: 8-bit reload
62
  TH0 = -DICE_TIMER;
63
  TH1 = -DISPLAY_TIMER;
64
  TCON = TR0_ + TR1_ + TF1_;
65
  IE = EA_ + ET0_;
66
  for(;;){        // main loop
67
    if( TF1 == 0 )
68
      continue;
69
    TF1 = 0;
70
    if( --timer_100ms )
71
      continue;
72
    timer_100ms = DISPLAY_SPEED;
73
74
    P1 = DICE[dice_view];    // display dice value
75
76
    switch( dice_state ){    // dice state machine
77
78
      case PRESS_BUTTON:
79
  if( --timeout == 0 ){    // key pressed too long
80
    dice_state = NEXT_DICE;
81
    timeout = T_POWER_OFF;
82
    P1 = 0xFE;      // all LEDs off
83
    PCON = PD_;      // enter power down
84
  }
85
  if( dice_new > 5 )
86
    break;      // "break;" = run dice
87
  timeout = T_ROLL_OUT + 1;
88
  dice_state = ROLL_OUT;    // button released
89
90
      case ROLL_OUT:
91
  if( --timeout )      // some further rolls
92
    break;      // "break;" = run dice
93
  dice_state = STOP;
94
95
      case STOP:
96
  if( dice_new != dice_view )  // continue until new value reached
97
    break;      // "break;" = run dice
98
  timeout = T_WAIT + 1;
99
  dice_state = WAIT;
100
101
      case WAIT:      // display new value
102
  if( --timeout )
103
    continue;      // "continue;" = stop dice
104
  timeout = T_POWER_OFF + 1;
105
  dice_state = NEXT_DICE;
106
107
      case NEXT_DICE:
108
      default:
109
  if( BUTTON ){      // key still released
110
    if( --timeout )
111
      continue;      // "continue;" = stop dice
112
          // key released too long
113
    timeout = T_POWER_OFF;
114
    P1 = 0xFE;      // all LEDs off
115
    PCON = PD_;      // enter power down
116
  }
117
  dice_state = PRESS_BUTTON;  // key pressed again
118
  dice_new = 6;      // mark as invalid
119
  timeout = T_POWER_OFF;
120
    }
121
122
    if( ++dice_view > 5 )    // run visible dice
123
      dice_view = 0;
124
  }
125
}
126
127
128
void t0_interrupt( void ) interrupt INT_T0
129
{
130
  static uchar dice;      // real dice (invisible)
131
  if( BUTTON && dice_new > 5 )    // if key released
132
    dice_new = dice;      // get new dice value
133
  if( ++dice > 5 )      // 0,1,2,3,4,5
134
    dice = 0;
135
}