$TITLE(MAIN.A51) ; Module MAIN.A51 Rev 1.0 $XREF ; By Frank Fritz -- Copyright 1997 (C) Frank Fritz $DEBUG ; $NOLIST ; switch off generation of the listing file $NOMOD51 ; switch off 8051 controller defaults and use... $INCLUDE (c:\fsi\inc\reg51.inc) ; Include the 8051 register definitions/declarations. $LIST ; switch on listing. EXTRN DATA (temperature, intr_count, disp_val, ee_address, ee_lsb, ee_msb, ee_cntrl, pwm_cntr, error, cv, duty_cycle, i_old_h, i_old_l) EXTRN DATA (active_pb, limit_cntr_lo, limit_cntr_hi, old_temp, h_list_dptr, c_list_dptr, ai_cntr_hi, ai_cntr_lo, test_pb, ai_old_temp) EXTRN XDATA (h_list, c_list) EXTRN BIT (on_targ_flag, pid_error_flag, limit_flag, DS1620_FLAG, eesv_flag, neg_flag, while_flag1, mode, while_dtt_flag, ai_tl_flag) EXTRN BIT (bit_defined_flag, error_flag) EXTRN NUMBER (ai_cntr_hi_val, ai_cntr_lo_val, setpoint, write_ee, ewen, ewds) EXTRN CODE (while_ee, init) PUBLIC main MAINLINE SEGMENT CODE RSEG MAINLINE ; switch to mainline code segment USING 0 ; Use register set 0 ; ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ; Module: MAIN ; Revision: 1.0 ; Date: August 8, 1997 ; By: Frank Fritz ; About: The MAIN module serves as the mainline code which runs in the foreground of the program (i.e. not interrupt ; driven). The function of MAIN is to wait in an endless loop until the AI function is invoked from the INT_0 module, ; and then execute the body of the AI Training/Learning algorithm. Upon completion of the AI algorithm, conditions ; are reset, and MAIN continues to execute in its endless loop until another AI request is made. ; ; The AI Learning Algorithm in General: ; ; 1. Wait for stable temperature. ; 2. Select the first output-port bit (P1.0). ; 3. Search h_list and c_list to see if selected bit is already defined. ; 4. If Bit is defined, select next bit position. Goto #3. ; 5. If bit is undefined, turn on bit (100%). ; 6. Wait a specific amount of time. ; 7. If no temperature change, and not at the end of the port, select next bit position. Goto #3. ; 8. If temperature change increases the error, select next bit and Goto #3, else Goto #9. ; 9. If temperature at the setpoint temperature, then goto #10. else goto #6. ; 10. Update the appropriate list with the new port bit location. ; 11. Save new list configuration to the EEPROM. ; 12. Clear flags, return to main loop. ; ; Program Flow ; Called From: INIT ; Input: Nothing ; Output: Nothing ; Modifies: h_list and c_list lists ; Calls: while_ee ; ; History: Date Comments ; ------------ -------------------------------------------------------------------------------------------------------------------------------- ; 08/08/97 Developed Rev 1.0 ; ; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- main: JNB ai_tl_flag,main ; If AI Training/Learning is not required, stay in this loop. stable: MOV ai_old_temp, temperature ; PID control is locked out from INTR 0, so no control changes are being made. MOV ai_cntr_hi,#ai_cntr_hi_val ; Phase 1: Wait for stable conditions (i.e. no temperature change for (t) minutes). MOV ai_cntr_lo,#ai_cntr_lo_val ; Reload count-down values. (Counters are serviced in INTR_0 module). stable_0: MOV A,temperature ; Check for temperature change. CJNE A,ai_old_temp,stable ; If old and new temp's aren't equal, reset counter. MOV A,ai_cntr_hi ; - JNZ stable_0 ; - ; Perform a Depth-First Search (bit P1.0 to P1.4) MOV test_pb,#00H ; Initialize Learning algotithm - Test Port Bit to bit #0 (P1.0). ; Test to see if bit in test_pb already exists in a list. ai_0: CLR bit_defined_flag ; Set bit_defined_flag to 0 (not defined). SETB F0 ; Using bit F0 as a loop marker. MOV DPTR,#h_list+1 ; Initailize data pointer to heat list + 1 (first valid port-bit location). ai_1: MOV R0,#05H ; R0 is the list element counter. ai_2: MOVX A,@DPTR ; Get list data from RAM. CJNE A,test_pb,ai_3 ; If List data port-bit <> to current test port bit, then keep searching. SETB bit_defined_flag ; List port-bit was = to test bit, so this bit already exists in a list - set flag. ai_3: INC DPTR ; Extend search to next port-bit. DJNZ R0,ai_2 ; If we are not at the end of the list, get next list element. MOV DPTR,#c_list+1 ; Now check the cool list. JBC F0,ai_1 ; Clear the F0 bit and jump back to body of search algorithm. JNB bit_defined_flag,ai_5 ; If test_pb bit is undefined, goto label 5. INC test_pb ; Test_pb bit was already defined, try the next port bit. MOV A,#05H ; Test to see if we are at the last possible output port bit (P1.4). CJNE A,test_pb,ai_0 ; If NOT at P1.5, then jump back into list-bit compair routine. SETB error_flag ; If we got to here then there are no available output port bits to do the job. ai_4: MOV disp_val,#0E1H ; Error condition #1. Display error code '01' at display. SJMP ai_4 ; Loop forever. ai_5: LCALL ai_set_pb ; Enable the test bit at 100% (full on). MOV R1,temperature ; Record temperature in R1. CLR C ; Find Error. MOV A,#setpoint ; - SUBB A,R1 ; Acc = setpoint - current temperature. JNC ai_6 ; If error was negative, invert to positive. MOV R3,A ; Invert error. CLR A ; CLR C ; SUBB A,R3 ; Acc = 0 - error. ai_6: MOV R2,A ; R2 = initial error. MOV ai_cntr_hi,#ai_cntr_hi_val ; Phase 2: Wait for stable conditions (i.e. no temperature change for (t) minutes). MOV ai_cntr_lo,#ai_cntr_lo_val ; Reload count-down values. (Counters are serviced in INTR_0 module). ai_7: MOV A,temperature ; Is temp = old temp? CLR C ; - SUBB A,R1 ; - JNZ ai_9 ; If not, goto label 9. MOV A,ai_cntr_hi ; Temp = old_temp. Wait for timeout. JNZ ai_7 ; - ai_8: LCALL ai_clr_pb ; NO temperature change was observed, turn off this bit, try next one. INC test_pb ; Try next Port Bit. SJMP ai_0 ; - ai_9: MOV R1,temperature ; Temperature change. Is it to or from setpoint? CLR C ; Find error. MOV A,#setpoint ; - SUBB A,R1 ; Acc = setpoint - current temperature. JNC ai_10 ; If error was neg (i.e temp > setpoint), invert to positive. MOV R3,A ; - CLR A ; - CLR C ; - SUBB A,R3 ; Acc = new error. ai_10: CLR C ; - SUBB A,R2 ; Acc = Error - Old Error. (IF C = 1, TO setpoint. IF C = 0, FROM setpoint). JNC ai_8 ; If moving FROM setpoint (bad), disable this bit (off). Try next bit (if any). MOV A,#setpoint ; Are we at setpoint yet? CLR C ; - SUBB A,temperature ; 0 if at setpoint. JNZ ai_5 ; If not at setpoint, loop back to 'wait for temperature change'. ai_11: JNB mode,ai_12 ; At setpoint. This port bit (device) will do the job. Update the proper list. MOV DPTR,#c_list ; Setup for updating cool list. INC c_list_dptr ; Point to next location. MOV R0,c_list_dptr ; - SJMP ai_13 ; - ai_12: MOV DPTR,#h_list ; Setup for updating heat list. INC h_list_dptr ; Point to next location. MOV R0,h_list_dptr ; - ai_13: MOV A,DPL ; Setup address. ADD A,R0 ; Acc = low address. MOV DPL,A ; DPTR correct. MOV A,test_pb ; Acc = new port bit location. MOVX @DPTR,A ; Update the list. ; Save lists to EEPROM. MOV ee_cntrl,#ewen ; Enable write to EEPROM. LCALL while_ee ; Wait for EEPROM to work. MOV ee_cntrl,#write_ee ; Initialize EEPROM to WRITE mode. MOV ee_address,#00H ; Set EEPROM address to first memory location. MOV DPTR,#h_list ; Set Data Pointer to first (heat) list of RAM. LCALL save_to_ee ; Save the HEAT list data to the EEPROM. MOV DPTR,#c_list ; Now setup to save the second (COOL) list data from RAM to the EEPROM. LCALL save_to_ee ; Save COOL list data. MOV ee_cntrl,#ewds ; Disable WRITE to EEPROM. LCALL while_ee ; Wait for EEPROM to work. ; Finished with 'Save RAM Data to EEPROM'. MOV active_pb,test_pb ; Make the active port bit the new (test) port bit. CLR ai_tl_flag ; End of AI algorithm, resume normal control sequence. LJMP main ; Loop back to MAIN. Wait for next AI Training / Learning condition. ; --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ; Common algorithm to 'Save RAM Data to EEPROM'. save_to_ee: MOV R0,#04H ; R0 is the counter for number of byte-pairs to transfer. save_to_ee0: MOVX A,@DPTR ; Get list data from RAM. MOV ee_msb,A ; Move list data to first eeprom temp storage byte. INC DPTR ; Point to next list location. MOVX A,@DPTR ; Get next list data from RAM. MOV ee_lsb,A ; Move list data to second eeprom temp storage byte. LCALL while_ee ; Wait for EEPROM to work. INC DPTR ; Point to next RAM list address. INC ee_address ; Point to next EEPROM address. DJNZ R0,save_to_ee0 ; If not at the end, loop back for remaining bytes. RET ; Exit. ; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ; Module: AI_SET_PB, AI_CLEAR_PB ; Revision: 1.0 ; Date: August 8, 1997 ; By: Frank Fritz ; About: The ai_clr_pb / ai_set_pb will clear (ai_clr_pb) or turn on (ai_set_pb) the port bit specified in variable test_pb. ; ; Program Flow ; Called From: MAIN ; Input: test_pb ; Output: Sets or Clears the desired port bit. ; Modifies: Nothing ; Calls: Nothing ; ; History: Date Comments ; ------------ -------------------------------------------------------------------------------------------------------------------------------- ; 08/08/97 Developed Rev 1.0 ; ; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ai_clr_pb: MOV DPTR,#ai_table_c ; Load table base address to clear ACTIVE bit. SJMP ai_pb_op ; Do rest of routine. ai_set_pb: MOV DPTR,#ai_table_s ; Load table base address to set ACTIVE bit. ai_pb_op: MOV A,test_pb ; Load test port bit to Acc. MOV B,#03H ; Do offset calculation. MUL AB ; Acc has offset. JMP @A+DPTR ; Branch to appropriate table position. ai_table_s: SETB P1.0 ; Set active port bit P1.0. RET ; Return to AI controller. SETB P1.1 ; Set active port bit P1.1. RET ; - SETB P1.2 ; Set active port bit P1.2. RET ; - SETB P1.3 ; Set active port bit P1.3. RET ; - SETB P1.4 ; Set active port bit P1.4. RET ; - ai_table_c: CLR P1.0 ; Clear active port bit P1.0. RET ; Return to AI controller. CLR P1.1 ; Clear active port bit P1.1. RET ; - CLR P1.2 ; Clear active port bit P1.2. RET ; - CLR P1.3 ; Clear active port bit P1.3. RET ; - CLR P1.4 ; Clear active port bit P1.4. RET ; - ; ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- END