C51 COMPILER V7.09   MAIN                                                                  06/14/2006 18:23:33 PAGE 1   


C51 COMPILER V7.09, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE main.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          /*
   2          **********************************************************************************************************
             -*********
   3          *                                                                                       RING TONE DEMO 1 BY HARDWARE TIMER
   4          *
   5          * Description:  This program plays a short ring tone music composed of different notes with individual not
             -e duration
   6          *                               defined in the arrays noteDuration[] and noteFreq[]. Instead of using software delayMs() loop,
   7          *                               hardware Timer 0 is used here to make a "real-time" system. The noteDuration[] is defined
   8          *                               in the unit of millisec. Therefore, noteDuration[0]=15 => the first note sounds for 150ms;
   9          *                               noteFreq[0]=2093 => the note frequency is 2093 Hz. Timer 0 is used to count expiry
  10          *                               of the noteDuration[noteIdx], with noteIdx being the array index.
  11          *                               Since hardware timer Timer 0 has been loaded with (TH0,TL0) of 0xDC00, it gives 10ms interrupt
  12          *                               when external crystal is 11.0592MHz. A variable notePlayCtr is used to count down on
  13          *                               noteDuration[noteIdx] until the end of the ring tone music, indicated by a noteDuration of 0.
  14          *
  15          * File:                 cd:\src\chp3\src3_2\main.c
  16          * Software:             Keil C (C51) compiler, Eval version 7.09 under uVision2 IDE v2.40
  17          * Programmer:   John Leung, TechToys Co. (www.TechToys.com.hk)
  18          * Hardware:             AT89S52-gLCD-STK1, with Atmel 89S52, 11.0592 MHz crystal
  19          * Date:                 3rd June 2006
  20          * Version:              1.0
  21          * Programmer:   John Leung
  22          **********************************************************************************************************
             -*********
  23          */
  24          
  25          #include <REGX52.h>
  26          #include "delay.h"
  27          
  28          #define ON              0
  29          #define OFF             1
  30          #define TRUE    1
  31          #define FALSE   0
  32          #define CLOSE   0
  33          #define OPEN    1
  34          
  35          /*
  36          **********************************************************************************************************
             -*********
  37          *                                                                                               HARDWARE DEFINITION
  38          **********************************************************************************************************
             -*********
  39          */
  40          sbit LED        = P2^0;
  41          sbit KEYUP      = P1^6;
  42          sbit KEYDN      = P1^4;
  43          sbit BUZZER = P1^0;
  44          
  45          bit notePlayEn = FALSE;
  46          unsigned int notePlayCtr=0;
  47          unsigned char noteIdx=0;
  48          code unsigned int noteDuration[]        = {15,15,30,15,15,30,15,15,15,15,15,15,30,15,15,15,15,15,15,15,30,15,15,
             -30,15,\
  49          30,30,60,0};
C51 COMPILER V7.09   MAIN                                                                  06/14/2006 18:23:33 PAGE 2   

  50          code unsigned int noteFreq[]            = {2093,880,0,2093,1760,0,2093,880,2093,880,2093,1760,0,0,2093,2349,2637,0,
             -\
  51          2637,2794,3136,0,2349,2093,2349,2794,1865,1760,4186,0};
  52          
  53          /*
  54          **********************************************************************************************************
             -*********
  55          *                                                                                               FUNCTION PROTOTYPE
  56          **********************************************************************************************************
             -*********
  57          */
  58          void Tmr0Init();
  59          void ToneGen(unsigned int tone);
  60          void notePlayStart(void);
  61          
  62          
  63          /*
  64          **********************************************************************************************************
             -*********
  65          *                                                                                       Timer 0 interrupt service routine
  66          *
  67          * Function:     This function reloads Timer 0 for a 10ms interrupt. A gate 'notePlayEn' is used to start and s
             -top
  68          *                       the 'notePlayCtr' decrement process, thus enable or disable ring tone play and stop. 
  69          *                       Music playback is started by making 'notePlay' to TRUE, and setting notePlayCtr to '1' to control an
  70          *                       immediate playback. Upon the first notePlayCtr--, notePlayCtr decrement to 0, thus ToneGen() is loaded
  71          *                       with the first note frequency noteFreq[0]. Then, notePlayCtr is loaded with noteDuration[0], being the
  72          *                       corresponding playback duration of the first note. After a hardware delay of 10ms * noteDuration[0],
  73          *                       the process is repeated by loading the second noteFrequency 'noteFreq[1]' 
  74          *                       and noteDuration 'noteDuration[1] until the end of the music indicated by noteDuration[noteIdx]=0.
  75          *                       
  76          * Argument:     none
  77          * Return:       none
  78          * Note: 
  79          **********************************************************************************************************
             -*********
  80          */
  81          Tmr0() interrupt 1
  82          {
  83   1              if(notePlayEn==TRUE){
  84   2                      if(notePlayCtr>0){
  85   3                              notePlayCtr--;
  86   3                              if(notePlayCtr==0){
  87   4                                      notePlayEn = FALSE;
  88   4                                      if(noteDuration[noteIdx]!=0)
  89   4                                      {
  90   5                                              ToneGen(noteFreq[noteIdx]);
  91   5                                              notePlayCtr = noteDuration[noteIdx];
  92   5                                              noteIdx++;
  93   5                                              notePlayEn = TRUE;
  94   5                                      } else {
  95   5                                              TR2     = 0;
  96   5                                              BUZZER  = OFF;
  97   5                                      }
  98   4                              }
  99   3                      }
 100   2              }
 101   1              TH0 =   0xDC;                   //10ms hardware delay, 11.0592MHz => 1 machine cycle at 1.085usec
 102   1              TL0 =   0x00;                   //Number of cycles to delay 10ms = 10000/1.085 = 9216
 103   1                                                              //T0 in 16-bit mode => T0 preload with a value (65536-9216)=56,320, i.e. 0xDC00
 104   1      }
 105          
C51 COMPILER V7.09   MAIN                                                                  06/14/2006 18:23:33 PAGE 3   

 106          /*
 107          **********************************************************************************************************
             -*********
 108          *                                                                               Timer 0 initialization routine
 109          * Function:     This function initializes Timer 0 to 16-bit manual reload mode while leaving Timer 1 parameter
             -s
 110          *                       unchanged. Timer 0 interrupt enabled and started here.
 111          * Argument:     none
 112          * Return:       none
 113          * Note: 
 114          **********************************************************************************************************
             -*********
 115          */
 116          void Tmr0Init(void)
 117          {
 118   1      
 119   1              TMOD=   TMOD&0xF0;              //reset TIMER0 configuration
 120   1              TMOD=   TMOD|0x01;              //leave TIMER1 configuration unchanged and set T0 to 16-bit timer mode
 121   1      
 122   1              TH0 =   0xDC;                   //10ms hardware delay, 11.0592MHz => 1 machine cycle at 1.085usec
 123   1              TL0 =   0x00;                   //Number of cycles to delay 10ms = 10000/1.085 = 9216
 124   1                                                              //T0 in 16-bit mode => T0 preload with a value (65536-9216)=56,320, i.e. 0xDC00
 125   1              TF0 =   0;                              //clear overflow flag
 126   1              ET0     =       1;                              //enable T0 interrupt
 127   1              TR0 =   1;                              //start timer 0
 128   1      }
 129          
 130          /*
 131          **********************************************************************************************************
             -*********
 132          *                                                                                       TONE GENERATION ROUTINE
 133          * Function:     This function generates a single tone of a certain frequency 'tone' in Hz by Timer 2 
 134          *                       in programmable clock out mode
 135          * Argument:     'tone'          frequency of the tone to generate, in Hz
 136          *
 137          * Return:       none
 138          *
 139          * Note:         *** Please note that there is a limit in the frequency range. We are using a crystal frequency of
 140          *                               11.0592MHz. From equal Clock-out Freq= Oscillator Freq / (4*(65536-RCAP2H,RCAP2L)).
 141          *                               Thus, max Clock-out Freq = 2.7648MHz; min Clock-out Freq = 42 Hz.
 142          *                               Human audible range is around 20Hz - 20kHz, and the frequency response of piezo sounder has 
 143          *                               a limited range, too. We just cannot make infinite pitch from our hardware! ***
 144          **********************************************************************************************************
             -*********
 145          */
 146          void ToneGen(unsigned int tone)
 147          {
 148   1              unsigned long tmp;
 149   1              if(tone!=0)
 150   1              {
 151   2              T2CON = 0x00;                   // reset T2CON, the Timer 2 control register. Important for stopping Timer 2 by TR2=0
 152   2       
 153   2              T2MOD = T2MOD&0xFE;
 154   2              T2MOD = T2MOD|0x02;             // sets T2OE=1; DCEN=0; for a clock out mode, no interrupt generated in this mode
 155   2      
 156   2              tmp = (11059200UL>>2)/tone;
 157   2              tmp = 65536UL - tmp;    
 158   2              RCAP2H = (unsigned char) (tmp>>8);
 159   2              RCAP2L = (unsigned char) (tmp&0xFF);
 160   2              TH2 = RCAP2H;
 161   2              TL2 = RCAP2L;
 162   2      
C51 COMPILER V7.09   MAIN                                                                  06/14/2006 18:23:33 PAGE 4   

 163   2              TR2 = 1;                                //Start Timer 2 for clock out
 164   2              } 
 165   1              else
 166   1              {
 167   2              TR2= 0;                                 //tone frequency=0, TR2 = 0 to shut down clock out
 168   2              BUZZER = OFF;
 169   2              }
 170   1      }
 171          
 172          /*
 173          **********************************************************************************************************
             -*********
 174          *                                                                                       RING TONE MUSIC PLAY STARTED
 175          * Function:     This function starts the ring tone music defined by the arrays noteDuration[] and noteFreq[].
 176          *                       noteIdx set to 0 to play start the first note. 
 177          *                       notePlayEn set to TRUE to start the hardware countdown process, thus starting the music.
 178          *                       notePlayCtr set to an initial value of 1 to force play the music with almost no delay.
 179          * Argument:     none
 180          *
 181          * Return:       none
 182          *
 183          * Note:
 184          **********************************************************************************************************
             -*********
 185          */
 186          void notePlayStart(void)
 187          {
 188   1              noteIdx = 0;                    //Play from the first note
 189   1              notePlayEn = TRUE;              //Play note enable
 190   1              notePlayCtr = 1;                //Play force immediately
 191   1      }
 192          
 193          
 194          /*
 195          **********************************************************************************************************
             -*********
 196          *                                                                                       RING TONE MUSIC PLAY STOP
 197          * Function:     This function stops the ring tone music defined by the arrays noteDuration[] and noteFreq[].
 198          *                       notePlayEn set to FALSE to stop the hardware countdown process, thus stoping the music.
 199          * Argument:     none
 200          *
 201          * Return:       none
 202          *
 203          * Note:
 204          **********************************************************************************************************
             -*********
 205          */
 206          void notePlayStop(void)
 207          {
 208   1              notePlayEn = FALSE;
 209   1              TR2     = 0;
 210   1              BUZZER  = OFF;
 211   1      }
 212          
 213          /*
 214          **********************************************************************************************************
             -*********
 215          *                                                                                                               MAIN
 216          **********************************************************************************************************
             -*********
 217          */
 218          void main(void)
C51 COMPILER V7.09   MAIN                                                                  06/14/2006 18:23:33 PAGE 5   

 219          {
 220   1              Tmr0Init();
 221   1              EA = 1;                                                                 //enable global interrupt flag
 222   1              
 223   1              for(;;)
 224   1              {       
 225   2                      if(KEYUP==CLOSE)
 226   2                      {
 227   3                              DelayMs(20);                                    //key debounce for 20ms
 228   3                              if(KEYUP==CLOSE)                                //a true user input, a true key
 229   3                                      {       while(KEYUP==CLOSE);    //the user should release the key to begin playback
 230   4                                              notePlayStart();                //start play
 231   4                                              LED = ON;                               //ON LED for visual indication
 232   4                                      }
 233   3                      }
 234   2      
 235   2                      if(KEYDN==CLOSE)
 236   2                      {
 237   3                              DelayMs(20);
 238   3                              if(KEYDN==CLOSE) notePlayStop();
 239   3                              LED = OFF;
 240   3                      }
 241   2      
 242   2              }
 243   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    343    ----
   CONSTANT SIZE    =    118    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =      3       4
   IDATA SIZE       =   ----    ----
   BIT SIZE         =      1    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)
