Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : pic4550 umschalten der Eingänge und Ausgänge



hixc
18.04.2008, 13:45
Hallo, ich habe hier ein Project mit einem pic 18f4550.
Mit dem Controller wird eine 2 Farben LED angesteuert. Das ganze ist etwas kompliziert gemacht, da diese LED keine gemeinsame Masse hat und die LEDs antiparallel geschaltet sind.

Nun wollte ich erstmal ein kleines Testprogramm schreiben, bei dem die LED grün und rot abwechselnd blinkt.

Bei der schaltung müssen für rot folgende Bedingungen erfüllt sein:
RB0: Input
RB1: Output und High
RB2: Input
RB3: Output und Low

für grün siehts so aus:
RB0: Output und low
RB1: Input
RB2: Output und High
RB3: Input

Wenn ich nur eine der Farben erzeugen will funktioniert das ganze auch, nur klappt es nicht wenn ich die Farben wechseln will.
Was mache ich falsch?
Kann ich die nicht einfach neu definieren, so wies hier steht?

Hab mal die Spannungen gemessen. Komischerweise sind RB1 und RB2 bei 5V und RB0 und RB3 bei0V

Eine Frage hab ich noch:
Wie kann ich die Internen Pullups aktivieren, oder sind die bei Input schon automatisch aktiv?


/** I N C L U D E S ************************************************** ********/
#include <p18cxxx.h>
#include "delays.h"

/** V A R I A B L E S ************************************************** ******/
#pragma udata


int switch_setting = 0;

/** P R I V A T E P R O T O T Y P E S ***************************************/

/** V E C T O R R E M A P P I N G *******************************************/

extern void _startup (void); // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
;
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
;
}
#pragma code

/** D E C L A R A T I O N S **************************************************/
#pragma code
/************************************************** ****************************
* Function: void main(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Main program entry point.
*
* Note: None
************************************************** ***************************/
/** L E D ************************************************** *********/
#define mInitAllLEDs() LATD &= 0xF0; TRISD &= 0xF0;

#define mLED_1 LATDbits.LATD0
#define mLED_2 LATDbits.LATD1
#define mLED_3 LATDbits.LATD2
#define mLED_4 LATDbits.LATD3

#define mLED_1_On() mLED_1 = 1;
#define mLED_2_On() mLED_2 = 1;
#define mLED_3_On() mLED_3 = 1;
#define mLED_4_On() mLED_4 = 1;

#define mLED_1_Off() mLED_1 = 0;
#define mLED_2_Off() mLED_2 = 0;
#define mLED_3_Off() mLED_3 = 0;
#define mLED_4_Off() mLED_4 = 0;

#define mLED_1_Toggle() mLED_1 = !mLED_1;
#define mLED_2_Toggle() mLED_2 = !mLED_2;
#define mLED_3_Toggle() mLED_3 = !mLED_3;
#define mLED_4_Toggle() mLED_4 = !mLED_4;

/** PORTB Red LED ************************************************** ****/


#define mInitRedLED() LATB &= 0xF5; TRISB &= 0xF5;

#define mRB1 LATBbits.LATB1
#define mRB3 LATBbits.LATB3

#define mRB1Red() mRB1 = 1;
#define mRB3Red() mRB3 = 0;


/** PORTB Green LED ************************************************** ****/


#define mInitGreenLED() LATB &= 0xFA; TRISB &= 0xFA;

#define mRB0 LATBbits.LATB0
#define mRB2 LATBbits.LATB2

#define mRB0Green() mRB0 = 0;
#define mRB2Green() mRB2 = 1;


/** S W I T C H ************************************************** ***/
#define mInitAllSwitches() TRISBbits.TRISB4=1;TRISBbits.TRISB5=1;
#define mInitSwitch2() TRISBbits.TRISB4=1;
#define mInitSwitch3() TRISBbits.TRISB5=1;
#define sw2 PORTBbits.RB4
#define sw3 PORTBbits.RB5



void main(void)
{
ADCON1 |= 0x0F; // Default all pins to digital
mInitAllSwitches();
mInitAllLEDs();

while(1){

mInitGreenLED();
mRB0Green();
mRB2Green();

Delay10KTCYx(1000);

mInitRedLED();
mRB1Red();
mRB3Red();

Delay10KTCYx(1000);







}//end while
}//end main


Hier nochmal der Teil, worauf es mir ankommt. Die Umschaltung der der Eingänge zu Ausgängen und die der einzelnen Pegel:


/** PORTB Red LED ************************************************** ****/


#define mInitRedLED() LATB &= 0xF5; TRISB &= 0xF5;

#define mRB1 LATBbits.LATB1
#define mRB3 LATBbits.LATB3

#define mRB1Red() mRB1 = 1;
#define mRB3Red() mRB3 = 0;


/** PORTB Green LED ************************************************** ****/


#define mInitGreenLED() LATB &= 0xFA; TRISB &= 0xFA;

#define mRB0 LATBbits.LATB0
#define mRB2 LATBbits.LATB2

#define mRB0Green() mRB0 = 0;
#define mRB2Green() mRB2 = 1;

while(1){

mInitGreenLED();
mRB0Green();
mRB2Green();

Delay10KTCYx(1000);

mInitRedLED();
mRB1Red();
mRB3Red();

Delay10KTCYx(1000);







}//end while




Vielen Dank fürs Lesen.

PICture
19.04.2008, 20:33
Hallo hixc!

Ich kenne die C Programmiersprache zwar nicht, aber denke so:

Wenn die LEds antiparallel verbunden sind, um beide Farben zu kriegen reichen 2 Pins die gegengesetzte Zustände haben (einer Low, während der andere High, und umgekehrt) oder 1 pin+ Inverter. Wozu braucht man ein Pin als Input?

Um auf einem Portpin ein bestimmtes Pegel zu haben muss der PORT direkt beschrieben werden, also Benutzung des Latches ist falsch.

MfG

hixc
20.04.2008, 11:41
Danke für den Hinweis. Das mit dem PORT probier ich morgen mal direkt aus.
Ich hab sowieso noch nicht ganz verstanden, wieso ich noch dieses Latch register hab. Hab mich da n bisschen am Beispiel orientiert.

Und zu den LEDs:
Das Problem bei diesen antiparallelen LEDs ist, das man 2 unterschiedliche Vorwiderstände braucht. Um das zu realisieren hab ich diese Schaltung hier benutzt:

http://mitglied.lycos.de/schtiewen/antileds.bmp

stalky13
20.04.2008, 14:10
hi

das Register LATB ist ein Latch und enthält die sollzustände der ausgänge das Register PORTB entält die Level an den pins. warum das sein mus steht hier (http://www.sprut.de/electronic/pic/fallen/fallen.html#inout). wenn du einen ausgang setzen willst dann must du das bit im Latch setzen und wenn du ein Level von einem eingang einlesen willst dann must du das über das Register PORT machen ist aber glaub ich erst ab den 18er typen so. die pullups von PORTB sin nach einem (POR) Power On Reset aus du kannst sie über das Register INTCON2 bit 7 (RBPU) einschalten die beschreibung dazu findest du in dem datenblatt von deinem PIC.

du schreibst TRISB &= 0xF5

da ist dein problem es mus heisen TRISB = 0xF5 da bei einem bitweise & (und) die bits nur eins sind wenn beide eins sind also von 0xF5 und von TRISB da aber von der vorherigen LED Farbe die Bits bereits 0 sind werden sie nicht 1 und du hast beim umschalten alle ports als ausgänge!!!!

auserdem kannst du besser 0b11110101 stat 0xf5 schreiben das ist übersichtlicher

noch mal zusammengefasst

TRISB &= 0b11110101
TRISB hat den wert 0b0b11111010 (von der letzten LED) also...

0b11111010 &= 0b11110101
ergibt
0b11110000 #-o

wenn du die ersten vier bits unabhängig von den letzten verändern willst ann must du das so machen


#define mInitRedLED() LATB &= 0b11110000; TRISB |= 0b00001111; TRISB &= 0b11110101;

von LATB die ersten vier bit löschen
von TRISB die ersten vier bit setzen
von TRISB die bits 1 und 3 löschen O:)

hixc
20.04.2008, 21:02
besten dank!
Du hast den fehler erkannt.
Morgen werde ich es ausprobieren und bei erfolg werde ichs posten :D
good night


edit:
habs geändert und es hat dann auch funktioniert.
Allerdings musste ich noch die Led an PORTA anschließen,
weil bei PORTB die outputs und inputs nicht richtig initialisiert wurden.
O:)

PICture
22.04.2008, 18:48
Hallo!

@ hixc

Durch Anwendung von 2 normalen Dioden, kannst du die 2 LEDs mit nur 2 Portpins ohne Umschalten auf Input/Output steuern.

MfG

Portpins
V V
| |
| +----+----+
| | |
| V -
| - ^
| | |
| .-. .-.
| | |RLED1 | |RLED2
| LED1 | | | |
| +-|<-+ '-' '-'
| | | | |
+---+ +---+---------+
|LED2|
+->|-+

hixc
23.09.2008, 15:05
danke, das problem ist nur, das diese dual led in nem taster fest eingebaut ist. aber egal, jetzt funzt es ja xD