Subversion Repositories svnkaklik

Rev

Go to most recent revision | Details | Last modification | View Log

Rev Author Line No. Line
2 kaklik 1
// DART01A verze programu 1.00
2
// (c)miho 2005
3
 
4
#include "DART.h"
5
 
6
 
7
#define BEEP0     PIN_A6   // pipak, prvni vystup
8
#define BEEP1     PIN_A7   // pipak, druhy vystup
9
#define PWM       PIN_B3   // PWM vystup pro menic
10
#define REFPOWER  PIN_B1   // napajeni zdroje Vref
11
#define MOTOR     PIN_B2   // zapinani motoru
12
#define SW0       PIN_B7   // konfiguracni prepinac 0
13
#define SW1       PIN_B6   // konfiguracni prepinac 1
14
 
15
 
16
void InitRS232()
17
// Inicializace HW RS232
18
{
19
   SPBRG=xclock/9600/16-1; // ryclost 9600Bd
20
   RCSTA=0b10000000;       // enable USART
21
   TXSTA=0b00100100;       // BRGH=1, TX enable
22
}
23
 
24
 
25
void Putc(char c)
26
// Posilani znaku pres HW RS232
27
{
28
   while(TRMT==0);         // cekej na prazdny TX buffer
29
   TXREG=c;                // predej data
30
}
31
 
32
 
33
// Globalni promenna pro data posilana na SSP
34
//   Nastavuje se funkci MotorPatternSet()
35
//   Vyuziva se v prerusovaci rutine IntSSP()
36
unsigned int8 MotorPattern;   // aktualni data pro SSP jednotku
37
 
38
 
39
void MotorPatternSet(unsigned int Gear)
40
// Na zaklade rychlosti nastavi MotorPattern pro SSP
41
// Rychlost 0 znamena stop, rychlost 8 je maximum
42
{
43
   // Tabulka rychlost -> pattern pro SSP
44
   unsigned int8 const ExpTab[8] = {0x02,0x06,0x0e,0x1e,0x3e,0x7e,0xfe,0xff};
45
 
46
   // Vyber patternu
47
   if (Gear==0)                     // stav 0 znamena stop
48
   {
49
      output_low(MOTOR);            // klidovy stav
50
      SSPSTAT = 0;
51
      SSPCON1 = 0;                  // SPI stop
52
      disable_interrupts(INT_SSP);  // neni preruseni od SSP
53
   }
54
   else                             // rizeny vykon
55
   {
56
      if (Gear>7)                   // stav 8 a vice znamena plny vykon
57
      {
58
         Gear=8;                    // plny plyn
59
      }
60
 
61
      MotorPattern=ExpTab[--Gear];  // prevod z hodnoty plynu na data pro SSP
62
      output_low(MOTOR);            // klidovy stav
63
      SSPSTAT = 0;
64
      SSPCON1 = 0x22;               // SPI OSC/64
65
 
66
      SSPBUF=MotorPattern;          // prvni data pro vyslani
67
      enable_interrupts(INT_SSP);   // az budou vyslana prijde interrupt od SSP
68
   }
69
}
70
 
71
 
72
// Obsluha preruseni od SSP jednotky, posila data z promenne MotorRun do SSP.
73
#INT_SSP
74
void IntSSP()
75
{
76
   SSPBUF=MotorPattern;             // znova hdnota PWM patternu na SSP
77
}
78
 
79
 
80
void MotorSet(unsigned int Gear)
81
// Nastavi vykon motoru dle hodnoty Gear a zahaji posilani PWM dat pres SSP pod prerusenim
82
// od SSP jednotky
83
//    0   stop
84
//    1-7 pocet 1/8 vykonu
85
//    >7  plny vykon
86
{
87
   // Nastav PWM pattern
88
   MotorPatternSet(Gear);           // nastav PWM pattern pro SSP
89
 
90
   // Povol preruseni
91
   enable_interrupts(GLOBAL);       // povol preruseni
92
}
93
 
94
 
95
void InitT0()
96
// Inicializace casovace T0 (cca 1000x za sekundu)
97
{
98
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);  // T0 z internich hodin 1/4
99
   enable_interrupts(INT_RTCC);              // generuj preruseni od T0
100
   enable_interrupts(GLOBAL);                // povol preruseni
101
}
102
 
103
 
104
// Globalni promenna pro mereni casu
105
//   Nastavuje se procedurou TimeSet()
106
//   Testuje se funkci TimeIf()
107
//   Modifikuje se pri preruseni od casovace IntTo()
108
unsigned int16 TimeTime;
109
 
110
 
111
void TimerSet(unsigned int16 Time)
112
// Nastavi casovac na zadany pocet ms
113
// Test uplynuti casu se dela pomoci TimerIf()
114
{
115
   // Nastav hodnotu
116
   disable_interrupts(INT_RTCC);    // nesmi prijit preruseni
117
   TimeTime=Time;                   // pri nastavovani hodnoty
118
   enable_interrupts(INT_RTCC);     // promenne (o delce vice nez 8 bitu)
119
}
120
 
121
 
122
int1 TimerIf()
123
// Vraci TRUE pokud casovac jiz dobehl
124
{
125
   int1 Flag;                       // pomocna promenna
126
 
127
   // Otestuj casovac
128
   disable_interrupts(INT_RTCC);    // nesmi prijit preruseni
129
   Flag=(TimeTime==0);              // behem testu promenne
130
   enable_interrupts(INT_RTCC);     // ted uz muze
131
 
132
   // Navratova hodnota
133
   return Flag;                     // TRUE znamena dobehl casovac
134
}
135
 
136
 
137
// Globalni promenne pro akceleraci
138
//   Nastavuje se metodou MotorStart()
139
//   Pouziva se v obsluze preruseni IntT0()
140
unsigned int8 MotorTime;            // aktualni casovac pro rozjezd
141
unsigned int8 MotorDelay;           // spozdeni mezi razenim
142
unsigned int8 MotorGear;            // rychlostni stupen
143
 
144
 
145
void MotorStart(unsigned int8 Delay)
146
// Provede rizeny rozjezd motoru
147
{
148
   disable_interrupts(INT_RTCC);
149
   MotorGear=1;
150
   MotorDelay=Delay;
151
   MotorTime=MotorDelay;
152
   enable_interrupts(INT_RTCC);
153
 
154
   MotorPatternSet(1);
155
}
156
 
157
 
158
#INT_TIMER0
159
void IntT0()
160
// Preruseni od casovace cca 1000x za sekundu
161
{
162
   // Odpocitavani casovace
163
   if (TimeTime) TimeTime--;
164
 
165
   // Obsluha akcelerace
166
   if (MotorTime) MotorTime--;                           // dekrementuj casovac rozjezdu
167
   if ((MotorGear>0) && (MotorGear<8) && (!MotorTime))   // dalsi rychlostni stupen
168
   {
169
      MotorTime=MotorDelay;         // znovu nastav casovac
170
      MotorGear++;                  // dalsi rychlost
171
      MotorPatternSet(MotorGear);   // nastav rychlost
172
   }
173
}
174
 
175
 
176
// Cteni dat z AD prevodniku, zadava se cislo kanalu
177
int8 ReadAD(int8 Ch)
178
{
179
   // Pokud merim Vref zapnu si jeho napajeni
180
   if (Ch==4) output_high(REFPOWER);
181
 
182
   // Inicializace a cislo kanalu
183
   ADCON1=0x30;         // Vref+-, bez deleni hodin, Left Justify
184
   ADCON0=0x41+(Ch<<3); // on, Tosc/8, cislo kanalu
185
 
186
   // Mereni
187
   delay_us(50);        // doba na prepnuti kanalu
188
   ADCON0 |= 4;         // start prevodu
189
   delay_us(50);        // doba na prevod
190
 
191
   // Vypnu napajeni Vref (vzdycky)
192
   output_low(REFPOWER);
193
 
194
   // Navrat hodnoty
195
   return ADRESH;
196
}
197
 
198
 
199
void main()
200
{
201
   unsigned int8 Debug;
202
   unsigned int8 i;
203
 
204
   // Hodiny
205
   OSCCON = 0x62;          // 4 MHz interni RC oscilator
206
 
207
   // Digitalni vystupy
208
   output_low(PWM);        // PWM vystup
209
   output_low(MOTOR);      // Proud do motoru
210
   output_low(REFPOWER);   // Napajeni Vref
211
   port_b_pullups(TRUE);   // Zbyvajici vyvody portu B
212
 
213
   // Watch Dog
214
   PSA=0;                  // preddelic prirazen casovaci
215
   WDTCON=0x0E;            // Watch Dog cca 130ms
216
/*
217
   // Analogove vstupy
218
   ANSEL = 0x1F;           // AN0 az AN4
219
 
220
   // nastaveni RS232
221
   InitRS232();            // inicializace HW RS232 (nutno pockat cca 10ms)
222
 
223
   // Pipnuti (a cekani)
224
   for (i=1;i<30;i++)      // pocet 1/2 period
225
   {
226
      int1 beep;           // stavova promenna pro pipak
227
 
228
      output_bit(BEEP0,beep);
229
      beep=~beep;
230
      output_bit(BEEP1,beep);
231
      delay_us(1000);
232
   }
233
 
234
   // Rozhodnuti o rezimu cinnosti
235
   Debug=0;
236
   if (~input(SW0)) Debug|=1;    // precti bit 0
237
   if (~input(SW1)) Debug|=2;    // precti bit 1
238
   output_low(SW0);              // nastav L aby se snizila spotreba
239
   output_low(SW1);              // na obou vstupech
240
 
241
   // Zobrazeni rezimu
242
   printf(Putc,"\fMode:%d",Debug);
243
*/
244
   // Inicializace PWM
245
   PR2     = 0x1F;      // perioda PWM casovace
246
   T2CON   = 0x04;      // povoleni casovace T2 bez preddelicu a postdelicu
247
   CCP1CON = 0x0C;      // PWM mode, lsb bity nulove
248
   CCPR1L  =    0;      // na zacatku nulova data
249
   output_low(PWM);     // PWM vystup
250
 
251
//!!!KAKL
252
CCPR1L = 20;              // pouziti vystupu
253
disable_interrupts(GLOBAL);
254
while(true);
255
 
256
   // Inicializace casovace
257
   InitT0();            // nastav casovac na cca 1ms
258
 
259
//!!!KAKL
260
Debug=3;
261
 
262
   // Test menice PWM a rozjezdoveho PWM
263
   if (Debug==1)
264
   {
265
      unsigned int8 Data1;       // poteniometr P1 = PWM
266
      unsigned int8 Data2;       // poteniometr P2 = Rozjezd
267
 
268
      while (1)
269
      {
270
         // watch dog
271
         restart_wdt();
272
 
273
         // mereni vstupu
274
         Data1=ReadAD(0);        // nacti parametr pro PWM
275
         Data1>>=2;              // redukuj rozsah na 0 az 63
276
         Data2=ReadAD(1);        // nacti parametr pro rozjezd
277
         Data2>>=4;              // redukuj rozsah na 0 az 15
278
 
279
         // zobrazeni
280
         printf(Putc,"\nPWM:%03u RUN:%03u",Data1,Data2);
281
         delay_ms(20);
282
 
283
         // nastaveni parametru PWM
284
         CCPR1L = Data1;
285
 
286
         // nastaveni parametru RUN
287
         MotorSet(Data2);
288
      }
289
   }
290
 
291
   // Testovani rozjezdu
292
   // Zadava se cas mezi stupni razeni pro rozjezd v ms
293
   if (Debug==2)
294
   {
295
      int8 Data;
296
      int8 Start;
297
 
298
      Start=0;                               // uvodni stav
299
      while(1)
300
      {
301
         // Nacti a zobraz parametr
302
         Data=ReadAD(1);                     // potenciometr P2 = rozjezd
303
         printf(Putc,"\nRUN: %3ums ",Data);  // zobraz
304
         delay_ms(10);                       // prodleva pro terminal
305
 
306
         // Uvodni pauza
307
         if (Start==0)                       // spousti se 1x na zacatku
308
         {
309
            Start++;                         // dalsi stav je cekani
310
            TimerSet(2000);                  // na dokonceni uvodni prodlevy
311
         }
312
 
313
         // Rozjezd
314
         if ((Start==1) && TimerIf())
315
         {
316
            Start++;
317
            printf(Putc,"R");
318
            MotorStart(Data);                // rozjezd s nastavenim prodlevy
319
 
320
            TimerSet(2000);                  // nastav celkovy cas jizdy
321
         }
322
 
323
         // Zastaveni
324
         if ((Start==2) && TimerIf())
325
         {
326
            Start++;
327
            printf(Putc,"S");
328
            MotorSet(0);                     // pokud dobehl casovac zastav motor
329
         }
330
 
331
         // watch dog
332
         restart_wdt();
333
      }
334
   }
335
 
336
   // Test nabijeciho algoritmu
337
   if (Debug==3)
338
   {
339
      unsigned int8 PwmOut;   // akcni hodnota pro PWM
340
      unsigned int8 Req;      // pozadovana hodnota z P1
341
      unsigned int8 Vref;     // merena hodnota vref
342
 
343
      // Inicializace stavove promenne
344
      PwmOut=0;
345
 
346
      // Hlavni smycka
347
      while (1)
348
      {
349
         // watch dog
350
         restart_wdt();
351
 
352
         // pozadovana hodnota (potenciometr P1)
353
         Req=ReadAD(0);
354
         Req=50+(ReadAD(0)>>1);                      // 50 az 177
355
 
356
         // napeti na napajeni (vref)
357
         Vref=ReadAD(4);
358
 
359
         // ricici algoritmus
360
         if ((Vref<Req) &&(PwmOut<30)) PwmOut++;
361
         if ((Vref>=Req)&&(PwmOut> 0)) PwmOut--;
362
         Vref+=10;
363
         if ((Vref<(Req))&&(PwmOut<30)) PwmOut++;    // urychleni nabehu
364
 
365
         // nastaveni parametru PWM
366
         if (PwmOut>24) PwmOut=24;     // saturace
367
//!!!KAKL
368
PwmOut=20;
369
         CCPR1L = PwmOut;              // pouziti vystupu
370
disable_interrupts(GLOBAL);
371
while(true);
372
         // zobrazeni
373
         printf(Putc,"\nALG:%03u %03u %03u",Req,Vref,PwmOut);
374
         delay_ms(10);
375
      }
376
   }
377
 
378
   // Standardni beh
379
   if (Debug==0)
380
   {
381
      unsigned int8 PwmOut;   // akcni hodnota pro PWM
382
      unsigned int8 Req;      // pozadovana hodnota z P1
383
      unsigned int8 Vref;     // merena hodnota vref
384
      int1 Run;
385
 
386
      // Inicializace stavove promenne
387
      PwmOut=0;
388
      TimerSet(14000);        // casovani startu
389
      Run=1;
390
 
391
      // Hlavni smycka
392
      while (1)
393
      {
394
         // watch dog
395
         restart_wdt();
396
 
397
         // pozadovana hodnota (potenciometr P1)
398
         Req=ReadAD(0);
399
         Req=50+(ReadAD(0)>>1);                      // 50 az 177
400
 
401
         // napeti na napajeni (vref)
402
         Vref=ReadAD(4);
403
 
404
         // ricici algoritmus
405
         if ((Vref<Req) &&(PwmOut<30)) PwmOut++;
406
         if ((Vref>=Req)&&(PwmOut> 0)) PwmOut--;
407
         Vref+=10;
408
         if ((Vref<(Req))&&(PwmOut<30)) PwmOut++;    // urychleni nabehu
409
 
410
         // nastaveni parametru PWM
411
         if (PwmOut>24) PwmOut=24;     // saturace
412
         CCPR1L = PwmOut;              // pouziti vystupu
413
 
414
         // zobrazeni
415
         printf(Putc,"\nALG:%03u %03u %03u",Req,Vref,PwmOut);
416
         delay_ms(10);
417
 
418
         // rozjezd
419
         if (TimerIf()&&Run)
420
         {
421
            Run=0;
422
            MotorStart(65);
423
         }
424
      }
425
   }
426
}