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