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