C Ansteuern einer 7-Segmentanzeige

AVRuser

Neues Mitglied
20. Apr. 2011
217
0
0
Niedersachsen
Sprachen
  1. BascomAVR
  2. ANSI C
Hallo Leute,

nach meinen ersten erfolgreichen C-Versuchen will ich nun für eine
vorhandene Hardware das Bascom Prog ersetzen...
Im Moment stecke ich jedoch noch bei der Ansteuerung einer 7-Segment-anzeige
über ein 74HC595 fest und kann einfach keinen Fehler festmachen!:(

Theoretisch sollte auf dem Display ein E. erscheinen, stattdessen leuchtet
nach jedem reset des µCs ein Segment nach dem anderen, in einer festen Reihenfolge auf.::confused:
1. -> f
2. -> g
3. -> e
4. -> d
5. -> a
6. -> b
7. -> c
8. -> dot
...was übrigens der Harwäremäßigen Pinbelegung entspricht...

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#ifndef F_CPU	
	#define F_CPU 8000000
#endif

#define ein		PD5
#define aus		PB2
#define shd		PA1
#define sho		PD1
#define shc		PD0
#define sw		PA0
#define LPE		PB1
#define NPE		PD6
#define LN		PB0

void def(void){
	DDRA = 0b00000010;
	DDRB = 0b00001100;
	DDRD = 0b00000011;
	PORTA |= (1<<sw);
	PORTB |= (1<<LPE);
	PORTB |= (1<<LN);
	PORTD |= (1<<NPE);
	PORTD |= (1<<ein);	
}

void set_disp(char disp,uint8_t dot){
	uint8_t sgm[8];
	uint8_t i;
	sgm[8] = dot;
	switch(disp) {
		case 'A' : {sgm[1] = 1; sgm[2] = 1; sgm[3] = 1; sgm[4] = 0; 
				   sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;} 
				   
		case 'E' : {sgm[1] = 0; sgm[2] = 0; sgm[3] = 1; sgm[4] = 1;
				   sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;} 
				   
		case 'F' : {sgm[1] = 0; sgm[2] = 0; sgm[3] = 1; sgm[4] = 0;
				   sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;} 
				   
		case 'H' : {sgm[1] = 1; sgm[2] = 1; sgm[3] = 0; sgm[4] = 0;
				   sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;} 
				   
		case 'L' : {sgm[1] = 0; sgm[2] = 0; sgm[3] = 0; sgm[4] = 1;
				   sgm[5] = 1; sgm[6] = 0; sgm[7] = 1;} 
				   
		case '0' : {sgm[1] = 1; sgm[2] = 1; sgm[3] = 1; sgm[4] = 1;
				   sgm[5] = 1; sgm[6] = 0; sgm[7] = 1;} 

		case '8' : {sgm[1] = 1; sgm[2] = 1; sgm[3] = 1; sgm[4] = 1;
				   sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;} 
	}
	for (i = 1; i <= 8; i++) {
		if (sgm[i] == 1) {
			PORTA |= (1<<shd);
		} 
		else {
			PORTA &= (1<<shd);
		}
		_delay_ms(1);
		PORTD |= (1<<shc);
		_delay_ms(1);
		PORTD &= (1<<shc);
		_delay_ms(1);
	}
	_delay_ms(1);
	PORTD |= (1<<sho);
	_delay_ms(1);
	PORTD &= (1<<sho);	
}

int main(void) {
	def();
	set_disp('E',0);
	while(1){		
	}
}

Schaltung (auf geätzter Platine) hat mit Bascom zuvor tadellos funktioniert!
Hier der entsprechende Bascom Codeauschnitt:
Code:
$regfile = "attiny2313.dat "
$framesize = 16
$swstack = 64
$hwstack = 16
$crystal = 8000000

Shd Alias Porta.1
Sho Alias Portd.1
Shc Alias Portd.0

Config Shd = Output
Config Shc = Output
Config Sho = Output

Dim Anz As String * 8 , I As Byte , Aw As String * 1 , Dot As Bit
Dim Alw As Bit , Awalt As String * 1 , Cnt As Integer , Lein As Bit

...

      If Dot = 1 Then
         Anz = "1"
      Else
         Anz = "0"
      End If

      Select Case Aw
      Case "A" : Anz = Anz + "1110111"
      Case "E" : Anz = Anz + "0011111"
      Case "F" : Anz = Anz + "0010111"
      Case "H" : Anz = Anz + "1100111"
      Case "L" : Anz = Anz + "0001101"
      Case "0" : Anz = Anz + "1111101"
      End Select
      Dot = 0
      For I = 1 To 8
         If Mid(anz , I , 1) = "1" Then
            Shd = 1
         Else
            Shd = 0
         End If
         NOP
         Shc = 1
         NOP
         Shc = 0
         NOP
      Next
      Sho = 1
      NOP
      Sho = 0

...

Wäre schön wenn sich das mal jemand anschauen könnte, ich bin ziemlich ratlos...

Schonmal Danke im Vorraus!
 
Guten Morgen AVRuser,

ich habe deinen Code nur ganz kurz überflogen (ist ja auch noch früh :D), dabei ist mir ein Fehler aufgefallen:

Code:
    switch(disp) {         
       case 'A' : {sgm[1] = 1; sgm[2] = 1; sgm[3] = 1; sgm[4] = 0; sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;[B]break[/B];}                             
       case 'E' : {sgm[1] = 0; sgm[2] = 0; sgm[3] = 1; sgm[4] = 1; sgm[5] = 1; sgm[6] = 1; sgm[7] = 1;[B]break[/B];}
  // ...

case musst du mit break abschließen.
Schau vielleicht erst mal danach.

(Noch ein paar Tipps wie du vielleicht was verbessern kannst: Ich würde die Dekodierung über eine Tabelle im Flash Memory erledigen. Die Segmentbits würde ich auch nicht in einem Array von uint8_t verarbeiten, dafür reicht eigentlich ein Byte)

Dirk :ciao:
 
Hallo Dirk,

hab das Case durch eine matrix ersetzt, was jedoch keine Änderung brachte...:(

Ich hab irgentwie eher die Vermutung das die For-schleife nicht funzt, da ich mit dem Logicanalyser
herausgefunden habe, das der der shc-pin(clock) einmalig einen ca. 2,68ms langen impuls sendet...:confused::eek:
während sho(to_output_clock) und shd(serial_data) dauerhaft high sind...

Wenn ich die Funktion nicht aufrufe bleiben alle Low...
 
Ich bin immer noch Dirk ;)

Ich schau mir das später nochmal näher an. Leider habe ich im Moment keine Zeit.

Was ich aber gerade noch gesehen habe: Der Index des Arrays muss 0..7 sein, nicht 1..8.

Dirk :ciao:
 
...Die For funktioniert....
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)