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