minor updates
[fw/sdcc] / device / examples / mcs51 / simple / hi.c
1 /*------------------------------------------------------------------------
2  hi.c - This is a simple program designed to operate on basic MCS51
3    hardware at 11.0592Mhz.  It sets up the baudrate to 9600 and sends
4    a "Hi\n" "There\n" message every few seconds.  The timer interrupt
5    is used.
6
7    Its intended to be a simple example for SDCC, a good first
8    program to compile and play with.
9
10    The simulator can be used to run this program:
11    s51 -Sout=serial.txt hi.ihx (run, stop, quit)
12
13  6-28-01  Written by Karl Bongers(karl@turbobit.com)
14 |------------------------------------------------------------------------*/
15 #include <8052.h>
16
17 typedef unsigned char byte;
18 typedef unsigned int word;
19 typedef unsigned long l_word;
20
21 //---- most of the following declares are simply to demostrate some
22 // of SDCC's variable storage declaration syntax
23
24 // volatile keyword is needed for variables shared by interrupt routine
25 // and normal application thread, otherwise things get optimized out.
26 volatile data byte timer;
27 volatile data byte hi_flag;
28
29 data byte a_data_byte;    // normal < 128 bytes of 8031 internal memory.
30 idata byte a_idata_byte;  // in +128 byte internal memory of 8032
31 xdata byte a_xdata_byte;  // in external memory.
32 xdata at 0x8000 byte mem_mapped_hardware; // example at usage
33
34 bit my_bit;  // mcs51 bit variable, stored in single bit of register space
35
36 sfr at 0xd8 WDCON;  // special function register declaration
37 sbit LED_SYS = 0xb5;  // P3.5 is led, example use of sbit keyword
38
39 code char my_message[] = {"GNU rocks"};  // placed in code space
40
41 void timer0_irq_proc(void) interrupt 1 using 2;
42
43 /*------------------------------------------------------------------------
44   timer0_int - Timer0 interrupt.  Notice we are using register bank 2
45     for this interrupt.
46 |------------------------------------------------------------------------*/
47 void timer0_irq_proc(void) interrupt 1 using 2
48 {
49   if (timer != 0)
50   {
51     --timer;
52   }
53   else
54   {
55     hi_flag = 1;
56     timer = 250;
57   }
58
59   TR0 = 0; /* Stop Timer 0 counting */
60   TH0 = (~(5000)) << 8;
61   TL0 = (~(5000)) & 8;
62   TR0 = 1; /* Start counting again */
63 }
64
65 #if 0
66 /*------------------------------------------------------------------------
67   uart0_int - Interrupt 4 is for the UART, notice we use register bank 1
68     for the interrupt routine.
69 |------------------------------------------------------------------------*/
70 void uart0_int(void) interrupt 4 using 1
71 {
72   if (RI)
73   {
74     c = SBUF;
75     RI = 0;
76   }
77 }
78 #endif
79
80 /*------------------------------------------------------------------------
81   tx_char - transmit(tx) a char out the serial uart.
82 |------------------------------------------------------------------------*/
83 void tx_char(char c)
84 {
85   while (!TI)
86     ;
87   TI = 0;
88   SBUF = c;
89 }
90
91 /*------------------------------------------------------------------------
92   tx_str - transmit(tx) a string out the serial uart.
93 |------------------------------------------------------------------------*/
94 void tx_str(char *str)
95 {
96   
97   while (*str)
98     tx_char(*str++);
99 }
100
101 /*------------------------------------------------------------------------
102   stop - a break point in Daniel D's s51 can be set at 65535 memory
103     location to stop the simulation.  This routine also shows how to
104     embed assembly.
105 |------------------------------------------------------------------------*/
106 void stop(void)
107 {
108  _asm;
109   mov dptr, #65535;
110   movx a, @dptr;
111   nop;
112  _endasm;
113 }
114
115 /*------------------------------------------------------------------------
116   main - Simple test program to send out something to the serial port.
117 |------------------------------------------------------------------------*/
118 void main(void)
119 {
120   PCON = 0x80;  /* power control byte, set SMOD bit for serial port */
121   SCON = 0x50;  /* serial control byte, mode 1, RI active */
122   TMOD = 0x21;  /* timer control mode, byte operation */
123   TCON = 0;     /* timer control register, byte operation */
124
125   TH0 = (~(5000)) << 8;  /* the initial time is not important */
126   TL0 = (~(5000)) & 8;
127
128   TH1 = 0xFA;   /* serial reload value, 9,600 baud at 11.0952Mhz */
129   TR1 = 1;      /* start serial timer */
130
131   TR0 = 1;      /* start timer0 */
132   ET0 = 1;      /* Enable Timer 0 overflow interrupt IE.1 */
133   EA = 1;       /* Enable Interrupts */
134
135   TI = 0;       /* clear this out */
136   SBUF = '.';   /* send an initial '.' out serial port */
137   hi_flag = 1;
138   //ES = 1;                           /* Enable serial interrupts IE.4 */
139
140   tx_str(my_message);
141
142   for (;;)
143   {
144     if (hi_flag)
145     {
146       tx_str("Hi\n");
147       tx_str("There\n");
148       hi_flag = 0;
149     }
150
151 stop();
152
153 #ifdef TEST_IDLE_MODE
154     // this was a simple test of the low power sleep mode of a
155     // dallas DS5000 cmos part, to see how much power requirements
156     // dropped in sleep mode.
157     
158     // into idle mode until next interrupt.  Draws only 3ma.
159     PCON = 0x81;
160 #endif
161   }
162
163 }
164