Forum: Mikrocontroller und Digitale Elektronik C8051F020Dk Port4-7 aktivieren bzw. freischalten (SFR)?


von batty m. (battyman)


Lesenswert?

Hallöle,

ich habe da mal wieder eine Frage zu meinem µC-Board, da ich aus dem DS 
nicht wirklich schlau werde.
Also mein Board hat 8 (0-7) Digitale Port's.
Die ersten 4 Port's sind alle I/O-fähig mit PushPull oder Open-Drain. 
Leider sind diese aber alle schon belegt als PushPull.
Die Port's 4 - 7 kann ich so leider nicht mehr initialisieren. Problem 
dabei, er scheint sie erst gar nicht zu sehen. Dazu will ich aber sagen, 
dass ich diese bzw. einen von diesen als Eingabe - Open Drain - haben 
wollte (z.B. Schalterstellung). Ein Blick ins DS (S.179) zeigt mir nun 
folgendes an:
1
//P74OUT: Ports 7-4 Output Mode Register
2
//SFR Address: 0xB5 //-> wenn ich dem header nun ...
3
4
sfr16 P74OUT = 0xb5 // ...gebe kommt nur "redefinition" - warum???

Denn dann dachte ich mir, dass ich einen Port mir frei wählen kann um 
davon die dazugehörigen Pin's als Open-Drain zu deklarieren.
z.B.:
1
//Port5L: Output Mode Low Nibble Bit
2
0:P5.[3:0] configured as Open-Drain

Brauche mal wieder etas Hilfeleistung von einem schlauen Fuchs. DANKE

von Jim M. (turboj)


Lesenswert?

Marcel M. schrieb:
> sfr16 P74OUT = 0xb5 // ...gebe kommt nur "redefinition" - warum???

Weil P74OUT normalerweise schon in irgendeinem Header definiert ist. 
Außerdem sieht das sfr16 falsch aus, das ist ein einzelnes Byte.

Richtig wäre also für P5 Low nibble als Push-Pull:
1
  P74OUT |= (1<<2);

von batty m. (battyman)


Lesenswert?

Danke für die schnelle Antwort, kannst du mir jedoch noch kurz erklären 
warum du das so geschrieben hast?
1
 P74OUT |= (1<<2);

Woher weiß denn der µC, das ich den Port 5 mit LOW möchte, wenn ich 
P74OUT schreibe?
Wenn ich mir das so ansehe dann initiere ich die Port 4-7 für den Output 
Mode mit "P74OUT". In der Klammer steht ("0" Open-Drain / "1" PushPull 
für den Bit "<<" 2) , welcher ja Port 5 Low wäre - ist dem so richtig???

von batty m. (battyman)


Lesenswert?

Moins,

erstmal noch mal Danke, das hat er so gefressen. Problem ist jetzt nur 
das bei der Input-Abfrage ich den Port nicht ansprechen kann, also:
1
 sbit SW1 = P5^2; //invalid base address 
2
3
void Port_Init (void)
4
{
5
P74OUT |= (0<<2); // Low-Bit-Variante, damit P5 Pin 2; 0=OpenDrain
6
}

mit:
1
 sbit SW1 = P74^2; //undefined identifier

Wie kann ich denn jetzt dem µC klar machen das an Port 5 Pin 2 ein 
"High" oder "Low" (0V bzw. 5V) anliegt und er danach entscheiden soll 
was zu tun ist???

Danke

von Peter D. (peda)


Lesenswert?

Bitadressierbar sind nur IO-Adressen mit 0 oder 8 am Ende.
Die höheren Ports werden das wohl nicht sein.
Mußt also das ganze Byte lesen und das gewünschte Bit maskieren.

von batty m. (battyman)


Lesenswert?

Mhh,

laut DS ist zu den Port 0-3 je 8Pins I/O-Bitwiese adressierbar, für 
Pushpull oder OpenDrain.
Nun habe ich noch die Ports4-7, wo je Port immer 2 Pins 
I/O-Funktionalität besitzen sollen.

Port 4: Pin 0 - Low Level PP/OD
        Pin 1 - High Level PP/OD

Port 5: Pin 2 - Low Level PP/OD
        Pin 3 - High Level PP/OD

Port 6: Pin 4 - Low Level PP/OD
        Pin 5 - High Level PP/OD

Port 7: Pin 6 - Low Level PP/OD
        Pin 7 - High Level PP/OD

Da ich nun einen Schlater auf den 2ten Pin meines Port 5 gelegt habe 
wollte ich auch genau diesen ansprechen.

Mit "P74OUT" kann ich eigentlich diese Port/Pins gewünscht als PushPull 
= 1 / OpenDrain = 0 initialisieren.
Damit sind doch die Pins für I/O Funktion bereit. Diesen muss ich dann 
auch ansprechen können um High oder Low auszulesen. Das wäre nun mein 
kleines Problem. Das DS hilft mir da i-wie nicht weiter :-(

 Vielen Dank

von batty m. (battyman)


Lesenswert?

Auszug aus DS für C8051F020!!! Habe ich! :-)
1
// 17.2. Ports 4 through 7 (C8051F020/2 only)----------------------
2
//-----------------------------------------------------------------
3
// All Port pins on Ports 4 through 7 can be accessed as General-Purpose I/O (GPIO) pins a set of SFRs which are byte-addressable.
4
5
// 17.2.2. Configuring the Output Modes of the Port Pins-----------
6
//-----------------------------------------------------------------
7
// The output mode of each port pin can be configured to be either 
8
// Open-Drain or Push-Pull. The output modes of the Port pins on Ports 4 through 7 are determined by the bits in the P74OUT register (see Figure 17.20). Each bit in P74OUT 
9
// controls the output mode of a 4-bit bank of Port pins on Ports 4, 5, 6, and 7. A logic 1 in P74OUT.7 will configure the output modes of 4
10
// most-significant bits of Port 7, P7.[7:4], to Push-Pull; a logic 0 in 
11
// P74OUT.7 will configure the output modes of P7.[7:4] to Open-Drain.
12
13
// 17.2.3. Configuring Port Pins as Digital Inputs-----------------
14
//-----------------------------------------------------------------
15
// A Port pin is configured as a digital input by setting its output mode 
16
// to “Open-Drain” and writing a logic 1 to the associated bit in the Port Data register. For example, P7.7 is configured as a digital input by 
17
// setting P74OUT.7 to a logic 0 and P7.7 to a logic 1.

Ich werde leider aus dem dortigen nicht wirklich schlau, denn egal was 
ich in welcher Variation eingebe kommt immer nur i-eine Fehlermeldung, 
wie:
1
invalid base address
2
invalid bit
3
undefined identifier
Ob mit "." "^" "[]" "{}" ":" "," "=0" "=0x00" ... er schluckt i-wie alle 
Varianten nicht.

Was mach ich denn FALSCH????

von Peter D. (peda)


Lesenswert?

Marcel M. schrieb:
> i-eine Fehlermeldung,

Wie schon gesagt, sbit geht nur bei bitadressierbaren IOs.

von Garden (Gast)


Lesenswert?

Guck doch einmal in die inkludierte h-Datei.

Dort steht die Basisadresse des Ports.
Und wenn sie nicht auf 0 oder 8 endet, dann kannst Du den Port nur 
byte-weise beschreiben.

von Wilhelm F. (Gast)


Lesenswert?

Garden schrieb:

> Guck doch einmal in die inkludierte h-Datei.
>
> Dort steht die Basisadresse des Ports.

In der H-Datei sind meistens auch die bits der bitadressierbaren 
Register noch mal mit sbit definiert, und man sollte es daran alleine 
schon sehen können.



Peter Dannegger schrieb:

> Bitadressierbar sind nur IO-Adressen mit 0 oder 8 am Ende.
> Die höheren Ports werden das wohl nicht sein.
> Mußt also das ganze Byte lesen und das gewünschte Bit maskieren.

Beim ollen SAB80C517A ist es auch so. Dort ist das Steuerregister SCON1 
für den zweiten UART nicht auf einer glatt durch 8 teilbaren Adresse, 
und man muß zur Bearbeitung, sei es nur TI oder RI zurück setzen, immer 
Byteoperationen durch führen.

An einem meiner Boards ist es so gemacht, und es geht genau so gut wie 
Bitoperationen, hat nur ein bis zwei Bytes mehr Code und die eine oder 
andere µS mehr Laufzeit. Das Board hat nämlich COM0 an der 
LWL-Schnittstelle, und COM1 an der RS232, die ja zum Programmdownload am 
PC hängt. Auch die höheren Ports, die gegenüber dem Standard-8051 
erweitert sind, sind im 80C517A nur byteadressierbar.



Im Manual zum µC sollte aber alles auch stehen, da muß man eben durch.

von batty m. (battyman)


Lesenswert?

Ui-jui!  :-D

Also laut header-Datei und auch DS ist die SFR-Add. für Port5 "P5" = 
0x85!
Hab nun auch verstanden, dass ich diese eben nicht Bitweise auslesen 
kann. Alles schön und gut.
Ich würde dann eben auch gerne den gesamten P5 als Byte auslesen und nur 
Pin3 (0x04) markieren um damit weiter zu machen.

Problem dabei ist nur, dass er auf nichts reagiert. Ich kann den nicht 
als char , unsigned char, long, etc. deklarieren. wie soll ich denn P5 
auslesen, wenn ich nicht wirklich weiß wie ich an den ran komme?
habs so auch noch mal probiert:
1
unsigned cahr SW1;
2
static long accumulator = 0L;
3
//-----------------------------------------
4
void Port_Init (void)
5
{
6
  XBR2 = 0x40;
7
  P74OUT |= 0x00;  // alle auf Null, dann sind wirklich alle für OpenDrain
8
}
9
//-----------------------------------------
10
void main (void)
11
{
12
  Port_Init();
13
  Timer3_Init(SYSCLK/12/10);
14
  EA = 1;
15
  while (1)
16
  {
17
  }
18
}
19
//--------------------------------------
20
void Timer_ISR (void) interrupt 14
21
{
22
  accumulator += P5;
23
24
  SW1 = accumulator >> 8;
25
  accumulator = 0L;
26
27
  if (SW1 & 0x04)
28
  {
29
    P1 = 0x00;  //ausschalten der Port0 Pins0-7
30
  }
31
}

Er reagiert auf kein Switschen des Schalters! :-(  ...alle Port's 0-3 
bleiben an - leider auch Port 1!
Ist ein Kippschalter, der an +5V und GND, sowie an P5^3 angeschlossen 
ist. Ich wollte nun P5^3 auslesen, um zu sehen ob "high = 1" oder "low = 
0" anliegen. Das es nun Bit-mäßig nicht funzt - Düüf! - aber nicht 
änderbar.

Nur was muss ich denn anders machen?

von Peter D. (peda)


Lesenswert?

Marcel M. schrieb:
> Ich wollte nun P5^3 auslesen

Dann tue es.

Dein kruder Code macht folgenden Unsinn:
((0 + P5) / 256) & 4
Klar kann da immer nur 0 rauskommen.

Und er compiliert nichtmal.
> unsigned cahr SW1;

Schreib Code nicht ab, sondern Copy&Paste !!!

von batty m. (battyman)


Lesenswert?

Hehe, ich habe so beim Lesen das Gefühl, das mein Problem ziemlich easy 
ist zu beheben. Ich steh nur leider vor nem Programmiercode und seh die 
Anweisung vor lauter HEX-EN nicht. Bräuchte mal n Besen der meine 
Festplatte entstaubt und anschließend resetet. Vielleicht bekomm ich 
dann wieder den Durchblick aber voll sorry, man kommt sich nach Tagen 
einfach nur noch blöd vor.
Egal was man macht, die Gegenseite macht nicht mit und ick raff nicht 
warum. Echt nicht.
Hab auch versucht mal den Temp-Sensor auszulesen, aber auch den Port 
anzusprechen fällt mir schwer. Auch mit Alk ist meine Zunge nicht 
lockerer geworden und die CPU zickt nur rum. Wollt den für mein 
Zufallszahlgenerator als Startwert nutzen.

Wie ich nur das DS richtig verstehen könnte, denn das was die da so von 
sich geben ist mir Logisch klar, aber die Umsetzung in den Programmcode 
ist n biisl tricky.

von Peter D. (peda)


Lesenswert?

Marcel M. schrieb:
> Ich wollte nun P5^3 auslesen

Wozu dann das ganze Geschwurbel mit long?

Teste P5 direkt:
1
  if( P5 & (1<<3) )
2
    printf( "P5.3 is high\n" );
3
  else
4
    printf( "P5.3 is low\n" );

War das nun so schwer?

von batty m. (battyman)


Lesenswert?

Peter Dannegger schrieb:
>
1
>   if( P5 & (1<<3) )
2
>
>


Warum schreibt ihr ale eigentlich "<<" was heißt das denn konkret?

Und danke erstmal, meckern tut das Program wenigstens jetzt nicht mehr. 
Muss nur noch rausfinden warum er nicht auf diesen einen Pin reagiert, 
egal welche Schalterstellung aktuell ist.
Hab eben mit n Multi nochmal durch gemessen, alles korrekt.
- Schalterstellung Null = Auf dem Bord Port5 Pin2 0V
- Schalterstellung Eins = -"-  5V

Aber ich gucke weiter...

von troll (Gast)


Lesenswert?

Marcel M. schrieb:
> Warum schreibt ihr ale eigentlich "<<" was heißt das denn konkret?
Bitmanipulation oder ein beliebiges C-Buch lesen.

von batty m. (battyman)


Lesenswert?

Mhh, nein ich habe weiterhin das Dilemma, dass er auf meinen Schalter 
nicht reagiert, siehe Code:
1
#include <c8051f020.h>                    // SFR declarations
2
#include <stdio.h>
3
#include <stdlib.h>
4
//------------------------------------------------------------------------------------
5
// 16-bit SFR Definitions for 'F02x
6
//------------------------------------------------------------------------------------
7
8
sfr16 DP       = 0x82;                    // data pointer
9
sfr16 TMR3RL   = 0x92;                    // Timer3 reload value
10
sfr16 TMR3     = 0x94;                    // Timer3 counter
11
sfr16 ADC0     = 0xbe;                    // ADC0 data
12
sfr16 ADC0GT   = 0xc4;                    // ADC0 greater than window
13
sfr16 ADC0LT   = 0xc6;                    // ADC0 less than window
14
sfr16 RCAP2    = 0xca;                    // Timer2 capture/reload
15
sfr16 T2       = 0xcc;                    // Timer2
16
sfr16 RCAP4    = 0xe4;                    // Timer4 capture/reload
17
sfr16 T4       = 0xf4;                    // Timer4
18
sfr16 DAC0     = 0xd2;                    // DAC0 data
19
sfr16 DAC1     = 0xd5;                    // DAC1 data
20
//------------------------------------------------------------------------------------
21
// Global CONSTANTS
22
//------------------------------------------------------------------------------------
23
#define SYSCLK 2000000                    // approximate SYSCLK frequency in Hz
24
25
// globale zaehlvariable
26
int rand(void);              // rand = Zufall; void = Funktion -> erzeugt Zufallszahl
27
void srand (seed);            // srand initialisiert die Zufallszahl und gibt den Startwert vor
28
unsigned int seed;            // seed = Saat und ist der Zufallszahlgeneratorstartwert
29
unsigned char n = 0;          // Zaehlvariable n für LED-Hex-Wert-Feld
30
unsigned char t1 = 0;          // Zaehlavariable für 1Hz Taktratengenerierung
31
unsigned char t2;
32
unsigned char t3;
33
unsigned char sec05=1;
34
35
36
// Projekt - LED_Kofferraumbeleuchtung - Laborversuch in Kleinmaßstab - 27.04.2013
37
38
//------- Hex-Werte für jede einzelne LED auf der Labor-Platine - 29.04.2013 -----------------
39
// für jede LED ist ein HEX-Wert (entspricht Pin) pro Port zugeordnet. Da bei 28 LED's 4 Ports
40
// benötigt werden, ist hier ein Hex-Array (Feld) für 4 Port's und 8 LED-Reihen erstellt
41
//LED Blau
42
unsigned char code L_LED_Blau0[9] = { 0x00, 0x01, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 };
43
unsigned char code L_LED_Blau1[9] = { 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00 };
44
unsigned char code L_LED_Blau2[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0x00 };
45
unsigned char code L_LED_Blau3[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C };
46
47
48
//LED Rot
49
unsigned char code L_LED_Rot0[9] = { 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };  
50
unsigned char code L_LED_Rot1[9] = { 0x00, 0x00, 0x00, 0x01, 0x08, 0x40, 0x00, 0x00, 0x00 };
51
unsigned char code L_LED_Rot2[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00 };
52
unsigned char code L_LED_Rot3[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10 };
53
54
//LED Grün
55
unsigned char code L_LED_Gruen0[9] = { 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };  
56
unsigned char code L_LED_Gruen1[9] = { 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00 };
57
unsigned char code L_LED_Gruen2[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00 };
58
unsigned char code L_LED_Gruen3[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x60 };
59
60
//Deklaration einer Port-"Puffer"-Variablen; wird später als Algorithmus-Zaehlvariable benutz.
61
// Um eine volle Farbleiste oder ein sich aufbauenden Lichtbalken zu generieren müssen die
62
// Hex-Werte logisch verknüpft, also aufaddiert, werden. Um das LED-weise zu machen, wird eine
63
// Hilfsvariable als Zwischenspeicher verwendet, um die Portausgabe nicht direkt zu überschreiben.
64
unsigned char B_LED_P0 = 0;
65
unsigned char B_LED_P1 = 0;
66
unsigned char B_LED_P2 = 0;
67
unsigned char B_LED_P3 = 0;
68
69
unsigned char P0h = 0;
70
unsigned char P1h = 0;
71
unsigned char P2h = 0;
72
unsigned char P3h = 0;
73
//------------------------------------------------------------------------------------
74
// Function PROTOTYPES
75
//------------------------------------------------------------------------------------
76
void PORT_Init (void);        //Funktionsaufruf für die Port* Initialisierung
77
void Timer3_Init (int counts);    //Funktionsaufruf für die Timer3 Initialisierung
78
void Timer3_ISR (void);        //Funktionsaufruf der Timer3 Interrupt Service Routine
79
//------------------------------------------------------------------------------------
80
// MAIN Routine
81
//------------------------------------------------------------------------------------
82
void main (void)          // ist das eigentlich auszuführende Programm
83
{
84
85
   // disable watchdog timer
86
   WDTCN = 0xde;
87
   WDTCN = 0xad;
88
89
   PORT_Init ();
90
   Timer3_Init (SYSCLK / 12 / 10);  // Init Timer3 to generate interrupts at 10Hz rate
91
   srand(TMR3*rand());
92
        
93
   EA =1;
94
95
   while (1)             // spin forever
96
   {       
97
     if(P5 & (1<<3) )
98
    P1 = P3 = 0x00;   //macht P1 und 3 aus
99
  else
100
    P2 = 0;           //macht P2 aus
101
   
102
  }
103
104
}
105
//------------------------------------------------------------------------------------
106
// PORT_Init
107
//------------------------------------------------------------------------------------
108
//
109
// Configure the Crossbar and GPIO ports
110
111
void PORT_Init (void)
112
{
113
   XBR2    = 0x40;              // Enable crossbar and weak pull-ups
114
   P0MDOUT |= 0xff;             // enable Port0 as push-pull output  
115
   P1MDOUT |= 0xff;             // enable Port1 as push-pull output  
116
   P2MDOUT |= 0xff;             // enable Port2 as push-pull output  
117
   P3MDOUT = 0x7f;              // enable Port3 Pin 0-6 as push-pull output
118
                                // Pin 7 as Open Drain
119
120
   P74OUT |= 0x00;   // Initialisierung aller als OpenDrain
121
   P5 = 0xff;   //auf allen Pin's liegen 3V an ausser auf Pin3
122
   //P5 = 0x00;   // auf allen Pin's liegen 0V an
123
                       //bei beiden Varianten ist P3 Schlaterabhängig und messbar 0V oder 5V
124
}

Also laut DS muss ich P74OUT als OpenDrain initialisieren, damit ist 
jedoch immer noch auf Port 5 Spannung aufgelegt.
mit dem While-Code mach der nun folgendes mit mir:

P5 = 0x00 -> gibt keinen Spannung frei - Es wird die else-Anwendung 
ausgeführt
P5 = 0xff -> Spannung auf Pin 0-1 und 3-7 - Es wird die If-Anwendung 
ausgeführt

Wenn ich den Schalter switche dann ändert sich die Spannung am Pin2 von 
0V auf 5V, jedoch reagiert das Programm nicht darauf. Demnach lese ich 
wohl einen anderen, nicht gewollten Pin aus da ich per Hex-Code ja dort 
mal 0 oder 1 anliegen habe und dann  auch das If-Else richtig ausgeführt 
wird.

(1<<3) - verstehe ich so: Bit1 schiebe ich von der 0-Stelle auf die 
3-Stelle, demnach Pin2  -  RICHTIG???

von Garden (Gast)


Lesenswert?

Marcel M. schrieb:
> if( P5 & (1<<3) )
>> >
>
>
> Warum schreibt ihr ale eigentlich "<<" was heißt das denn konkret?

Du kanst auf folgendes schreiben:

if( P5 & (0x08) )

Guck mal hier, vielleicht hilft Dir das Video:
http://et-tutorials.de/1908/bitweise-manipulation/

von Thomas (Gast)


Lesenswert?

nun wenn du schon SFR16 verwendest mußt du aber schon verstanden haben 
wie das funktioniert. Einfach Register als SFR16 zu definieren ohne zu 
wissen was da abgeht ist mutig.

C Grundlagen wären auch keine schlechte Idee:
>P74OUT |= 0x00;   // Initialisierung aller als OpenDrain
Diese Zeile macht genau garnichts.

Thomas

von batty m. (battyman)


Lesenswert?

Mhh, super!

Also mit den direkten HEX-Zuweisungen hab ich es auch schon probiert = 
nix da.
Denn habe ich auch das Obige
1
P74OUT |= (0<<2);
 auch probiert, gleiche Ergebnis.

Sorry das ich n blutiger Anfänger bin und versuche durch alles durch zu 
steigen, hab hier zu C-Programmierung div. Leseunterlagen und auch 
verschiedene, zum Board, txt-examples.

Bisher habe ich mehr in VB und VBA meine Nase gesteckt. das ist von den 
deklarationen und Anweisungen alles etwas anders.

Habt bitte n bissl Verständnis, ich les ja schon immer noch in den 
Unterlagen um das, was ihr hier so schreibt auch gleich 
nachzuvollziehen. Ich lern das hier immer so 2-3h Abends dabei, neben 
40h Arb.Woche und Fr.-Sa-Uni zzgl. Lernzeit So wie ges. Arb.-woche.
Ach ja, bin selber Chemotechniker und bring mir das so allmälich 
elektrotechnisch (Hardware, Funktionsweise), sowie softwaretechnisch 
immer nebenbei bei. :-)

Vielen Dank

von Wilhelm F. (Gast)


Lesenswert?

Marcel M. schrieb:

> Mhh, nein ich habe weiterhin das Dilemma, dass er auf meinen Schalter
> nicht reagiert, siehe Code:

Haben die SiLabs-µC nicht auch SFR-Pages, die man vor einem Zugriff 
umschalten muß? Im Code sehe ich sowas jedenfalls nicht. Ohne das jetzt 
im Datenblatt nachzuschauen. Mit Glück liegen deine verwendeten SFR alle 
in SFR-Page 0, ohne umzuschalten. Die SFR-Pages mußte man damals 
einführen, weil die üblichen 128 Bytes SFR eines 8051 nicht für alle 
neuen SFR-Register ausreichten. Notfalls kann man sich bestimmt Makros 
definieren, die beim Zugriff auf ein SFR gleich die richtige Page mit 
einschalten.

SiLabs hat aber auf der Homepage ganz bestimmt massenhaft Beispielcode. 
Auf einer CD zu einem Board, welches ich habe, war auch Beispielcode 
drauf.

Brauchbare C-Tutorials findet man massenweise im Internet, ich fand vor 
Jahren schon mal auf Anhieb drei in einer Viertelstunde. Der olle K&R 
(Kernighan/Ritchie, die Erfinder von C, C-Referenz) ist aber auch heute 
immer noch gut brauchbar.

Ohne C-Kenntnisse kannst du das Teil aber auch in 8051-Assembler 
programmieren. Das war damals mein erster Test mit dem Board, ein 
LED-Blinkprogramm von der mit gelieferten CD.



Marcel M. schrieb:

> Sorry das ich n blutiger Anfänger bin

Das sag ich doch hier manchmal auch, daß für einen Anfänger manchmal ein 
oller Standard-8051 aus der Steinzeit zum Lernen und Verstehen besser 
ist. Etwas, was keine Unmengen integrierte Peripherals hat, keine 
Pinzuweisungen und keine SFR-Pages und all so nen Kram. Diese 
SiLabs-Teile sind schon etwas komplexer, auch wenn sie "nur" einen 
8051-Core haben, aber sie sind halt kein Standard-8051.

von Garden (Gast)


Lesenswert?

Wilhelm Ferkes schrieb:
> Haben die SiLabs-µC nicht auch SFR-Pages, die man vor einem Zugriff
> umschalten muß?

Vor allem haben die Silabs-uC eine CrossBar, die sicher noch 
konfiguriert werden muss, um überhaupt den Port auf physikalische Pins 
zu lsegen.

Ich weiß aber nicht, ob dies bei diesem Modell auch so ist.

von Wilhelm F. (Gast)


Lesenswert?

Garden schrieb:

> Vor allem haben die Silabs-uC eine CrossBar, die sicher noch
> konfiguriert werden muss, um überhaupt den Port auf physikalische Pins
> zu lsegen.

Das ist es ja, für einen Anfänger allerhand zusätzliche Hürden. Als ich 
aber selbst ein SiLabs-Board bekam, stieg ich durch die Crossbar 
immerhin noch ohne das Crossbar-Tool durch, alleine aus dem Datenblatt. 
Es bedingt aber, sich drei Stunden (und länger) nur damit alleine mal 
auseinander zu setzen, wenn man eine bestimmte Pinkonfiguration braucht. 
Es gibt aber auch ein Crossbar-Tool zur Konfigurierung, es ist 
anscheinend auch sehr hilfreich.

> Ich weiß aber nicht, ob dies bei diesem Modell auch so ist.

Mein SiLabs C8051F064 Evaluation Kit liegt immer noch im Schrank, es ist 
inzwischen auch 8 Jahre alt. Aber das modernste, was ich habe. Neu 
probierte ich es nur mal kurz aus, als Funktionstest, mehr nicht. Für 
den Betrieb am PC müßte ich da einiges tun, weiß nicht, ob und wie die 
Tools von der CD (IDE, Compiler, Assembler) auf meinem neueren Rechner 
spielen. Der C-Compiler ist auf 2k Code begrenzt, da muß ich parallel 
schon wieder mit dem unlimitierten freien SDCC-Compiler für 8051 
tricksen. Ich bin aber im Augenblick auch mit Retro-Dingen (8048) 
beschäftigt, alles parallel probieren und machen mag ich nicht, also 
keine richtige Zeit für alles.

von batty m. (battyman)


Lesenswert?

So, nun mal wieder n paar Stunden mit PDF's verbracht :-D

also, ja es gibt ne Crossbar
XBR0 ; XBR1 und XBR2, die alle auch was machen - wenn man nen Durchblick 
hat, dann bestimmt auch das Richtige!

Des Weiteren sieht's mit den Port's so aus, das auch die P4-7 alle Pins 
I/O fähig sind. Ist ja auch fast logisch, da ich ja die anliegende 
Spannung von gut 3,2V auf den Pins messen konnte.
Kurrioser Weise reagiert die Software ja auch auf die Spannungsänderung, 
die per Software herbeigeführt wurde, und führt die If- oder eben die 
Else- Anwendung aus.

Nun habe ich mir noch folgenden Gednaken gemacht - ich will ja eig den 
Low-Bit von Port5 ansprechen und auslesen. Hab nun aber gelesen, das, 
wenn ich mit 5V Input kommen möchte auf High gehen muss. Dann müsste ich 
erstmal noch mal die Hardware umlöten von P5^2 auf P5^3, da dieser ja 
wohl den High-OpenDrain kann.

Puuuhh...jeder Anfang ist ja schwer aber gleich so. Wenn man schon 8 I/O 
Ports drauf bastelt, dann kann man die doch auch alle gleich behandel. 
"rrrrr" ;-)

Auszug von SiLabs.com:
1
entity C8051F020 is
2
generic(PHYSICAL_PIN_MAP: string := "TQFP_100");
3
4
5
port(
6
    
7
  P0_0  : INOUT BIT; ...  P4_0  : INOUT BIT;   P5_0  : INOUT BIT; ...analog bis P7
8
  P0_1  : INOUT BIT; ...  P4_1  : INOUT BIT;   P5_1  : INOUT BIT;
9
  P0_2  : INOUT BIT; ...  P4_2  : INOUT BIT;   P5_2  : INOUT BIT;
10
  P0_3  : INOUT BIT; ...  P4_3  : INOUT BIT;   P5_3  : INOUT BIT;
11
  P0_4  : INOUT BIT; ...  P4_4  : INOUT BIT;   P5_4  : INOUT BIT;
12
  P0_5  : INOUT BIT; ...  P4_5  : INOUT BIT;   P5_5  : INOUT BIT;
13
  P0_6  : INOUT BIT; ...  P4_6  : INOUT BIT;   P5_6  : INOUT BIT;
14
  P0_7  : INOUT BIT; ...  P4_7  : INOUT BIT;   P5_7  : INOUT BIT;

Dazu noch:
1
6. Target Board
2
3
The C8051F02x Development Kit includes a target board with a C8051F020 device pre-installed for evaluation and
4
preliminary software development. Numerous input/output (I/O) connections are provided to facilitate prototyping
5
using the target board. Refer to Figure 2 for the locations of the various I/O connectors.
6
P1 Power connector (accepts input from 7 to 15 VDC unregulated power adapter)
7
8
J1 Connects SW2 to P3.7 pin
9
J3 Connects LED D3 to P1.6 pin
10
J4 JTAG connector for Debug Adapter interface
11
J5 DB-9 connector for UART0 RS232 interface
12
J6 Connector for UART0 TX (P0.0)
13
J8 Connector for UART0 RTS (P4.0)
14
J9 Connector for UART0 RX (P0.1)
15
J10 Connector for UART0 CTS (P4.1)
16
J11 Analog loopback connector
17
J12-J19 Port 0 - 7 connectors
18
J20 Analog I/O terminal block
19
J22 VREF connector
20
J23 VDD Monitor Disable
21
J24 96-pin Expansion I/O connector
mit:
1
6.6. PORT I/O Connectors (J12 - J19)
2
In addition to all port I/O signals being routed to the 96-pin expansion connector, each of the eight parallel ports of
3
the C8051F020 has its own 10-pin header connector. Each connector provides a pin for the corresponding port
4
pins 0-7, +3.3 VDC and digital ground. Table 5 defines the pins for the port connectors. The same pin-out order is
5
used for all of the port connectors.
6
7
6.8. VREF Connector (J22)
8
The VREF connector (J22) can be used to connect the VREF (Voltage Reference) output of the C8051F020 to any
9
(or all) of its voltage reference inputs. Install shorting blocks on J22 in the following manner:
10
11
1-2 to connect VREF to VREFD
12
3-4 to connect VREF to VREF0
13
5-6 to connect VREF to VREF1
14
Table 5. J12- J19 Port Connector Pin Descriptions
15
Pin # Description
16
1 Pn.0
17
2 Pn.1
18
3 Pn.2
19
4 Pn.3
20
5 Pn.4
21
6 Pn.5
22
7 Pn.6
23
8 Pn.7
24
9 +3 VD (+3.3 VDC)
25
10 GND (Ground)

von flomann (Gast)


Lesenswert?

Marcel M. schrieb:
> Mhh, super!
>
> Also mit den direkten HEX-Zuweisungen hab ich es auch schon probiert =
> nix da.
> Denn habe ich auch das ObigeP74OUT |= (0<<2); auch probiert, gleiche Ergebnis.
>
Wenn du bits selektiv null setzen möchtest dann & verknüpfen:
 P74OUT&=0xf7; //setzt bit 3 null restlichen bleiben wie zuvor.
Zum setzen von bits | verknüpfen:
P74OUT|=0x08; //setzt bit 3 eins restlichen bleiben wie zuvor.

In so einem Fall lass das bit schieben einfach sein, zumal nur nullen 
schieben nicht wirklich Sinn macht.

Der f020 hat soweit ich mich erinnere keine SFR pages.

Wenn du inputs möchtest, port Pins auf open drain definieren und die 
betreffenden
Port bits eins setzen. Das du dabei dann eine Spannung messen kannst 
bzw.
Der pin als high eingelesen wird, liegt am weak pull up.
 Siehe xbar für pull up konfig. Schalte/taste den pin z.b gegen masse.
 Wenn der Schalter/Taster(ausgehend von einem Schließer) betätigt also 
geschlossen
wird liest du eine null ein, offen dann eins . Oder wenn du unbedingt 
auf plus schalten
möchtest, dann nutze einen pulldown am port pin.
Weak pull up dann aus oder niederohmiger pulldown ab 10k und kleiner 
sollte gehen,
da der weak pull up oft im Bereich 100k liegt. Lasse die Pins nicht 
Floaten.
aber lese selbst mal nach, den f020 kenne ich nicht direkt.

von batty m. (battyman)


Lesenswert?

Aus dem DS für C8051F020 extra Port 4 - 7:
1
17.2.2. Configuring the Output Modes of the Port Pins
2
The output mode of each port pin can be configured to be either Open-Drain or Push-Pull. In the Push-Pull configuration, a logic 0 in the associated bit in the Port Data register will cause the Port pin to be driven to GND, and a logic 1 will cause the Port pin to be driven to VDD. In the Open-Drain configuration, a logic 0 in the associated bit in the
3
Figure 17.19. P3IF: Port3 Interrupt Flag RegisterBit7:IE7: External Interrupt 7 Pending Flag0: No falling edge has been detected on P3.7 since this bit was last cleared.1: This flag is set by hardware when a falling edge on P3.7 is detected.Bit6:IE6: External Interrupt 6 Pending Flag0: No falling edge has been detected on P3.6 since this bit was last cleared.1: This flag is set by hardware when a falling edge on P3.6 is detected.Bits5-4:UNUSED. Read = 00b, Write = dont care.Bit3:IE7CF: External Interrupt 7 Edge Configuration0: External Interrupt 7 triggered by a falling edge on the IE7 input.1: External Interrupt 7 triggered by a rising edge on the IE7 input.Bit2:IE6CF: External Interrupt 6 Edge Configuration0: External Interrupt 6 triggered by a falling edge on the IE6 input.1: External Interrupt 6 triggered by a rising edge on the IE6 input.Bits1-0:UNUSED. Read = 00b, Write = dont care.R/WR/WRRR/WR/WR/WR/WReset ValueIE7IE6--IE7CFIE6CF--00000000Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0SFR Address:0xAD
4
C8051F020/1/2/3
5
178 Rev. 1.4
6
Port Data register will cause the Port pin to be driven to GND, and a logic 1 will cause the Port pin to assume a high-impedance state. The Open-Drain configuration is useful to prevent contention between devices in systems where the Port pin participates in a shared interconnection in which multiple outputs are connected to the same physical wire.
7
8
The output modes of the Port pins on Ports 4 through 7 are determined by the bits in the P74OUT register (see Figure 17.20). Each bit in P74OUT controls the output mode of a 4-bit bank of Port pins on Ports 4, 5, 6, and 7. A logic 1 in P74OUT.7 will configure the output modes of 4 most-significant bits of Port 7, P7.[7:4], to Push-Pull; a logic 0 in P74OUT.7 will configure the output modes of P7.[7:4] to Open-Drain.
1
17.2.3. Configuring Port Pins as Digital Inputs
2
A Port pin is configured as a digital input by setting its output mode to Open-Drain and writing a logic 1 to the associated bit in the Port Data register. For example, P7.7 is configured as a digital input by setting P74OUT.7 to a logic 0 and P7.7 to a logic 1.
3
4
17.2.4. Weak Pull-ups
5
By default, each Port pin has an internal weak pull-up device enabled which provides a resistive connection (about 100 kΩ) between the pin and VDD. The weak pull-up devices can be globally disabled by writing a logic 1 to the Weak Pull-up Disable bit, (WEAKPUD, XBR2.7). The weak pull-up is automatically deactivated on any pin that is driving a logic 0; that is, an output pin will not contend with its own pull-up device.

Das habe ich versucht umzusetzen:
1
Figure 17.20. P74OUT: Ports 7 - 4 Output Mode Register
2
Bit7:P7H: Port7 Output Mode High Nibble Bit.
3
       0: P7.[7:4] configured as Open-Drain.
4
       1: P7.[7:4] configured as Push-Pull.
5
Bit6:P7L: Port7 Output Mode Low Nibble Bit.
6
       0: P7.[3:0] configured as Open-Drain.
7
       1: P7.[3:0] configured as Push-Pull.
8
Bit5:P6H: Port6 Output Mode High Nibble Bit.
9
       0: P6.[7:4] configured as Open-Drain.
10
       1: P6.[7:4] configured as Push-Pull.
11
Bit4:P6L: Port6 Output Mode Low Nibble Bit.
12
       0: P6.[3:0] configured as Open-Drain.
13
       1: P6.[3:0] configured as Push-Pull.
14
Bit3:P5H: Port5 Output Mode High Nibble Bit.
15
       0: P5.[7:4] configured as Open-Drain.
16
       1: P5.[7:4] configured as Push-Pull.
17
Bit2:P5L: Port5 Output Mode Low Nibble Bit.
18
       0: P5.[3:0] configured as Open-Drain.
19
       1: P5.[3:0] configured as Push-Pull.
20
Bit1:P4H: Port4 Output Mode High Nibble Bit.
21
       0: P4.[7:4] configured as Open-Drain.
22
       1: P4.[7:4] configured as Push-Pull.
23
Bit0:P4L: Port4 Output Mode Low Nibble Bit.
24
       0: P4.[3:0] configured as Open-Drain.
25
       1: P4.[3:0] configured as Push-Pull.

in Verbindung mit:
1
Figure 17.22. P5: Port5 Data Register
2
Bits7-0:  P5.[7:0]: Port5 Output Latch Bits.
3
          Write - Output appears on I/O pins.
4
          0: Logic Low Output.
5
          1: Logic High Output (Open-Drain if corresponding P74OUT bit = 0). See Figure 17.20.
6
          Read - Returns states of I/O pins.
7
          0: P5.n pin is logic low.
8
          1: P5.n pin is logic high.
9
Note:P5.[7:0] can be driven by the External Data Memory Interface (as Address[15:8] in Non-multiplexed mode). See Section 16. EXTERNAL DATA MEMORY INTERFACE AND ON-CHIP XRAM on page 145 for more information about the External Memory Interface.

Wie habe ich denn fogende Schreibweise "0: P5.[7:4]" zu verstehen???

Echt vielen Dank an euch :-)

von batty m. (battyman)


Lesenswert?

flomann schrieb:
> Wenn du bits selektiv null setzen möchtest dann & verknüpfen:
>  P74OUT&=0xf7; //setzt bit 3 null restlichen bleiben wie zuvor.
> Zum setzen von bits | verknüpfen:
> P74OUT|=0x08; //setzt bit 3 eins restlichen bleiben wie zuvor.
Danke, dass mit dem & | Verknüpfung ist mir so klarer geworden!


> Der f020 hat soweit ich mich erinnere keine SFR pages.
Hab auch nichts dazu gefunden. mit "incl. c8051f020.h" schein ich schon 
alle sfr-reg mit eingebunden zu haben.

> Wenn du inputs möchtest, port Pins auf open drain definieren und die
> betreffenden
> Port bits eins setzen.
Genau da scheint es bei mir an der Umsetzung zu hapern.

> ...wird liest du eine null ein, offen dann eins . Oder wenn du unbedingt
> auf plus schalten
> möchtest, dann nutze einen pulldown am port pin.
Was heißt möchte? hab einen Schalter auf einer exteren Platine. Der ist 
mit GND und +5V belegt. der dritte Schalter-Pin ist mit dem P5^2 
kontaktiert. SW offen = 0V auf µC-Board P5^2. SW geschl. = +5V ...

> Weak pull up dann aus oder niederohmiger pulldown ab 10k und kleiner
> sollte gehen,
> da der weak pull up oft im Bereich 100k liegt. Lasse die Pins nicht
> Floaten.
jup sind 100kOhm - ui jui, wenn ich also Pech habe, habe ich den Port 
Pin schon abgeschossen

Vielen Dank

von battyman (Gast)


Lesenswert?

mhh, jup - scheint wohl abgeschossen - mittels Hex-Zuweisung jeden zu 
Fuss angesprochen und Spannung gemessen. Alle ausser Pin 2 geben noch 
3,2V aus. Pin 2 hängt bei 0V.

von Wilhelm F. (Gast)


Lesenswert?

battyman schrieb:

> mhh, jup - scheint wohl abgeschossen - mittels Hex-Zuweisung jeden zu
> Fuss angesprochen und Spannung gemessen. Alle ausser Pin 2 geben noch
> 3,2V aus. Pin 2 hängt bei 0V.

Warst du da mal mit zu hoher Fremdspannung an den Pins?

von batty m. (battyman)


Lesenswert?

Joar, war ich wohl. Bzw., da ich mit 5V Input geh hatte ich den falschen 
Pin angesprochen.

Aber erstmal echt vielen Dank an allen hier noch mal.
Lösung meines Schalter-Port-Problem:
Das µC-Board C8051F020DK hat 0-3 Port als I/O-Digitalpins - ansprechbar 
als sbit ;-)
Port 4-7 sind zuerst nicht ansprechbar.
mit P74OUT kann man jedoch die Port's 4-7 ansprechen und mit der 
entsprechenden Logik "&","|", sowie den Hexwert für die gewünschten Pins 
als PushPull oder OpenDrain initialisieren.
Wichtig hierbei ist nun, dass bei Input auf die Eingangsspannung 
geachtet wird. Denn bei für die Port's 4-7 sind die Pins 0-3 für eine 
Vmax = 3V ausgelegt, da auf Masse gelegt wird [sofern OpenDrain :-) ]. 
Wenn man wie ich mit 5V Input den Pin abfragen möchte, dann muss man auf 
die Pins 4-7 gehen, da diese gegen einen höheren Widerstand aufgelegt 
werden.

Bei beachten dieser Dinge war es am Ende denn doch recht einfach. Wenn 
man erstmal verstanden hat warum manches eben geht und manches nicht.
Blöd für mich waren noch zwei dinge:
1. Pin abgeschossen, deswegen immer als Bit = 0 und kein reagieren auf 
Schalterwechsel
2. Da ich dann ein Zaehlvariables-Progrämmchen ablaufen lassen wollte, 
musste ich "t1++" zu "t1+1" umschreiben, denn komischer weise ist er bei 
"t++" nie in die If-Schleife gewandert.

Nu ist aber echt alles gut, hab mich vorhin tierisch gefreut.  :-D

Lösung:
1
// Includes
2
//------------------------------------------------------------------------------------
3
#include <c8051f020.h>                    // SFR declarations
4
#include <stdio.h>
5
#include <stdlib.h>
6
7
// Global CONSTANTS
8
#define SYSCLK 2000000                    // approximate SYSCLK frequency in Hz
9
10
// globale zaehlvariable
11
int rand(void);              // rand = Zufall; void = Funktion -> erzeugt Zufallszahl
12
void srand (seed);            // srand initialisiert die Zufallszahl und gibt den Startwert vor
13
unsigned int seed;
14
unsigned char a;
15
unsigned char n = 0;          // Zaehlvariable n für LED-Hex-Wert-Feld
16
unsigned char t1 = 0;          // Zaehlavariable für 1Hz Taktratengenerierung
17
18
//LED Blau
19
//LED Rot
20
//LED Grün
21
//Puffer-Variable
22
23
// Function PROTOTYPES
24
void PORT_Init (void);        //Funktionsaufruf für die Port* Initialisierung
25
void Timer3_Init (int counts);    //Funktionsaufruf für die Timer3 Initialisierung
26
void Timer3_ISR (void);        //Funktionsaufruf der Timer3 Interrupt Service Routine
27
28
// MAIN Routine
29
void main (void)          // ist das eigentlich auszuführende Programm
30
{
31
   // disable watchdog timer
32
   WDTCN = 0xde;
33
   WDTCN = 0xad;
34
   PORT_Init ();
35
   Timer3_Init (SYSCLK / 12 / 10);  // Init Timer3 to generate interrupts at 10Hz rate
36
   srand(TMR3*rand());
37
        
38
   EA =1;
39
   while (1)             // spin forever
40
   {
41
     a = P5 & (0x40);             //Port5-Anwahl und Pin6-Maskierung
42
   }
43
}
44
45
// PORT_Init
46
void PORT_Init (void)
47
{
48
   XBR2     = 0x40;              // Enable crossbar and weak pull-ups
49
   P74OUT  &= 0x0f;      // Initialisierung von Port5Pin4-7 zu NULL für OpenDrain
50
}
51
52
// Timer3_Init
53
void Timer3_Init (int counts)
54
   TMR3CN = 0x00;                      // Stop Timer3; Clear TF3;
55
                                       // use SYSCLK/12 as timebase
56
   TMR3RL  = 0xffff -counts;                  // Init reload values
57
   TMR3    = 0xffff;                   // set to reload immediately
58
   EIE2   |= 0x01;                     // enable Timer3 interrupts
59
   TMR3CN |= 0x04;                     // start Timer3
60
}
61
62
// Interrupt Service Routines
63
// Timer3_ISR
64
void Timer3_ISR (void) interrupt 14
65
{
66
  TMR3CN &= ~(0x80);                       // clear TF3
67
  if(a<1)                                 //Abfrage Schalterstellung
68
  {
69
    t1 = t1+1;          
70
    if(t1>100)            
71
       {  
72
          //...
73
        }
74
      }
75
      t1 = 0;    
76
       } 
77
     }
78
79
  if(a>=1)
80
  {
81
     t1 = t1+1;          
82
    if(t1>10)            
83
       {  
84
      n = n + 1;          
85
         if(n>8)              
86
      {
87
         n = 0;          
88
        t2 = rand()%13+2;    //Zufallszahlen von 1 bis 13 für die verschiedenen Case's
89
      }
90
      if (t2<14)          //wenn t2 kleiner 14 ist wird die "switch"-Anweisung ausgeführt
91
      {
92
        //...
93
        }
94
      }
95
       t1 = 0;    
96
    }  
97
   } 
98
}

Funtioniert super mit dem Schalter.

Jetzt geht's ans Auslesen des schon vorhandenen Temp.-Sensors, für 
Zufallszahlstartwert.  ;-) - puuuhhh, wird wohl nicht einfacher!!!

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.