Forum: Mikrocontroller und Digitale Elektronik Microchip C18 & Pic 18f242


von Marco B. (0plan)


Lesenswert?

Mir reichts ich habe eigentlich keinen Plan von pic´s bin aber sehr 
interessiert und habe auch schon einiges umgesetzt und das funzt auch 
lcd timer usw. aber beim auslesen eines pis auf seinen status klppt was 
nicht was mache ich falsch oder ist mein pic im A"".
Hier mein aus Verzweifelung reduzierter code ( eigentlich wollte ich 
einen Anlaogport abfragen und das auf einem Display ausgeben)

/** Configuration 
********************************************************/
#pragma config OSC = HS   //CPU=10 MHz
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  //Watchdog Timer
#pragma config LVP = OFF  //Low Voltage ICSP


/** D E C L A R A T I O N S 
**************************************************/
int result;
#pragma code
void main(void)
{

TRISAbits.TRISA0 = 0; // RA0 als Eingang
TRISAbits.TRISA1 = 0; // RA1 als Eingang
TRISAbits.TRISA2 = 0; // RA2 als Ausgang
TRISAbits.TRISA3 = 0; // RA3 als Ausgang
TRISAbits.TRISA4 = 0; // RA4 als Ausgang
TRISAbits.TRISA5 = 1; // RA5 als Ausgang


loop:

if(PORTAbits.RA5 == 1) // abrage ob 1
  {
        LATAbits.LATA1=1;
  }  //end if

goto loop;

}//end main

Gruß marco

von omeier (Gast)


Lesenswert?

Ich denke dein PIC ist OK, das ist etwas anderes im A... ;)

Im Datenblatt steht zu PORTA:

  "Note: On a Power-on Reset, RA5 and RA3:RA0
  are configured as analog inputs and read
  as ‘0’. RA6 and RA4 are configured as
  digital inputs."

Das Bedeudet das RA5 nach einem Reset/Powerup als Analoger eingang 
geschaltet ist und beim (digitalen) einlesen immer eine "0" liefert.

-> Du musst zuerst die verwendeten Ports auf "digital" umschalten 
(ADCON1 Register, die Bits PCFG3:PCFG0).

-> Falls Du später den Port mit dem ADC abtasten willst, musst du 
natürlich wieder umstellen.

mfg
omeier

von Sven S. (stepp64) Benutzerseite


Lesenswert?

RA5 ist ein Analogpin. Du musst den erst auf digital umschalten, bevor 
du ihn  als digitalen PIN benutzen kannst.

Sven

von Marco B. (0plan)


Lesenswert?

Tja jetzt habe ich das zwar gemacht ist ja auch logo habe ich schon 
mehrfach gelesen.
ABER es geht immer noch nicht.
Was habe ich denn falsch. Binn schon voll genervt kann
doch nicht so schwierig sein.
Hier nochmal mein KOT

/** I N C L U D E S 
**********************************************************/
#include "p18f242.h"


/** Configuration 
********************************************************/
#pragma config OSC = HS   //CPU=10 MHz
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  //Watchdog Timer
#pragma config LVP = OFF  //Low Voltage ICSP


/** D E C L A R A T I O N S 
**************************************************/
int result;
#pragma code
void main(void)
{

ADCON1 = 0x03; // Port RA0 & RA1 als digitale Eingaenge
//TRISAbits.TRISA0 = 1; // RA0 als Eingang
//TRISAbits.TRISA1 = 1; // RA1 als Eingang
TRISAbits.TRISA2 = 0; // RA2 als Ausgang
TRISAbits.TRISA3 = 0; // RA3 als Ausgang
TRISAbits.TRISA4 = 0; // RA4 als Ausgang
TRISAbits.TRISA5 = 0; // RA5 als Ausgang


loop:

if(PORTAbits.RA1 == 1) // abrage ob null
  {
        LATAbits.LATA5=1;
  }  //end if

goto loop;

}//end main

von holger (Gast)


Lesenswert?

>ADCON1 = 0x03; // Port RA0 & RA1 als digitale Eingaenge

Da muß keine 3 sondern eine 6 rein.
Am besten benutzt du RA0 und RA1 gar nicht als
digitale IO. Sonst kannste den AD Wandler im PIC
gleich knicken.

von Marco B. (0plan)


Lesenswert?

das verstehe ich nicht in der manual:

00-- 0000 von hinten PCFG3 PCFG2 PCFG1 PCFG0

dann würde ja RA1 und RA2 als Eingang setzen.

oder?

von Marco B. (0plan)


Lesenswert?

Habe alternativ auch schon für die if schleife einfach mal:
LATAbits.LATA2 =  PORTAbits.RA0  ;   // RA2 = RA0
ausprobiert, das aber auch nicht geht.
Hingegen
Alle Ports auf Eingang setzen: TrisB = 0xFF voweg
LATAbits.LATA3 = PORTBbits.RB0  ; // RA3 = RB0
im selben code funktioniert, was mich sehr erleichtert
hat, dachte ich währe doch einfach zu blöd einen Eingang
abzufragen und habe es nicht verstanden.
Trotz allem wurmt mich das das es nicht geht.

von holger (Gast)


Lesenswert?

>00-- 0000 von hinten PCFG3 PCFG2 PCFG1 PCFG0
>dann würde ja RA1 und RA2 als Eingang setzen.

Irgendwie hast du ne andere Tabelle als ich.
Mit den Werten sind alle wieder analoge Pins.

von Marco B. (0plan)


Lesenswert?

Das ist richtig.
Also nochmal ganz
zeil ist RA0 und RA1 als digital input --> 00-- 0011 oder ?
das währe bei mir in hex 0x03 bzw 3 oder sehe ich da was falsch?

von Daniel X. (daniel_78)


Lesenswert?

Hallo,

hier vieleicht ein kleines Beispiel. Evtl. hilfts

PIC18F4580 mit 4 MHz. Ist etwas Mix aus eng. und deutsch! Interrupt ist 
aktiviert wird aber nicht genutzt. Also kein Problem. Ausgabe auf RS232 
mit Hyperterminal. Es sind mehr als ein ADC Port aktiviert !! Viel 
Erfolg. Daniel

/** I N C L U D E S 
**********************************************************/
#include <p18f4580.h>
#include <delays.h>                          // for short delays
#include <usart.h>
#include <adc.h>
#include <stdio.h>
#include <timers.h>

#pragma config OSC = HS        // HS
#pragma config FCMENB = OFF      //Fail-safe clock monitor disabled
#pragma config IESOB = OFF      //Internal OSC switch over bit
#pragma config PWRT = ON      //Power up timer ON
#pragma config BOR = BOACTIVE    //enabled whenever part is active, 
SBOREN disabled
#pragma config BORV = 42      // Reset if Vcc smaller 4,2V
#pragma config WDT = ON        //Watchdog ON
#pragma config WDTPS = 16384    //after 65,54s reset
#pragma config PBADEN = ON      //Pins are configured as analog input 
channels on Reset
#pragma config LPT1OSC = OFF    //bei 0; Timer1 configured for higher 
power operation
#pragma config MCLRE = ON      //Reset at MCLR ON
#pragma config LVP = OFF      //LVP OFF







//---------------------------------------------------------------------- 
----------------------------------------------
void free_buffer(char* array)
{
int i;                             //Laufvariable deklarieren
int len;                          //Variable für die Länge deklarieren
len = sizeof(array) / sizeof(char);          //Länge ermitteln
for(i=0;i<len;i++)                    //In einer for-Schleife alle
 array='\0';                        //Felder mit terminierter Null
                                //belegen
}
//---------------------------------------------------------------------- 
----------------------------------------------




void main(void)
{

unsigned int AN0;                     //0...65565
float VL_HEIZUNG;                     //
unsigned int VL_HEIZUNG_1;                 //0...65565
unsigned char delayADC = 25;              //0 bis 255 DELAY ADC Messung
unsigned char KommaFaktor =1;

char buffer[20];

INTCON = 0x20;                             //disable global and enable 
TMR0 interrupt
INTCON2 = 0x84;                            //TMR0 high priority
RCONbits.IPEN = 1;                         //enable priority levels
INTCONbits.GIEH = 1;                       //enable interrupts



T0CONbits.T0PS0=1;                    //Teiler 1:256
T0CONbits.T0PS1=1;                    //Teiler 1:256
T0CONbits.T0PS2=1;                    //Teiler 1:256
T0CONbits.T0PS3=0;                    //laut Datenblatt (PSA=0) 
Vorteiler wird verwendet
T0CONbits.T0SE=1;                      //H-L wird gezählt
T0CONbits.T0CS=0;                      //der Takt ist 1/4 des PIC-Taktes
T0CONbits.T08BIT=0;                    //16bit Timer
T0CONbits.TMR0ON=1;                    //enable Timer 0



OpenUSART( USART_TX_INT_OFF &              // Transmit interrupt off
USART_RX_INT_OFF &                     // Receive interrupt off
USART_ASYNCH_MODE &                    // Asynchronous mode
USART_EIGHT_BIT &                     // 8-bit data
USART_CONT_RX &                     // Continuous reception
USART_BRGH_HIGH,                     // High baud rate
25 );                            // 12 für 19200 baud, 25 für 9600 baud

ADCON0bits.ADON = 1;                   //1 = A/D converter module is 
enabled
ADCON0bits.GO = 1;                    //1 = A/D conversion in progress
ADCON0bits.CHS0 = 0;                   //1010 = Channel 10 (AN9)
ADCON0bits.CHS1 = 1;                   //1010 = Channel 10 (AN9)
ADCON0bits.CHS2 = 0;                   //1010 = Channel 10 (AN9)
ADCON0bits.CHS3 = 1;                   //1010 = Channel 9 (AN9)
ADCON1bits.PCFG0 = 1;                   //1111  (AN10) A A A A A A A A A 
A A A A (AN0)
ADCON1bits.PCFG1 = 1;                   //1111  (AN10) A A A A A A A A A 
A A A A (AN0)
ADCON1bits.PCFG2 = 1;                   //1111  (AN10) A A A A A A A A A 
A A A A (AN0)
ADCON1bits.PCFG3 = 1;                   //1111  (AN10) A A A A A A A A A 
A A A A (AN0)
ADCON1bits.VCFG0 = 1;                   //1 = VREF+ (AN3)
ADCON1bits.VCFG1 = 0;                   //1 = VREF- (AN2)  Masse =0
ADCON2bits.ADCS0 = 0;                   //110 = FOSC/64
ADCON2bits.ADCS1 = 1;                   //110 = FOSC/64
ADCON2bits.ADCS2 = 1;                   //110 = FOSC/64
ADCON2bits.ACQT0 = 1;                   //111 = 20 TAD
ADCON2bits.ACQT1 = 1;                   //111 = 20 TAD
ADCON2bits.ACQT2 = 1;                   //111 = 20 TAD
ADCON2bits.ADFM = 1;                   //1 = Right justified

TRISAbits.TRISA0 = 1;                   // VL_HEIZUNG


TRISCbits.TRISC7 = 1;                   // RX RS232
TRISCbits.TRISC6 = 0;                   // TX RS232


free_buffer(buffer);

while (1)
  {
//---------------------------------------------------------------------- 
----------------------------------//
     // Messung aller Temperaturen

  ClrWdt()

     Delay10TCYx(delayADC);
     SetChanADC( ADC_CH0);
     Delay10TCYx(delayADC);
     ConvertADC();
     Delay10TCYx(delayADC);
     while( BusyADC() ){}
     AN0 = ReadADC();
     VL_HEIZUNG = (float) AN0 * 0.258823 - 87.749070;     //calculating 
Temperature
     VL_HEIZUNG_1 = (float) VL_HEIZUNG * KommaFaktor;

  free_buffer(buffer);
  sprintf(buffer,"%d  \t",VL_HEIZUNG_1);
  putsUSART(buffer);
  putrsUSART ("\n\r");
  }

von holger (Gast)


Lesenswert?

>zeil ist RA0 und RA1 als digital input --> 00-- 0011 oder ?

Dann kannst du den AD Wandler vergessen.

>das währe bei mir in hex 0x03 bzw 3 oder sehe ich da was falsch?

Ja, bei mir ist das 0x06 oder 6 oder 011x. Wobei x für egal steht.

Schau dir die verdammte Tabelle zu ADCON1 noch mal genau an.
Du hast NICHT die freie Wahl welche Pins analog oder digital sind.
Es gibt nur wenige Kombinationen.

von Marco B. (0plan)


Lesenswert?

nett hilft mir weiter bei dem nächsten schritt die AD wandler zu 
benutzen, ledier aber nicht bei dem Problem das ich den RA0 und RA1 
nicht in den
digitalen input bekommme um ihn einfach auszulesen.
Trotzdem danke Daniel

von holger (Gast)


Lesenswert?

>nett hilft mir weiter bei dem nächsten schritt die AD wandler zu
>benutzen, ledier aber nicht bei dem Problem das ich den RA0 und RA1
>nicht in den
>digitalen input bekommme um ihn einfach auszulesen.

ADCON1 = 0x06; // Alle ANx digital IO ! Adios AD Wandler ! nicht mehr 
möglich.
TRISAbits.RA0 = 1;
TRISAbits.RA1 = 1;

von Marco B. (0plan)


Lesenswert?

Danke holger jetzt läufts. Muss mir diese verdammte Tabelle noch mal 
genau ansehen.

Adios AD Wandler ! nicht mehr möglich.
Wollte ich ja auch nicht. Jetzt weiß ich auf jedenfall das es
ein ADCON1 Problem war.

Werde mir das nochmal genau ansehen damit ich wenn ich die AD´s
wieder einschalte keine Probleme habe.
Danke nochmal für den Springenden Punkt.

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.