Stoppuhr

Sean Goff

Neues Mitglied
21. Mai 2009
11
0
0
Sprachen
hi zusammen

ich habe eine Stoppuhr mit 6 7-segmentanzeigen gebaut (hundeltster sekunden / sekunden / minuten ) und krampfe jetzt mit dem programmieren vom atmega88 herum. hatt jemand ein beispielprogramm? danke im vorraus ein absoluter programmieranfänger. :confused:

sean :eek:
 
Hallo Sean,

willkommen in unserem Forum.

Ich habe jetzt leider keinen fertigen Programmcode für dich, der Programmcode ist ja auch ein bisschen abhängig von der Hardware, aber vielleicht kann ich dir einige Tipps geben.

In welcher Programmiersprache programmierst du denn? Hast du denn bereits etwas Code geschrieben, oder fängst du absolut von Null an?

Du kannst auch die Forumsuche nutzen, im Forum wurde schon mal das Thema Stoppuhr behandelt, vielleicht findest du dort auch einen Beispielcode.

Grüße,
Dirk
 
Prinzipiell empfielt es sich Bitmuster für die einzelnen Zahlen zurecht zu basteln. Also das man nur noch sagen muss "Port B = Sieben". In C ginge das mit den Preprozessoranweisungen (#define nnull 0b00000000) in ASM geht das so ähnlich (das würdest du bei Mikrocontroller.net im Tutorial finden), bei Bascom weis ich nich das hatte ich nie in der Hand.

Die Uhr selbst kannst du mit den Timern gestalten. Also einen Timerinterrupt laufen lassen der alle 1/100s ausgelöst wird. Wie du den einrichtest => Datenblatt. In der ISR (Interrupt Service Routine) lässt du dann einen Counter hochzählen (counter++ in C zum Beispiel oder in ASM add r16, 0x01 nagelt mich nich fest ob das passt ...) und du musst abfragen (zum Beispiel mit if() und einem in ASM gleichen Konstrukt mit den Vergleichsoperationen siehe INstruction Set (Atmel Webpage bzw Datenblatt letzte Seiten) ob du un eine Sekunde rum hast oder nicht, wenn ja zählst du den nächsten Counter hoch und setzt den alten auf Null (cnt_hundert, cnt_sek zB für C). Die Counter Werte gibst du entsprechent am ende der ISR aus.

Hoffe das war jetz nich zu viel vorgekaut ;)
 
hi dirk

ich fange absolut von null an und möchte in c programmieren (avr studio 4)
hier die beschaltung:

PB0 ELEKTRONISCHER STARTPFIFF
PB1 IR SENDEDIODE (LICHTSCHRANKE FÜR START GETAKTET)
PB2 IR TRANSISTOR (LICHTSCHRANKE FÜR START GETAKTET)
PB3 RS232
PB4 RS232
PB5 TASTER (STOPP)

PD0 - PD7 SEGMENT A-G + DP REIENFOLGE NOCH OFFEN

PC0 - PC5 GEMEINSAME ANODE DER SEGMENTE (MULTIPLEX)

WICHTIGE FUNKTIONEN:

starten mit getakteter Lichtschranke stoppen mit taster und ergebnis auf den pc laden.
 
hi BlackDevil

also etwa so ?:

#define null 0b11101110
#define eins 0b00100100
#define zwei 0b10111010
#define drei 0b10110110
#define vier 0b01110100
#define fünf 0b11010110
#define sechs 0b11011110
#define sieben 0b10100100
#define acht 0b11111110
#define neun 0b11110110
 
Hallo Sean

Ich würde dir mal den Thread Durch Tastendrucke + 7 Segment Ports Schalten
Empfehlen.

Da steht viel Code und auch die Überlegungen zu 7Segmentanzeigen drinnen. (in C);)


Ach übrigens: Die Namen von Makros schreibt man stylischerweise groß.
Z.b.: #define NULL 0b11101110
Das ist aber nicht zwingend erforderlich und fällt in die gleiche Kategorie wie:
"Beim Teetrinken spreizt man den kleinen Finger von der Tasse ab"
"Beim Diniern mit Klingonen wird das Nichtrülpsen als Beleidigung aufgefasst" :D
 
Hi Sean,

es ist schwer, dir ein fertiges C-Programm zu liefern. Ich würde an deiner Stelle erst mal anfangen, die Siebensegment-Anzeige anzusteuern. Deine Anzeige läuft ja im Multiplexbetrieb, du benötigst hier also ein Zeitsignal (Timer-Interrupt), durch das du immer auf die nächste Ziffer umschaltest, das heißt du aktivierst immer die nächste Siebensegmentanzeige, indem du den entsprechenden Portpin high schaltest, alle anderen sind dabei low (gem. Anode). Du muss hier auf den Gesamtstrom achten, also wenn alle Segmente der Anzeige aktiviert sind, ist der zu hoch, dann ggf. über externes Transistor-Array-IC (ULN...) schalten.

Was muss dein Programm nun machen ...
  1. Ports initialisieren (Eingänge und Ausgänge definieren)
  2. USART initialisieren (für später, musst du für die Anzeige noch nicht machen)
  3. Timer initialisieren, Timerinterrupt initialsieren (Zeit ca. 10ms bis 20ms), Timer starten
  4. ggf. noch ein Timer für Stoppuhr initialisieren (ist für Anzeige auch noch nicht nötig)
  5. In einer while(1) Schleife, dann (erst mal) eine zum Variable Anzeigen ändern, zum Testen, diese Variable wird nach Siebensegment gewandelt (ich würde es über eine Tabelle im Flash machen) dieses Wandelergebnis wird dann zum Portregister für die Segmente kopiert.
Im Timerinterrupt schaltest du auf die nächste Anzeige (im Idealfall schiebst du einfach ein Bit im Portregister, Anode der Anzeige) und gibst für die Dezimalzahl die entsprechenden Segmente aus.

Im Forum gibt es bestimmt auch Beispiele, wie man eine Anzeige im Multiplex ansteuert. Ich würde sagen, versuche erst einmal die Anzeige zum Laufen zu bekommen, das andere kannst du später machen.

Gruß,
Dirk
 
hi dirk

wie weiss der mega88 denn, welcher port welchem bei entschpricht (#define NULL 0b11101110) ? :pcguru:

danke im foraus :D

sean
 
Hallo Sean,
wie weiss der mega88 denn, welcher port welchem bei entschpricht (#define NULL 0b11101110) ? :pcguru:

du musst natürlich den Port für die Segmente festlegen und die entsprechenden Portpins so ansteuern, dass die Dezimalzahlen 0 bis 9 auch richtig angezeigt werden, die Segmente müssen also richtig angesteuert werden.

Du kannst einen Segmentdekoder zum Beispiel über eine Tabelle im Flash realisieren, so in etwa:


Code:
const uint8_t Siebensegment[] PROGMEM =
{ 0b10101010, 0b00001111, 0b11100011, 0b..., 0b... 0b..., 0b..., 0b..., 0b..., 0b... };  // Segmente für dezimal 0 bis 9
// Die Werte in der Tabelle sind hier nur Beispiele


// Du kannst dann folgendermaßen auf die Tabelle zugreifen:
PortB = pgm_read_byte(&Siebensegment[i]); 
// i ist die eine Dezimalzahl 0 bis 9
// PortB ist dein Port für die Segmente a bis g, das kann natürlich auch ein anderer Port sein
Grüße,
Dirk
 
Hi Sean,

wie weiss der mega88 denn, welcher port welchem bei entschpricht (#define NULL 0b11101110) ? :pcguru:

0b11101110 > 0b (Bit7) (Bit6) (Bit5) (Bit4) (Bit3) (Bit2) (Bit1) (Bit0)

wenn man das auf Port B ausgibt dann ist das ...

0b (PB7) (PB6) (PB5) (PB4) (PB3) (PB2) (PB1) (PB0)

War es das, was du wissen wolltest ?

Gruß
Dino
 
hi dino

danke genau das dachte ich. noch ne kleine frage: wie muss ich die loops für den dekadischen zähler programmieren?

danke sean :D
 
wie muss ich den dekadischen zähler programmieren, wenn ich die ports so definiere? :trytofly:

#define NULL 0d11101110 //ziffern
#define EINS 0d00100100
#define ZWEI 0d10111010
#define DREI 0d10110110
#define VIER 0d01110100
#define FÜNF 0d11010110
#define SECHS 0d11011110
#define SIEBEN 0d10100100
#define ACHT 0d11111110
#define NEUN 0d11110110
#define DP 0d00000001

#define A 0c10000000 //anzeigen
#define B 0c01000000
#define C 0c00100000
#define D 0c00000100
#define E 0c00000010
#define F 0c00000001
 
Hi Sean,

wie muss ich den dekadischen zähler programmieren, wenn ich die ports so definiere? :trytofly:

#define NULL 0d11101110 //ziffern
#define EINS 0d00100100
#define ZWEI 0d10111010
#define DREI 0d10110110
#define VIER 0d01110100
#define FÜNF 0d11010110
#define SECHS 0d11011110
#define SIEBEN 0d10100100
#define ACHT 0d11111110
#define NEUN 0d11110110
#define DP 0d00000001

#define A 0c10000000 //anzeigen
#define B 0c01000000
#define C 0c00100000
#define D 0c00000100
#define E 0c00000010
#define F 0c00000001

ich glaube, da gibt es ein paar Verständnisprobleme ;)

0b = Binärzahl
0x = Hexadezimalzahl (manchmal auch als 0h... oder ...h)
dann gibt es auch noch Octalzahlen (3Bit-Basis - 0..7 ) :)

Also 0xFF = 0b11111111 = 255 ...

Das am Anfang ist NICHT der Port sondern das Zahlensystem.
Der Compiler muß ja irgendwie wisse das du mit 110 eine Binärzahl und
keine Dezimalzahl meinst :)

Sieh dir mal den Thread an Erste Anfänge mit C und AVR
da wurde das alles durchgekaut und erklärt. Oder hier ...
Kani-Coaching (C lernen mit Nomis)
Da sind auch Anfänge von einer Multiplexanzeige drin.

@Kani : Gut das wir das mal alles so haarklein durchgekaut haben.
Jetzt hilft es anderen :)

Gruß
Dino
 
schau mal:
bis jezt sieht es so aus:

#include <avr/io.h>
#define F_CPU 8000000L
#include <util/delay.h>

#define SEGPORT PORTC //Port des 7Seg Elementes
#define ANZPORT PORTD //Port der Anzeige
#define WAIT 5

int hunderts1=0;
int hunderts2=0;
int sekunden1=0;
int sekunden2=0;
int minuten1=0;
int minuten2=0;

void initIO()
{

DDRC = 0xff;
DDRD = 0xff;
DDRB = 0x00;
sei();
}

void initTimer()
{
TCCR0A |= _BV(CS00) |_BV(CS01); // /64 Prescaler
OCR0=125; //Interrupt alle 125 Takt/ 1000 Hz
}

ISR(TIM1_OVF)
{
hunderts1 = hunderts1+1;
if(hunderts1>=10)
{
hunderts1=0;
hunderts2=hunderts2+1;
}
if(hunderts2>=10)
{
hunderts2=0;
sekunden1=sekunden1+1;
}
if(sekunden1>=10)
{
sekunden1=0;
sekunden2=sekunden2+1;
}
if(sekunden2>=6)
{
sekunden2=0;
minuten1=minuten1+1;
}
if(minuten1>=10)
{
minuten1=0;
minuten2=minuten2+1;
}
}
void seg(int s, int v)
{
switch(v)
{
case 1:
SEGPORT=0b00001100;
break;
case 2:
SEGPORT=0b10110110;
break;
case 3:
SEGPORT=0b10011110;
break;
case 4:
SEGPORT=0b11001100;
break;
case 5:
SEGPORT=0b11011010;
break;
case 6:
SEGPORT=0b11111010;
break;
case 7:
SEGPORT=0b00001110;
break;
case 8:
SEGPORT=0b11111110;
break;
case 9:
SEGPORT=0b11011110;
break;
case 0:
SEGPORT=0b01111110;
break;
}
ANZPORT = 1 << s;
}

int main()
{

initIO();
initTimer();

while (1)
{
if ( PINB & (1<<PINB1) ) {
seg(1, hunderts1);
_delay_ms(WAIT);
seg(2, hunderts2);
_delay_ms(WAIT);
seg(3, sekunden1);
_delay_ms(WAIT);
seg(4, sekunden2);
_delay_ms(WAIT);
seg(5, minuten1);
_delay_ms(WAIT);
seg(6, minuten2);
_delay_ms(WAIT);
}

}

}

ist das soweit okay?
noch ne kleine frage:
wie mach ich das mit dem UART (ich möchtedie Variablen
hunderts1
hunderts2
sekunden1
sekunden2
minuten1
minuten2
über RS232 an den PC senden und in eine Exeltabelle einlesen. Zudem möchte ich den mega88 über RS232 programmieren können.)
 
Für das Programmieren brauchst du nur einen Programmer, für das UART brauchst du dir nur gedanken machen welche Register du brauchst und wie du sendest und empfängst ;) Is nich schwer
 
Ähm Schwarzteufel.:)

Ich glaube Sean meinte mit der Möglichkeit das Ganze über USART programmieren zu können einen Bootloader mit dem er sich neue Programme auf den Controller laden kann.

Und die Sache mit dem Exel Dokument ist etwas aufwändiger, weil man dazu eine Anwendung für den PC schreiben müsste die mit Office direkt interagiert oder ein Exel-dokument erstellt. Das geht aber angeblich(Achtung: Spekulation) mit den .NET -Sprachen halbwegs einfach.
 
Guten Morgen zusammen,

... Und die Sache mit dem Exel Dokument ist etwas aufwändiger, weil man dazu eine Anwendung für den PC schreiben müsste die mit Office direkt interagiert oder ein Exel-dokument erstellt. Das geht aber angeblich(Achtung: Spekulation) mit den .NET -Sprachen halbwegs einfach.

man könne die Daten eventuell schon vorformatiert senden (CSV, semikolon-getrennt) und mit einem Terminalprogramm speichern, danach mit Excel importieren.

Grüße,
Dirk
 
hi nomis
genau das meinte ich ;) PS: möchte bei einer kleinen programmänderung nicht immer die megas vom fahnenmast holen:rolleyes:

gruss sean
 
Ähm Schwarzteufel.:)

Ich glaube Sean meinte mit der Möglichkeit das Ganze über USART programmieren zu können einen Bootloader mit dem er sich neue Programme auf den Controller laden kann.

Und die Sache mit dem Exel Dokument ist etwas aufwändiger, weil man dazu eine Anwendung für den PC schreiben müsste die mit Office direkt interagiert oder ein Exel-dokument erstellt. Das geht aber angeblich(Achtung: Spekulation) mit den .NET -Sprachen halbwegs einfach.

Naja dann hab ich das falsch verstanden ...
 
weiss nun jemand, wie ich diese 6 variablen über RS232 senden kann? ich meine ich möchte danach am pc sowas sehen:

034642
(zehnminuten/minuten/zehnsekunden/sekunden/zehntel/hunderztel)
kann ich nicht einfach schreiben

UDR = minuten2
delay_ms(10)
UDR = minuten1
delay_ms(10)
UDR = sekunden2
delay_ms(10)
UDR = sekunden1
delay_ms(10)
UDR = hunderts2
delay_ms(10)
UDR = hunderts1
delay_ms(10)
 

Ü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)