📄 control.c
字号:
/* 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 + -