Controller hängt sich unregelmäßig auf

OP #2451801
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
OP #2451864
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
OP #2451870
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
}
#2451876
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.
#2452094
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.
Gast #2452193
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
Gast #2452237
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
Gast #2452272
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.
OP #2452498
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 :)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren