Rev 2008 Rev 2009
1 #include "reflow.h" 1 #include "reflow.h"
2 #include "process.h" 2 #include "process.h"
3 #include <math.h> 3 #include <math.h>
4   4  
5 // nastaveni teplot a casu 5 // nastaveni teplot a casu
6 #define TEPLOTA_PREDEHREVU 120 6 #define TEPLOTA_PREDEHREVU 120
7 #define DOBA_PREDEHREVU 60 7 #define DOBA_PREDEHREVU 60
8   8  
9 #define TEPLOTA_VRCHOLU 210 9 #define TEPLOTA_VRCHOLU 210
10 #define DOBA_VRCHOLU 5 10 #define DOBA_VRCHOLU 5
11   11  
12 // CPU IO rozhrani 12 // CPU IO rozhrani
13 #define LCD_RS PIN_C1 // rizeni registru LCD displeje 13 #define LCD_RS PIN_C1 // rizeni registru LCD displeje
14 #define LCD_E PIN_C2 // enable LCD displeje 14 #define LCD_E PIN_C2 // enable LCD displeje
15 #define LCD_DATA_LSB PIN_D0 // data LCD 15 #define LCD_DATA_LSB PIN_D0 // data LCD
16 #include "lcd.c" 16 #include "lcd.c"
17   17  
18 #define TL1 PIN_B3 // tlacitko S1 18 #define TL1 PIN_B3 // tlacitko S1
19 #define TL2 PIN_B2 // tlacitko S2 19 #define TL2 PIN_B2 // tlacitko S2
20 #define TL3 PIN_B1 // tlacitko S3 20 #define TL3 PIN_B1 // tlacitko S3
21 #define TL4 PIN_B0 // tlacitko S4 21 #define TL4 PIN_B0 // tlacitko S4
22   22  
23 #define POWER_T3 PIN_C4 // ovladani optotriaku T3 23 #define POWER_T3 PIN_C4 // ovladani optotriaku T3
24 #define POWER_T4 PIN_C5 // ovladani optotriaku T4 24 #define POWER_T4 PIN_C5 // ovladani optotriaku T4
25 #define POWER_T5 PIN_C6 // ovladani optotriaku T5 25 #define POWER_T5 PIN_C6 // ovladani optotriaku T5
26   26  
27 #define ADC_PIN PIN_A0 //info, nelze menit - pin pouzit jako input analog 27 #define ADC_PIN PIN_A0 //info, nelze menit - pin pouzit jako input analog
28 #define ADC_PIN_NC PIN_A1 //info, nelze menit - pin pouzit jako input analog 28 #define ADC_PIN_NC PIN_A1 //info, nelze menit - pin pouzit jako input analog
29 #define REF_PIN PIN_A3 //info, nelze menit - pin pouzit jako input reference 2.5V 29 #define REF_PIN PIN_A3 //info, nelze menit - pin pouzit jako input reference 2.5V
30   30  
31 // interni 31 // interni
32 #define PowerOn() output_low(POWER_T4);output_low(POWER_T5) 32 #define PowerOn() output_low(POWER_T4);output_low(POWER_T5)
33 #define PowerOff() output_high(POWER_T4);output_high(POWER_T5) 33 #define PowerOff() output_high(POWER_T4);output_high(POWER_T5)
34   34  
35 // globalni promenne 35 // globalni promenne
36 struct time 36 struct time
37 { 37 {
38 volatile signed int8 hod; 38 volatile signed int8 hod;
39 volatile signed int8 min; 39 volatile signed int8 min;
40 volatile signed int8 sec; 40 volatile signed int8 sec;
41 }cas; 41 }cas;
42   42  
43 unsigned int top_heat_power=0; // range 0-200% nad 100% je ale teleso jiz pretizene 43 unsigned int top_heat_power=0; // range 0-200% nad 100% je ale teleso jiz pretizene
44 unsigned int bottom_heat_power=0; // contains heating power range 0-100% 44 unsigned int bottom_heat_power=0; // contains heating power range 0-100%
45 unsigned int period; 45 unsigned int period;
46   46  
47 float temp_last=0; 47 float temp_last=0;
48 float temp_slope=0; 48 float temp_slope=0;
49   49  
50   50  
51 void GeneralCpuInit() // inicializace 51 void GeneralCpuInit() // inicializace
52 { 52 {
53 output_high(POWER_T4); 53 output_high(POWER_T4);
54 output_high(POWER_T5); 54 output_high(POWER_T5);
55 port_b_pullups(true); 55 port_b_pullups(true);
56 56
57 setup_psp(PSP_DISABLED); 57 setup_psp(PSP_DISABLED);
58 setup_spi(SPI_SS_DISABLED); 58 setup_spi(SPI_SS_DISABLED);
59 59
60 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64); //nepouzit 60 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64); //nepouzit
61 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // rizeni 61 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // rizeni
62 setup_timer_2(T2_DIV_BY_16,249,10); //rtc 40ms 62 setup_timer_2(T2_DIV_BY_16,249,10); //rtc 40ms
63 63
64 setup_comparator(NC_NC_NC_NC); 64 setup_comparator(NC_NC_NC_NC);
65 setup_vref(FALSE); 65 setup_vref(FALSE);
66 66
67 enable_interrupts(GLOBAL); 67 enable_interrupts(GLOBAL);
68 enable_interrupts(INT_TIMER2); 68 enable_interrupts(INT_TIMER2);
69 enable_interrupts(INT_TIMER0); 69 enable_interrupts(INT_TIMER0);
70 70
71 setup_adc_ports(AN0_AN1_VSS_VREF); //A0 vstup cidla, A1 nepozit, A3 - ref. 2.5V 71 setup_adc_ports(AN0_AN1_VSS_VREF); //A0 vstup cidla, A1 nepozit, A3 - ref. 2.5V
72 setup_adc(ADC_CLOCK_DIV_8); 72 setup_adc(ADC_CLOCK_DIV_8);
73 SET_ADC_CHANNEL(0); //AN0, PIN_A0 73 SET_ADC_CHANNEL(0); //AN0, PIN_A0
74 } 74 }
75   75  
76 void heat_failure() // exception in case of heating fail 76 void heat_failure() // exception in case of heating fail
77 { 77 {
78 top_heat_power=0; 78 top_heat_power=0;
79 bottom_heat_power=0; 79 bottom_heat_power=0;
80   80  
81 lcd_gotoxy(1,2); 81 lcd_gotoxy(1,2);
82 printf(lcd_putc,"HEATING FAILURE!"); 82 printf(lcd_putc,"HEATING FAILURE!");
83 83
84 while(true); 84 while(true);
85   85  
86 } 86 }
87   87  
88 unsigned int16 adc(void) // adc read and filtering 88 unsigned int16 adc(void) // adc read and filtering
89 { 89 {
90 unsigned int16 analog; 90 unsigned int16 analog;
91 unsigned int8 a; 91 unsigned int8 a;
92   92  
93 analog = 0; 93 analog = 0;
94 for (a=0;a<32;a++) 94 for (a=0;a<32;a++)
95 { 95 {
96 analog += read_adc(); 96 analog += read_adc();
97 delay_us(50); 97 delay_us(50);
98 } 98 }
99 return (analog >> 5 ); // prumer = analog/32 99 return (analog >> 5 ); // prumer = analog/32
100 } 100 }
101   101  
102 float teplota(void) // temperature measuring 102 float teplota(void) // temperature measuring
103 { 103 {
104 return (0.674201*adc() - 294.35); // temperature calculaton (linear aproximation) 104 return (0.674201*adc() - 294.35); // temperature calculaton (linear aproximation)
105 } 105 }
106   106  
107 void top_heating() 107 void top_heating()
108 { 108 {
109 if (period < top_heat_power){ 109 if (period < top_heat_power){
110 output_low(POWER_T4); 110 output_low(POWER_T4);
111 output_low(POWER_T5); 111 output_low(POWER_T5);
112 } 112 }
113 else{ 113 else{
114 output_high(POWER_T4); 114 output_high(POWER_T4);
115 output_high(POWER_T5); 115 output_high(POWER_T5);
116 } 116 }
117 } 117 }
118   118  
119 void bottom_heating() 119 void bottom_heating()
120 { 120 {
121   121  
122 if (period < 2*bottom_heat_power){ 122 if (period < 2*bottom_heat_power){
123 output_low(POWER_T3); 123 output_low(POWER_T3);
124 } 124 }
125 else{ 125 else{
126 output_high(POWER_T3); 126 output_high(POWER_T3);
127 } 127 }
128 } 128 }
129   129  
130 #int_TIMER0 130 #int_TIMER0
131 void heating_control() //rizeni topnych teles pri preteceni casovace 131 void heating_control() //rizeni topnych teles pri preteceni casovace
132 { 132 {
133 float temp; 133 float temp;
134   134  
135 top_heating(); 135 top_heating();
136 bottom_heating(); 136 bottom_heating();
137 137
138 138
139 if (period == 200) 139 if ((period == 100) || (period == 0))
140 { 140 {
141 temp=teplota(); 141 temp=teplota();
142 temp_slope=(temp - temp_last) /(2*100.0*256.0/62500.0); // vypocet strmosti narustu teploty ve stupnich/s 142 temp_slope=(temp - temp_last) /(100.0*256.0/62500.0); // vypocet strmosti narustu teploty ve stupnich/s
143 temp_last = temp; 143 temp_last = temp;
-   144 printf("%02u %02u %3.3f \r\n",cas.min,cas.sec,temp); //vypis pro zaznam profilu
144 } 145 }
145 146
146 if (period < 200) period++; 147 if (period < 200) period++;
147 else period=0; 148 else period=0;
148 } 149 }
149   150  
150 #int_TIMER2 151 #int_TIMER2
151 void Rtc(void) //40ms 152 void Rtc(void) //40ms
152 { 153 {
153 static unsigned int8 ms40=0; 154 static unsigned int8 ms40=0;
154 struct time* time; 155 struct time* time;
155 156
156 time=&cas; 157 time=&cas;
157 if ( ++ms40 < 25) return; 158 if ( ++ms40 < 25) return;
158 159
159 ms40=0; 160 ms40=0;
160 if (++(time->sec) >= 60) 161 if (++(time->sec) >= 60)
161 { 162 {
162 time->sec=0; //1min 163 time->sec=0; //1min
163 if (++(time->min) >= 60) 164 if (++(time->min) >= 60)
164 { 165 {
165 time->min = 0; //1hod 166 time->min = 0; //1hod
166 (time->hod)++; 167 (time->hod)++;
167 } 168 }
168 } 169 }
169 } 170 }
170   171  
171 void slope_control(float ramp, unsigned int balance) // P proporcionalni rizeni narustu teploty predpoklada periodicke volani 1x/s 172 void slope_control(float ramp, unsigned int balance) // P proporcionalni rizeni narustu teploty predpoklada periodicke volani 1x/s
172 { 173 {
173 float slope_deviation; 174 float slope_deviation;
174   175  
175 slope_deviation = temp_slope - ramp; // vypocet strmosti a odchylky od pozadovane strmosti 176 slope_deviation = temp_slope - ramp; // vypocet strmosti a odchylky od pozadovane strmosti
176   177  
177 if(slope_deviation < 0) 178 if(slope_deviation < 0)
178 { 179 {
179 top_heat_power= 67 + balance; 180 top_heat_power= 67 + balance;
180 bottom_heat_power= 100; 181 bottom_heat_power= 100;
181 } 182 }
182 else{ 183 else{
183 top_heat_power=0; 184 top_heat_power=0;
184 bottom_heat_power=0; 185 bottom_heat_power=0;
185 } 186 }
186 } 187 }
187   188  
188 void level_control(float level) // P proporcionalni rizeni teploty 189 void level_control(float level) // P proporcionalni rizeni teploty
189 { 190 {
190 if (teplota() > level) 191 if (teplota() > level)
191 { 192 {
192 top_heat_power=0; 193 top_heat_power=0;
193 bottom_heat_power=0; 194 bottom_heat_power=0;
194 } 195 }
195 else 196 else
196 { 197 {
197 top_heat_power=70; 198 top_heat_power=70;
198 bottom_heat_power=80; 199 bottom_heat_power=80;
199 } 200 }
200 } 201 }
201   202  
202   203  
203 void nullcas(struct time* time) 204 void nullcas(struct time* time)
204 { 205 {
205 disable_interrupts(INT_TIMER2); 206 disable_interrupts(INT_TIMER2);
206 207
207 time->sec=0; 208 time->sec=0;
208 time->hod=0; 209 time->hod=0;
209 time->min=0; 210 time->min=0;
210 211
211 enable_interrupts(INT_TIMER2); 212 enable_interrupts(INT_TIMER2);
212 } 213 }
213   214  
214 void reflow_solder() 215 void reflow_solder()
215 { 216 {
216   217  
217 struct time process_time; 218 struct time process_time;
218   219  
219 // ------------------- PREHEAT --------------------- 220 // ------------------- PREHEAT ---------------------
220   221  
221 nullcas(&cas); 222 nullcas(&cas);
222 lcd_gotoxy(1,2); 223 lcd_gotoxy(1,2);
223 printf(lcd_putc,"PREHEAT"); 224 printf(lcd_putc,"PREHEAT");
-   225 printf("#PREHEAT\r\n");
224   226  
225 do { 227 do {
226 slope_control(PREHEAT_SLOPE, 0); // hlida strmost predehrevu 228 slope_control(PREHEAT_SLOPE, 0); // hlida strmost predehrevu
227   229  
228 lcd_gotoxy(1,1); 230 lcd_gotoxy(1,1);
229 printf(lcd_putc,"%3.1f\21C ",teplota()); 231 printf(lcd_putc,"%3.1f\21C ",teplota());
230   232  
231 lcd_gotoxy(12,1); 233 lcd_gotoxy(12,1);
232 printf(lcd_putc,"%02u:%02u",cas.min,cas.sec); 234 printf(lcd_putc,"%02u:%02u",cas.min,cas.sec);
233   235  
234 lcd_gotoxy(10,2); 236 lcd_gotoxy(10,2);
235 printf(lcd_putc,"%1.1f\21C/s ",temp_slope); 237 printf(lcd_putc,"%1.1f\21C/s ",temp_slope);
236   238  
237 delay_ms(200); 239 delay_ms(200);
238 if (cas.min>3) heat_failure(); 240 if (cas.min>3) heat_failure();
239 } 241 }
240 while (teplota() < SOAK_TEMP); 242 while (teplota() < SOAK_TEMP);
241   243  
242 // ----------- SOAK --------------- 244 // ----------- SOAK ---------------
243 nullcas(&cas); 245 nullcas(&cas);
244 process_time.min = SOAK_TIME/60; 246 process_time.min = SOAK_TIME/60;
245 process_time.sec = SOAK_TIME - process_time.min*60; 247 process_time.sec = SOAK_TIME - process_time.min*60;
246   248  
247 lcd_clr(); 249 lcd_clr();
248 lcd_gotoxy(1,2); 250 lcd_gotoxy(1,2);
249 printf(lcd_putc,"SOAK "); 251 printf(lcd_putc,"SOAK ");
-   252 printf(lcd_putc,"#SOAK\r\n");
250   253  
251 while (process_time.sec!=0 || process_time.min!=0) 254 while (process_time.sec!=0 || process_time.min!=0)
252 { 255 {
253 level_control(SOAK_TEMP); 256 level_control(SOAK_TEMP);
254   257  
255 lcd_gotoxy(1,1); 258 lcd_gotoxy(1,1);
256 printf(lcd_putc,"%3.1f\21C ",teplota()); 259 printf(lcd_putc,"%3.1f\21C ",teplota());
257   260  
258 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59; 261 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59;
259   262  
260 process_time.min = (SOAK_TIME - cas.min*60 - cas.sec)/60; 263 process_time.min = (SOAK_TIME - cas.min*60 - cas.sec)/60;
261 process_time.sec = (SOAK_TIME - cas.min*60 - cas.sec) - process_time.min*60; 264 process_time.sec = (SOAK_TIME - cas.min*60 - cas.sec) - process_time.min*60;
262   265  
263 lcd_gotoxy(9,1); 266 lcd_gotoxy(9,1);
264 printf(lcd_putc,"%02u:%02u", process_time.min, process_time.sec); 267 printf(lcd_putc,"%02u:%02u", process_time.min, process_time.sec);
265 delay_ms(200); 268 delay_ms(200);
266 -  
267 } 269 }
268 270
269 //----------------- solder ---------------------------- 271 //----------------- solder ----------------------------
270   272  
271 nullcas(&cas); 273 nullcas(&cas);
272 lcd_clr(); 274 lcd_clr();
273 lcd_gotoxy(1,2); 275 lcd_gotoxy(1,2);
274 printf(lcd_putc,"SOLDER"); 276 printf(lcd_putc,"SOLDER");
-   277 printf("#SOLDER\r\n");
275   278  
276 do { 279 do {
277 slope_control(SOLDER_SLOPE, 10); // hlida strmost predehrevu 280 slope_control(SOLDER_SLOPE, 10); // hlida strmost predehrevu
278   281  
279 lcd_gotoxy(1,1); 282 lcd_gotoxy(1,1);
280 printf(lcd_putc,"%3.1f\21C ",teplota()); 283 printf(lcd_putc,"%3.1f\21C ",teplota());
281   284  
282 lcd_gotoxy(12,1); 285 lcd_gotoxy(12,1);
283 printf(lcd_putc,"%02u:%02u",cas.min,cas.sec); 286 printf(lcd_putc,"%02u:%02u",cas.min,cas.sec);
284   287  
285 lcd_gotoxy(10,2); 288 lcd_gotoxy(10,2);
286 printf(lcd_putc,"%1.1f\21C/s ",temp_slope); 289 printf(lcd_putc,"%1.1f\21C/s ",temp_slope);
287   290  
288 delay_ms(200); 291 delay_ms(200);
289 if (cas.min>3) heat_failure(); 292 if (cas.min>2) heat_failure();
290 } 293 }
291 while (teplota() < SOLDER_TEMP); 294 while (teplota() < SOLDER_TEMP);
292   295  
293 // ---------------- TAO ------------------------ 296 // ---------------- TAO ------------------------
294   297  
295   298  
296 while (process_time.sec!=0 || process_time.min!=0) 299 while (process_time.sec!=0 || process_time.min!=0)
297 { 300 {
298 level_control(SOLDER_TEMP); 301 level_control(SOLDER_TEMP);
299   302  
300 lcd_gotoxy(1,1); 303 lcd_gotoxy(1,1);
301 printf(lcd_putc,"%3.1f\21C ",teplota()); 304 printf(lcd_putc,"%3.1f\21C ",teplota());
302   305  
303 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59; 306 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59;
304   307  
305 process_time.min = (SOLDER_TIME - cas.min*60 - cas.sec)/60; 308 process_time.min = (SOLDER_TIME - cas.min*60 - cas.sec)/60;
306 process_time.sec = (SOLDER_TIME - cas.min*60 - cas.sec) - process_time.min*60; 309 process_time.sec = (SOLDER_TIME - cas.min*60 - cas.sec) - process_time.min*60;
307   310  
308 lcd_gotoxy(9,1); 311 lcd_gotoxy(9,1);
309 printf(lcd_putc,"%02u:%02u", process_time.min, process_time.sec); 312 printf(lcd_putc,"%02u:%02u", process_time.min, process_time.sec);
-   313
310 delay_ms(200); 314 delay_ms(200);
311 315
312 } 316 }
313   317  
314 // ---------------- COOLING ------------------------ 318 // ---------------- COOLING ------------------------
315   319  
316 top_heat_power=0; 320 top_heat_power=0;
317 bottom_heat_power=0; 321 bottom_heat_power=0;
318   322  
319 lcd_clr(); 323 lcd_clr();
320   324  
321 lcd_gotoxy(1,2); 325 lcd_gotoxy(1,2);
322 printf(lcd_putc,"REFLOW COMPLETE"); 326 printf(lcd_putc,"REFLOW COMPLETE");
-   327 printf("COOLING \r\n");
-   328  
323 329  
324 while(true) 330 while(true)
325 { 331 {
326 lcd_gotoxy(1,1); 332 lcd_gotoxy(1,1);
327 printf(lcd_putc,"%3.1f\21C ",teplota()); 333 printf(lcd_putc,"%3.1f\21C ",teplota());
328   334  
329 lcd_gotoxy(10,1); 335 lcd_gotoxy(10,1);
330 printf(lcd_putc,"%1.1f\21C/s ",temp_slope); 336 printf(lcd_putc,"%1.1f\21C/s ",temp_slope);
331   -  
332 } 337 }
333 } 338 }
334   339  
335 void main() // main loop 340 void main() // main loop
336 { 341 {
337 GeneralCpuInit(); 342 GeneralCpuInit();
338 PowerOff(); 343 PowerOff();
339 344
340 lcd_init(); 345 lcd_init();
341 lcd_define_char(1,LCD_CHAR_STUPEN); 346 lcd_define_char(1,LCD_CHAR_STUPEN);
342 347
343 nullcas(&cas); 348 nullcas(&cas);
344 349
345 while(true) 350 while(true)
346 { 351 {
347 delay_ms(300); 352 delay_ms(300);
348 reflow_solder(); 353 reflow_solder();
349 354
350 } 355 }
351 } 356 }