Rev 1963 Rev 2007
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 unsigned int8 hod; 38 volatile unsigned int8 hod;
39 volatile unsigned int8 min; 39 volatile unsigned int8 min;
40 volatile unsigned int8 sec; 40 volatile unsigned 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;
-   49  
48   50  
49 void GeneralCpuInit() // inicializace 51 void GeneralCpuInit() // inicializace
50 { 52 {
51 output_high(POWER_T4); 53 output_high(POWER_T4);
52 output_high(POWER_T5); 54 output_high(POWER_T5);
53 port_b_pullups(true); 55 port_b_pullups(true);
54 56
55 setup_psp(PSP_DISABLED); 57 setup_psp(PSP_DISABLED);
56 setup_spi(SPI_SS_DISABLED); 58 setup_spi(SPI_SS_DISABLED);
57 59
58 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //nepouzit 60 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //nepouzit
59 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // rizeni 61 setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // rizeni
60 setup_timer_2(T2_DIV_BY_16,249,10); //rtc 40ms 62 setup_timer_2(T2_DIV_BY_16,249,10); //rtc 40ms
61 63
62 setup_comparator(NC_NC_NC_NC); 64 setup_comparator(NC_NC_NC_NC);
63 setup_vref(FALSE); 65 setup_vref(FALSE);
64 66
65 enable_interrupts(GLOBAL); 67 enable_interrupts(GLOBAL);
66 enable_interrupts(INT_TIMER2); 68 enable_interrupts(INT_TIMER2);
67 enable_interrupts(INT_TIMER1); 69 enable_interrupts(INT_TIMER1);
68 70
69 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
70 setup_adc(ADC_CLOCK_DIV_8); 72 setup_adc(ADC_CLOCK_DIV_8);
71 SET_ADC_CHANNEL(0); //AN0, PIN_A0 73 SET_ADC_CHANNEL(0); //AN0, PIN_A0
72 } 74 }
73   75  
74 void heat_failure() // exception in case of heating fail 76 void heat_failure() // exception in case of heating fail
75 { 77 {
-   78 top_heat_power=0;
-   79 bottom_heat_power=0;
-   80  
76 lcd_gotoxy(1,2); 81 lcd_gotoxy(1,2);
77 printf(lcd_putc,"HEATING FAILURE!"); 82 printf(lcd_putc,"HEATING FAILURE!");
78 83
79 while(true); 84 while(true);
80   85  
81 } 86 }
82   87  
83 unsigned int16 adc(void) 88 unsigned int16 adc(void) // adc read and filtering
84 { 89 {
85 unsigned int16 analog; 90 unsigned int16 analog;
86 unsigned int8 a; 91 unsigned int8 a;
87   92  
88 analog = 0; 93 analog = 0;
89 for (a=0;a<32;a++) 94 for (a=0;a<32;a++)
90 { 95 {
91 analog += read_adc(); 96 analog += read_adc();
92 delay_us(50); 97 delay_us(50);
93 } 98 }
94 return (analog >> 5 ); // prumer = analog/32 99 return (analog >> 5 ); // prumer = analog/32
95 } 100 }
96   101  
97 float teplota(void) 102 float teplota(void) // temperature measuring
98 { 103 {
99 return (0.674201*adc() - 294.35); 104 return (0.674201*adc() - 294.35); // temperature calculaton (linear aproximation)
100 } 105 }
101   106  
102 void top_heating() 107 void top_heating()
103 { 108 {
104 if (period < top_heat_power){ 109 if (period < top_heat_power){
105 output_low(POWER_T4); 110 output_low(POWER_T4);
106 output_low(POWER_T5); 111 output_low(POWER_T5);
107 } 112 }
108 else{ 113 else{
109 output_high(POWER_T4); 114 output_high(POWER_T4);
110 output_high(POWER_T5); 115 output_high(POWER_T5);
111 } 116 }
112 } 117 }
113   118  
114 void bottom_heating() 119 void bottom_heating()
115 { 120 {
116   121  
117 if (period < 2*bottom_heat_power){ 122 if (period < 2*bottom_heat_power){
118 output_low(POWER_T3); 123 output_low(POWER_T3);
119 } 124 }
120 else{ 125 else{
121 output_high(POWER_T3); 126 output_high(POWER_T3);
122 } 127 }
123   128  
124 } 129 }
125   130  
126 #int_TIMER1 131 #int_TIMER1
127 void heating_control() //rizeni topnych teles pri preteceni casovace 132 void heating_control() //rizeni topnych teles pri preteceni casovace
128 { 133 {
-   134 float temp;
-   135  
129 top_heating(); 136 top_heating();
130 bottom_heating(); 137 bottom_heating();
-   138
-   139 temp=teplota();
-   140
-   141 temp_slope=(temp - temp_last)*100.0; ///(4000000.0/65536.0); // vypocet strmosti narustu teploty ve stupnich/s
-   142 temp_last = temp;
131   143  
132 if (period <= 200) period++; 144 if (period < 200) period++;
133 else period=0; 145 else period=0;
134 } 146 }
135   147  
136 #int_TIMER2 148 #int_TIMER2
137 void Rtc(void) //40ms 149 void Rtc(void) //40ms
138 { 150 {
139 static unsigned int8 ms40=0; 151 static unsigned int8 ms40=0;
140 struct time* time; 152 struct time* time;
141 153
142 time=&cas; 154 time=&cas;
143 if ( ++ms40 < 25) return; 155 if ( ++ms40 < 25) return;
144 156
145 ms40=0; 157 ms40=0;
146 if (++(time->sec) >= 60) 158 if (++(time->sec) >= 60)
147 { 159 {
148 time->sec=0; //1min 160 time->sec=0; //1min
149 if (++(time->min) >= 60) 161 if (++(time->min) >= 60)
150 { 162 {
151 time->min = 0; //1hod 163 time->min = 0; //1hod
152 (time->hod)++; 164 (time->hod)++;
153 } 165 }
154 } 166 }
155 } 167 }
156   168  
157 void slope_control(float ramp, unsigned int balance) // P proporcionalni rizeni narustu teploty predpoklada periodicke volani 1x/s 169 void slope_control(float ramp, unsigned int balance) // P proporcionalni rizeni narustu teploty predpoklada periodicke volani 1x/s
158 { 170 {
159 float slope_deviation; 171 float slope_deviation;
160   172  
161 slope_deviation = (teplota() - temp_last) - ramp; // vypocet strmosti a odchylky od pozadovane strmosti 173 slope_deviation = temp_slope - ramp; // vypocet strmosti a odchylky od pozadovane strmosti
162   174  
163 if(slope_deviation < 0) 175 if(slope_deviation < 0)
164 { 176 {
165 top_heat_power= 80 + balance; 177 top_heat_power= 80 + balance;
166 bottom_heat_power= 90; 178 bottom_heat_power= 90;
167 } 179 }
168 else{ 180 else{
169 top_heat_power=0; 181 top_heat_power=0;
170 bottom_heat_power=0; 182 bottom_heat_power=0;
171 } 183 }
172 temp_last = teplota(); -  
173 } 184 }
174   185  
175 void level_control(float level) // P proporcionalni rizeni teploty 186 void level_control(float level) // P proporcionalni rizeni teploty
176 { 187 {
177 if (teplota() > level) 188 if (teplota() > level)
178 { 189 {
179 top_heat_power=0; 190 top_heat_power=0;
180 bottom_heat_power=0; 191 bottom_heat_power=0;
181 } 192 }
182 else 193 else
183 { 194 {
184 top_heat_power=70; 195 top_heat_power=70;
185 bottom_heat_power=80; 196 bottom_heat_power=80;
186 } 197 }
187 } 198 }
188   199  
189   200  
190 void nullcas(struct time* time) 201 void nullcas(struct time* time)
191 { 202 {
192 disable_interrupts(INT_TIMER2); 203 disable_interrupts(INT_TIMER2);
193 204
194 time->sec=0; 205 time->sec=0;
195 time->hod=0; 206 time->hod=0;
196 time->min=0; 207 time->min=0;
197 208
198 enable_interrupts(INT_TIMER2); 209 enable_interrupts(INT_TIMER2);
199 } 210 }
200   211  
201 void reflow_solder() 212 void reflow_solder()
202 { 213 {
203   214  
204 struct time process_time; 215 struct time process_time;
205   216  
206 // preheat 217 // preheat
-   218  
207 nullcas(&cas); 219 nullcas(&cas);
208 lcd_gotoxy(1,2); 220 lcd_gotoxy(1,2);
209 printf(lcd_putc,"PREHEAT"); 221 printf(lcd_putc,"PREHEAT");
210   222  
211 do { 223 do {
212 slope_control(PREHEAT_SLOPE, 0); // hlida strmost predehrevu 224 slope_control(PREHEAT_SLOPE, 0); // hlida strmost predehrevu
213   225  
214 lcd_gotoxy(1,1); 226 lcd_gotoxy(1,1);
215 printf(lcd_putc,"%3.1f\21C ",teplota()); 227 printf(lcd_putc,"%3.1f\21C ",teplota());
216   228  
217 lcd_gotoxy(9,1); 229 lcd_gotoxy(12,1);
218 printf(lcd_putc,"%2u:%02u:%02u",cas.hod,cas.min,cas.sec); 230 printf(lcd_putc,"%02u:%02u",cas.min,cas.sec);
-   231  
-   232 lcd_gotoxy(10,2);
-   233 printf(lcd_putc,"%1.1f\21C/s ",temp_slope);
219   234  
220 delay_ms(1000); 235 delay_ms(1000);
221 if (cas.min>3) heat_failure(); 236 if (cas.min>3) heat_failure();
222 } 237 }
223 while (teplota() < SOAK_TEMP); 238 while (teplota() < SOAK_TEMP);
224   239  
225 // soak 240 // soak
226 nullcas(&cas); 241 nullcas(&cas);
227 process_time.min = SOAK_TIME/60; 242 process_time.min = SOAK_TIME/60;
228 process_time.sec = SOAK_TIME - process_time.min*60; 243 process_time.sec = SOAK_TIME - process_time.min*60;
229 244
230 lcd_gotoxy(1,2); 245 lcd_gotoxy(1,2);
231 printf(lcd_putc,"SOAK "); 246 printf(lcd_putc,"SOAK ");
232   247  
233 while (process_time.sec!=0 || process_time.min!=0) 248 while (process_time.sec!=0 || process_time.min!=0)
234 { 249 {
235 level_control(SOAK_TEMP); 250 level_control(SOAK_TEMP);
236   251  
237 lcd_gotoxy(1,1); 252 lcd_gotoxy(1,1);
238 printf(lcd_putc,"%3.1f\21C ",teplota()); 253 printf(lcd_putc,"%3.1f\21C ",teplota());
239   254  
240 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59; 255 if ((process_time.sec = process_time.sec - cas.sec)<0) process_time.sec=59;
241   256  
242 process_time.min = (SOAK_TIME - cas.min*60 - cas.sec)/60; 257 process_time.min = (SOAK_TIME - cas.min*60 - cas.sec)/60;
243 process_time.sec = (SOAK_TIME - cas.min*60 - cas.sec) - process_time.min*60; 258 process_time.sec = (SOAK_TIME - cas.min*60 - cas.sec) - process_time.min*60;
244   259  
245 lcd_gotoxy(9,1); 260 lcd_gotoxy(9,1);
246 printf(lcd_putc,"%2u:%02u:%02u",cas.hod, process_time.min, process_time.sec); 261 printf(lcd_putc,"%2u:%02u:%02u",cas.hod, process_time.min, process_time.sec);
247 delay_ms(1000); 262 delay_ms(1000);
248 } 263 }
249 264
250 // solder 265 // solder
251 266
252 } 267 }
253   268  
254   269  
255 void main() // main loop 270 void main() // main loop
256 { 271 {
257 GeneralCpuInit(); 272 GeneralCpuInit();
258 PowerOff(); 273 PowerOff();
259 274
260 lcd_init(); 275 lcd_init();
261 lcd_define_char(1,LCD_CHAR_STUPEN); 276 lcd_define_char(1,LCD_CHAR_STUPEN);
262 277
263 nullcas(&cas); 278 nullcas(&cas);
264 279
265 while(true) 280 while(true)
266 { 281 {
267 delay_ms(300); 282 delay_ms(300);
268 reflow_solder(); 283 reflow_solder();
269 284
270 } 285 }
271 } 286 }