Forum: Mikrocontroller und Digitale Elektronik Projekt: Temperaturanzeige


von Franz F. (celsiusw370)


Angehängte Dateien:

Lesenswert?

Hallo,

ich spiele schon eine ganze weile mit Microcontroller herum. Zuerst mit 
der Arduino-Plattform, die meine Lust auf mehr weckte und jetzt mit 
"selbsgebastelten" Boards mit AVR-Controller. Nun habe ich ein Board 
entwickelt und bereits aufgebaut, dass die Temperatur mit einen 
digitalen Temp.-Sensor misst und über zwei 7-Segment-Anzeigen ausgeben 
soll. Die Siebensegment-Anzeigen werden jeweils über 2 M74HC5981 
Schieberegiester angesteuert.

Nun habe ich das Problem das ich es momentan nicht hinbekomme die 
Schieberegiester anzusteuern. Habe das Datenblatt ausführlich gelesen. 
Welche PINs High, welche LOW sein müssen, wo der Impuls von LOW -> HIGH
angelegt werden muss.

Als Controller verwende ich einen AVR Attiny 2313.

Es soll Software-SPI werden, da ich die PINs für Hardware SPI irgendwie 
nicht direkt finden konnte.(Außerdem unterstütz der 2313 doch kein 
Hardware SPI sondern "nur" USI?)

Der Schaltplan ist jetzt nicht so schön aber er müsste lesbar sein! (=

Der Code sieht momtentan so aus:
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
4
#define F_CPU 8000000 /** MAX: _delay_ms(32,76) **/
5
#define MAX_DELAY 32.76
6
7
#define SCLR     3
8
#define SI       2
9
#define RCK      1
10
#define SCK      0
11
#define SHIFTPort   PORTB
12
#define SHIFTReg  DDRB
13
14
uint8_t BIT;
15
16
17
inline void NoEndLoop();
18
19
inline void initSHIFTRegister();
20
inline void Schiebe_1Bit();
21
22
23
int main(){
24
25
  DDRA  = 0b101; 
26
  PORTA = 0b010; /** Signal LED einschalten **/
27
28
  initSHIFTRegister();
29
30
  NoEndLoop();
31
  /**
32
33
  Wird Nie erreicht!
34
35
  **/
36
return 0;
37
}
38
39
inline void NoEndLoop(){
40
41
  BIT = 1;
42
43
  while(1)
44
  {
45
46
    
47
      Schiebe_1Bit();
48
      Schiebe_1Bit();
49
      Schiebe_1Bit();
50
      Schiebe_1Bit();
51
        Schiebe_1Bit();
52
      Schiebe_1Bit();
53
      Schiebe_1Bit();
54
      Schiebe_1Bit();
55
        Schiebe_1Bit();
56
      Schiebe_1Bit();
57
      Schiebe_1Bit();
58
      Schiebe_1Bit();
59
        Schiebe_1Bit();
60
      Schiebe_1Bit();
61
      Schiebe_1Bit();
62
      Schiebe_1Bit();
63
  
64
    //Alle LEDs einschalten
65
    
66
    SHIFTPort |= (0 << RCK);
67
    _delay_ms(MAX_DELAY);
68
    SHIFTPort |= (1 << RCK);
69
    _delay_ms(MAX_DELAY);
70
71
  }
72
}
73
74
/******************************************************************************************************************************************************************************/
75
76
inline void initSHIFTRegister(){
77
78
  SHIFTReg = 0xFF;
79
  SHIFTPort = 0b00001000;  // SCLR Port auf High schalten um Werte setzen zu können
80
81
}
82
83
inline void Schiebe_1Bit(){
84
85
  SHIFTPort |= (BIT << SI);
86
  _delay_ms(MAX_DELAY);
87
  SHIFTPort |= (0 << SCK);
88
  _delay_ms(MAX_DELAY);
89
  SHIFTPort |= (1 << SCK);
90
  _delay_ms(MAX_DELAY);
91
92
}


Es kann sein das die PINs im Code nicht mit der Skizze übereinstimmen, 
da ich die Skizze ziemlich schnell gemacht habe! (=


Schonmal Danke für euere Hilfe!!


Gruß
Franz

von Karl H. (kbuchegg)


Lesenswert?

Franz Fries schrieb:

> inline void Schiebe_1Bit(){
>
>   SHIFTPort |= (BIT << SI);
>   _delay_ms(MAX_DELAY);
>   SHIFTPort |= (0 << SCK);


Ähm.
So löscht man aber kein Bit

    SHIFTPort &= ~(1 << SCK );

von Karl H. (kbuchegg)


Lesenswert?

Ich denke nicht, dass das hier

> inline void Schiebe_1Bit(){
>
>   SHIFTPort |= (BIT << SI);

das macht, was du willst.

   if( BIT )
     SHIFTPort |= ( 1 << SI );
   else
     SHIFTPort &= ~( 1 << SI );

Und an dieser Stelle darf das auszugebende Bit ruhig Funktionsargument 
sein und muss keine globale Variable sein. Die Aufrufe der Funktion und 
ob da jetzt eine 1 oder eine 0 ausgegeben werden soll, wird dann um 
einiges klarer
1
inline void Schiebe_1Bit( uint8_t Bit ){
2
3
   if( Bit )
4
     SHIFTPort |= ( 1 << SI );
5
   else
6
     SHIFTPort &= ~( 1 << SI );
7
8
  _delay_ms(MAX_DELAY);
9
10
  SHIFTPort &= ~(1 << SCK);
11
  _delay_ms(MAX_DELAY);
12
  SHIFTPort |= (1 << SCK);
13
  _delay_ms(MAX_DELAY);
14
}

Die Aufrufe sehen dann so aus:
1
  while(1)
2
  {
3
      Schiebe_1Bit( 1 );
4
      Schiebe_1Bit( 1 );
5
      Schiebe_1Bit( 0 );
6
      Schiebe_1Bit( 1 );
7
      Schiebe_1Bit( 0 );
8
      Schiebe_1Bit( 1 );
9
      Schiebe_1Bit( 0 );
10
11
      ...

und du musst in Gedanken nicht mehr mitverfolgen, wie jetzt gerade BIT 
steht um zu wissen, ob da jetzt ein 1 Bit oder ein 0 Bit ausgegeben 
wird.


PS: Beim RCK musst du natürlich das 0-setzen auch ändern.

von Karl H. (kbuchegg)


Lesenswert?

Auf deinem Schaltplan stimmt was nicht.
Das obere SR hat 2 SI Eingänge. Das kann nicht sein. Bei 2 kaskadierten 
SR können niemals alle 4 Steuerleitungen einfach komplett parallel zur 
ansteuernden Schaltung laufen.

von Franz Fries (Gast)


Lesenswert?

Ja der Schaltplan hat einen Fehler bitte einfach ignorieren!!(Das ist 
nicht wirklich so angeschlossen!)



Danke

Werde es mal ausprobieren!!!

von Klaus W. (mfgkw)


Lesenswert?

Wenn du dir in Zukunft etwas Arbeit und Platz auf der Platine
sparen willst. es gibt auch Widerstandsnetzwerke, z.B.
http://such001.reichelt.de/?SID=28iKqAZawQARwAACXHWvU7d334c9c85a1aecaad7f4167ee32dacd;ACTION=444

von Franz F. (celsiusw370)


Angehängte Dateien:

Lesenswert?

Hi,

jetzt habe ich den Code umgebaut. Es funktioniert leider trotzdem nicht!

Irgendwas sehe ich einfach nicht!

Vll. sieht einer meinen Fehler. Habe mal die Wahrheitstabelle 
hochgeladen.
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
4
#define MAX_DELAY 32.76
5
6
#define SCLR     3
7
#define SI       2
8
#define RCK      1
9
#define SCK      0
10
#define SHIFTPort   PORTB
11
#define SHIFTReg  DDRB
12
13
14
void NoEndLoop();
15
16
void initSHIFTRegister();
17
void Schiebe_1Bit( uint8_t Bit );
18
19
20
int main(){
21
22
  DDRA  = 0b101; 
23
  PORTA = 0b010; /** Signal LED einschalten **/
24
25
  initSHIFTRegister();
26
27
  NoEndLoop();
28
  /**
29
30
  Wird Nie erreicht!
31
32
  **/
33
return 0;
34
}
35
36
void NoEndLoop(){
37
  while(1)
38
  {
39
    SHIFTPort &= ~(1 << SCLR); 
40
    _delay_ms(MAX_DELAY);
41
    SHIFTPort |= (1 << SCLR);
42
    _delay_ms(MAX_DELAY);
43
44
45
   Schiebe_1Bit(1);
46
   Schiebe_1Bit(1);
47
   Schiebe_1Bit(1);
48
   Schiebe_1Bit(1);
49
   Schiebe_1Bit(1);
50
   Schiebe_1Bit(1);
51
   Schiebe_1Bit(1);
52
   Schiebe_1Bit(1);
53
   Schiebe_1Bit(1);
54
   Schiebe_1Bit(1);
55
   Schiebe_1Bit(1);
56
   Schiebe_1Bit(1);
57
   Schiebe_1Bit(1);
58
   Schiebe_1Bit(1);
59
   Schiebe_1Bit(1);
60
   Schiebe_1Bit(1);
61
62
  _delay_ms(MAX_DELAY);
63
64
  SHIFTPort &= ~(1 << RCK);
65
  _delay_ms(MAX_DELAY);
66
  SHIFTPort |= (1 << RCK);
67
  _delay_ms(MAX_DELAY);
68
69
  }
70
}
71
72
/******************************************************************************************************************************************************************************/
73
74
void initSHIFTRegister(){
75
76
  SHIFTReg = 0xFF;
77
  SHIFTPort = 0b00001000;  // SCLR Port auf High schalten um Werte setzen zu können
78
79
}
80
81
void Schiebe_1Bit( uint8_t Bit ){
82
83
   if( Bit )
84
     SHIFTPort |= ( 1 << SI );
85
   else
86
     SHIFTPort &= ~( 1 << SI );
87
88
  _delay_ms(MAX_DELAY);
89
90
  SHIFTPort &= ~(1 << SCK);
91
  _delay_ms(MAX_DELAY);
92
  SHIFTPort |= (1 << SCK);
93
  _delay_ms(MAX_DELAY);
94
95
}

Gruß
Franz


P.S. Das mit den Widerstandsnetzwerke ist ein guter Tipp hate leider 
keine Daheim und wollte nicht nur wegen Wiederständen beim Reichelt 
einkaufen

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.