int main(void) { // PORT config DDRC = 0xFF; PORTC = 0x00; //1111 1111 : 0000 0000 //DDRB = 0xFF; PORTB = 0x00; //1111 1111 : 0000 0000 DDRB = 0x03; PORTB = 0x00; DDRA = 0xFD; PORTA = 0x02; //1111 1101 : 0000 0010 DDRD = 0x0a; PORTD = 0x05; //scheduler setup static task motionSensorPoll, lcdDisplay, uoutTask, RT_Task, M_Task, hvacTask, sensorTimeoutTask; task *tasks[] = { &lcdDisplay, &motionSensorPoll, &uoutTask, &RT_Task, &M_Task, &hvacTask, &sensorTimeoutTask }; unsigned short numTasks = sizeof(tasks)/sizeof(task*); //USART task uoutTask.period = 50; uoutTask.TickFn = &uoutTick; //Remote timeout task RT_Task.period = 1000; RT_Task.TickFn = &remoteTimeoutTask; //Menu task M_Task.period = 100; M_Task.TickFn = &menuTask; //LCD display task lcdDisplay.period = 100; lcdDisplay.TickFn = &lcdDisplayTick; //Motion sensor polling task motionSensorPoll.period = 100; motionSensorPoll.TickFn = &motionSensorTick; //HVAC hvacTask.period = 500; hvacTask.TickFn = &hvacTick; // sensor timeout sensorTimeoutTask.period = 500; sensorTimeoutTask.TickFn = &sensorTimeoutTick; // Init radio spiInitMaster(); nrfMaster(); enableINT0(); // Init USART uoutInit(0); delay_ms(20); uoutSend("\n\r\n\r\n\r"); uoutSend(" Welcome to thermostat!\n\r"); uoutSend("==========================\n\r"); unsigned short gcd = tasksInit(tasks, numTasks); // Timer TimerSet(gcd); TimerOn(); //custom character for lcd unsigned char personPattern[8] = {0x04, 0x0A, 0x04, 0x1f, 0x04, 0x04, 0x0A, 0x11}; unsigned char fanOnPattern[8] = {0x00,0x06,0x1A,0x15,0x0B,0x0C,0x00,0x1F}; unsigned char fanAutoPattern[8] = {0x00,0x06,0x1A,0x15,0x0B,0x0C,0x00,0x00}; unsigned char onPattern[8] = {0x10, 0x12, 0x16, 0x1C, 0x18, 0x10, 0x10, 0x10}; unsigned char offPattern[8] = {0x10, 0x10, 0x10, 0x18, 0x1C, 0x16, 0x12, 0x10}; LCD_build(0,personPattern); LCD_build(1,fanOnPattern); LCD_build(2,fanAutoPattern); LCD_build(3,onPattern); LCD_build(4,offPattern); while(1) { sensor = GetBit(PINA,1); tasksTick(tasks, numTasks); while(!TimerFlag); // Wait for a GCD period TimerFlag = 0; } return 0; }
void stateMachine(void) { /****************************************************************************** * INIT State * Executes at boot up or when the processor is reset. * ******************************************************************************/ if (state == STATE_INIT) { initPeripherals(); initInterrupts(); unsigned int checkRead; checkRead = M24LC64FReadWord(CHECK_ADDRESS, M24LC64F_ADDRESS_0); __delay32(EEPROM_DELAY*10); if (checkRead) { homePos = 0; M24LC64FWriteWord(HOME_ADDRESS, homePos ,M24LC64F_ADDRESS_0); __delay32(EEPROM_DELAY*10); M24LC64FWriteWord(CHECK_ADDRESS, homePos ,M24LC64F_ADDRESS_0); __delay32(EEPROM_DELAY*10); } homePos = M24LC64FReadWord(HOME_ADDRESS, M24LC64F_ADDRESS_0); /* Retrieve the stored delay value */ //homePos = 0; __delay32(EEPROM_DELAY*10); motorPos = M24LC64FReadWord(MOTOR_POS_ADDRESS, M24LC64F_ADDRESS_0); /* Retrieve the stored Motor Position value */ //motorPos = 0; __delay32(EEPROM_DELAY*10); initPWM(); initADC(); initTMR(); indexMotor(homePos, MAX_STEPS); //MAX_STEPS is 250, moveMotor() steps 4 motor steps at a time. } /* End of INIT State*/ /****************************************************************************** * WARM_UP State * As long as the warm up complete signal is not given the AFC will remain in * this state. ******************************************************************************/ /*if (state == STATE_WARM_UP) { triggerINT = disableINT0(); //updateAnalogOut(homePos); bufferFull = 0; }*/ /****************************************************************************** * MAN State * Executes if the user selected MAN using the proper hardware control signals * This state enables the user to manually change configuration parameters and * the position of the motor. ******************************************************************************/ if (state == STATE_MAN) { if (triggerINT || IFS0bits.INT0IF) /* Disabling the external interrupt INT0, only needed in AFC state */ { triggerINT = disableINT0(); } if (!MAN_DELAY_CTRL == 1) /* Check if we are setting Motor Position (= 1) or Delay (= 0) */ { motorOrDelay = 0; homePos = motorPos; updateAnalogOut(homePos); M24LC64FWriteWord(HOME_ADDRESS, homePos ,M24LC64F_ADDRESS_0); } else { motorOrDelay = 1; updateAnalogOut(motorPos); } if (!MAN_DELAY_UP == 1) { __delay32(EEPROM_DELAY*10); /* Debouncing (50ms Delay) can be made faster for practical application */ if (motorOrDelay == 1) { unsigned int countTemp = 0; count =0; //do{ while(!MAN_DELAY_UP == 1) { //__delay32(EEPROM_DELAY*4); setDir = FORWARD; motorPos++; moveMotor(setDir, TIMER_PERIOD2); while(count==countTemp); countTemp++; updateAnalogOut(motorPos); } //M24LC64FWriteWord(MOTOR_POS_ADDRESS, motorPos, M24LC64F_ADDRESS_0); //}while (count <500); setDir = STOP; moveMotor(setDir, TIMER_PERIOD2); } else { if (homePos >= MAX_STEPS) homePos = MAX_STEPS; else homePos ++; updateAnalogOut(homePos); M24LC64FWriteWord(HOME_ADDRESS, homePos ,M24LC64F_ADDRESS_0); } } if (!MAN_DELAY_DOWN == 1) { __delay32(EEPROM_DELAY*10); /* Debouncing (50ms Delay) can be made faster for practical application */ if (motorOrDelay == 1) { unsigned int countTemp = 0; count =0; //do{ while(!MAN_DELAY_DOWN == 1) { //__delay32(EEPROM_DELAY*4); setDir = REVERSE; motorPos--; moveMotor(setDir, TIMER_PERIOD2); while(count==countTemp); countTemp++; updateAnalogOut(motorPos); } //M24LC64FWriteWord(MOTOR_POS_ADDRESS, motorPos, M24LC64F_ADDRESS_0); //}while (count <500); setDir = STOP; moveMotor(setDir, TIMER_PERIOD2); } else { if (homePos <= MIN_DELAY) homePos = 0; else homePos --; updateAnalogOut(homePos); M24LC64FWriteWord(HOME_ADDRESS, homePos ,M24LC64F_ADDRESS_0); } } } /* End of MAN State*/ /****************************************************************************** * AFC State * Executes if the user selected AFC using the proper hardware control signals * This state locks all manual control and the AFC controls the motor position ******************************************************************************/ if (state == STATE_AFC) { if (!MAN_DELAY_UP == 1) { indexMotor(motorPos, MAX_STEPS); } if (!MAN_DELAY_DOWN == 1) { indexMotor(homePos, MAX_STEPS); } heatPerPulse = 0; if (sampleTrigger) { sampleTrigger = 0; prevReflectedPower = 0; /* The ADC is triggered by a special comparison event of the PWM module */ ADCPC2bits.SWTRG5 = 1; /*Trigger ADC to convert AN11 (Heat Per Pulse input from PLC) */ while(!ADSTATbits.P5RDY); heatPerPulse = ADCBUF11; ADCPC0bits.SWTRG0 = 1; /*Trigger ADC to convert AN0 (Reflected port) */ while(!ADSTATbits.P0RDY); prevReflectedPower = reflectedPower; reflectedPower = ADCBUF0; // delta = ADCBUF1; ADSTATbits.P0RDY = 0; /* Clear the ADSTAT bits */ //ADSTATbits.P1RDY = 0; ADSTATbits.P5RDY = 0; /*__asm__ volatile ("clr B"); __asm__ volatile ("lac %0,B":"+r"(heatPerPulse)); __asm__ volatile ("sftac B,#16"); __asm__ volatile ("add A");*/ heatAccumulator += heatPerPulse; /*No buffer*/ error = (int)(reflectedPower - prevReflectedPower); /* Filtering using a FIFO buffer*/ /*errorArray[strPTR] = (int)(reflectedPower - prevReflectedPower); strPTR++; if (strPTR >= endPTR) { bufferFull = 1; strPTR = 0; } if (bufferFull == 1) { int i; for (i = 0; i < endPTR; i++) { error += errorArray[i]; } error = error >> 5; //BUFFER_SIZE = 32 -> 2^5 = 32 }*/ /* else { int j; for (j = 0; j < strPTR; j++) { error += errorArray[j]; } error = error/strPTR; }*/ triggerINT = enableINT0(); //calcError(); /* Calculate Error based on A/D results for reflected power*/ //moveMotor(setDir, motorStep); //while (T2CONbits.TON); } if (thermalCounter == 50000) //Using the PWM special event interrupt to increment every TMR1 period match (~20us) 5000*20uS ~= 100mS { /*Reduce the accumulator by the cool rate coef.*/ heatAccumulator -= (heatAccumulator>>COOL_SHIFTS)*COOL_RATE; } /* Outer loop, calculates Thermal Drift effects and moves motor proactivley (Feedforward)*/ target = homePos + calcThermalError() + error; moveMotorThermal(); }