00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "pic24_all.h"
00030 #include <stdio.h>
00031 #include "reflow_oven.h"
00032
00040 static inline void CONFIG_ZEROCROSS_ENABLE() {
00041 CONFIG_RB6_AS_DIG_INPUT();
00042 ENABLE_RB6_PULLUP();
00043 CONFIG_INT1_TO_RP(6);
00044 DELAY_US(1);
00045 _INT1IF = 0;
00046 _INT1IP = 1;
00047 _INT1EP = 0;
00048 _INT1IE = 1;
00049 }
00050
00051 void configTimer2(void) {
00052 T2CON = T2_OFF | T2_IDLE_CON | T2_GATE_OFF
00053 | T2_32BIT_MODE_OFF
00054 | T2_SOURCE_INT
00055 | T2_PS_1_8 ;
00056 PR2 = 0xFFFF;
00057 TMR2 = 0;
00058 }
00059
00060 #define TRIAC_PW_HIGH 100 //in microseconds, triac gate pulse width high
00061 #define HALF_CYCLE 8000 //in microseconds, part of half-cycle to use for triggering
00062 #define CYCLE_OFFSET 200 //don't start right at zero crossing
00063 uint8 u8_currPowerSetting;
00064 uint16 u16_halfCycleTicks;
00065 uint16 u16_triacPWHighTicks;
00066 uint16 u16_cycleOffsetTicks;
00067
00068 void configOutputCapture1(void) {
00069 T2CONbits.TON = 0;
00070 TMR2 = 0;
00071 CONFIG_OC1_TO_RP(14);
00072 OC1R = 1;
00073 OC1RS = 2;
00074
00075 OC1CON = OC_TIMER2_SRC |
00076 OC_SINGLE_PULSE;
00077 T2CONbits.TON = 1;
00078 }
00079
00080
00081
00082
00083
00084
00085 static inline void TRIAC_ON() {
00086 uint32 u32_x;
00087 T2CONbits.TON = 0;
00088 TMR2 = 0;
00089
00090 u32_x = u16_halfCycleTicks;
00091 u32_x = (u32_x * u8_currPowerSetting)/MAX_POWER_SETTING;
00092 u32_x = u16_halfCycleTicks - u32_x;
00093 OC1R = u32_x+u16_cycleOffsetTicks;
00094 OC1RS = u32_x+u16_triacPWHighTicks+u16_cycleOffsetTicks;
00095 OC1CON = OC_TIMER2_SRC |
00096 OC_SINGLE_PULSE;
00097 T2CONbits.TON = 1;
00098 }
00099
00100
00101 void configureTriacControl() {
00102 configTimer2();
00103 configOutputCapture1();
00104 u16_halfCycleTicks = usToU16Ticks(HALF_CYCLE,getTimerPrescale(T2CONbits));
00105 u16_triacPWHighTicks = usToU16Ticks(TRIAC_PW_HIGH, getTimerPrescale(T2CONbits));
00106 u16_cycleOffsetTicks = usToU16Ticks(CYCLE_OFFSET, getTimerPrescale(T2CONbits));
00107 }
00108
00109
00110
00111 void _ISRFAST _INT1Interrupt (void) {
00112 _INT1IF = 0;
00113 if (u8_currPowerSetting) TRIAC_ON();
00114 }
00115
00116
00117 void configSPI1(void) {
00118
00119 SPI1CON1 = SEC_PRESCAL_1_1 |
00120 PRI_PRESCAL_64_1 |
00121 CLK_POL_ACTIVE_HIGH |
00122 SPI_CKE_OFF |
00123 SPI_MODE16_ON |
00124 MASTER_ENABLE_ON;
00125
00126 CONFIG_SCK1OUT_TO_RP(7);
00127 CONFIG_SDI1_TO_RP(5);
00128 CONFIG_SLAVE_ENABLE();
00129 SLAVE_DISABLE();
00130 SPI1STATbits.SPIEN = 1;
00131 }
00132
00133 uint16 readMAX6675(void) {
00134 uint16 u16_x;
00135 SLAVE_ENABLE();
00136 u16_x = ioMasterSPI1(0);
00137 SLAVE_DISABLE();
00138 return(u16_x);
00139 }
00140
00141 float getCelsiusFloatTemp(void) {
00142 uint16 u16_x;
00143 float f_tempC;
00144 u16_x = readMAX6675();
00145 u16_x = u16_x >> 3;
00146 f_tempC = u16_x;
00147 f_tempC = f_tempC/4;
00148 return(f_tempC);
00149 }
00150
00151
00152 int16 getCelsiusI16Temp(void) {
00153 uint16 u16_x;
00154 uint16 u16_frac;
00155
00156 u16_x = readMAX6675();
00157 u16_frac = (u16_x & 0x1F) >> 3;
00158 u16_x = u16_x >> 5;
00159 if (u16_frac >= 2) u16_x++;
00160 return((int16) u16_x);
00161 }
00162
00163
00164
00165 uint16 volatile u16_tenthSeconds = 0;
00166
00167 void _ISRFAST _T3Interrupt (void) {
00168 _T3IF = 0;
00169 u16_tenthSeconds++;
00170 }
00171
00172 #define ISR_PERIOD 100 // in ms
00173 void configTimer3(void) {
00174
00175 T2CONbits.T32 = 0;
00176 T3CON = T3_OFF |T3_IDLE_CON | T3_GATE_OFF
00177 | T3_SOURCE_INT
00178 | T3_PS_1_256 ;
00179 PR3 = msToU16Ticks (ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
00180 TMR3 = 0;
00181 _T3IF = 0;
00182 _T3IP = 1;
00183 _T3IE = 1;
00184 T3CONbits.TON = 1;
00185 }
00186
00187
00188 void decrementPower(void) {
00189 if (!u8_currPowerSetting) return;
00190 u8_currPowerSetting--;
00191 }
00192
00193 void incrementPower(void) {
00194 if (u8_currPowerSetting == MAX_POWER_SETTING) return;
00195 u8_currPowerSetting++;
00196 }
00197
00198 void setPower(uint8 newPower) {
00199 u8_currPowerSetting = newPower;
00200 }
00201
00202 uint8 getPower(void) {
00203 return(u8_currPowerSetting);
00204 }
00205
00206
00207 void doMainMenu(void) {
00208 uint8 u8_c;
00209 printf("Current profile: %s\n", getProfileDesc(u8_currentProfile));
00210 printf("Reflow oven menu:\n");
00211 printf(" 'S' - start oven for current profile \n");
00212 printf(" 'p' - reflow profile menu \n");
00213 printf(" 'd' - debug menu\n");
00214 printf("Enter character: ");
00215 u8_c = inCharEcho();
00216 printf("\n");
00217 if (u8_c == 'd') doDebugMenu();
00218 if (u8_c == 'p') doProfileMenu();
00219 if (u8_c == 'S') doReflow();
00220 printf("\n");
00221 }
00222
00223
00224 int main (void) {
00225 configBasic(HELLO_MSG);
00226 configureTriacControl();
00227 CONFIG_ZEROCROSS_ENABLE();
00228 configSPI1();
00229 configTimer3();
00230 doRead(&fdata);
00231
00232 while (1) {
00233 doMainMenu();
00234 }
00235 }