⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f411_vr.c

📁 用c8051f410和FLASH(SPI接口)实现的数字录音机。
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// PCA_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure PCA0 modules 0 and 1 to 8-bit PWM mode using the system clock.
//
void PCA_Init (void)
{
   PCA0MD = 0x88;                      // set PCA to use system clock, disable
                                       // idle mode

   // PCA0 (for LED1)
   PCA0CPM0 = 0x42;                    // set PCA0 for 8-bit PWM mode
   PCA0CPH0 = 0x00;                    // set LED to off originally

   // PCA1 (for LED0)
   PCA0CPM1 = 0x42;                    // set PCA1 for 8-bit PWM mode
   PCA0CPH1 = 0x00;                    // set LED to off originally

   // add another PCA module for another LED here, if desired

   PCA0CN = 0x40;                      // turn on the PCA timer/counter
}

//-----------------------------------------------------------------------------
// SPI0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the SPI to run in 4-wire master mode at SYSCLK / 4 (1.53 MHz)
// using clock phase 0 and clock polarity 0 to interface with the SST Flash
// memory.
//
void SPI0_Init (void)
{
   SPI0CFG = 0x40;                     // set the master mode, polarity and
                                       // phase
   // set the SPI frequency to SYSCLK / 2*(1+1) = SYSCLK / 4
   SPI0CKR = 0x01;
   SPI0CN = 0x0C;                      // clear flags, turn off NSS
                                       // set the 4-wire mode
   SPIEN = 1;                          // enable the SPI
}

//-----------------------------------------------------------------------------
// Timer0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int period - number of timer counts to generate the desired period
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer0 to 16-bit mode.  Timer0 is used to control the load
// time of the PCA PCA0CPHn registers, which changes the PWM intensity of the
// LEDs.
//
// The input parameter can be calculated as follows:
//   (Oscillator (Hz) / 4) / Desired_Freq (Hz) = Timer Ticks
//
void Timer0_Init (int period)
{
   TMOD |= 0x01;                       // set Timer 0 to mode 1 (16 bit)
   CKCON |= 0x04;                      // use the system clock
   ET0 = 1;                            // enable Timer 0 interrupts
   PT0 = 1;                            // set Timer 0 interrupts to high
                                       // priority (has to interrupt T1)

   TL0 = (-period) & 0x00FF;           // set the desired period
   TH0 = ((-period) & 0xFF00) >> 8;

   TR0 = 0;                            // keep Timer 0 off (LED
                                       // functions will turn it on)
}

//-----------------------------------------------------------------------------
// Timer1_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int period - number of timer counts to generate the desired period
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer1 to 16-bit mode.  Timer1 controls the switch polling.
//
// To calculate:
//   (Oscillator (Hz) / 4) / 48 / Desired_Freq (Hz) = Timer Ticks
//
// NOTE -  the extra 48 in this equation is present because of the settings
// in CKCON.
//
void Timer1_Init (int period)
{
   TMOD |= 0x10;                       // set Timer 1 to mode 1 (16 bit)
   CKCON |= 0x02;                      // use the system clock / 48
   ET1 = 1;                            // enable Timer 1 interrupts

   TL1 = (-period) & 0x00FF;           // set the desired period
   TH1 = ((-period) & 0xFF00) >> 8;

   TR1 = 0;                            // keep Timer 1 off until needed
}

//-----------------------------------------------------------------------------
// Timer2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int period - number of timer counts to generate the desired period
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer2 to 16-bit auto reload mode.  Timer2 controls the ADC0
// start-of-conversion rate.
//
// To calculate:
//   (Oscillator (Hz) / 4) / Desired_Freq (Hz) = Timer Ticks
//
void Timer2_Init (int period)
{
   CKCON |= 0x10;                      // use the system clock
   TMR2CN = 0x00;                      // 16-bit auto-reload mode
   ET2 = 0;                            // disable T2 interrupts (use ADC
                                       // conversion complete interrupt)

   TMR2RL = -period;                   // set the desired period

   TMR2 = -period;                     // initialize the timer

   TR2 = 0;                            // keep Timer 2 off until the RECORD
                                       // function is used
}

//-----------------------------------------------------------------------------
// Timer3_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int period - number of timer counts to generate the desired period
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer3 to 16-bit auto reload mode.  Timer3 controls the DAC output
// rate.
//
// To calculate:
//   (Oscillator (Hz) / 4) / Desired_Freq (Hz) = Timer Ticks
//
void Timer3_Init (int period)
{
   CKCON |= 0x40;                      // use the system clock
   TMR3CN = 0x00;                      // 16-bit auto-reload mode
   EIE1 |= 0x80;                       // enable Timer 3 interrupts
   EIP1 |= 0x80;                       // set Timer 3 interrupts to high
                                       // priority

   TMR3RL = -period;                   // set the desired period

   TMR3 = -period;                     // initialize the timer

   TMR3CN = 0x00;                      // keep Timer 3 off until the PLAY
                                       // function is used
}

//-----------------------------------------------------------------------------
// RTC_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Enable the RTC so it doesn't cause a wake-up from suspend mode.
//
void RTC_Init (void)
{
   RTC0KEY = 0xA5;                     // unlock the RTC interface
   RTC0KEY = 0xF1;
   RTC0ADR = 0x06;                     // point to RTC0CN
   RTC0DAT = 0x80;                     // enable the RTC
}

//-----------------------------------------------------------------------------
// Recording_Search
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Search for a recording already residing in memory on power-up and set the
// rec_end_addr accordingly.
//
void Recording_Search(void)
{
   unsigned long address = 0x00000000;
   bit end_flag = 0;

   // indicate to the user that the microcontroller is not ready to record
   // or playback
   LED_DCH = &LED0_DC;
   Brighten_LED ();
   LED_DCH = &LED1_DC;
   Brighten_LED ();

   // search through the SST flash until a series of 0xFF is found, indicating
   // cleared memory
   while (end_flag != 1)
   {
      if (Read_MEM_Init (address) == 0xFF)
      {
         // double-check that the 0xFF found is not just a data byte of 0xFF
         if (Read_MEM_Init (address+10) == 0xFF)
         {
            if (Read_MEM_Init (address+40) == 0xFF)
            {
               end_flag = 1;
            }
         }
      }

      address++;

      if (address == MAX_MEM_ADDR)
      {
         end_flag = 1;
      }
   }

   rec_end_addr = address-1;           // set the recording ending address

   // turn off the LEDs so the user knows the recording search has ended
   LED_DCH = &LED0_DC;
   Dim_LED ();
   LED_DCH = &LED1_DC;
   Dim_LED ();
}

////////////////////////// INTERRUPT SERVICE ROUTINES /////////////////////////

//-----------------------------------------------------------------------------
// Timer0_ISR
//-----------------------------------------------------------------------------
//
// Handle the 76Hz (13ms) Timer 0 interrupt.
//
// Timer 0 controls the rate at which the microcontroller changes the duty
// cycle of the PCA controlling the LEDs
//
// The LEDs are updated periodically, even if the LED PWM hasn't changed.
// By using the pointer (which is set before calling the LED functions) and
// updating all LEDs in the ISR every time, the same functions can be used for
// any number of LEDs.  To add an LED, simply set-up another PCA channel,
// point to that LED before calling the LED functions, and update the LED in
// the ISR.
//
void Timer0_ISR (void) interrupt 1 using 1
{
   *LED_DCH += ADJ;                    // calculate the new duty cycle based
                                       // on the values set by the LED
                                       // functions

   PCA0CPH1 = LED0_DC;                 // load all LEDs with the possibly
   PCA0CPH0 = LED1_DC;                 // updated value
   // add another LED update here, if desired

   TL0 = (-LED_PWM) & 0x00FF;          // wait the time specified by the
   TH0 = ((-LED_PWM) & 0xFF00) >> 8;   // calling LED function

   LED_PWM += LED_PWM_CHANGE;          // change the interrupt rate, if
                                       // necessary
}

//-----------------------------------------------------------------------------
// Timer1_ISR
//-----------------------------------------------------------------------------
//
// Handle the 64 Hz (15.63 ms) Timer 1 interrupt.
//
// Timer 1 controls the rate at which the microcontroller checks the switches
// for activity while in full power mode.
//
// for RECORD - press and hold REC_PLAY button, release stops recording
// for PLAYBACK - press and release REC_PLAY button, press and release again
//                  to stop
//
void Timer1_ISR (void) interrupt 3 using 0
{
   // interrupt again in 15.63 ms, unless a switch is pressed
   unsigned short reload_value = POLLING;

   static unsigned char record_counter = 0;
   static unsigned short suspend_counter = 0;

   bit switch_pressed_flag = 0;

   // REC_PLAY button pressed
   if (REC_PLAY == 0)
   {
      switch_pressed_flag = 1;         // record the user interaction

      // check if the recording time ran out, and stop any interaction
      // from the switch until the switch is released and pressed again
      if ((system_state & END_MEM) != END_MEM)
      {
         // the REC_PLAY button must be pressed and held for a period of time
         // in order to start the RECORD function
         record_counter++;

         // check if the REC_PLAY button was held down long enough to begin
         // recording (7 x 150 ms = 1.5 seconds)
         // ignore the ERASED and END_MEM state bits, check if the system is
         // idle and can start recording
         if ((record_counter > 7) && ((system_state & 0x03) == IDLE))
         {
            TR2 = 1;                   // turn on the RECORD timer
            system_state |= RECORDING; // start recording

            LED_DCH = &LED0_DC;        // point to the record LED's duty cycle
                                       // address
            Brighten_LED();            // ramp on the record LED

            record_counter = 0;        // reset the counter

            reload_value = PRCHANGE*2; // give a longer time period to check
                                       // the button (effectively debouncing)
         }

         // check if the recording time is running out (button must be held
         // to continue recording)
         if (TR2 == 1)
         {
            if (MEM_END_NEAR_FLAG == 1)
            {
               LED_DCH = &LED0_DC;
               Flutter_LED ();         // indicate to the user that time is
                                       // almost out
            }
         }
         else
         {
            // check if end of the memory has been reached
            if (MEM_END_FLAG == 1)
            {
               // stop recording
               system_state = IDLE | END_MEM;   // indicate that the end of
                                                // memory was reached
               MEM_END_FLAG = 0;

               LED_DCH = &LED0_DC;     // point to the record LED's duty cycle
                                       // address
               Dim_LED ();             // dim off the record LED
            }
         }
      }
   }
   else
   {
      // check if the switch was pressed, but not long enough to start
      // recording
      if (record_counter > 0)
      {
         switch_pressed_flag = 1;      // record the user interaction

         // the system is currently playing - stop playing
         // ignore the ERASED and END_MEM state bits
         if ((system_state & 0x03) == PLAYING)
         {
            system_state &= ~PLAYING;  // clear the PLAYING state bit
            DAC_STOP_FLAG = 1;
            IDA0DAT = 0x0800;

            LED_DCH = &LED1_DC;        // point to the play LED's duty cycle
                                       // address
            Dim_LED ();                // dim off the play LED
         }
         else
         {
            // the system is idle - start playing
            // ignore the ERASED and END_MEM state bits
            if ((system_state & 0x03) == IDLE)
            {
               system_state |= PLAYING;
               TMR3CN = 0x04;          // start the timer controlling the DAC
               REC_END_FLAG = 0;       // reset the "end of recording" flag
               DAC_STOP_FLAG = 0;

               LED_DCH = &LED1_DC;     // point to the play LED's duty cycle
                                       // address
               Brighten_LED ();        // ramp on the play LED
            }
         }

         record_counter = 0;           // switch-press registered, reset

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -