/********************************** Nick Sitarski Vladi Gergov Project ECE 473 W 2003 Professor Shaout **********************************/ /********************************* INCLUDES **********************************/ #include #include #include /********************************* GLOBAL VARIABLES **********************************/ unsigned int sensor; unsigned int ontime; unsigned int offtime; unsigned int avgtemp; unsigned int dummy; unsigned char sensor1; unsigned char onoroff; unsigned char temperature; unsigned int temparray[255]; /********************************* BIT MASK **********************************/ #define bit0 0x01 #define bit1 0x02 #define bit2 0x04 #define bit3 0x08 #define bit4 0x10 #define bit5 0x20 #define bit6 0x40 #define bit7 0x80 /********************************* PRAGMA STATEMENTS **********************************/ #pragma interrupt_handler ThreadSwitch() /************************************************************* Function: initialize Purpose: This function initializes the hc11 board. Powers up the A/D converter, waits untill its powered up via the 100 us delay, sets up initial fan speed to 50% duty cycle, sets motor on or off status flag to 0 meaning motor is off, and initializes the sensor variable to 256. Inputs: None Outputs: None **************************************************************/ void initialize() { int i; int j; OPTION = (OPTION | 0xC0); // Power up A/D, set csel for (i=0; i<200; i++) // Delay 100 us dummy = i; ADCTL = 0X31; // Set SCAN & MULT for the A/D ontime = 10000; // Initialize ontime to 50% duty offtime = 10000; // Initialize offtime to 50% duty onoroff = 0; // Initialize global motor flag PORTA = 0; // Stop the motor sensor = 256; // Initialize sensor to 256 for (j=0; j<256; j++){ temparray[j] = (84.147-(14.637 * (j * .019531))); } } /************************************************************* Function: atod Purpose: This function initializes the hc11 board. Powers up the A/D converter, waits untill its powered up via the 100 us delay, sets up initial fan speed to 50% duty cycle, sets motor on or off status flag to 0 meaning motor is off, and initializes the sensor variable to 256. Inputs: None Outputs: None **************************************************************/ void atod( void ) { int i; while(1) { sensor1 = ADR2; // Get data from A/D converter //printf("%d\n", sensor); ontime = (((256 - sensor) * 30) + 10000); offtime = 20000 - ontime; temperature = temparray[sensor1]; } } /************************************************************* Function: temp Purpose: This function goes in an infinite loop Inputs: None Outputs: None **************************************************************/ void temp( void ){ int i; while(1) { for (i=0; i<2000; i++); printf("\n%d",temperature); } } /************************************************************* Function: tempcheck Purpose: This function checks to see if the sensor has gotten in the critical tempeture range. It the ontime is 16k which is equivalent to 70 Degrees celcius then print Too Hot on the screen. Inputs: None Outputs: None **************************************************************/ void tempcheck( void ) { while(1) { if (ontime > 16000) { asm("sei"); printf("\nToo Hot"); asm("cli"); } } } /************************************************************* Structure: TCB Purpose: This structure is the thread control block which has all the info required for the Thread switch interrupt to control the stack pointer, registers, and the id of eatch thread. Inputs: None Outputs: None **************************************************************/ struct TCB { struct TCB *Next; unsigned char *SP; unsigned int ID; unsigned char MoreStack[150]; unsigned char CCR; unsigned char RegB; unsigned char RegA; unsigned int RegX; unsigned int RegY; void (*PC)(void); }; typedef struct TCB TCBType; typedef TCBType * TCBPtr; TCBType sys[3]={ { &sys[1], &sys[0].MoreStack[149], 1, { 0}, 0x40,0,0,0,0, atod, }, { &sys[2], &sys[1].MoreStack[149], 2, { 0}, 0x40,0,0,0,0, temp, }, { &sys[0], &sys[2].MoreStack[149], 4, { 0}, 0x40,0,0,0,0, tempcheck, } }; TCBPtr RunPt; /************************************************************* Function: ThreadSwitch Purpose: This function is used to switch between the three threads that we have. It also uses the onoroff flagg to decide if our fan is off or on and schedule the interrupt accordingly. If the fan is off then it will be turned on and TOC3 will be rescheduled with ontime. If the fan is on then it will be turned off and TOC3 will be rescheduled with offtime. Inputs: None Outputs: None **************************************************************/ void ThreadSwitch( void ) { asm("ldx _RunPt\n" "sts 2,x"); RunPt=RunPt->Next; // Set the RunPt to point the the next thread PORTD=RunPt->ID; // Display the current Thread on PORTD asm("ldx _RunPt\n" "lds 2,x"); if (onoroff == 0) { onoroff = 1; // Set the global fan status flag PORTA = bit6; // Turn the motor on TOC3 += ontime; // Reschedule the OC3 with ontime } else { onoroff = 0; // Clear the global fan status flag PORTA = 0x00; // Turn the motor off TOC3 += offtime;// Reschedule the OC3 with offtime } TFLG1=0x20; // Clear the OC3 Interrupt flag } /************************************************************* Function: main Purpose: The main function calls the initialize function to set up the hc11 board, then sets up the the run pointer to go to the first thread, enables interrupts, and it also uses the onoroff flagg to decide if our fan is off or on and schedule the interrupt accordingly. If the fan is off then it will be turned on and TOC3 will be rescheduled with ontime. If the fan is on then it will be turned off and TOC3 will be rescheduled with offtime. Also sets portd to the current interrupt. Inputs: None Outputs: None **************************************************************/ void main( void ) { initialize(); // Initialize the hc11 RunPt=&sys[0]; // Setup the pointer to point to first thread asm("sei"); // Enable interrupts TOC3vector=&ThreadSwitch; // Setup the vector jump table TFLG1 = 0x20; // Clear the OC3 Interrupt Flag TMSK1 = 0x20; // Enable the OC3 Interrupt if (onoroff == 0) { onoroff = 1; // Set the global fan status flag PORTA = bit6; // Turn the motor on TCNT += ontime; // Reschedule the OC3 interrupt with ontime } else { onoroff = 0; // Clear the global fan status flag PORTA = 0x00; // Clear PortA which clears the motor TCNT += offtime; // Reschedule the OC3 interrupt with offtime } PORTD=RunPt->ID // Display the current thread on PORTD asm("ldx _RunPt\n" "lds 2,x\n" "cli\n" "rti"); }