Guten Morgen,
bin grad dabei die Daten die ich über eine I2C Schnittstelle einles im
uC (LPC2129) zu verarbeiten und in Abhängigkeit der Größe sollen 1 bis 5
Leds brennen. Durch einen Taster soll dies geschehn.
Weiß jemand wie man zu den IO ports, den notwendigen Taster und die 5
Leds initialisiert? Was müsste denn dafür alles gemacht werden?
Wieviel IO Ports benötigt man denn um dies realisieren zu können?
Bin noch nicht all zu lang in der Materie drinnen.
Würd mich freun wenn mir jemand weiterhelfen könnte.
Gruß
Steff wrote:
> Weiß jemand wie man zu den IO ports, den notwendigen Taster und die 5> Leds initialisiert? Was müsste denn dafür alles gemacht werden?
Du hast bestimmt einen Example-Ordner in Deiner Compilerinstallation,
lese darin.
> Wieviel IO Ports benötigt man denn um dies realisieren zu können?
Einfach mal zählen.
> Bin noch nicht all zu lang in der Materie drinnen.
Das heißt?
Wieviel Projekte hast Du denn schon mit diesem 32Bit-Monsterboliden
programmiert?
Hast Du überhaupt schon mal was mit MCs gemacht?
Hast Du überhaupt schon mal in C programmiert?
> Würd mich freun wenn mir jemand weiterhelfen könnte.
Bei 32-Bittern ist ein gewisses Grundverständnis (Datenblatt, Usermanual
lesen können usw.) unbedingte Vorraussetzung.
Solche Boliden sind ja keine Anfänger-Projekte.
Peter
Da geb ich dir voll und ganz Recht.
Ja hab ich schon, aber nicht alleine. Das Beispielprogramm hab ich auch
schon angesehn.
Bräuchte ja dann insgesmt 6 IOs. Weiß halt nicht welche ich überhaupt
nehmen könnte. So wie ich das seh sind da garkeine 6. Wäre dir echt
dankbar wenn du mir einbisschen auf die Sprünge helfen könntest.
Taster-Port als Eingang, die LED-Ports als Ausgang. Modus auf GPIO
setzen, "neither pull-up nor pull-down" setzen und dann brauchste nur
noch ein und ausschalten.
Guck dir diesbezueglich im Datenblatt des Prozessors das Kapitel 8 oder
9 (glaube, eher 9, weiss es nich genau ausm Kopf) an, da werden die
Register PINSEL und PINMODE erklaert. In Kapitel 10 dann die Register
FIOxSET, FIOxCLR und FIOxDIR angucken, verstehen wie das funktioniert
und dann nur noch die Applikation schreiben. Fertig
Steff wrote:
> Bräuchte ja dann insgesmt 6 IOs. Weiß halt nicht welche ich überhaupt> nehmen könnte. So wie ich das seh sind da garkeine 6.
???
Also laut NXP hat der "46 fast GPIO lines".
Peter
> und dann nur noch die Applikation schreiben. Fertig
Wäre schön wenn das so einfach wäre*g*
> Taster-Port als Eingang, die LED-Ports als Ausgang
Hab die relevanten Seiten schon durchgelesen, werd daraus aber
leider nicht schlau. Könntest du mir evtl. mal eine Initialisierung
von
einem Port und die des Tasters zeigen, wenns es nicht all zu aufwändig
wird?
Das hier ist ein Teil von dem Beispielprogramm:
Könnte ich das dann einfach dann so schreiben wie hier, nur dann einfach
für 5 leds und einem Taster?
// button.h
#include <iolpc2129.h>
#define BUT1_PRESSED IO0PIN_bit.P0_15
#define BUT2_PRESSED IO0PIN_bit.P0_16
Wieso kann ich das einfach so schreiben? IO0PIN_bit.P0_15 Wieso nehmen
die grad port 15 und 16?
// init buttons port
void InitButtons(void);
//buttons.c
#include <iolpc2129.h>
#include "buttons.h"
// init buttons port
void InitButtons(void) {
IO0DIR_bit.P0_15 = 0; //set port0.15 as input
IO0DIR_bit.P0_16 = 0; //set port0.16 as input
}
//led.c
#include <iolpc2129.h>
#include "led.h"
//it's a simple delay
void Delay (unsigned long a) {
while (--a!=0);
}
// init led port
void LedsInit(void) {
IO0DIR_bit.P0_12 = 1; //set port0.12 to output
IO0DIR_bit.P0_13 = 1; //set port0.13 to output
}
// single blink led 1
void Led1Blink(void) {
IO0CLR_bit.P0_12 = 1; //on led
Delay(500000); //delay
IO0SET_bit.P0_12 = 1; //off led
Delay(500000); //delay
}
// turn on led 1
void Led1On(void) {
IO0CLR_bit.P0_12 = 1; //on led
}
// turn off led 1
void Led1Off(void) {
IO0SET_bit.P0_12 = 1; //off led
}
// single blink led 2
void Led2Blink(void) {
IO0CLR_bit.P0_13 = 1; //on led
Delay(500000); //delay
IO0SET_bit.P0_13 = 1; //off led
Delay(500000); //delay
}
// turn on led 2
void Led2On(void) {
IO0CLR_bit.P0_13 = 1; //on led
}
// turn off led 2
void Led2Off(void) {
IO0SET_bit.P0_13 = 1; //off led
}
Haengt ein wenig davon ab, was fuer ein Taster dranhaengt und wie toll
du das haben willst. So richtig p*rno wird das natuerlich mit einem
entprellten Taster, aber das lassen wir der einfachheit halber mal weg.
Also, gehen wir davon aus, der Taster sitzt auf Pin P0.14:
1
voidSwitchInit(void)
2
{
3
/* Set Pin to GPIO mode */
4
PINSEL0&=~(1<<28);
5
PINSEL0&=~(1<<29);
6
7
/* NO Pullup, NO Pulldown */
8
PINMODE0&=~(1<<28);
9
PINMODE0|=(1<<29);
10
11
/* Set Pin as Input */
12
FIO0DIR&=~(1<<14);
13
}
14
15
uint8_tSwitchRead(void)
16
{
17
if(FIO0PIN&0x00002000)
18
{
19
return(1);
20
}
21
else
22
{
23
return(0);
24
}
25
}
Sollte so hinhauen, hoffe ich. Habs nich gestestet, sondern ausm Kopf
gebastelt
sowas will ich auch mal von alleine hinbekommen, aber da wird noch sehr
viel Zeit ins Land gehn.Danke das du dir so mühe machst.
Wieso gehn denn die bei dem Beispielprogramm direkt auf die Ports?Was
ist denn da anderst?
Weil die schreiben ja nur IO0DIR_bit.P0_15 = 0; //set port0.15 as
input
Du schreibst ja FIO0DIR &=~(1 << 14);
Wie schreibt man denn die Anweisung PINSEL0 &=~(1 << 28) ausführlich,
das das ein Anfänger auch verstehn kann?
Steff wrote:
> sowas will ich auch mal von alleine hinbekommen, aber da wird noch sehr> viel Zeit ins Land gehn.Danke das du dir so mühe machst.
Das kommt schneller als du willst :)
> Wieso gehn denn die bei dem Beispielprogramm direkt auf die Ports?Was> ist denn da anderst?> Weil die schreiben ja nur IO0DIR_bit.P0_15 = 0; //set port0.15 as> input> Du schreibst ja FIO0DIR &=~(1 << 14);
Dein Beispiel hat eine LPC23xx.h Datei (so, oder so aehnlich). Darin
sind die einzelnen Ports mit ihren Adressen angegeben. Zusaetzlich hat
der Ersteller deines Beispiels sich die Muehe gemacht, saemltiche
zusammengehoerigen Bits (wie z.B. die jeweiligen 2 Bits der Pinregister)
zu Elementen in Strukturen zusammenzufassen. Daher kann dein Beispiel
ueber Strukturen mehrere Bits direkt ansprechen. Es macht aber das
gleiche wie meins auch. Ich persoenlich mag das so lieber, weil ich
direkt sehe, was mit welchem Bit passiert. Ist aber Geschmacksache. Die
Strukturen sind einfacher anzuwenden, vor allem, wenn sie jemand anders
schon fertig erstellt hat.
> Wie schreibt man denn die Anweisung PINSEL0 &=~(1 << 28) ausführlich,> das das ein Anfänger auch verstehn kann?
PINSEL0 = (PINSEL0 & ~(1 << 28));
Soll heissen: PINSEL0 soll gleich PINSEL0 sein, nur dass das 28te Bit
(per Shift) via ~1 (also 0) geUNDed wird. Irgendwas UND 0 ist immer 0,
dadurch loescht man also ein einzelnes Bit.
Den ODER-Operator vor das Gleichheitszeichen zu stellen erleichtert den
Ueberblick. Wenn du dir mein Beispiel anschaust, kannst du anhand der
Operatoren am Gleichheitszeichen immer sofort sehen, ob ein Bit gesetzt
oder geloescht werden soll. Da ich die Code-Zeilen (sofern moeglich) auf
die gleichzeichen "zentriere" (also so schreibe, dass sie immer
untereinander stehen), sehe ich direkt, was passiert und muss den
Operator nicht weiter hinten in der Zeile suchen.
Vielen vielen Dank für die super Erklärung.
Könnte man das ung. so auch schreiben? das ist eigentlich das
Beispielprogramm, aber mit mehreren Ausgängen und ein Eingang
Das Programm von dir ist für mich noch einbisschen zu kompliziert.
trotzdem sehr hilfreich.
// init buttons port 0.17
void InitButtons(void)
{
IODIR0 &= ~(0x0001 << 17); //set port0.17 as input
}
void LedsInit(void)
{
IODIR0 |= (0x0001 << 18); //set port0.18 to output
IODIR0 |= (0x0001 << 19); //set port0.19 to output
IODIR0 |= (0x0001 << 20); //set port0.20 to output
IODIR0 |= (0x0001 << 21); //set port0.21 to output
IODIR0 |= (0x0001 << 22); //set port0.22 to output
}
void Led1On(void)
{
IOCLR0 |= (0x0001 << 18); //on led port0.18
}
// turn off led 1
void Led1Off(void)
{
IOSET0 |= (0x0001 << 18); //off led port0.18
}
Ist die Vergabe der Ports frei wählbar, hauptsache die sind im manual
verfügbar?
>Ist die Vergabe der Ports frei wählbar, hauptsache die sind im manual>verfügbar?
Was meinst du mit Vergabe?
>IODIR0 |= (0x0001 << 18); //set port0.18 to output
32 bit sehen so aus 0x00000001. Nur der Vollständigkeit halber.
Deshalb bleib beim Schieben mal lieber bei einer schnöden 1.
Sieht doch gut aus... Die HexAngabe laesst man normalerweise weg und
schreibt nur ne 1 in die Klammern, aber das ist nur n schoenheitsding..
Programm sieht jedenfalls OK aus. Die Ports kannst du frei waehlen wie
du willst, du musst teilweise nur auf deren Modus achten. Wenn ich mich
recht erinnere, werden alle GPIOs auch im GPIO modus gestartet beim
power-up. Willst du was anderes damit machen (z.B. das MCI Interface
benutzen oder die UARTS), dann musst du natuerlich via PINSELx den Modus
des Pins aendern.
Was du jetzt noch machen koenntest (das wirkt professioneller) sind
bitmasken fuer die einzelnen Ports. Statt:
1
IODIR0|=(0x0001<<18);//set port0.18 to output
2
IODIR0|=(0x0001<<19);//set port0.19 to output
3
IODIR0|=(0x0001<<20);//set port0.20 to output
4
IODIR0|=(0x0001<<21);//set port0.21 to output
5
IODIR0|=(0x0001<<22);//set port0.22 to output
koenntest du schreiben
1
#define LED1MASK (1UL << 18)
2
#define LED2MASK (1UL << 19)
3
#define LED3MASK (1UL << 20)
4
#define LED4MASK (1UL << 21)
5
#define LED5MASK (1UL << 22)
6
7
voidLEDInit(void)
8
{
9
IODIR0|=LED1MASK;//set port0.18 to output
10
IODIR0|=LED2MASK;//set port0.19 to output
11
IODIR0|=LED3MASK;//set port0.20 to output
12
IODIR0|=LED4MASK;//set port0.21 to output
13
IODIR0|=LED5MASK;//set port0.22 to output
14
}
Bei diesem Beispiel ist das noch vernachlaessligbar, aber bei groesseren
Sachen sind solche Maskierungen recht hilfreich. Es erhoeht die
Uebersicht, weil statt Bits da aussagekraeftige Symbole stehen und es
ist leichter abaenderbar (im falle eines Redesigns oder wiederverwertung
des codes auf einem aehnlichen Prozessor).
Damit hab ich gemeint ob ich einfach sagen kann das der Port 0.18 ein
Ausgang ist?!
Mit Vergabe meinte ich, das ich einfach eines der 46 IO ports als ein-
oder Ausgng nehmen kann, also frei wählbar. Kann man das so machen?
Wenn ich das dann so IODIR0 |= (0x00000001 << 18); schreib, würde das
dann gehn das der port0.18 als Ausgang initialisiert wird?
Steff wrote:
> Damit hab ich gemeint ob ich einfach sagen kann das der Port 0.18 ein> Ausgang ist?!
Ja
> Mit Vergabe meinte ich, das ich einfach eines der 46 IO ports als ein-> oder Ausgng nehmen kann, also frei wählbar. Kann man das so machen?
Ja
> Wenn ich das dann so IODIR0 |= (0x00000001 << 18); schreib, würde das> dann gehn das der port0.18 als Ausgang initialisiert wird?
Ja. Das Shift macht nichts anderes, als den vorangesetzten Wert um die
zu shiftenden Stellen nach Links zu bewegen.
Beispiel (8Bit):
|0000|0001| und die 1 wird um 3 geshiftet, dann steht da |0000|1000|
Aber da du nur ein einziges Bit setzen willst, schreib einfach (1 << 18)
Achso. Schreib alles bisschen ausführlicher, aber danke für den Tipp.
Neueinsteiger eben*g*
In dem Programm sollen je nach Status 1 bis 5 leds brennen. Wie kann man
denn am geschicktesten mehrere Leds aufeinmal zum brennen bringen?
void Led1On(void)
{
IOCLR0 |= (0x0001 << 18); //on led port0.18
}
ledmask&=0x1F;// set leading three bits of mask to 0
6
7
IOCLR0|=(ledmask<<18);// Set LED Bits
8
}
Die erfahrerenen Programmierer moegen mich bitte korrigieren, falls das
so nicht hinhaut. Ausm Stehgreif ohne groessere defines und Background
wuerd ichs so versuchen.
Vorteil: du kannst alle LEDs mit nur einem Funktionsaufruf
setzen/loeschen
Matthias Nix wrote:
> IOCLR0 &=~(0x1F << 18); // Set all LED Bits to 0
IOCLR0 = 0x1F << 18; // Set all LED Bits to 0
> IOCLR0 |= (ledmask << 18); // Set LED Bits
IOSET0 = (ledmask << 18); // Set LED Bits
Bei meinem programm ist das halt so das es 5 unterschiedliche
Schaltpunkte gibt, also eher selten alle EIN oder alle AUS sind.
Dann bringt das mit der Maske eher weniger,oder?
Ist es dann besser einfach für jeden Schaltpunkt die jeweiligen Leds ein
bzw auszuschlten?
A. K. wrote:
> Matthias Nix wrote:>>> IOCLR0 &=~(0x1F << 18); // Set all LED Bits to 0>> IOCLR0 = 0x1F << 18; // Set all LED Bits to 0>>> IOCLR0 |= (ledmask << 18); // Set LED Bits>> IOSET0 = (ledmask << 18); // Set LED Bits
Deine Version hat aber doch einfluss auf alle andere Pins oder? 0x1F <<
18 setzt alles ausserhalb der Maske auf 0, oder irre ich?
Was hat denn das uint8_t ledmask auf sich?
Werden bei folgende Anweisung IOCLR0 &=~(0x1F << 18); einfach alle
Ausgänge mit UND zusammengefast, deshalb werden dann die 5 bits 18
Stellen verschoben?
Morgen,
Wäre echt nett wenn du dir mal anschaun könntest ob man das so schreibt.
// Einschalten Led1 bis Led4
void Led1_4On(void)
{
IOCLR0 |= (0x0001 << 18); //on led1
IOCLR0 |= (0x0001 << 19); //on led2
IOCLR0 |= (0x0001 << 20); //on led3
IOCLR0 |= (0x0001 << 21); //on led4
Diese Anweisung sagt das gleiche aus wie die 4 oben,oder?
//IOCLR0 |= (0x000F << 18);
}
Danke schonmal
Ja, macht das gleiche. Ist aber nicht besonders ueblich, es so zu
machen, da man schon wieder genau gucken und rechnen muss um zu
verstehen, was genau passiert.
Matthias Nix wrote:
> Deine Version hat aber doch einfluss auf alle andere Pins oder? 0x1F <<> 18 setzt alles ausserhalb der Maske auf 0, oder irre ich?
Du irrst. IOCLR0=1; löscht Bit 0 und ändert sonst nichts, IOSET0=1;
setzt Bit0 und ändert sonst nichts. Was meinst du denn warum die so
heissen?
Ja dann mach ich es besser mit den Bitmasken, wie du es mir gestern
gezeigt hast, dann wirds glaub gut aussehn.
Für was steht denn in den Masken das UL?
A. K. wrote:
> Matthias Nix wrote:>>> Deine Version hat aber doch einfluss auf alle andere Pins oder? 0x1F <<>> 18 setzt alles ausserhalb der Maske auf 0, oder irre ich?>> Du irrst. IOCLR0=1; löscht Bit 0 und ändert sonst nichts, IOSET0=1;> setzt Bit0 und ändert sonst nichts. Was meinst du denn warum die so> heissen?
JapJap, du hast recht, bei den Set und Clr Registern kann man das ja so
machen, weil 0 schreiben keinen Effekt hat. Ich vergas :) War in
Gedanken bei bei "normalen" Registern.
@Steff:
UL bedeutet UNSIGNED LONG und soll einfach garantieren, dass das ganze
32Bit konform behandelt wird, obwohl es sicherlich auch ohne gehen
wuerde. Aber sicher ist sicher, is kacke zu debuggen, sowas :)
Steff wrote:
> IOCLR0 |= (0x0001 << 18); //on led1> IOCLR0 |= (0x0001 << 19); //on led2> IOCLR0 |= (0x0001 << 20); //on led3> IOCLR0 |= (0x0001 << 21); //on led4
Laß mal die ganzen |= weg und schreibe nur =
Das |= ist unnötig, auch beim IOSET0.
Ich bin mir auch nicht sicher, was man aus dem IOCLR zurückliest, 1-er
Bits würden dann gelöscht.
Peter
Morgen,
bins schon wieder.
Weiß jemand wie man den Pin (P0.14), den ich für einen Button benutze
wahlweiße als Taster für Kapazitätabfrage und für einen Interrupt um den
uC aus dem Sleep Mode zu holen programmieren kann?
Wenn der uC im Sleep Mode ist und man den Taster drückt soll er erst
aufwachen und bei einer evtl. wiederholten Tastenbetätigung der
Kapstatus abgefragt werden
Kennt sich damit jemand aus?
Also so langsam solltest du mit Datenblatt und Tutorial selbst ein
bisschen was hinbekommen. Erstmal musst du ueberhaupt kucken, ob der Pin
P0.14 einen Interrupt auslösen kann (koennen naemlich nicht alle GPIOs).
Dann guckst du im Datenblatt, was fuer ein Interrupt das sein wird, dann
guckst du, wie du den entsprechenden Interrupt im Vector einstellen
musst und dann schreibst du eine Interrupt Service Routine, die du im
entsprechenden Interrupt hinterlegst. Wenn ich mich recht erinnere, ist
das hier im ARM tutorial ganz gut erklärt.
Ja p0.14 kann einen interrupt auslösen.
Bin halt ein kompletter Anfänger und hab noch nie so eine Interrupt
Routine noch nie geschrieben, geschweige denn gesehn wie eine aussieht.
Weisst du wo man evtl. eine anschaun kann?
Matthias Nix
kennst du dich zufällig damit aus wie man Daten über i2C in ein
dataflash schreibt oder hast du evtl. online eine Quelle wo es bisschen
ausführlicher beschrieben ist als im Datenblatt, evtl mit Beispiel?
Du hast doch immer so supper Tipps
Vielleicht kuckst du dann zu Beginn mal hier auf uC.net ins ARM
tutorial. Da sind Beispielprogramme drin. Als zweites kannst du dich bei
yahoo.de in der Gruppe LPC2000 anmelden, da gibts tonnenweise
beispielcode und auch super Hilfe (aber alles auf Englisch).
Als Neuling mit der 32Bit ARM Machine anzufangen, ist so besonders
clever übrigens nicht. Wie weiter oben schonmal erwähnt, sollte man da
zumindest etwas Erfahrung mitbringen. Mein Respekt, dass du dich da von
Null durcharbeitest, haste trotzdem.
Ne ISR (Interrupt Service Routine) kann ich dir jetzt ausm Kopf nicht
zusammenfummeln, das muesste ich jetzt auch mitm Datenblatt basteln.
Aber so schwer isses auch nicht. Schau ins tutorial, da sollte sowas
drinstehen.
Update: Hab noch nie mit I2C gearbeitet, sorry. Guck in die Yahoo Group,
da gibts bestimmt was
Also auf der yahoo Seite gibts schon einiges, aber leider für mich
nichts brauchbares.
Bräuchte irgendwie ein grundlegendes Beispiel oder sowas ähnliches.
Mit EEproms kennst dich nichs so aus, oder etwa doch? Das mit i2C ist
nicht mehr so wichtig.
Die Daten sollen normal vom uC im EEprom abgelegt werden.
Bin für jeden Rat dankbar
Muss es einmal über I2C und einmal über SPI einbinden. Zuerst aber mal
über SPI. Dort sollen die gemessenen Messdaten, die der uC über I2C
einliest abgelegt werden. Was meinst du mit: Was willst du wie darin
ablegen?
Das ist ein Flash, kein eeprom.
Im Datenblatt erfaehrst du alle Befehle, die noetig sind, um mit dem
Speicher zu interagieren. Das Datenblatt der SPI-Schnittstelle des LPCs
sagt dir, wie du die entsprechenden Register fuettern musst.
Am sinnvollsten ist es, 2 Funktionen zu erstellen. Die eine baut die SPI
befehle zum Schreiben auf dem Flash, die andere baut die befehle zum
Lesen. Als Parameter wuerde ich Adresse, Databuffer und Datalength
benutzen. So kannst du Algorithmen bauen, um auch laengere Datensaetze
mit nur einem funktionsaufruf schreiben und lesen zu koennen. In der
yahoo-Group sollte es aber einiges zum Thema SPI geben, da eigentlich
alle DemoBoards der LPCs n Flash oder n EEPROM am SPI haengen haben.
Sonst such mal speziell nach nem Board, das sowas hat (Olimex LPC2368
zB), der Prozessor ist zwar n anderer, das SPI arbeitet aber auf allen
gleich
Ja das steht schon alles im Datenblatt.Weiß nur überhaupt nicht wie ich
da vorgehen/anfangen soll.
Hättest du evtl irgendein Beispiel parat, wie sowas aussehen könnte?