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