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