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

📄 control.c

📁 熟悉verilog,帮助初学者尽快掌握verilog
💻 C
📖 第 1 页 / 共 3 页
字号:

   /* Update the Service Soon LED */
   if (bServiceSoon) {
      output_high (SERVICE_LED);
	}
   else {
		output_low (SERVICE_LED);
   }

   /* Control charger relay and charger LED */
   if (bCharging) {
      bEverCharged = TRUE;
      output_high (CHARGE_RLY);
      output_high (CHARGE_LED);
   }
   else {
      output_low (CHARGE_RLY);
      output_low (CHARGE_LED);
   }

   }
}  /*********** End of the Main Loop **************/




/***********************************************/
/*                                             */
/*    Low-Level I/O Functions                  */
/*                                             */
/***********************************************/

/* Called on power up to see if Self Test needs to be run. */
int SelfTestRequested (void)
{
   if (!input(PIN_C5))
      return TRUE;
   else
      return FALSE;
}


/* Start Motor */
void StartMotor (void)
{
   bMotorOn = TRUE;
	output_high (MOTOR_RLY);
}

/* Stop Motor */
void StopMotor (void)
{
   bMotorOn = FALSE;
   output_low (MOTOR_RLY);
}

/* Forward */
void Forward (void)
{
   output_low (DIR_RLY);
}

/* Reverse */
void Reverse (void)
{
   output_high (DIR_RLY);
}

/* Return true if the retracted sensor is active */
int SenseRetracted (void)
{
   return input (RETRACTED);
}

/* Return true if the forward over pressure sensor is active */
int SenseExtended (void)
{
   /* Sensor is asserted when grounded, or zero, so invert */
   return input (EXTENDED);
}

/* Called on power up to give operator warm fuzzy that all is working. */
void LampTest (void)
{
	/* Light all the LEDs */
   output_high (CYCLE1_LED);
	output_high (CYCLE2_LED);
   output_high (CYCLE3_LED);
   output_high (SPA_LED);
   output_high (CHARGE_LED);
   output_high (SERVICE_LED);

   /* Delay for 1/4 second */
   byTicks_Delay = TICKS_LAMPTEST;
   while (byTicks_Delay != 0);

   /* Extinguish all the LEDs */
   output_low (CYCLE1_LED);
   output_low (CYCLE2_LED);
   output_low (CYCLE3_LED);
   output_low (SPA_LED);
   output_low (CHARGE_LED);
   output_low (SERVICE_LED);
}

/*****************************************************************************/
/*   TIMER INTERRUPT                                                         */
/*                                                                           */
/*   Timer Interrupt occurs at every overflow of the free-running counter.   */
/*   We use this simply as a timebase.  This interrupt service routine       */
/*   will decrement any ticks we are managing.  Ticks are decremented        */
/*   down to zero and then they are not decremented further.  Main thread    */
/*   routines read these tick counters and set them when they need a         */
/*   countdown.                                                              */
/*****************************************************************************/

#int_timer1
void TimerInterrupt (void)
{
   /* Decrement every tick counter we are currently using. */
   if (nTicks_Reverse > 0)
      nTicks_Reverse--;
   if (nTicks_Forward > 0)
      nTicks_Forward--;
	if (byTicks_CycleSwitch > 0)
      byTicks_CycleSwitch--;
	if (byTicks_Delay > 0)
      byTicks_Delay--;
   if (byTicks_Display > 0)
      byTicks_Display--;
   if (byTicks_Charger_Hysterysis > 0)
      byTicks_Charger_Hysterysis--;
   if (byTicks_Initial_Charge > 0)
      byTicks_Initial_Charge--;

   /* Interrupt remains enabled.. No need to do anything.. */
}


/**************************************************************/
/*                                                            */
/*                        A/D Drivers                         */
/*                                                            */
/**************************************************************/

/*
	 A/D Has up to 8 channels it can sample.  Here is our current
    channel allocation:

       Channel#    Usage
	  0        Battery Voltage
	  1        Multiple Cycles Enable    (Low means disabled)
	  2        Initial Retraction Enable (Low means disabled)
	  3        Not Used.
	  4        Not Used.
	  5        Not Used.
	  6        Not Used.
	  7        Not Used.
*/

void GetBatteryVoltage (void)
{
   /* Battery Voltage is wired to input channel #0 */
   GetAD (0);

   /* Copy to the global variable */
	nBatteryVoltage = nADSample;
}

int MultiCyclesEnabled (void)
{
   /* Multicycle option strap is wired to input channel #1 */
   GetAD (1);

   /* Copy to the global variable */
   if (nADSample < 0x0100) {
      /* Low voltage, jumper is IN, therefore option is DISABLED */
      return FALSE;
   }
   else {
      /* High voltage, jumper is OUT, therefore option is ENABLED */
      return TRUE;
   }
}

int InitialRetractsEnabled (void)
{
   /* Multicycle option strap is wired to input channel #4 */
   GetAD (2);

   /* Copy to the global variable */
   if (nADSample < 0x0100) {
      /* Low voltage, jumper is IN, therefore option is DISABLED */
      return FALSE;
   }
   else {
      /* High voltage, jumper is OUT, therefore option is ENABLED */
      return TRUE;
   }
}

/* Here's the basic driver to the MAXIM chip */
void GetAD (byte byChannel)
{
   byte byControlWord;
   byte byBitCounter;

   /* Read the A/D chip.

      Control Byte is:

	 1ccc1111

      Where ccc is the channel.  Now, the channel encoding
      is a little screwy.  It depends on whether it is in
      unipolar or differential mode.  This circuit is wired
      up as unipolar and is encoded as follows:

	 Channel   ccc
	 -------------
	    0      000
	    1      100
		 2      001
	    3      101
	    4      010
	    5      110
		 6      011
	    7      111

      The other bits control unipolar versus differential and other neat
      stuff not needed for this project.  See the MAXIM data sheet for
      details.
   */

   switch (byChannel) {
      case 0:  byControlWord = 0b10001111; break;
      case 1:  byControlWord = 0b11001111; break;
      case 2:  byControlWord = 0b10011111; break;
      case 3:  byControlWord = 0b11011111; break;
      case 4:  byControlWord = 0b10101111; break;
      case 5:  byControlWord = 0b11101111; break;
      case 6:  byControlWord = 0b10111111; break;
		case 7:  byControlWord = 0b11111111; break;
      default: printf ("Bad A/D Channel!\r");
	 return;
      break;
	}

   nADSample = 0;

   output_low (ADC_CS);

   /* Shift the control byte into A/D */
   for (byBitCounter = 0; byBitCounter < 8; byBitCounter++) {
      if ((byControlWord & 0x80) == 0x80) {
	 output_high (ADC_DIN);
      }
      else {
	 output_low (ADC_DIN);
      }
      // Pulse clock
      output_high (ADC_CLK);
		output_low  (ADC_CLK);
      byControlWord = byControlWord << 1;
      delay_us(50);
   }


   /* Shift out 10 bits of data from A/D */
   for (byBitCounter = 0; byBitCounter < 10; byBitCounter++) {
      /* A/D outputs the next converted bit after the falling edge */
      output_high (ADC_CLK);
      output_low  (ADC_CLK);

      /* Get the bit */
      shift_left(&nADSample,2,input(ADC_DOUT));
      delay_us(50);
   }

   /* All done. Bring CS back HI */
   output_high (ADC_CS);
}

/**************************************************************/
/*                                                            */
/*                        Self Test                           */
/*                                                            */
/*  This Self Test is triggered by state of PIN_C5 on         */
/*  power up.  We are using a special test jig for            */
/*  this test.  This is done at manufacturing time.           */
/*  Look at first part of main() to see how self test         */
/*  is triggered.                                             */
/*                                                            */
/*  The goal of self test is to catch basic board-level       */
/*  problems, unprogrammed chips, etc.  This is NOT a         */
/*  performance tester.  We test that relays flip and the     */
/*  switches are connected.  We also test LEDs and test that  */
/*  the A/D seems to react to changes in voltage.             */
/*  This will catch most basic manufacturing problems.        */
/*                                                            */
/*  See the additional testing procedure for exactly what     */
/*  steps to do for the test.                                 */
/*                                                            */
/**************************************************************/
void SelfTest ()
{
	/* Phase 1.
      Energize each relay and see if switch detects a low.
      The test jig is wired to help us with this...
      If not, test fails.  First, check all switch inputs
      which should initially all be high.
   */

   if (!input(CYCLE_SW) ||
       !input(RECYCLE_SW) ||
       !input(RETRACTED) ||
       !input (EXTENDED)) {
      printf ("*");  /* for the ambitious technician... */
      SelfTestFail ();
   }

   output_high (MOTOR_RLY);
   delay_ms (1000);
   if (input(CYCLE_SW)) {
      printf ("a");  /* for the ambitious technician... */
		SelfTestFail ();
	}

   output_high (RECYCLE_RLY);
   delay_ms (1000);
   if (input(RECYCLE_SW)) {
      printf ("b");  /* for the ambitious technician... */
      SelfTestFail ();
   }

   output_high (CHARGE_RLY);
   delay_ms (1000);
   if (input(RETRACTED)) {
      printf ("c"); /* for the ambitious technician... */
      SelfTestFail ();
   }

   output_high (DIR_RLY);
   delay_ms (1000);
   if (input(EXTENDED)) {
		printf ("d"); /* for the ambitious technician... */
		SelfTestFail ();
   }


   /* Phase 2.
      Enter into a loop where we sample the A/D voltage and
      indicate on the LEDs that we are reading a voltage.
      We aren't concerned about an actual, accurate indication.
      We want to see all the LEDs change and we want to see
      that the voltage affects this process.
   */
   printf ("!");    /* for the ambitious technician... */
   for (;;) {
      delay_ms (255);

      output_low (CYCLE3_LED);
      output_low (CYCLE2_LED);
      output_low (CYCLE1_LED);
      output_low (SPA_LED);
		output_low (CHARGE_LED);
		output_low (SERVICE_LED);

      GetBatteryVoltage();
      /* The test fixture test voltage ranges approx. between 1.77V and 3.22V.
	 This corresponds to samples between 442 - 805.

	 Also, to display a "bar graph" indicator of this voltage, order
	 the LEDs as they physically are ordered on the board.
      */
      if (nADSample > 600) {
	 output_high (CYCLE3_LED);
	 if (nADSample > 620) {
	    output_high (CYCLE2_LED);
	    if (nADSample > 640) {
	       output_high (CYCLE1_LED);
	       if (nADSample > 660) {
		  output_high (SERVICE_LED);
		  if (nADSample > 680) {
		     output_high (SPA_LED);
			  if (nADSample > 700) {
			output_high (CHARGE_LED);
		     }
		  }
	       }
	    }
	 }
      }
   }
}

/* Need to do something to indicate to the human that test has failed...
   Just blink LEDs forever... */
void SelfTestFail ()
{
   for (;;) {
      /* Light all the LEDs */
      output_high (CYCLE1_LED);
      output_high (CYCLE2_LED);
      output_high (CYCLE3_LED);
      output_high (SPA_LED);
		output_high (CHARGE_LED);
      output_high (SERVICE_LED);

      /* Delay for 1/4 second */
      delay_ms (250);

      /* Extinguish all the LEDs */
      output_low (CYCLE1_LED);
      output_low (CYCLE2_LED);
      output_low (CYCLE3_LED);
      output_low (SPA_LED);
      output_low (CHARGE_LED);
      output_low (SERVICE_LED);

      /* Delay for 1/4 second */
      delay_ms (1000);
   }
}

/* END!  */

⌨️ 快捷键说明

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