Forum: Mikrocontroller und Digitale Elektronik Controller hängt sich unregelmäßig auf


von Mike M. (mikeii)


Lesenswert?

Hi,

ich habe ein umfangreicheres Programm für meine Wordclock geschrieben.
Die Frage ist, wann und wo es sich aufhängt, da die Uhr einfach 
irgendwann mal stehen bleibt.
Den Code habe ich jetzt schon zwei mal durch, sehe aber keine 
Möglichkeit wo ein Überlauf entstehen kann, es gibt keine Interrupts, 
Wertzuweisungen  sind alle okay, etc.

Gibt es eine Möglichkeit, wie ich rausfinden kann, wo das Problem hängt?

Danke

von Udo S. (urschmitt)


Lesenswert?

Sind die Spannungen ok?
Wenn du noch Pins frei hast kannst du an den Verdachtsstellen 
(Schleifen) Port Pins auf eindeutige Werte setzen und wenn er 
"abgestürzt" ist anhand der Port Pin Spannungen schauen in welcher 
Schleife er kreist.

von Kevin (Gast)


Lesenswert?

Hm, meine Glaskugel ist beim Service.
Vielleicht hast du die Uhr zu wenig aufgezogen.

Schaltung, Programmcode usw. wären sehr hilfreich,
ansonsten sehe ich 'dunkelschwarz'.

von Mike M. (mikeii)


Lesenswert?

Spannungen passen alle, sind bei 4,9 Volt laut Multimeter.

Die Schleifen habe ich auch schon alle geprüft, beim Eintritt der 
Schleife einen Pin auf High, und direkt danach auf Low.
"Leider" hängt er sich in keiner Schleife auf.
Und das Programm ist sehr komplex, als das ich überall diese Checks 
machen könnte.
Aber wahrscheinlich geht es erstmal nicht anderst und ich sollte einfach 
mal alles durchechecken

von Mike M. (mikeii)


Lesenswert?

Ich hoffe der Code ist nicht zu "minderwertig"
Als Echtzeituhr kommt eine DS1307 zum Einsatz.

Unter der Settime.c nicht wundern, warum ich das byte zum Senden so 
komisch generiere, da ich gestern Nacht ein paar Denkfehler hatte, bis 
ich wieder ins Datenblatt der DS3017 geschaut habe. Man kann es um 
einiges kürzer machen, aber ich denke so müsste es passen.
Format ist folgendes:

Für die Minuten:

0  | 3bit für die Zehnerstelle der Minuten  |  4 bit für die Einer der 
Minuten

Für die Stunden im 24h Modus:

00 | 2 bit für Zehnerstelle der Stunden | 4 bit für die Einer der 
Minuten


das TWI_SEND(0x00,0x00) ist dafür da, falls jemand die Batterie aus der 
RTC nimmt, damit der Clock wieder aktiviert wird.

main.c
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/signal.h>
4
#include <util/delay.h>
5
#include <stdlib.h>
6
#include <avr/pgmspace.h>
7
#include <stdint.h>
8
#include "i2c.c"
9
#include "settime.c"
10
11
12
#define BAUD 9600UL
13
#define UBRR_VAL 51
14
15
#define SHOW    PORTB |= _BV(PB4)
16
17
#define BLAU    0,0,1
18
#define GRUEN   0,1,0
19
#define TURKIS  0,1,1
20
#define ROT     1,0,0
21
#define LILA    1,0,1
22
#define ORANGE  1,1,0
23
#define WEISS   1,1,1
24
#define FASTPWM TCCR2 &= ~(1<<CS22);TCCR2 |= (1<<CS21);
25
#define SLOWPWM TCCR2 &= ~(1<<CS21);TCCR2 |= (1<<CS22);
26
#define PWM_AUS TCCR2 &= ~(1<<WGM20) & ~(1<<COM21) & ~(1<<CS22) & ~(1<<CS20);
27
#define PWM_AN TCCR2 |= (1<<WGM20) | (1<<COM21) | (1<<CS22) | (1<<CS20);
28
29
30
31
32
uint8_t karth_to_line(uint8_t x,uint8_t y);
33
void set_global_colors(uint8_t r,uint8_t g,uint8_t b);
34
uint8_t get_color_code(uint8_t r,uint8_t g,uint8_t b,uint8_t modr,uint8_t modg,uint8_t modb,uint8_t latch);
35
void put_pixel_on_strip(uint8_t x,uint8_t y,uint8_t modus,uint8_t r,uint8_t g,uint8_t b);
36
void timer1 (void);
37
void master_init (void);
38
void master_transmit (uint16_t data);
39
void init_line(void);
40
void init_strip(void);
41
void grid_add_pixel(uint8_t x,uint8_t y);
42
void grid_flush(void);
43
void send_line(uint8_t effect);
44
void init_grey_line(void);
45
void init_grey_line_buffer(void);
46
void buffer_grey_line(void);
47
void grid_push_up(uint8_t n);
48
void grid_push_down(uint8_t n);
49
void flush(void);
50
void display_time(uint8_t fade, uint8_t effect);
51
void matrix_effect(void);
52
53
54
unsigned char status = 0;
55
volatile unsigned char count;
56
uint8_t globalcoloron = 0b10000010;
57
uint8_t globalcolor_fade_on = 0b10000000;
58
uint8_t globalcolor_fade_off = 0b10000000;
59
uint8_t global_r;
60
uint8_t global_g;
61
uint8_t global_b;
62
uint8_t line[100];
63
uint8_t grey_line[100];
64
uint8_t grey_line_buffer[100];
65
uint8_t grid[10][10];
66
uint8_t hours=5,minutes=0;
67
uint8_t nightmode = 0;
68
69
70
71
void time_to_array(uint8_t hours,uint8_t minutes)
72
{
73
74
    //Array leeren
75
    grid_flush();
76
77
    //Pixel in Array füllen
78
79
    //ES IST
80
    grid_add_pixel(0,0);
81
    grid_add_pixel(1,0);
82
    grid_add_pixel(4,0);
83
    grid_add_pixel(5,0);
84
    grid_add_pixel(6,0);
85
86
87
88
    //Minuten anzeige
89
    if(minutes >= 5 && minutes < 10)
90
    {
91
        //Fünf
92
93
        grid_add_pixel(1,1);
94
        grid_add_pixel(2,1);
95
        grid_add_pixel(3,1);
96
        grid_add_pixel(4,1);
97
        //Nach
98
        grid_add_pixel(0,3);
99
        grid_add_pixel(1,3);
100
        grid_add_pixel(2,3);
101
        grid_add_pixel(3,3);
102
    }
103
    else if(minutes >= 10 && minutes < 15)
104
    {
105
        //Zehn
106
        grid_add_pixel(6,1);
107
        grid_add_pixel(7,1);
108
        grid_add_pixel(8,1);
109
        grid_add_pixel(9,1);
110
        //Nach
111
        grid_add_pixel(0,3);
112
        grid_add_pixel(1,3);
113
        grid_add_pixel(2,3);
114
        grid_add_pixel(3,3);
115
    }
116
    else if(minutes >= 15 && minutes < 20)
117
    {
118
        //Viertel
119
        grid_add_pixel(3,2);
120
        grid_add_pixel(4,2);
121
        grid_add_pixel(5,2);
122
        grid_add_pixel(6,2);
123
        grid_add_pixel(7,2);
124
        grid_add_pixel(8,2);
125
        grid_add_pixel(9,2);
126
127
        //Nach
128
        grid_add_pixel(0,3);
129
        grid_add_pixel(1,3);
130
        grid_add_pixel(2,3);
131
        grid_add_pixel(3,3);
132
    }
133
    else if(minutes >= 20 && minutes < 25)
134
    {
135
136
        //Zehn
137
        grid_add_pixel(6,1);
138
        grid_add_pixel(7,1);
139
        grid_add_pixel(8,1);
140
        grid_add_pixel(9,1);
141
        //Vor
142
        grid_add_pixel(6,3);
143
        grid_add_pixel(7,3);
144
        grid_add_pixel(8,3);
145
        //Halb
146
        grid_add_pixel(0,4);
147
        grid_add_pixel(1,4);
148
        grid_add_pixel(2,4);
149
        grid_add_pixel(3,4);
150
151
    }
152
    else if(minutes >= 25 && minutes < 30)
153
    {
154
        //Fünf
155
        grid_add_pixel(1,1);
156
        grid_add_pixel(2,1);
157
        grid_add_pixel(3,1);
158
        grid_add_pixel(4,1);
159
        //Vor
160
        grid_add_pixel(6,3);
161
        grid_add_pixel(7,3);
162
        grid_add_pixel(8,3);
163
        //Halb
164
        grid_add_pixel(0,4);
165
        grid_add_pixel(1,4);
166
        grid_add_pixel(2,4);
167
        grid_add_pixel(3,4);
168
    }
169
    else if(minutes >= 30 && minutes < 35)
170
    {
171
        //Halb
172
        grid_add_pixel(0,4);
173
        grid_add_pixel(1,4);
174
        grid_add_pixel(2,4);
175
        grid_add_pixel(3,4);
176
    }
177
    else if(minutes >= 35 && minutes < 40)
178
    {
179
        //Fünf
180
        grid_add_pixel(1,1);
181
        grid_add_pixel(2,1);
182
        grid_add_pixel(3,1);
183
        grid_add_pixel(4,1);
184
        //Nach
185
        grid_add_pixel(0,3);
186
        grid_add_pixel(1,3);
187
        grid_add_pixel(2,3);
188
        grid_add_pixel(3,3);
189
        //Halb
190
        grid_add_pixel(0,4);
191
        grid_add_pixel(1,4);
192
        grid_add_pixel(2,4);
193
        grid_add_pixel(3,4);
194
    }
195
    else if(minutes >= 40 && minutes < 45)
196
    {
197
        //Zehn
198
        grid_add_pixel(6,1);
199
        grid_add_pixel(7,1);
200
        grid_add_pixel(8,1);
201
        grid_add_pixel(9,1);
202
        //Nach
203
        grid_add_pixel(0,3);
204
        grid_add_pixel(1,3);
205
        grid_add_pixel(2,3);
206
        grid_add_pixel(3,3);
207
        //Halb
208
        grid_add_pixel(0,4);
209
        grid_add_pixel(1,4);
210
        grid_add_pixel(2,4);
211
        grid_add_pixel(3,4);
212
    }
213
    else if(minutes >= 45 && minutes < 50)
214
    {
215
        //Viertel
216
        grid_add_pixel(3,2);
217
        grid_add_pixel(4,2);
218
        grid_add_pixel(5,2);
219
        grid_add_pixel(6,2);
220
        grid_add_pixel(7,2);
221
        grid_add_pixel(8,2);
222
        grid_add_pixel(9,2);
223
        //Vor
224
        grid_add_pixel(6,3);
225
        grid_add_pixel(7,3);
226
        grid_add_pixel(8,3);
227
    }
228
    else if(minutes >= 50 && minutes < 55)
229
    {
230
        //Zehn
231
        grid_add_pixel(6,1);
232
        grid_add_pixel(7,1);
233
        grid_add_pixel(8,1);
234
        grid_add_pixel(9,1);
235
        //Vor
236
        grid_add_pixel(6,3);
237
        grid_add_pixel(7,3);
238
        grid_add_pixel(8,3);
239
240
    }
241
    else if(minutes >= 55 && minutes < 60)
242
    {
243
244
        //Fünf
245
        grid_add_pixel(1,1);
246
        grid_add_pixel(2,1);
247
        grid_add_pixel(3,1);
248
        grid_add_pixel(4,1);
249
        //Vor
250
        grid_add_pixel(6,3);
251
        grid_add_pixel(7,3);
252
        grid_add_pixel(8,3);
253
    }
254
255
    //Stunden auf 12h-Format Konvertieren
256
    if(hours >= 12)
257
    {
258
        hours -= 12;
259
    }
260
261
    if(minutes >= 20)
262
    {
263
        hours++;
264
    }
265
    if(hours == 12)
266
    {
267
        hours = 0;
268
    }
269
270
271
272
    switch(hours)
273
    {
274
    case 0:
275
        //Zwölf
276
        grid_add_pixel(0,9);
277
        grid_add_pixel(1,9);
278
        grid_add_pixel(2,9);
279
        grid_add_pixel(3,9);
280
        grid_add_pixel(4,9);
281
        break;
282
    case 1:
283
        //EIN(S)
284
        grid_add_pixel(2,7);
285
        grid_add_pixel(3,7);
286
        grid_add_pixel(4,7);
287
        if(minutes > 4)
288
        {
289
            grid_add_pixel(5,7);
290
        };
291
        break;
292
    case 2:
293
        //Zwei
294
        grid_add_pixel(6,8);
295
        grid_add_pixel(7,8);
296
        grid_add_pixel(8,8);
297
        grid_add_pixel(9,8);
298
        break;
299
    case 3:
300
        //Drei
301
        grid_add_pixel(0,7);
302
        grid_add_pixel(1,7);
303
        grid_add_pixel(2,7);
304
        grid_add_pixel(3,7);
305
        break;
306
    case 4:
307
        //Vier
308
        grid_add_pixel(1,6);
309
        grid_add_pixel(2,6);
310
        grid_add_pixel(3,6);
311
        grid_add_pixel(4,6);
312
        break;
313
    case 5:
314
        //Fünf
315
        grid_add_pixel(2,8);
316
        grid_add_pixel(3,8);
317
        grid_add_pixel(4,8);
318
        grid_add_pixel(5,8);
319
        break;
320
    case 6:
321
        //Sechs
322
        grid_add_pixel(5,7);
323
        grid_add_pixel(6,7);
324
        grid_add_pixel(7,7);
325
        grid_add_pixel(8,7);
326
        grid_add_pixel(9,7);
327
        break;
328
    case 7:
329
        //Sieben
330
        grid_add_pixel(4,5);
331
        grid_add_pixel(5,5);
332
        grid_add_pixel(6,5);
333
        grid_add_pixel(7,5);
334
        grid_add_pixel(8,5);
335
        grid_add_pixel(9,5);
336
        break;
337
    case 8:
338
        //Acht
339
        grid_add_pixel(0,5);
340
        grid_add_pixel(1,5);
341
        grid_add_pixel(2,5);
342
        grid_add_pixel(3,5);
343
        break;
344
    case 9:
345
        //Neun
346
        grid_add_pixel(6,4);
347
        grid_add_pixel(7,4);
348
        grid_add_pixel(8,4);
349
        grid_add_pixel(9,4);
350
        break;
351
    case 10:
352
        //Zehn
353
        grid_add_pixel(5,6);
354
        grid_add_pixel(6,6);
355
        grid_add_pixel(7,6);
356
        grid_add_pixel(8,6);
357
        break;
358
    case 11:
359
        //Elf
360
        grid_add_pixel(0,8);
361
        grid_add_pixel(1,8);
362
        grid_add_pixel(2,8);
363
        break;
364
    }
365
    if(minutes < 5)
366
    {
367
        grid_add_pixel(7,9);
368
        grid_add_pixel(8,9);
369
        grid_add_pixel(9,9);
370
    }
371
372
373
}
374
375
void array_to_line(uint8_t *array)
376
{
377
378
    for(uint8_t x = 0; x<10; x++)
379
    {
380
        for(uint8_t y = 0; y<10; y++)
381
        {
382
            grey_line[karth_to_line(x,y)] = array[x*10+y];
383
        }
384
    }
385
386
387
}
388
389
void grid_add_pixel(uint8_t x,uint8_t y)
390
{
391
392
    grid[x][y] = 1;
393
394
}
395
void grid_flush(void)
396
{
397
398
    for(uint8_t i=0; i<10; i++)
399
    {
400
        for(uint8_t j=0; j<10; j++)
401
        {
402
            grid[i][j] = 0;
403
        }
404
    }
405
406
}
407
408
void assemble_line(uint8_t mode)
409
{
410
411
    //Mode 1 = Faden
412
    //Mode X = Static On
413
    //Mode 2 = Nightmode
414
    //GreyLine Buffern
415
    buffer_grey_line();
416
    //Array in Line convertieren
417
    init_grey_line();
418
419
    array_to_line(&grid[0][0]);
420
421
422
423
424
    //Löschen der Line
425
    init_line();
426
427
    if(mode == 1)
428
    {
429
430
        for (int i=0; i<100; i++)
431
        {
432
433
            if((grey_line[i] == 0) && (grey_line_buffer[i] == 0))
434
            {
435
                line[i] = 0b10000000;
436
            }
437
            if((grey_line[i] == 1) && (grey_line_buffer[i] == 1))
438
            {
439
                //ON
440
                line[i] = globalcoloron;
441
            }
442
            if((grey_line[i] == 1) && (grey_line_buffer[i] == 0))
443
            {
444
                //Fade On
445
                line[i] = globalcolor_fade_on;
446
            }
447
            if((grey_line[i] == 0) && (grey_line_buffer[i] == 1))
448
            {
449
                //Fade Off
450
                line[i] = globalcolor_fade_off;
451
            }
452
453
454
        }
455
    }
456
    else if(mode == 2)
457
    {
458
        for(uint8_t i = 0; i<100; i++)
459
        {
460
            if(grey_line[i] == 1)
461
            {
462
                line[i] = globalcolor_fade_on;
463
464
            }
465
        }
466
467
    }
468
    else
469
    {
470
        for(uint8_t i = 0; i<100; i++)
471
        {
472
            if(grey_line[i] == 1)
473
            {
474
                line[i] = globalcoloron;
475
476
            }
477
        }
478
    }
479
480
}
481
482
483
484
void send_line(uint8_t effect)
485
{
486
487
    if((effect == 1) && (minutes%5 == 0))
488
    {
489
490
491
        for(uint8_t j=0; j<10; j++)
492
        {
493
            if(minutes < 5)
494
            {
495
                time_to_array(hours-1,59);
496
            }
497
            else
498
            {
499
                time_to_array(hours,minutes-5);
500
            }
501
502
503
504
            grid_push_down(j);
505
            assemble_line(0);
506
            for(uint8_t i=0; i<100; i++)
507
            {
508
                master_transmit(line[i]);
509
            }
510
            SHOW;
511
            _delay_ms(300);
512
        }
513
514
        for(uint8_t j=0; j<10; j++)
515
        {
516
            time_to_array(hours,minutes);
517
            grid_push_up(10-j);
518
            assemble_line(0);
519
            for(uint8_t i=0; i<100; i++)
520
            {
521
                master_transmit(line[i]);
522
            }
523
            SHOW;
524
            _delay_ms(300);
525
526
        }
527
        time_to_array(hours,minutes);
528
        assemble_line(0);
529
530
        for(uint8_t i=0; i<100; i++)
531
        {
532
            master_transmit(line[i]);
533
        }
534
        SHOW;
535
        _delay_ms(300);
536
537
    }
538
    else
539
    {
540
        for(uint8_t i=0; i<100; i++)
541
        {
542
            master_transmit(line[i]);
543
544
        }
545
        SHOW;
546
    }
547
548
549
}
550
551
///<____MATRIX EFFECT
552
void matrix_effect(void)
553
{
554
555
    uint8_t x,y,uart_zeichen;
556
    uint8_t feld[10][10];
557
    init_strip();
558
559
    //PWM AN, falss Nightmode sie aus gemacht hat
560
    PWM_AN;
561
    //Feld nullen
562
    for(uint8_t i = 0; i<10; i++)
563
    {
564
        for(uint8_t j = 0; j<10; j++)
565
        {
566
            feld[i][j] = 0;
567
        }
568
    }
569
570
    ///Bit von oben einfüllen
571
572
    while(1)
573
    {
574
575
576
        if(rand() % 4 > 1)
577
578
        {
579
            do
580
            {
581
                x = rand()%10;
582
                y = 9 - rand()%2;
583
            }
584
            while((feld[x][y] == 1)||(feld[x][y-1] == 1)||(feld[x][y-2] == 1));
585
586
587
            feld[x][y] = 1;
588
589
        }
590
        //Array nach unten kopieren
591
592
593
        for(uint8_t yc = 0; yc <9; yc++)
594
        {
595
            for(uint8_t xc = 0; xc <10; xc++)
596
            {
597
                feld[xc][yc] = feld[xc][yc+1];
598
            }
599
        }
600
        for(uint8_t xc = 0; xc <10; xc++)
601
        {
602
            feld[xc][9] = 0;
603
        }
604
605
606
607
        ///Feld Ausgeben
608
        for(uint8_t x = 0; x<10; x++)
609
        {
610
            for(uint8_t y = 0; y<10; y++)
611
            {
612
                if(feld[x][y]==1)
613
                    put_pixel_on_strip(x,y,2,0,1,0);
614
            }
615
        }
616
617
        if((UCSRA & (1<<RXC)))
618
        {
619
            uart_zeichen = UDR;
620
            if(uart_zeichen == 'e')
621
            {
622
                //PWM aus, wenn nightmode an!
623
                if(nightmode)
624
                {
625
                    PWM_AUS;
626
                }
627
                return;
628
            }
629
        }
630
        _delay_ms(900);
631
632
    }
633
}
634
635
636
void set_global_colors(uint8_t r,uint8_t g,uint8_t b)
637
{
638
639
    //OFF  00
640
    //ON   01
641
    //FON  10
642
    //FOFF 11
643
    //BBRRGG
644
645
    //BB
646
    globalcoloron = 0b10000000 | (b<<4 & 0b10000);
647
    //RR
648
    globalcoloron |= (r<<2 & 0b100);
649
    //GG
650
    globalcoloron |= g;
651
    //BB
652
    globalcolor_fade_on = 0b10000000 | (b<<5 & 0b100000);
653
    //RR
654
    globalcolor_fade_on |= (r<<3 & 0b1000);
655
    //GG
656
    globalcolor_fade_on |= (g<<1 & 0b10);
657
658
    //BB
659
    globalcolor_fade_off = 0b10000000 | (b<<5 & 0b100000);
660
    globalcolor_fade_off |= (b<<4 & 0b10000);
661
    //RR
662
    globalcolor_fade_off |= (r<<3 & 0b1000);
663
    globalcolor_fade_off |= (r<<2 & 0b100);
664
    //GG
665
    globalcolor_fade_off |= (g<<1 & 0b10);
666
    globalcolor_fade_off |= g;
667
668
    if(r)
669
    {
670
        global_r = 1;
671
    }
672
    else
673
    {
674
        global_r = 0;
675
    }
676
677
    if(g)
678
    {
679
        global_g = 1;
680
    }
681
    else
682
    {
683
        global_g = 0;
684
    }
685
    if(b)
686
    {
687
        global_b = 1;
688
    }
689
    else
690
    {
691
        global_b = 0;
692
    }
693
694
}
695
696
void grid_push_up(uint8_t n)
697
{
698
699
    for(uint8_t k=0; k<n; k++)
700
    {
701
        for(uint8_t x = 0; x<10; x++)
702
        {
703
            for(uint8_t y = 0; y<9; y++)
704
            {
705
                grid[x][y] = grid[x][y+1];
706
            }
707
        }
708
        for(uint8_t x = 0; x<10; x++)
709
        {
710
            grid[x][9] = 0;
711
        }
712
    }
713
714
715
716
}
717
void grid_push_down(uint8_t n)
718
{
719
720
    for(uint8_t k=0; k<n; k++)
721
    {
722
        for(uint8_t x = 0; x<10; x++)
723
        {
724
            for(uint8_t y = 9; y>0; y--)
725
            {
726
                grid[x][y] = grid[x][y-1];
727
            }
728
        }
729
        for(uint8_t x = 0; x<10; x++)
730
        {
731
            grid[x][0] = 0;
732
        }
733
    }
734
735
736
}
737
738
uint8_t get_color_code(uint8_t r,uint8_t g,uint8_t b,uint8_t modr,uint8_t modg,uint8_t modb,uint8_t latch)
739
{
740
741
    //MOD 0 = FADE ON
742
    //MOD 1 = ON
743
    //MOD 2 = FADE OFF
744
745
    //OFF  00
746
    //ON   01
747
    //FON  10
748
    //FOFF 11
749
    //BRG
750
751
    uint8_t color = 0b00000000;
752
    if(latch)
753
    {
754
        color |= 0b10000000;
755
    }
756
757
    //ROT
758
    if(r)
759
    {
760
        switch(modr)
761
        {
762
        case 0:
763
            color |= 0b00001000;
764
            break;
765
        case 1:
766
            color |= 0b00000100;
767
            break;
768
        case 2:
769
            color |= 0b00001100;
770
            break;
771
        }
772
    }
773
    //BLAU
774
    if(b)
775
    {
776
        switch(modb)
777
        {
778
        case 0:
779
            color |= 0b00100000;
780
            break;
781
        case 1:
782
            color |= 0b00010000;
783
            break;
784
        case 2:
785
            color |= 0b00110000;
786
            break;
787
        }
788
    }
789
    //GRÜN
790
    if(g)
791
    {
792
        switch(modg)
793
        {
794
        case 0:
795
            color |= 0b00000010;
796
            break;
797
        case 1:
798
            color |= 0b00000001;
799
            break;
800
        case 2:
801
            color |= 0b00000011;
802
            break;
803
        }
804
    }
805
806
    return color;
807
808
}
809
810
811
void put_pixel_on_strip(uint8_t x,uint8_t y,uint8_t modus,uint8_t r,uint8_t g,uint8_t b)
812
{
813
814
815
    for (int i = 0; i<=100; i++)
816
    {
817
        //Push Dummy Bytes
818
        master_transmit(0b00000000);
819
    }
820
821
    master_transmit(get_color_code(r,g,b,modus,modus,modus,1));
822
    for (int i = karth_to_line(x,y); i>0; i--)
823
    {
824
        //Push Dummy Bytes
825
        master_transmit(0b00000000);
826
    }
827
    SHOW;
828
829
}
830
831
832
uint8_t karth_to_line(uint8_t x,uint8_t y)
833
{
834
835
    if((y%2 == 0) || (y == 0))
836
    {
837
        return (y*10+(9-x));
838
839
    }
840
    else
841
    {
842
        return (y*10+x);
843
    }
844
845
846
}
847
void buffer_grey_line(void)
848
{
849
850
    init_grey_line_buffer();
851
    for(uint8_t i=0; i<100; i++)
852
    {
853
        grey_line_buffer[i] = grey_line[i];
854
    }
855
856
}
857
858
859
860
void heart(void)
861
{
862
863
    init_strip();
864
    put_pixel_on_strip(4,1,0,1,0,0);
865
    put_pixel_on_strip(5,1,0,1,0,0);
866
    put_pixel_on_strip(3,2,0,1,0,0);
867
    put_pixel_on_strip(6,2,0,1,0,0);
868
    put_pixel_on_strip(2,3,0,1,0,0);
869
    put_pixel_on_strip(7,3,0,1,0,0);
870
    put_pixel_on_strip(1,4,0,1,0,0);
871
    put_pixel_on_strip(8,4,0,1,0,0);
872
    put_pixel_on_strip(1,5,0,1,0,0);
873
    put_pixel_on_strip(8,5,0,1,0,0);
874
    put_pixel_on_strip(4,5,0,1,0,0);
875
    put_pixel_on_strip(5,5,0,1,0,0);
876
    put_pixel_on_strip(2,6,0,1,0,0);
877
    put_pixel_on_strip(3,6,0,1,0,0);
878
    put_pixel_on_strip(6,6,0,1,0,0);
879
    put_pixel_on_strip(7,6,0,1,0,0);
880
881
    for (int i = 0; i<5; i++)
882
    {
883
        _delay_ms(2000);
884
    }
885
886
    if(!nightmode)
887
    {
888
889
890
        put_pixel_on_strip(4,1,2,1,0,0);
891
        put_pixel_on_strip(5,1,2,1,0,0);
892
        put_pixel_on_strip(3,2,2,1,0,0);
893
        put_pixel_on_strip(6,2,2,1,0,0);
894
        put_pixel_on_strip(2,3,2,1,0,0);
895
        put_pixel_on_strip(7,3,2,1,0,0);
896
        put_pixel_on_strip(1,4,2,1,0,0);
897
        put_pixel_on_strip(8,4,2,1,0,0);
898
        put_pixel_on_strip(1,5,2,1,0,0);
899
        put_pixel_on_strip(8,5,2,1,0,0);
900
        put_pixel_on_strip(4,5,2,1,0,0);
901
        put_pixel_on_strip(5,5,2,1,0,0);
902
        put_pixel_on_strip(2,6,2,1,0,0);
903
        put_pixel_on_strip(3,6,2,1,0,0);
904
        put_pixel_on_strip(6,6,2,1,0,0);
905
        put_pixel_on_strip(7,6,2,1,0,0);
906
    }
907
    _delay_ms(4000);
908
    _delay_ms(4000);
909
910
911
}
912
913
void init_main(void)
914
{
915
    DDRD = 0xFF;
916
    master_init();
917
918
    DDRA = 0xFF;
919
920
    //PWM
921
    TCCR2 |= (1<<WGM20) | (1<<COM21) | (1<<CS22) | (1<<CS20);
922
    OCR2 = 125;
923
924
    init_line();
925
    init_strip();
926
927
928
    //INIT KEYSHICE
929
930
931
932
933
    ///*UART Init*/
934
    UBRRH=UBRR_VAL >> 8;
935
    UBRRL = UBRR_VAL & 0xFF;
936
    UCSRB |= (1<<RXEN);
937
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
938
939
}
940
941
942
void init_line(void)
943
{
944
    for(uint8_t i=0; i<100; i++)
945
    {
946
        line[i] = 0b10000000;
947
    }
948
}
949
void init_strip(void)
950
{
951
    for(uint8_t i = 0; i<100; i++)
952
    {
953
        master_transmit(0b10000000);
954
    }
955
    SHOW;
956
}
957
void init_grey_line(void)
958
{
959
    for(uint8_t i=0; i<100; i++)
960
    {
961
        grey_line[i] = 0;
962
    }
963
}
964
void init_grey_line_buffer(void)
965
{
966
    for(uint8_t i=0; i<100; i++)
967
    {
968
        grey_line_buffer[i] = 0;
969
    }
970
}
971
972
973
974
void master_init (void)
975
{
976
    DDRB = _BV(PB4) | _BV(PB5) | _BV(PB7);    // setze SCK,MOSI,PB0 (SS) als Ausgang
977
    DDRB &= ~_BV(PB6);              // setze MISO als Eingang
978
    PORTB = _BV(PB5) | _BV(PB4);        // SCK und PB0 high (ist mit SS am Slave verbunden)
979
    SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);  //Aktivierung des SPI, Master, Taktrate fck/16
980
    status = SPSR;                //Status löschen
981
}
982
983
void master_transmit (uint16_t data)
984
{
985
    PORTB &= ~_BV(PB4);            //SS am Slave Low --> Beginn der Übertragung
986
    SPDR = data;                //Schreiben der Daten
987
    while (!(SPSR & (1<<SPIF)));
988
    //PORTB |= _BV(PB4);              //SS High --> Ende der Übertragung
989
}
990
void flush(void)
991
{
992
    init_line();
993
    init_grey_line();
994
    init_grey_line_buffer();
995
    init_strip();
996
}
997
998
void display_time(uint8_t fade, uint8_t effect)
999
{
1000
    time_to_array(hours,minutes);
1001
    if(!nightmode)
1002
    {
1003
        assemble_line(fade);
1004
        send_line(effect);
1005
    }
1006
    else
1007
    {
1008
        assemble_line(2);
1009
        send_line(0);
1010
    }
1011
1012
1013
}
1014
1015
1016
1017
int main (void)
1018
{
1019
    uint8_t hours_buffer,minutes_buffer;
1020
    uint8_t fade = 0, effect = 0;
1021
    uint8_t uart_zeichen;
1022
    init_main();
1023
1024
1025
1026
    ///TODO
1027
    /*
1028
    Helligkeit prüfen
1029
1030
    ADC ANBINDUNG FÜR HELLIGKEITSSENSOR
1031
1032
    Einstellungen auf Speicher in RTC Speichern
1033
1034
    RTC Anbindung
1035
1036
    */
1037
1038
1039
1040
1041
1042
1043
    set_global_colors(ROT);
1044
1045
    flush();
1046
    while(1)
1047
    {
1048
1049
        PORTA |= (1<<5);
1050
1051
        ///Machtmodus an!
1052
        nightmode = nightmode;
1053
        ///
1054
1055
1056
        //Buffer old time, um nicht unnötige Displayrefreshs zu machen
1057
        minutes_buffer = minutes;
1058
        hours_buffer = hours;
1059
1060
        ///GET TIME FROM RTC
1061
//        minutes = minutes;
1062
//        hours = hours;
1063
        minutes = TWI_GET(0x01);
1064
        minutes = (minutes&0b00001111) + ((minutes&0b01110000)>>4) * 10;
1065
        hours = TWI_GET(0x02);
1066
        hours = (hours&0b00001111) + ((hours&0b01110000)>>4) * 10;
1067
        ///
1068
1069
1070
        if((UCSRA & (1<<RXC)))
1071
        {
1072
            uart_zeichen = UDR;
1073
1074
            switch(uart_zeichen)
1075
            {
1076
            case 'h':
1077
                hours++;
1078
                if(hours >= 24)
1079
                {
1080
                    hours = 0;
1081
                }
1082
                TWI_SEND(0x00,0x00);
1083
                SET_TIME(hours,minutes);
1084
                break;
1085
            case 'm':
1086
                minutes+=1;
1087
                if(minutes > 59)
1088
                {
1089
                    minutes = 0;
1090
                    hours++;
1091
                }
1092
                if(hours >= 24)
1093
                {
1094
                    hours = 0;
1095
                }
1096
                TWI_SEND(0x00,0x00);
1097
                SET_TIME(hours,minutes);
1098
                break;
1099
            case 'b':
1100
                set_global_colors(BLAU);
1101
                display_time(fade,effect);
1102
                break;
1103
            case 'g':
1104
                set_global_colors(GRUEN);
1105
                display_time(fade,effect);
1106
                break;
1107
            case 't':
1108
                set_global_colors(TURKIS);
1109
                display_time(fade,effect);
1110
                break;
1111
            case 'r':
1112
                set_global_colors(ROT);
1113
                display_time(fade,effect);
1114
                break;
1115
            case 'l':
1116
                set_global_colors(LILA);
1117
                display_time(fade,effect);
1118
                break;
1119
            case 'o':
1120
                set_global_colors(ORANGE);
1121
                display_time(fade,effect);
1122
                break;
1123
            case 'w':
1124
                set_global_colors(WEISS);
1125
                display_time(fade,effect);
1126
                break;
1127
            case 'x':
1128
                heart();
1129
                display_time(fade,effect);
1130
                break;
1131
            case 'e':
1132
                matrix_effect();
1133
                init_strip();
1134
                display_time(fade,effect);
1135
                break;
1136
            case '1':
1137
                fade = 0;
1138
                effect = 0;
1139
                display_time(fade,effect);
1140
                break;
1141
1142
            case '2':
1143
                fade = 1;
1144
                effect = 0;
1145
                display_time(fade,effect);
1146
                break;
1147
1148
            case '3':
1149
                fade = 0;
1150
                effect = 1;
1151
                display_time(fade,effect);
1152
                break;
1153
            case '4':
1154
                if(nightmode)
1155
                {
1156
                    PWM_AN;
1157
                    nightmode = 0;
1158
                }
1159
                else
1160
                {
1161
                    PWM_AUS;
1162
                    nightmode = 1;
1163
                }
1164
1165
                display_time(fade,effect);
1166
                break;
1167
            }
1168
1169
1170
        }
1171
1172
        if(!nightmode)
1173
        {
1174
            PWM_AN;
1175
        }
1176
1177
        switch(minutes%5)
1178
        {
1179
            case 0:PORTA = 0b00000000;break;
1180
            case 1:PORTA = 0b00000001;break;
1181
            case 2:PORTA = 0b00000011;break;
1182
            case 3:PORTA = 0b00000111;break;
1183
            case 4:PORTA = 0b00001111;break;
1184
        }
1185
1186
1187
        ///Update nur wenn zeit verändert
1188
1189
        if((hours_buffer!=hours) || (minutes_buffer!=minutes))
1190
        {
1191
            display_time(fade,effect);
1192
        }
1193
1194
        ///ZEIT DEBUG
1195
1196
1197
//minutes += 5;
1198
        _delay_ms(50);
1199
        PORTA &= ~(1<<5);
1200
1201
    }
1202
    return 0;
1203
}

i2c.c
1
#include <util/twi.h>
2
3
4
5
6
#define   START           0x08
7
8
#define     WRITE           0
9
#define     READ            1
10
#define   MT_DATA_ACK     0x28
11
#define     MT_SLA_ACK      0x40
12
13
#define     ADRESSE        0b11010000
14
15
#define     REGISTER_SEC    0x00
16
#define     REGISTER_MIN    0x01
17
#define     REGISTER_HOUR   0x02
18
19
void ERROR(void)
20
{
21
    ///:P
22
23
}
24
25
26
void TWI_START(void)
27
{
28
    ///Startconditions
29
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
30
    ///Wait für TWINT Flag -> START condition set!
31
    while (!(TWCR & (1<<TWINT)));
32
    ///Errorhandling
33
    if ((TWSR & 0xF8) != START) ERROR();
34
}
35
36
void TWI_SLA_ADRESS(uint8_t rw)
37
{
38
39
    ///Adress and W
40
    TWDR = ADRESSE | rw;
41
    ///Starts Transmittion
42
    TWCR = (1<<TWINT) | (1<<TWEN);
43
44
45
46
}
47
48
void TWI_ACK(void)
49
{
50
51
    ///ACK Received?
52
    while (!(TWCR & (1<<TWINT)));
53
    ///Errorhandling
54
    if ((TWSR & 0xF8) != MT_SLA_ACK) ERROR();
55
}
56
57
void TWI_NAK(void)
58
{
59
   TWCR = (1<<TWINT) | (1<<TWEN);
60
  while(!(TWCR & (1<<TWINT)));
61
62
63
}
64
65
66
void TWI_DATA(uint8_t DATA)
67
{
68
    ///Datasend
69
    TWDR = DATA;
70
    TWCR = (1<<TWINT) | (1<<TWEN);
71
    ///Data has been send?
72
    while (!(TWCR & (1<<TWINT)));
73
    ///Errorhandling
74
    if ((TWSR & 0xF8) != MT_DATA_ACK)
75
        ERROR();
76
}
77
78
79
void TWI_STOP(void)
80
{
81
    ///Stop
82
    TWCR = (1<<TWINT)|(1<<TWEN)|
83
           (1<<TWSTO);
84
}
85
86
87
uint8_t TWI_READ(void)
88
{
89
90
91
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
92
    while(!(TWCR & (1<<TWINT)));
93
94
    return TWDR;
95
96
97
98
}
99
100
uint8_t TWI_GET (uint8_t ADDR)
101
{
102
    uint8_t x;
103
    TWI_START();
104
    TWI_SLA_ADRESS(WRITE);
105
    TWI_ACK();
106
    TWI_DATA(ADDR);
107
    TWI_ACK();
108
    TWI_START();
109
    TWI_SLA_ADRESS(READ);
110
    TWI_ACK();
111
    x = TWI_READ();
112
    TWI_NAK();
113
    TWI_STOP();
114
    return x;
115
}
116
117
118
void TWI_SEND (uint8_t reg, uint8_t data)
119
120
{
121
122
123
    TWI_START();
124
    TWI_SLA_ADRESS(WRITE);
125
    TWI_ACK();
126
    TWI_DATA(reg);
127
    TWI_ACK();
128
    TWI_DATA(data);
129
    TWI_NAK();
130
    TWI_STOP();
131
}


settime.c
1
void SET_TIME ( uint8_t stunden,uint8_t minuten)
2
{
3
    uint8_t byte=0,modulus,buffer;
4
5
6
7
8
    buffer = (minuten - (minuten % 10)) / 10;
9
    byte = (buffer << 4) & 0b01110000;
10
    byte |= ((minuten % 10) & 0b00001111);
11
12
13
14
    TWI_START();
15
    TWI_SLA_ADRESS(WRITE);
16
    TWI_ACK();
17
    TWI_DATA(REGISTER_MIN);
18
    TWI_ACK();
19
    TWI_DATA(byte);
20
    TWI_NAK();
21
    TWI_STOP();
22
23
    if(stunden < 10)
24
    {
25
        byte = stunden;
26
    }
27
    else if(stunden < 20)
28
    {
29
        byte = stunden%10;
30
        byte |= 0b00010000;
31
    }
32
    else
33
    {
34
        byte = stunden%10;
35
        byte |= 0b00100000;
36
    }
37
38
39
40
41
    TWI_START();
42
    TWI_SLA_ADRESS(WRITE);
43
    TWI_ACK();
44
    TWI_DATA(REGISTER_HOUR);
45
    TWI_ACK();
46
    TWI_DATA(byte);
47
    TWI_NAK();
48
    TWI_STOP();
49
50
51
52
}

von Udo S. (urschmitt)


Lesenswert?

Mike Mike schrieb:
> "Leider" hängt er sich in keiner Schleife auf.

Ein Prozesser arbeitet einen Befehl ab und dann den nächsten.
Entweder er macht einen Reset (Brown out oder was anderes) oder er loopt 
irgendwo.
Wo musst du herausfinden.
Zerlege dein Programm in logische Blöcke
Prüfe zuerst in welchem Block er hängt.
Wenn du das weisst dann zerlege weiter.

Mike Mike schrieb:
> Und das Programm ist sehr komplex
Wirklich komplex oder Spagetticode, also nicht strukturiert.
Dann ist jetzt der Zeitpunkt Struktur reinzubringen.

von mike (Gast)


Lesenswert?

Spagetticode? Wo fehlt es da an Struktur?

Ich bin gerade dabei und checke an verschiedenen Stellen gerade ab wo er 
sich aufhängt. Problem ist nur, dass es zwischen 10 bis 60 minuten 
dauern kann

von Purzel H. (hacky)


Lesenswert?

Debuggen... Ist eine Kunst fuer sich. Schmeiss mal den Display raus, 
lass alternativ eine Led einmal pro Sekunde blinken. Wenn ein UART 
vorhanden ist, verwende das UART zum debuggen.

Ich sah eine beliebige Anzahl Warteschleifen. Das sollte man vermeiden. 
Mach eine Zustandsmschine und warte nur an einem Ort. Den Zustand kann 
man zB per UART , oder per blinkender LED mitteilen, dann weiss man wo 
der Code am Warten ist.

von MWS (Gast)


Lesenswert?

Grausamer Code.
Würde die TWI-Routinen um ein Timeout mit Recovery erweitern. Die RTC 
wird im 50ms Rhythmus abgefragt, sobald die hängt, steht alles.

von mike (Gast)


Lesenswert?

Zu der RTC, ich habe bisher noch keinen internen Timer Programmiert, 
weil ich noch nicht so weit war, aber genau das könnte das Problem sein.

Warum sollte ich ein delay im jetzigen Zustand vermeiden? Da passiert 
doch nichts anderes, als dass er so und soviel Prozessortakte nichts 
macht.
Für meine Anwendung ist das doch so völlig in Ordnung im Moment.
Wenn ich später den Timer für die Uhr laufen lasse, dann kann ich die 
Delays rausschmeissen.

Im übrigen warte ich 50ms, um sehen zu können, ob die DebugLed Flackert 
oder statisch leuchtet.

Ich werde das ganze jetzt mal mit einem internen Timer Umschreiben, denn 
es könnte echt an der sich aufhängenden RTC liegen

von MWS (Gast)


Lesenswert?

mike schrieb:
> Ich werde das ganze jetzt mal mit einem internen Timer Umschreiben,

Gute Entscheidung.

Sowas könnte auch helfen:
1
   toctr = 1;
2
   while((!(TWCR & (1<<TWINT))) & toctr)
3
      toctr++;
4
   if (!toctr)
5
      {
6
         // Fehlerbehandlung, TWI de-/reaktivieren
7
      }

von mike (Gast)


Lesenswert?

Hi, das verstehe ich jetzt nicht ganz, toctr wird doch in dem Fall nie 
0?

Ich hätte jetz das Timeout anderst gelöst, indem ich mir den Aktuellen 
Timer Wert in der while Schleife geholt hätte, und ab einer gewissen 
Differenz, hätte ich abgebrochen und die Kommunikation neu gestartet

von mike (Gast)


Lesenswert?

Ah, du wartest darauf, bis toctr überläuft und wieder 0 wird?

von Sam .. (sam1994)


Lesenswert?

mike schrieb:
> Spagetticode? Wo fehlt es da an Struktur?

Deine gesamte time_to_array funktion schreibt man elegant in max. 50 
Zeilen. Dafür nutzt man Daten-Arrays von denen die "Pixel" ins Array 
kopiert werden. Du wirst sehen, dass der Code nicht nur kürzer wird, die 
Performance wird auch erheblich steigen.

von MWS (Gast)


Lesenswert?

mike schrieb:
> Ah, du wartest darauf, bis toctr überläuft und wieder 0 wird?

Yep. Kannst auch von einem vorgegebenen Wert runterzählen, wenn Dir das 
logischer erscheint, Ergebnis ist gleich.

mike schrieb:
> Ich hätte jetz das Timeout anderst gelöst, indem ich mir den Aktuellen
> Timer Wert in der while Schleife geholt hätte, und ab einer gewissen
> Differenz, hätte ich abgebrochen und die Kommunikation neu gestartet

Geht auch. Aber hier geht's ja nicht um gutes Timing, sondern nur um die 
Unterscheidung lebt / tot.

von Mike M. (mikeii)


Lesenswert?

@Samuel, danke für den Tipp

@MWS

Habe es jetzt mal komplett entkoppelt, und lasse nur ca. alle 70 
Sekunden einen Uhrzeitabgleich machen, das ganze läuft bisher ohne 
Hänger.

Muss noch die Zeit "richtig" von der RTC entkoppeln, aber zumindest weiß 
ich jetzt, dass der Fehler an der I2C Kommunikation lag.

Danke dir :)

von Mike M. (mikeii)


Lesenswert?

Mal eine andere Frage, wäre es verwerflich, wenn ich im Sekundentakt die 
RTC Abfragen würde?
Ergeben sich dadurch Nachteile für mich?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.