Forum: Mikrocontroller und Digitale Elektronik PIC12F683 + A/D-Converter + PWM


von Clément K. (versuchx)


Lesenswert?

Hallo,

ich arbeite mich gerade in die Programmierung von PICs ein und habe 
derzeit ein kleines Problem.
Ich möchte mit Hilfe des A/D Converters die Stellung eines Potis 
auslesen und den Wert (sobald er eine bestimmte Grenze überschritten 
hat) in das CCPR1L Register schreiben um ein PWM Signal zu erzeugen (in 
Abhängigkeit der Potistellung).

Nun zum Hauptproblem: Der A/D Converter erittelt zwar einen Wert 
(schätze ich mal), jedoch wird nicht auf meine vorgesetzte Grenze (Wert 
5) geachtet und direkt ein PWM Signal ausgegeben. Leider ist die 
Helligkeit der angeschlossenen LED nicht konstant, sodass sie dauernd 
flackert.

Da ich noch Neuling bin und versuche mir alles selber beizubringen, bin 
ich gerade Ratlos, da ich keinen Fehler finden kann.....

Vielen Dank für eure Antwoten im Voraus
Clément

hier der Code:

//include files
#include <htc.h>
#include <pic12f683.h>

//configurations
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_OFF & 
CP_OFF & CPD_OFF);

//defines
#define reverse         GPIO5
#define reverseLED      GPIO1
#define low                     5
#define _XTAL_FREQ      4000000
#ifndef __ADCLP
#define __ADCLP

void initADC( void );
char BusyADC(void);
void CloseADC(void);
void ConvertADC(void);
int ReadADC(void);
void SetChanADC(unsigned char channel);

#endif

//prototypes
void initADC( void ) {
        ADCON0 = 0b00001101;

        ADIF = 0;               //Clear the ADC Interrupt bit
        ADIE = 0;               //ADC Interrupt ausschalten

        ADCON0bits.ADON = 1;    //AD-Wandler einschalten
        return;
}

char BusyADC(void) {
  return(ADCON0bits.GO);
}

void CloseADC(void) {
  ADCON0bits.ADON = 0;
  PIE1bits.ADIE = 0;
}

void ConvertADC(void) {
  ADCON0bits.GO = 1;
}

void SetChanADC(unsigned char channel)
{
  ADCON0 = ((channel << 2) & 0b00111100) |
           (ADCON0 & 0b11000011);
}

int ReadADC(void) {
  return (((unsigned int)ADRESH)<<8)|(ADRESL);
}

//main function
void main()
{
        int poti=0;

        ANSEL   = 0x10;                 //GP4 analog
        TRISIO  = 0x3B;                 //GP2 output
        CCP1CON = 0x3C;                 //Enable PWM on CCP1
        T2CON   = 0x04;                 //Enable TMR2 with prescaler = 1
        PR2     = 249;                  //PWM = (OSC/(4*presc*Freq))-1
        CCPR1L  = 0;                    //PWM = OSC/(4*presc*Freq) = 250

        while(1)
        {
                initADC();              //AD-Wandler initialisieren
                SetChanADC(3);          //Kanal einstellen, der für die
                                     //AD-Wandlung verwendet werden soll
                ConvertADC();           //Startet die Wandlung
                while (BusyADC());   //Warten, bis Wandlung beendet ist
                __delay_ms(50);
                poti = ReadADC();       //Auslesen des AD-Wertes
                CloseADC();             //AD-Wandler ausschalten

                poti /= 4;
                if(poti > low)
                {
                        poti -= 5;
                        CCPR1L = poti;
                } else {
                        CCPR1L = 0;
                }
                __delay_ms(10);
        }
}

von Max H. (hartl192)


Lesenswert?

Versuch mal den ADC in ADCON0 auf "Right justified" (ADFM = 1) 
umzustellen.

Schau dir mal TABLE 9-1 im Datenblatt an...

von Clément K. (versuchx)


Lesenswert?

Danke für deine Antwort!!! Jetzt geht's.

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.