Ich versuche, einen analogen Eingang mit meinem PIC18F66K22 mit ADC zu lesen. Aber der vermeintliche 10-Bit-Wert kommt oft auf Werte wie 63.241. Ich habe herausgefunden, dass ein negativer Wert (Drucken als unsigned) zum gleichen Verhalten führt.
Ich glaube, dass mit meinen ADC-Einstellungen etwas nicht stimmt. Mein PIC ist standardmäßig getaktet (8 MHz). Der Bereich des ADC sollte 0 V bis 2,5 V betragen, muss aber nicht so genau sein.
Ich kann anscheinend nicht die richtigen ADC-Einstellungen finden, glaube ich. Ich verwende den XC8-Compiler mit der adc.h
Bibliothek, die in MPLAB X IDE enthalten war.
Unten ist der Code (ich habe ein neues Projekt tot test gemacht, mit vereinfachtem Code.) Zuerst die adc.c, ich glaube, die Einstellungen sind falsch und ein Fehler beim Lesen sollte leicht zu erkennen sein.
#include <adc.h>
#include "adc.h"
void adcSetup()
{
OpenADC (
ADC_FOSC_8 &
ADC_RIGHT_JUST &
ADC_20_TAD,
ADC_CH4 &
ADC_INT_OFF &
ADC_REF_VDD_VDD &
ADC_REF_VDD_VSS,
ADC_CH4
);
ENABLE_AN4_ANA();
SetChanADC(ADC_CH4);
}
//TODO ADC with interrupts
unsigned int adcGet(void)
{
ConvertADC();
while(BusyADC()){}
return ReadADC();
}
auch meine main.c, die anderen xport-Dateien sind nicht so interessant und scheinen gut zu funktionieren. Ich bin mir meiner Konvertierung von uint in 'c-string' in der Funktion nicht so sichervoid buttonHandle(void)
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <p18f66k22.h>
#include <delays.h>
#include <usart.h>
#include "defines.h"
#include "configuration-bits.h"
#include "xport.h"
#include "adc.h"
#define __delay_us(x) _delay((unsigned long)((x)*(8000000/4000000UL)))
#define __delay_ms(x) _delay((unsigned long)((x)*(8000000/4000UL)))
volatile char RxBuf[] = " ";
volatile int RxI = 0;
volatile bool RxMessage = false;
volatile bool ButtonPressed = false;
void SetupRegisters(void);
void SetupInterrupts(void);
void interrupt HighISR(void);
void interrupt low_priority LowISR(void);
void delay_ms(unsigned int x);
void buttonHandle(void);
void messageHandle(void);
void SetupInterrupts(void)
{
INTCONbits.GIE = 1; //Global interrupt enable
RCONbits.IPEN = 1; //Enable priority interrupts
INTCONbits.GIEH = 1; //Global interrupt enable High
INTCONbits.GIEL = 1; //Global interrupt enable Low
INTCONbits.PEIE = 1; //Peripheral Interrupt Enable bit
INTCONbits.PEIE_GIEL = 1; //Peripheral Interrupt Enable?
INTCON3 = 0b00000000; //Clear intcon. INT1 and INT2 are now low priority
INTCON3bits.INT1E = 1; //Enable int1 (BUTTON)
}
void SetupRegisters(void)
{
//76543210
TRISA = 0b10101110; //7:RFID en2 6:x 5:POWER_LEVEL(analog) 4:PWRKEY 3:SW_CHRG 2:SW_FAULT 1:EXT_INP
TRISBbits.TRISB1 = 1; //BUTTON INPUT
TRISEbits.TRISE3 = 0; //XPort RESET
TRISGbits.TRISG3 = 1; //LDO pwrgd (input)
TRISGbits.TRISG4 = 0; //LDO shdn (ldo to toggle xport)
}
/* Main */
int main() {
//---Set up Registers/interrupts of PIC---
//See defines.h for al macros for LED_IN and other pin-renames.
SetupRegisters(); //Registers...
SetupInterrupts(); //Interrupts (button/uart)
adcSetup(); //ADC for power-detection (POWER-LEVEL)
//---Set up peripherals---
xportSetup(); //Using xport as debugging help.
xportEnable(); //Switch ldo to enable it.
while(true){
if(RxMessage){
messageHandle();
}else if(ButtonPressed){
buttonHandle();
ButtonPressed = false;
}
}
return 0;
}
void interrupt high_priority HighIsr(void) //High priority interrupt
{
if(PIR3bits.RC2IF){//USART INTERRUPT
RxBuf[RxI] = RCREG2;
if(RxBuf[RxI] == ';'){//TODO or full
RxMessage = true;
}
RxI++;
}else{
xportSendText("High - unhandled interrupt");
}
}
void interrupt low_priority LowIsr(void) //Low priority interrupt
{
if(INT1IF){ //Button interrupt
ButtonPressed = true; //Set flag (handled in main)
INT1IF = false; //clear interrupt flag afterwards to avoid hardware bounce re-interrupt
}else{ //Warning for unhandled interrupt
xportSendText("[ERROR] Low - unhandled interrupt!");
}
}
void delay_ms(unsigned int xc)
{
do
{
xc--;
__delay_ms(1);
}
while(xc > 0);
}
void buttonHandle(void){
delay_ms(100);
if(!BUTTON){
xportSendText("Button pressed");
//ADC DEBUG
char buffer[] = " ";
sprintf (buffer, "ADC: %u", adcGet());
xportSendText(buffer);
//RX DEBUG
xportSendText("RxBuf: ");
xportSendText(RxBuf);
//XPORT debug
xportDebug();
}
}
void messageHandle(void){
xportSendText(RxBuf); //Send/Handle the buffer
strcpy(RxBuf, " "); //Empty the buffer!
RxI = 0; //Start buffer at pos 0 again;
RxMessage = false; //Reset the flag
}
Ich erhalte im Grunde UART-Text in einem Interrupt. Und Drucken des Debug/Adc, wenn ein Button-Flag gesetzt wurde (durch den Button-Interrupt)
Dies ist meine Ausgabe nach mehrmaligem Drücken der Taste: Wie Sie sehen können, ist der Adc nicht sehr hartnäckig. Obwohl ich es an das Netzteil angeschlossen hatte (das nicht so stark fallen sollte (und nicht fällt).
Ich weiß, dass die Beispiele und Bibliotheken existieren, um Arbeit zu sparen, aber ich finde es oft hilfreich, sie zunächst nicht zu verwenden, während ich verifiziere, dass mein Verständnis und das Datenblatt korrekt sind und dass der Chip nicht kaputt ist. (Normalerweise ist das Problem mein Verständnis.)
Also, ohne die Bibliothek zu benutzen:
Sie werden wahrscheinlich feststellen, dass die Bibliothek korrekt ist und Ihnen etwas fehlt, was zu diesem Zeitpunkt offensichtlich wird, aber hin und wieder gibt es eine Bibliothek, die falsch oder zumindest schlecht geschrieben/dokumentiert ist.
Ich verstehe immer noch nicht wirklich, warum es überhaupt nicht funktioniert hat ... Könnte so gewesen sein, wie ich es gedruckt habe. Könnte die Bibliothek gewesen sein.
Obwohl ich es getan habe, indem ich die Register manuell eingestellt habe, funktioniert dies (besser) für mich.
static unsigned int result = 0;
ANCON0bits.ANSEL4 = 1; //AN4 to analog channel.
ADCON2 = 0b10111110; //Select channel
ADCON1 = 0b00110000;
ADCON0 = 0b00010011; //Start AN4 conversion
while(ADCON0 & 2){} //ADC busy
result = ADRESH;
result = result<<8;
result = result | ADRESL;
ADCON0 &= 0b11111110; // Turn converter off
return (result/85);
Reid
Paul
ENABLE_AN4_ANA();
sollten diesen Trick jedoch ausführen. Aber ja, könnte wirklich so eine Kleinigkeit sein.AaronD
Paul