PIC16F1503 ADC read problem while RC0 is 0

Thread Starter

azazil

Joined Nov 17, 2014
5
Hi,

We can read ADC value from RA4 pin but when RC0 pin is 0 we can not read adc value. It is always 0. We could not fine any relation between RA4 pin and RC0 pin. Could you please help us to solve this, this is an urgent situation.
 

Thread Starter

azazil

Joined Nov 17, 2014
5
unsigned int ReadADCValue(int channel) {
ADCON0bits.CHS = channel;ADCON0bits.GO_nDONE = 1;
while (ADCON0bits.GO);

return ((ADRESH * 256) + ADRESL);
}

we use this function to read adc. it is working well but when the rc0 is 0 it is not working. Actually, "return ((ADRESH * 256) + ADRESL)" this line is not working. When we return 500, 1000, 1023 all code work normal. we could not understand the relation between ADRES registers an RC0 pin.
 

Thread Starter

azazil

Joined Nov 17, 2014
5
And one more thing, this code is working when we first wrote it. I suspect that the update on xc8 and mplap cause this error.
 

tshuck

Joined Oct 18, 2012
3,534
What is your whole code? We need to be able to see how you've configured the device as well as the code snippet you've provided.

Also, please use code tags, [code ][/code ] (without spaces), when posting code.
 

Thread Starter

azazil

Joined Nov 17, 2014
5
I attached the whole code. This is a line follewer module that reads three sensors data that sense the line. Module has two outputs that driven by PWM. According to sensor data, code calculate pwm duty cycle as data, read from ra4, is the max value of the outputs. we limit the output voltage to be max equals to data input. It was working before but now the return ADRESH * 256 + ADRESL not working while RC0, which is the left sensor, is 0.

Code:
/*
* File:   Main.c
* Author: sahin
*
* Created on June 25, 2014, 5:54 PM
*/

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib/adc.h>

#pragma config FOSC = INTOSC, MCLRE = OFF, WDTE = OFF

#define _XTAL_FREQ 16000000

#define LEFTSENSOR PORTCbits.RC0
#define RIGHTSENSOR PORTCbits.RC4
#define MIDDLESENSOR PORTCbits.RC2

#define DATA PORTAbits.RA4

void Setup();
void InitTimer0();
void SendDataVia1W();
void InitPWMs();
void ConfigureADC();
unsigned int ReadADCValue(int channel);
///Action Methads
void LoadRoadData(char sensorData);
void GoFoarward();
void TurnLeft(float turnSpeed);
void TurnRight(float turnSpeed);
void Stop();
//////////

char _senseEnable = 0;

char _lastRoadDefinition = 2; // 2->bilinmiyor, 1->siyah, 0->beyaz

int main(int argc, char** argv) {
    Setup();

    float slowTurnSpeed = 0.75f;
    float fastTurnSpeed = 0.25f;

    while (1) {

        if (_senseEnable) {

            char sensorData = LEFTSENSOR * 4 + MIDDLESENSOR * 2 + RIGHTSENSOR; //0-7 aras?nda bir say?ya aktard?k ko?ullar?

            if (_lastRoadDefinition == 2) {
                LoadRoadData(sensorData);
                continue;
            }
            if (_lastRoadDefinition == 1) {
                switch (sensorData) {
                    case 0: // hepsi beyaz
                        Stop();
                        //Yoldan ç?kt?k. En son hangi tarafta oldu?umuza göre dönmek gerek.
                        //?imdilik duruyoruz
                        break;
                    case 1: // right siyah, left-middle beyaz
                        TurnRight(fastTurnSpeed);
                        break;
                    case 2: // middle siyah, right-left beyaz
                        GoFoarward();
                        break;
                    case 3: // middle-right siyah, left beyaz
                        TurnRight(slowTurnSpeed);
                        break;
                    case 4: //left siyah, middle-right beyaz
                        TurnLeft(fastTurnSpeed);
                        break;
                    case 5: // left-right siyah, middle beyaz
                        _lastRoadDefinition = 0;
                        GoFoarward();
                        break;
                    case 6: // left-middle siyah, right beyaz
                        TurnLeft(slowTurnSpeed);
                        break;
                    case 7: // hepsi siyah
                        GoFoarward();
                        break;
                    default: // hatal? rakamlar
                        GoFoarward();
                        break;
                }
            } else {
                switch (sensorData) {
                    case 0: // hepsi beyaz
                        GoFoarward();
                        break;
                    case 1: // right siyah, left-middle beyaz
                        TurnLeft(slowTurnSpeed);
                        break;
                    case 2: // middle siyah, right-left beyaz
                        _lastRoadDefinition = 1;
                        GoFoarward();
                        break;
                    case 3: // middle-right siyah, left beyaz
                        TurnLeft(fastTurnSpeed);
                        break;
                    case 4: //left siyah, middle-right beyaz
                        TurnRight(slowTurnSpeed);
                        break;
                    case 5: // left-right siyah, middle beyaz
                        GoFoarward();
                        break;
                    case 6: // left-middle siyah, right beyaz
                        TurnRight(fastTurnSpeed);
                        break;
                    case 7: // hepsi siyah
                        Stop();
                        //Yoldan ç?kt?k. En son hangi tarafta oldu?umuza göre dönmek gerek.
                        //?imdilik duruyoruz
                        break;
                    default: // hatal? rakamlar
                        GoFoarward();
                        break;
                }
            }

        }
    }
    return (EXIT_SUCCESS);
}

void LoadRoadData(char sensorData) {
//    if (sensorData == 2) {
//        _lastRoadDefinition = 1;
//    } else if (sensorData == 5) {
//        _lastRoadDefinition = 0;
//    } else {
//        _lastRoadDefinition = 2;
//    }
    _lastRoadDefinition = 1;
}

void GoFoarward() {
    //DATA hatt?ndan gelen gerilim de?eri bizim ç?k??ta maksimum verebilece?imiz PWM de?eri yani gerilim de?eri
    unsigned int upperLimit = ReadADCValue(0b00100);

    PWM1DCH = upperLimit >> 2;
    PWM1DCL = upperLimit << 6;

    PWM4DCH = upperLimit >> 2;
    PWM4DCL = upperLimit << 6;
}

void Stop() {
    PWM1DCH = 0;
    PWM1DCL = 0;

    PWM4DCH = 0;
    PWM4DCL = 0;
}

void TurnLeft(float turnSpeed) {
    unsigned int upperLimit = ReadADCValue(0b00100);
    //Sa?a dönmek için sol ç?k???n azalmas? gerekiyor. Turnspeed oran?nda bir azalma sa?lanarak sol ç?k??? süren PWM e veriliyor
    unsigned int slowSpeed = (unsigned int) (upperLimit * turnSpeed);

    PWM1DCH = upperLimit >> 2;
    PWM1DCL = upperLimit << 6;

    PWM4DCH = slowSpeed >> 2;
    PWM4DCL = slowSpeed << 6;
}

void TurnRight(float turnSpeed) {
    unsigned unsigned int upperLimit = ReadADCValue(0b00100);
    //Sa?a dönmek için sa? ç?k???n azalmas? gerekiyor. Turnspeed oran?nda bir azalma sa?lanarak sa? ç?k??? süren PWM e veriliyor
    unsigned int slowSpeed = (unsigned int) (upperLimit * turnSpeed);

    PWM1DCH = slowSpeed >> 2;
    PWM1DCL = slowSpeed << 6;

    PWM4DCH = upperLimit >> 2;
    PWM4DCL = upperLimit << 6;
}

void SendDataVia1W() {

}

void interrupt Interrupts() {

    if (TMR1IF) {
        TMR1IF = 0;
    }

    if (TMR0IF) {
        TMR0IF = 0;
        TMR0 = 100;
        _senseEnable = 1;
    }
}

void InitPWMs() {
    PR2 = 0xFF;
    T2CONbits.TMR2ON = 1;
    T2CONbits.T2CKPS0 = 1;
    T2CONbits.T2CKPS1 = 1;
    PIR1bits.TMR2IF = 0;
    PWM1CONbits.PWM1EN = 1;
    PWM1CONbits.PWM1OE = 1;

    PWM4CONbits.PWM4EN = 1;
    PWM4CONbits.PWM4OE = 1;

    PWM1DCH = 0x00; // ba?lang?cta dutycycle = 0;
    PWM1DCL = 0x00;

    PWM4DCH = 0x00;
    PWM4DCL = 0x00;
}

void Setup() {
    OSCCONbits.SCS = 0b11; //Internal oscillator is used for system clock
    OSCCONbits.IRCF = 0b1111; // 16MHz

    TRISC = 0b010101;
    TRISAbits.TRISA4 = 1;

    ANSELA = 0;
    ANSELC = 0;

    InitTimer0();
    ConfigureADC();
    InitPWMs();
}

void ConfigureADC() {
    ANSELAbits.ANSA4 = 1;
    ADCON1bits.ADCS = 0b101; //Fosc/16 - > 1us
    ADCON1bits.ADPREF = 0b00; //Vref = VDD
    ADCON1bits.ADFM = 1; //Right justified
    //ADCON0bits.CHS = 0b00100; //AN4 channel

    ADCON0bits.ADON = 1; //ADC enable
}

unsigned int ReadADCValue(int channel) {
    ADCON0bits.CHS = channel;
    ADCON0bits.GO_nDONE = 1;
    while (ADCON0bits.GO);

    return ((ADRESH * 256) + ADRESL);
}

void InitTimer0() {
    OPTION_REG = 0x87; // prescaler = 101 -> 1:64, PSA = 0 -> assigned to timer0
    TMR0 = 100; // 10 ms kesme

    INTCONbits.GIE = 1;
    INTCONbits.TMR0IE = 1;

    INTCONbits.TMR0IF = 0;
}
 

ErnieM

Joined Apr 24, 2011
8,415
Yikes, that's alota code. It is always best to trim your project down to the fewest features that still demonstrate the problem. You'll sometimes even find deleting something "irrelevant" makes the problem go away so you solve it doing something simple. It also induced people to read all your code.

Can you post your schematic? What is on these pins? Any chance something is shorted?
 

Thread Starter

azazil

Joined Nov 17, 2014
5
Yikes, that's alota code. It is always best to trim your project down to the fewest features that still demonstrate the problem. You'll sometimes even find deleting something "irrelevant" makes the problem go away so you solve it doing something simple. It also induced people to read all your code.

Can you post your schematic? What is on these pins? Any chance something is shorted?
No there is no short circuit on pins, becasue when you return any integer from ReadADC function everything is working. RC0 sensor pin works as expected. When we try to read ADRESH and ADRESL register while rc0 is 0 the result always 0. the other two sensor pins work as expected.
 

tshuck

Joined Oct 18, 2012
3,534
After looking at your code, I'm suspecting a hardware problem - could you post a picture of your setup with a schematic?

How are you checking RC0 at 0?
 

takao21203

Joined Apr 28, 2012
3,702
just a urgent remark, I know the 16f1503, and the configuration found in the source isnt appropiate at all.

do you use an old MPLAB or something else? Otherwise you can set the bits and let MPLABX generate the code.
All options should be handled.

Also
Code:
int main(int argc, char** argv)
doesnt make sense since a 8bit controller will neither receive a parameter, nor will it return a value to anywhere.
You should use
Code:
void main()
instead

Not even sure if the 16f1503 does have ADC on PORTC??
There is an issue where it doesnt have WPUC only WPUA while the datasheet isnt clear on that.

The 16F1824 is a similar IC by the way.
 
Top