main.c


1
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2
//:::Jan Coray:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
3
//:::ESCATEC Switzerland:::::::::::::::::::::::::::::::::::::::::::::::::::
4
//:::Projektarbeit RTC UHR:::::::::::::::::::::::::::::::::::::::::::::::::
5
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
6
7
#include "pic16f946.h"
8
#include <htc.h>
9
#include <stdlib.h>
10
#include <stdio.h>
11
#include <string.h>
12
13
//Configurations
14
#define _XTAL_FREQ 32768  //Quarz Oszillator RTC
15
#define FOSC 32768ul
16
#define FOSC_LP
17
#define PWRTE_OFF
18
#define MCLRE_ON
19
#define BOREN_OFF
20
21
22
//LCD Segments
23
//Digit1
24
#define D1A    SEG0COM0
25
#define D1B   SEG1COM0
26
#define D1C   SEG2COM0
27
#define D1D   SEG3COM0
28
#define D1E   SEG4COM0
29
#define D1F   SEG5COM0
30
#define D1G   SEG6COM0
31
#define D1DOT  SEG40COM0
32
33
//Digit2
34
#define D2A     SEG41COM0
35
#define D2B     SEG16COM0
36
#define D2C     SEG17COM0
37
#define D2D     SEG18COM0
38
#define D2E     SEG19COM0
39
#define D2F     SEG20COM0
40
#define D2G     SEG21COM0
41
#define D2DOT   SEG22COM0
42
43
//Digit3
44
#define D3A     SEG23COM0
45
#define D3B     SEG24COM0
46
#define D3C     SEG25COM0
47
#define D3D     SEG26COM0
48
#define D3E     SEG27COM0
49
#define D3F     SEG28COM0
50
#define D3G     SEG29COM0
51
#define D3DOT   SEG30COM0
52
53
//Digit4
54
#define D4A     SEG31COM0
55
#define D4B     SEG32COM0
56
#define D4C     SEG33COM0
57
#define D4D     SEG34COM0
58
#define D4E     SEG35COM0
59
#define D4F     SEG36COM0
60
#define D4G     SEG37COM0
61
#define D4DOT   SEG38COM0
62
63
#define COL    SEG8COM0  // double point
64
65
//Buttons
66
#define SW_mode   RC5
67
#define SW_temp    RC6
68
#define SW_down    RC4
69
#define SW_up    RB5
70
71
//LED's
72
#define red     RC1
73
#define green     RC0
74
#define blue     RD0
75
76
//MOSFET enable N chanel
77
#define temp_enable RD2
78
79
//Testpoint
80
#define TP2 RD1
81
82
//PROTOTYPES VARIABLES
83
84
//Time
85
unsigned char number=0;
86
unsigned char hour_high=0;
87
unsigned char hour_low=0;
88
unsigned char min_high=0;
89
unsigned char min_low=0;
90
unsigned char sec=0;
91
bit toggle =0;
92
unsigned char modify_digits=0;
93
unsigned char limit_digit2=0; 
94
95
//Stopwatch
96
unsigned char stop_min_high=0;
97
unsigned char stop_min_low=0;
98
unsigned char stop_sec_high=0;
99
unsigned char stop_sec_low=0;
100
bit start_flag=0;
101
bit break_flag=0;
102
bit stop_flag=0;
103
104
//Temperature
105
unsigned char set_time=0;
106
unsigned char temp_set=0;
107
int adc_value =0;
108
int temp_h=0;
109
int temp_l=0;
110
float temp=0;
111
112
//Buttons
113
unsigned char down_flag=0;
114
unsigned char status_down=0;
115
unsigned char up_flag=0;
116
unsigned char status_up=0;
117
unsigned char mode_flag=0;
118
unsigned char status_mode=0;
119
unsigned char mode_pressed=0;
120
121
//PROTOTYPES FUNCTIONS
122
123
void interrupt time(void);
124
void init(void);
125
void put_display(unsigned char digit1, unsigned char digit2, unsigned char digit3, unsigned char digit4);
126
void time_calculation(void);
127
void clear_all(void);
128
void read_temp(void);
129
void set_digits(void);
130
void stop_watch(void);
131
132
133
unsigned char button_up(void);
134
unsigned char button_down(void);
135
unsigned char button_mode(void);
136
137
//-------------------------------------------------------------------------------- Main --------------------------------------------------------------------------------------------------
138
139
main (void)
140
{
141
init();
142
143
  do
144
  {
145
    D1DOT=D2DOT=D3DOT=0;
146
    SLEEP();
147
    NOP();
148
    NOP();
149
  }while(1);
150
}
151
152
153
//--------------------------------------------------------------------------Interrupts --------------------------------------------------------------------------------------------------
154
155
//--------------------------------------------------------------------------Timer1 Interrupt --------------------------------------------------------------------------------------------------
156
void interrupt time (void)  
157
{
158
if(TMR1IF == 1)
159
{
160
  GIE=0;
161
  TMR1IE = 0;
162
  TMR1IF = 0;
163
  TMR1H=128;
164
  D1DOT=D2DOT=D3DOT=0;  
165
  sec++;              // count seconds
166
167
  TP2 = !TP2;
168
  COL = !COL;
169
170
    while(SW_temp == 1)
171
    {  
172
        GIE=1;
173
        TMR1IE = 1;  
174
        read_temp();
175
    }
176
  
177
    if(SW_mode == 1)      //Enter Clock SETUP
178
    {
179
    set_digits();
180
    }
181
182
183
  if((SW_up==1) || (stop_flag==1))  //Enter Stopwatch
184
  {
185
    stop_watch();
186
  }
187
  else
188
  {
189
    put_display(hour_high, hour_low, min_high, min_low);
190
  }
191
  
192
  time_calculation();
193
  blue=green=blue=0;
194
  GIE=1;              // Activate Interrupts
195
  TMR1IE = 1;  
196
  PEIE=1;
197
}
198
199
200
}
201
202
//-------------------------------------------------------------------------- Funktionen --------------------------------------------------------------------------------------------------
203
204
void init (void)
205
206
{
207
OSCCON = 0b1010111;    //1MHZ INTOSC Oscillator
208
209
//LCD initialisation::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
210
LCDSE0 = 0b11111111;  //  SE<7:0>
211
LCDSE1 = 0b10000001;  //  SE<15:8>
212
LCDSE2 = 0b11111111;  //  SE<23:16>
213
LCDSE3 = 0b11111111;  //  SE<31:24>
214
LCDSE4 = 0b11111111;  //  SE<39:32>
215
LCDSE5 = 0b00000011;  //  SE<41:40>
216
217
LCDCON = 0b10001100;  //   270Hz LCD Freqency LFINTOSC
218
LCDPS = 0b10110000;    //   Prescaler 1:1, Waveform B, Static mode
219
SLPEN = 0;        //  enable drive in sleep mode
220
LCDIE =1;        //  LCD INTERRUpt
221
  
222
LCDDATA0 = 0;      //  Clear all segments 
223
LCDDATA1 = 0;
224
LCDDATA2 = 0;
225
LCDDATA3 = 0;
226
LCDDATA12 = 0;
227
LCDDATA13 = 0;
228
LCDDATA14 = 0;
229
COL = 0;
230
231
//BUTTONS::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
232
TRISC6=1;        //  SW_temp Input
233
TRISC5=1;        //  SW_mode Input
234
TRISC4=1;        //  SW_down Input
235
TRISB5=1;        //  SW_up Input
236
237
//MOSFET enable N chanel
238
TRISD2 = 0;        //  TRISTATE
239
temp_enable = 1;
240
241
//Testpoint
242
TRISD1 = 0;        //  TP2 Toggle PIN
243
TRISA1 = 1;        //  TP1  VDD
244
245
246
//LED's::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
247
TRISC1=0;        //  red LED
248
TRISC0=0;        //  green LED
249
TRISD0=0;        //  blue LED
250
red = green = blue =0;
251
252
// Timer1 Registers: Prescaler=1:1; TMR1 Preset=57344; Freq=1.00Hz; Period=1.00 s
253
T1CKPS1 = 0;       // bits 5-4  Prescaler Rate Select bits
254
T1CKPS0 = 0;        // bit 4
255
256
T1OSCEN = 1;        // bit 3 Timer1 Oscillator Enable Control: bit 1=on
257
T1SYNC  = 1;        // bit 2 Timer1 External Clock Input Synchronization Control bit:1=Do not synchronize external clock input
258
TMR1CS  = 1;        // bit 1 Timer1 Clock Source Select bit:0=Internal clock (FOSC/4) / 1 = External clock from pin T1CKI (on the rising edge)
259
260
TMR1H = 0;             // preset for timer1 MSB register
261
TMR1L = 0;             // preset for timer1 LSB register
262
263
TMR1IF=0;
264
265
GIE = 1;
266
PEIE = 1;
267
TMR1IE = 1;
268
269
TMR1H = 128;          // preset for timer1 MSB register  224 for 32k/4
270
//TMR1L = 45;           // preset for timer1 LSB register
271
TMR1ON  = 1;        // bit 0 enables timer
272
273
//ADC Temperature::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
274
TRISA1=1;        //AN1 = Input
275
TRISA2=1;        //AN2 = Input
276
ANSEL = 0b00000110;    //AN1 and AN2 = Analog
277
ADCON0 = 0b10101000;  //ADFM=1.RJ,Vref-=VSS,Vref+=PIN,AN2 select010, GODONE=0,ADON=A/D operrating statusbit
278
ADCON1 = 0b10000000;  //Conversation time between 1.6us and 6.4us = FOSC/2 =(1/32768) = ~30us*2 =60us
279
ADRESH=0;
280
ADRESL=0;
281
282
//SHOW 00:00  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
283
put_display(0, 0, 0, 0);
284
285
}
286
287
//TIME CALCULATION:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
288
void time_calculation()
289
{
290
291
if(sec > 59)
292
{
293
  sec = 0;
294
  min_low++;
295
}
296
297
if(min_low > 9)
298
{
299
  min_low=0;
300
  min_high++;
301
}
302
303
if(min_high > 5)
304
{
305
  min_high=0;
306
  hour_low++;
307
}
308
if(hour_low > 9)
309
{
310
  hour_low=0;
311
  hour_high++;
312
}
313
314
if( (hour_high >= 2) && (hour_low >= 4) )
315
{
316
  hour_high=0;
317
  hour_low=0;
318
  min_high=0;
319
  min_low=0;
320
  sec=0;
321
}
322
323
324
}
325
326
//READ_TEMPERATURE:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
327
void read_temp(void)
328
{
329
  TRISD2=0;
330
  temp_enable=0;      //N-MOS enable
331
  ADCON0 = 0b10101000;  //ADFM=1.RJ,Vref-=VSS,Vref+=PIN,AN2 select010, GODONE=0,ADON=A/D operrating statusbit
332
  green =1;
333
  ADON=1;          //enable ADC module
334
  GO_DONE=1;        //Start conversation
335
  while(GO_DONE ==1);    //Wait for complete conversation
336
  temp_h = ADRESH;
337
  temp_l = ADRESL;
338
  
339
  adc_value = ((temp_h<<8) | temp_l);
340
  temp = ((adc_value*0.00244)/0.021) ; // Optimation0.0024414)/0.023)
341
  ADON=0;
342
  temp_h = temp/10;
343
  temp_l = temp-(temp_h*10);
344
  clear_all();
345
  put_display(temp_h, temp_l, '°','C' );
346
  temp_h = temp_l =0;
347
  ADON=0;
348
  green=0;
349
  temp_enable=1;
350
  //TRISD2=1;        //TRISTATE N-MOS disable
351
}
352
353
//SET_TIME::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
354
void set_digits(void)
355
{
356
put_display('°', '°', '°', '°');
357
COL=1;
358
blue=1;
359
hour_high = hour_low = min_high = min_low = 0;
360
while(SW_mode ==1);
361
362
do                              //DIGIT1
363
{
364
D1DOT=1;
365
  if(button_up()==1)
366
  {
367
    if((hour_high>=0) && (hour_high <2))
368
      {
369
      hour_high++;
370
      put_display(hour_high, '°', '°', '°');
371
      }
372
  }
373
  if(button_down())
374
  {
375
    if((hour_high>0) && (hour_high <3))
376
      {
377
      hour_high--;
378
      put_display(hour_high, '°', '°', '°');
379
      }
380
   }
381
}while(button_mode()==0);
382
if(hour_high == '°'){hour_high=0;}
383
put_display(hour_high, '°', '°', '°');
384
D1DOT=0;
385
386
do                              //DIGIT2
387
{
388
D2DOT=1;
389
if(hour_high >=2)
390
{
391
limit_digit2 = 3;
392
}
393
else
394
{
395
limit_digit2 = 9;
396
}
397
398
  if(button_up()==1)
399
  {
400
    if((hour_low>=0) && (hour_low < limit_digit2))    //VARIABLE FOR <24:00
401
      {
402
      hour_low++;
403
      put_display(hour_high, hour_low, '°', '°');
404
      }
405
  }
406
  if(button_down())
407
  {
408
    if((hour_low>0) && (hour_low < limit_digit2+1))
409
      {
410
      hour_low--;
411
      put_display(hour_high, hour_low, '°', '°');
412
      }
413
   }
414
}while(button_mode()==0);
415
if(hour_low == '°'){hour_low=0;}
416
put_display(hour_high, hour_low, '°', '°');
417
D2DOT=0;
418
419
do                              //DIGIT3
420
{
421
D3DOT=1;
422
  if(button_up()==1)
423
  {
424
    if((min_high>=0) && (min_high <5))
425
      {
426
      min_high++;
427
      put_display(hour_high, hour_low, min_high, '°');
428
      }
429
  }
430
  if(button_down())
431
  {
432
    if((min_high>0) && (min_high <6))
433
      {
434
      min_high--;
435
      put_display(hour_high, hour_low, min_high, '°');
436
      }
437
   }
438
}while(button_mode()==0);
439
if(min_high == '°'){min_high=0;}
440
put_display(hour_high, hour_low, min_high, '°');
441
D3DOT=0;
442
443
do                              //DIGIT4
444
{
445
  if(button_up()==1)
446
  {
447
    if((min_low>=0) && (min_low <9))
448
      {
449
      min_low++;
450
      put_display(hour_high, hour_low, min_high, min_low);
451
      }
452
  }
453
  if(button_down())
454
  {
455
    if((min_low>0) && (min_low <10))
456
      {
457
      min_low--;
458
      put_display(hour_high, hour_low, min_high, min_low);
459
      }
460
   }
461
}while(button_mode()==0);
462
if(min_high == '°'){min_high=0;}
463
put_display(hour_high, hour_low, min_high, min_low);
464
465
blue=0;
466
sec=0;
467
}
468
469
//STOP_WATCH:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
470
void stop_watch(void)
471
{
472
stop_flag =1;
473
red=1;
474
while( (SW_up==1) && (start_flag ==0));      //WAIT for start press
475
while( (button_up()==0) && (start_flag ==0));
476
start_flag=1;
477
red=0;
478
green=1;
479
480
if(SW_up==1)
481
{
482
  red=1;
483
  break_flag=1;
484
}
485
486
if(break_flag==0)
487
{
488
  stop_sec_low++;
489
}
490
else
491
{
492
  COL=1;
493
  red=1;
494
  green=0;
495
  
496
  if(SW_down==1)
497
  {
498
    stop_sec_high = stop_sec_low = stop_min_high = stop_min_low = 0;
499
    break_flag=0;
500
  }
501
}
502
    
503
    
504
    
505
if(stop_sec_low > 9)
506
{
507
  stop_sec_low=0;
508
  stop_sec_high++;
509
}
510
if(stop_sec_high > 5)
511
{
512
  stop_sec_high=0;
513
  stop_min_low++;
514
}
515
if(stop_min_low > 9)
516
{
517
  stop_min_low=0;
518
  stop_min_high++;
519
}
520
if(stop_min_high > 5)
521
{
522
  stop_sec_high = stop_sec_low = stop_min_high = stop_min_low = 0;
523
}
524
525
526
527
  put_display(stop_min_high, stop_min_low, stop_sec_high, stop_sec_low);
528
529
530
531
532
if ( (SW_up==1) && (SW_down==1) )  //FINISH STOP WATCH    //(SW_up==1) && (SW_down==1))  //FINISH STOP WATCH
533
{
534
blue=1;
535
stop_flag=0;
536
red = green =0;
537
start_flag=0;
538
while((SW_up==1) && (SW_down==1));
539
blue=0;
540
}
541
542
}
543
544
//DISPLAY:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
545
546
void put_display(unsigned char digit1, unsigned char digit2, unsigned char digit3, unsigned char digit4)
547
{
548
549
D1A = D1B = D1C = D1D = D1E = D1F = D1G = 0; //Clear  
550
switch(digit1)
551
  {  
552
    case 0:
553
      D1A = D1B = D1C = D1D = D1E = D1F = 1;
554
      break;    
555
    case 1:
556
      D1B = D1C = 1;          
557
      break;
558
    case 2:
559
      D1A = D1B = D1G = D1E = D1D = 1;
560
      break;
561
    case 3:
562
      D1A = D1B = D1G = D1C = D1D = 1;
563
      break;
564
    case 4:
565
      D1F = D1G = D1B = D1C = 1;
566
      break;
567
    case 5:
568
      D1A = D1F = D1G = D1C = D1D = 1;
569
      break;
570
    case 6:
571
      D1A = D1F = D1E = D1D = D1C = D1G = 1;
572
      break;
573
    case 7:
574
      D1A = D1B = D1C = 1;
575
      break;
576
    case 8:
577
      D1A = D1B = D1C = D1D = D1E = D1F = D1G = 1;
578
      break;
579
    case 9:
580
      D1A = D1B = D1C = D1D = D1F = D1G = 1;
581
      break;
582
    case '°':
583
      D1A = D1B = D1F = D1G = 1;
584
      break;
585
    case 'C':
586
      D1A = D1D = D1E = D1F = 1;
587
      break;
588
    }
589
590
591
D2A = D2B = D2C = D2D = D2E = D2F = D2G = 0; //Clear
592
switch(digit2)
593
  {
594
    case 0:
595
      D2A = D2B = D2C = D2D = D2E = D2F = 1;
596
      break;  
597
    case 1:
598
      D2B = D2C = 1;       
599
      break;
600
    case 2:
601
      D2A = D2B = D2G = D2E = D2D = 1;
602
      break;
603
    case 3:
604
      D2A = D2B = D2G = D2C = D2D = 1;
605
      break;
606
    case 4:
607
      D2F = D2G = D2B = D2C = 1;
608
      break;
609
    case 5:
610
      D2A = D2F = D2G = D2C = D2D = 1;
611
      break;
612
    case 6:
613
      D2A = D2F = D2E = D2D = D2C = D2G = 1;
614
      break;
615
    case 7:
616
      D2A = D2B = D2C = 1;
617
      break;
618
    case 8:
619
      D2A = D2B = D2C = D2D = D2E = D2F = D2G = 1;
620
      break;
621
    case 9:
622
      D2A = D2B = D2C = D2D = D2F = D2G = 1;
623
      break;
624
    case '°':
625
      D2A = D2B = D2F = D2G = 1;
626
      break;
627
    case 'C':
628
      D2A = D2D = D2E = D2F = 1;
629
      break;
630
    }
631
632
D3A = D3B = D3C = D3D = D3E = D3F = D3G = 0; //Clear
633
switch(digit3)
634
  {
635
    case 0:
636
      D3A = D3B = D3C = D3D = D3E = D3F = 1;
637
      break;  
638
    case 1:
639
      D3B = D3C = 1;          
640
      break;
641
    case 2:
642
      D3A = D3B = D3G = D3E = D3D = 1;
643
      break;
644
    case 3:
645
      D3A = D3B = D3G = D3C = D3D = 1;
646
      break;
647
    case 4:
648
      D3F = D3G = D3B = D3C = 1;
649
      break;
650
    case 5:
651
      D3A = D3F = D3G = D3C = D3D = 1;
652
      break;
653
    case 6:
654
      D3A = D3F = D3E = D3D = D3C = D3G = 1;
655
      break;
656
    case 7:
657
      D3A = D3B = D3C = 1;
658
      break;
659
    case 8:
660
      D3A = D3B = D3C = D3D = D3E = D3F = D3G = 1;
661
      break;
662
    case 9:
663
      D3A = D3B = D3C = D3D = D3F = D3G = 1;
664
      break;
665
    case '°':
666
      D3A = D3B = D3F = D3G = 1;
667
      break;
668
    case 'C':
669
      D3A = D3D = D3E = D3F = 1;
670
      break;
671
    }
672
D4A = D4B = D4C = D4D = D4E = D4F = D4G = 0; //Clear
673
switch(digit4)
674
  {
675
    case 0:
676
      D4A = D4B = D4C = D4D = D4E = D4F = 1;
677
      break;  
678
    case 1:
679
      D4B = D4C = 1;         
680
      break;
681
    case 2:
682
      D4A = D4B = D4G = D4E = D4D = 1;
683
      break;
684
    case 3:
685
      D4A = D4B = D4G = D4C = D4D = 1;
686
      break;
687
    case 4:
688
      D4F = D4G = D4B = D4C = 1;
689
      break;
690
    case 5:
691
      D4A = D4F = D4G = D4C = D4D = 1;
692
      break;
693
    case 6:
694
      D4A = D4F = D4E = D4D = D4C = D4G = 1;
695
      break;
696
    case 7:
697
      D4A = D4B = D4C = 1;
698
      break;
699
    case 8:
700
      D4A = D4B = D4C = D4D = D4E = D4F = D4G = 1;
701
      break;
702
    case 9:
703
      D4A = D4B = D4C = D4D = D4F = D4G = 1;
704
      break;
705
    case '°':
706
      D4A = D4B = D4F = D4G = 1;
707
      break;
708
    case 'C':
709
      D4A = D4D = D4E = D4F = 1;
710
      break;
711
    }
712
713
}
714
715
void clear_all(void)
716
{
717
LCDDATA0 = 0;
718
LCDDATA1 = 0;
719
LCDDATA2 = 0;
720
LCDDATA3 = 0;
721
LCDDATA12 = 0;
722
LCDDATA13 = 0;
723
LCDDATA14 = 0;
724
}
725
726
unsigned char button_up(void)
727
{
728
if(SW_up == 1)          
729
  {
730
  up_flag=1;
731
  }
732
status_up=0;
733
if((SW_up==0) && (up_flag==1))
734
  {
735
  up_flag =0;
736
      status_up=1;
737
  }
738
return (status_up);
739
}
740
741
unsigned char button_down(void)
742
{
743
if(SW_down == 1)          
744
  {
745
  down_flag=1;
746
  }
747
status_down=0;
748
if((SW_down==0) && (down_flag==1))
749
  {
750
  down_flag =0;
751
      status_down=1;
752
  }
753
return (status_down);
754
}
755
756
unsigned char button_mode(void)
757
{
758
if(SW_mode == 1)          
759
  {
760
  mode_flag=1;
761
  }
762
status_mode=0;
763
if((SW_mode==0) && (mode_flag==1))
764
  {
765
  mode_flag =0;
766
      status_mode=1;
767
  }
768
return (status_mode);
769
}
770
771
772
//EXAMPLE::::::::::::::::::::::::::::::::::::::::::::::::::::::
773
//GIE=0;    //  LED's überprüfen
774
//
775
//if(SW_mode==1)
776
//{
777
//green=1;
778
//}
779
//else{green=0;}
780
//if(SW_down==1)
781
//{
782
//red=1;
783
//}else{red=0;}
784
//if(SW_up==1)
785
//{
786
//blue=1;
787
//}else{blue=0;}