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  
1960 kaklik 23 #define POWER_T3 PIN_A3 // ovladani optotriaku T3
1861 kaklik 24 #define POWER_T4 PIN_A5 // ovladani optotriaku T4
25 #define POWER_T5 PIN_A4 // ovladani optotriaku T5
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);
67  
68 setup_adc_ports(AN0_AN1_VSS_VREF); //A0 vstup cidla, A1 nepozit, A3 - ref. 2.5V
69 setup_adc(ADC_CLOCK_DIV_8);
70 SET_ADC_CHANNEL(0); //AN0, PIN_A0
71 }
72  
73 unsigned int16 adc(void)
74 {
75 unsigned int16 analog;
76 unsigned int8 a;
77  
78 analog = 0;
79 for (a=0;a<32;a++)
80 {
81 analog += read_adc();
82 delay_us(50);
83 }
84 return (analog >> 5 ); // prumer = analog/32
85 }
86  
1957 kaklik 87 float teplota(void)
1861 kaklik 88 {
1957 kaklik 89 return (0.674201*adc() - 294.35);
1861 kaklik 90 }
91  
1960 kaklik 92 void top_heating()
93 {
94 if (period <= top_heat_power){
95 output_low(POWER_T4);
96 output_low(POWER_T5);
97 }
98 else{
99 output_high(POWER_T4);
100 output_high(POWER_T5);
101 }
102 }
1942 kaklik 103  
1960 kaklik 104 void bottom_heating()
105 {
106  
107 if (period <= 2*bottom_heat_power){
108 output_low(POWER_T3);
109 }
110 else{
111 output_high(POWER_T3);
112 }
113  
114 }
115  
116 #int_TIMER1
117 void heating_control() //rizeni topnych teles pri preteceni casovace
118 {
119  
120 top_heating();
121 bottom_heating();
122  
123 if (period <= 200) period++;
124 else period=0;
125 }
126  
127  
1861 kaklik 128 #int_TIMER2
129 void Rtc(void) //40ms
130 {
131 static unsigned int8 ms40=0;
132 struct time* time;
133  
134 time=&cas;
135 if ( ++ms40 < 25) return;
136  
137 ms40=0;
138 if (++(time->sec) >= 60)
139 {
140 time->sec=0; //1min
141 if (++(time->min) >= 60)
142 {
143 time->min = 0; //1hod
144 (time->hod)++;
145 }
146 }
147 }
148  
1960 kaklik 149 void slope_control(float ramp, unsigned int balance) // P proporcionalni rizeni narustu teploty predpoklada periodicke volani 1x/s
150 {
151 float slope_deviation;
152  
153 slope_deviation = (teplota() - temp_last) - ramp; // vypocet strmosti a odchylky od pozadovane strmosti
154  
155 if(slope_deviation < 0)
156 {
157 top_heat_power= slope_deviation*(-10) + balance;
158 bottom_heat_power= slope_deviation*(-10);
159 }
160 else{
161 top_heat_power=0;
162 bottom_heat_power=0;
163 }
164  
165 temp_last = teplota();
166 }
167  
168 void level_control(float level) // P proporcionalni rizeni teploty
169 {
170  
171 teplota();
172  
173 }
174  
175  
1861 kaklik 176 void nullcas(struct time* time)
177 {
178 disable_interrupts(INT_TIMER2);
179  
180 time->sec=0;
181 time->hod=0;
182 time->min=0;
183  
184 enable_interrupts(INT_TIMER2);
185 }
186  
1960 kaklik 187 void reflow_solder()
1861 kaklik 188 {
1960 kaklik 189  
190 // preheat
191 nullcas(&cas);
192  
193 do {
194 slope_control(PREHEAT_SLOPE, 0); // hlida strmost predehrevu
195  
196 lcd_gotoxy(1,1);
197 printf(lcd_putc,"%3.1f\21C ",teplota());
198  
199 lcd_gotoxy(9,1);
200 printf(lcd_putc,"%2u:%02u:%02u",cas.hod,cas.min,cas.sec);
201  
202 delay_ms(1000);
203 }
204 while (teplota() < SOAK_TEMP);
205  
206 // soak
207 nullcas(&cas);
208 while (cas.min*60+cas.sec <= SOAK_TIME)
209 {
210 level_control(SOAK_TEMP);
211  
212 lcd_gotoxy(1,1);
213 printf(lcd_putc,"%3.1f\21C ",teplota());
214  
215 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);
217 delay_ms(1000);
218 }
219  
220 // solder
221  
222 }
223  
224  
225 void main() // main loop
226 {
1861 kaklik 227 GeneralCpuInit();
228 PowerOff();
229  
230 lcd_init();
231 lcd_define_char(1,LCD_CHAR_STUPEN);
1942 kaklik 232  
1861 kaklik 233 nullcas(&cas);
234  
1942 kaklik 235 while(true)
236 {
1861 kaklik 237 delay_ms(300);
238  
1960 kaklik 239  
240 reflow_solder();
241  
1942 kaklik 242 }
1861 kaklik 243 }