PIC16F1503 ADC read problem while RC0 is 0

Discussion in 'Embedded Systems and Microcontrollers' started by azazil, Nov 17, 2014.

  1. azazil

    Thread Starter New Member

    Nov 17, 2014
    5
    0
    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.
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    What code are you using?

    And what is your schematic?
     
    Last edited: Nov 17, 2014
  3. azazil

    Thread Starter New Member

    Nov 17, 2014
    5
    0
    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.
     
  4. azazil

    Thread Starter New Member

    Nov 17, 2014
    5
    0
    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.
     
  5. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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.
     
  6. azazil

    Thread Starter New Member

    Nov 17, 2014
    5
    0
    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 (Text):
    1.  
    2.  
    3. /*
    4. * File:   Main.c
    5. * Author: sahin
    6. *
    7. * Created on June 25, 2014, 5:54 PM
    8. */
    9.  
    10. #include <xc.h>
    11. #include <stdio.h>
    12. #include <stdlib.h>
    13. #include <plib/adc.h>
    14.  
    15. #pragma config FOSC = INTOSC, MCLRE = OFF, WDTE = OFF
    16.  
    17. #define _XTAL_FREQ 16000000
    18.  
    19. #define LEFTSENSOR PORTCbits.RC0
    20. #define RIGHTSENSOR PORTCbits.RC4
    21. #define MIDDLESENSOR PORTCbits.RC2
    22.  
    23. #define DATA PORTAbits.RA4
    24.  
    25. void Setup();
    26. void InitTimer0();
    27. void SendDataVia1W();
    28. void InitPWMs();
    29. void ConfigureADC();
    30. unsigned int ReadADCValue(int channel);
    31. ///Action Methads
    32. void LoadRoadData(char sensorData);
    33. void GoFoarward();
    34. void TurnLeft(float turnSpeed);
    35. void TurnRight(float turnSpeed);
    36. void Stop();
    37. //////////
    38.  
    39. char _senseEnable = 0;
    40.  
    41. char _lastRoadDefinition = 2; // 2->bilinmiyor, 1->siyah, 0->beyaz
    42.  
    43. int main(int argc, char** argv) {
    44.     Setup();
    45.  
    46.     float slowTurnSpeed = 0.75f;
    47.     float fastTurnSpeed = 0.25f;
    48.  
    49.     while (1) {
    50.  
    51.         if (_senseEnable) {
    52.  
    53.             char sensorData = LEFTSENSOR * 4 + MIDDLESENSOR * 2 + RIGHTSENSOR; //0-7 aras?nda bir say?ya aktard?k ko?ullar?
    54.  
    55.             if (_lastRoadDefinition == 2) {
    56.                 LoadRoadData(sensorData);
    57.                 continue;
    58.             }
    59.             if (_lastRoadDefinition == 1) {
    60.                 switch (sensorData) {
    61.                     case 0: // hepsi beyaz
    62.                         Stop();
    63.                         //Yoldan ç?kt?k. En son hangi tarafta oldu?umuza göre dönmek gerek.
    64.                         //?imdilik duruyoruz
    65.                         break;
    66.                     case 1: // right siyah, left-middle beyaz
    67.                         TurnRight(fastTurnSpeed);
    68.                         break;
    69.                     case 2: // middle siyah, right-left beyaz
    70.                         GoFoarward();
    71.                         break;
    72.                     case 3: // middle-right siyah, left beyaz
    73.                         TurnRight(slowTurnSpeed);
    74.                         break;
    75.                     case 4: //left siyah, middle-right beyaz
    76.                         TurnLeft(fastTurnSpeed);
    77.                         break;
    78.                     case 5: // left-right siyah, middle beyaz
    79.                         _lastRoadDefinition = 0;
    80.                         GoFoarward();
    81.                         break;
    82.                     case 6: // left-middle siyah, right beyaz
    83.                         TurnLeft(slowTurnSpeed);
    84.                         break;
    85.                     case 7: // hepsi siyah
    86.                         GoFoarward();
    87.                         break;
    88.                     default: // hatal? rakamlar
    89.                         GoFoarward();
    90.                         break;
    91.                 }
    92.             } else {
    93.                 switch (sensorData) {
    94.                     case 0: // hepsi beyaz
    95.                         GoFoarward();
    96.                         break;
    97.                     case 1: // right siyah, left-middle beyaz
    98.                         TurnLeft(slowTurnSpeed);
    99.                         break;
    100.                     case 2: // middle siyah, right-left beyaz
    101.                         _lastRoadDefinition = 1;
    102.                         GoFoarward();
    103.                         break;
    104.                     case 3: // middle-right siyah, left beyaz
    105.                         TurnLeft(fastTurnSpeed);
    106.                         break;
    107.                     case 4: //left siyah, middle-right beyaz
    108.                         TurnRight(slowTurnSpeed);
    109.                         break;
    110.                     case 5: // left-right siyah, middle beyaz
    111.                         GoFoarward();
    112.                         break;
    113.                     case 6: // left-middle siyah, right beyaz
    114.                         TurnRight(fastTurnSpeed);
    115.                         break;
    116.                     case 7: // hepsi siyah
    117.                         Stop();
    118.                         //Yoldan ç?kt?k. En son hangi tarafta oldu?umuza göre dönmek gerek.
    119.                         //?imdilik duruyoruz
    120.                         break;
    121.                     default: // hatal? rakamlar
    122.                         GoFoarward();
    123.                         break;
    124.                 }
    125.             }
    126.  
    127.         }
    128.     }
    129.     return (EXIT_SUCCESS);
    130. }
    131.  
    132. void LoadRoadData(char sensorData) {
    133. //    if (sensorData == 2) {
    134. //        _lastRoadDefinition = 1;
    135. //    } else if (sensorData == 5) {
    136. //        _lastRoadDefinition = 0;
    137. //    } else {
    138. //        _lastRoadDefinition = 2;
    139. //    }
    140.     _lastRoadDefinition = 1;
    141. }
    142.  
    143. void GoFoarward() {
    144.     //DATA hatt?ndan gelen gerilim de?eri bizim ç?k??ta maksimum verebilece?imiz PWM de?eri yani gerilim de?eri
    145.     unsigned int upperLimit = ReadADCValue(0b00100);
    146.  
    147.     PWM1DCH = upperLimit >> 2;
    148.     PWM1DCL = upperLimit << 6;
    149.  
    150.     PWM4DCH = upperLimit >> 2;
    151.     PWM4DCL = upperLimit << 6;
    152. }
    153.  
    154. void Stop() {
    155.     PWM1DCH = 0;
    156.     PWM1DCL = 0;
    157.  
    158.     PWM4DCH = 0;
    159.     PWM4DCL = 0;
    160. }
    161.  
    162. void TurnLeft(float turnSpeed) {
    163.     unsigned int upperLimit = ReadADCValue(0b00100);
    164.     //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
    165.     unsigned int slowSpeed = (unsigned int) (upperLimit * turnSpeed);
    166.  
    167.     PWM1DCH = upperLimit >> 2;
    168.     PWM1DCL = upperLimit << 6;
    169.  
    170.     PWM4DCH = slowSpeed >> 2;
    171.     PWM4DCL = slowSpeed << 6;
    172. }
    173.  
    174. void TurnRight(float turnSpeed) {
    175.     unsigned unsigned int upperLimit = ReadADCValue(0b00100);
    176.     //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
    177.     unsigned int slowSpeed = (unsigned int) (upperLimit * turnSpeed);
    178.  
    179.     PWM1DCH = slowSpeed >> 2;
    180.     PWM1DCL = slowSpeed << 6;
    181.  
    182.     PWM4DCH = upperLimit >> 2;
    183.     PWM4DCL = upperLimit << 6;
    184. }
    185.  
    186. void SendDataVia1W() {
    187.  
    188. }
    189.  
    190. void interrupt Interrupts() {
    191.  
    192.     if (TMR1IF) {
    193.         TMR1IF = 0;
    194.     }
    195.  
    196.     if (TMR0IF) {
    197.         TMR0IF = 0;
    198.         TMR0 = 100;
    199.         _senseEnable = 1;
    200.     }
    201. }
    202.  
    203. void InitPWMs() {
    204.     PR2 = 0xFF;
    205.     T2CONbits.TMR2ON = 1;
    206.     T2CONbits.T2CKPS0 = 1;
    207.     T2CONbits.T2CKPS1 = 1;
    208.     PIR1bits.TMR2IF = 0;
    209.     PWM1CONbits.PWM1EN = 1;
    210.     PWM1CONbits.PWM1OE = 1;
    211.  
    212.     PWM4CONbits.PWM4EN = 1;
    213.     PWM4CONbits.PWM4OE = 1;
    214.  
    215.     PWM1DCH = 0x00; // ba?lang?cta dutycycle = 0;
    216.     PWM1DCL = 0x00;
    217.  
    218.     PWM4DCH = 0x00;
    219.     PWM4DCL = 0x00;
    220. }
    221.  
    222. void Setup() {
    223.     OSCCONbits.SCS = 0b11; //Internal oscillator is used for system clock
    224.     OSCCONbits.IRCF = 0b1111; // 16MHz
    225.  
    226.     TRISC = 0b010101;
    227.     TRISAbits.TRISA4 = 1;
    228.  
    229.     ANSELA = 0;
    230.     ANSELC = 0;
    231.  
    232.     InitTimer0();
    233.     ConfigureADC();
    234.     InitPWMs();
    235. }
    236.  
    237. void ConfigureADC() {
    238.     ANSELAbits.ANSA4 = 1;
    239.     ADCON1bits.ADCS = 0b101; //Fosc/16 - > 1us
    240.     ADCON1bits.ADPREF = 0b00; //Vref = VDD
    241.     ADCON1bits.ADFM = 1; //Right justified
    242.     //ADCON0bits.CHS = 0b00100; //AN4 channel
    243.  
    244.     ADCON0bits.ADON = 1; //ADC enable
    245. }
    246.  
    247. unsigned int ReadADCValue(int channel) {
    248.     ADCON0bits.CHS = channel;
    249.     ADCON0bits.GO_nDONE = 1;
    250.     while (ADCON0bits.GO);
    251.  
    252.     return ((ADRESH * 256) + ADRESL);
    253. }
    254.  
    255. void InitTimer0() {
    256.     OPTION_REG = 0x87; // prescaler = 101 -> 1:64, PSA = 0 -> assigned to timer0
    257.     TMR0 = 100; // 10 ms kesme
    258.  
    259.     INTCONbits.GIE = 1;
    260.     INTCONbits.TMR0IE = 1;
    261.  
    262.     INTCONbits.TMR0IF = 0;
    263. }
    264.  
    265.  
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    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?
     
  8. azazil

    Thread Starter New Member

    Nov 17, 2014
    5
    0
    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.
     
  9. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    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?
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    What is the voltage at pin RA4 when pin RC0 is zero?
     
  11. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    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 (Text):
    1. 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 (Text):
    1. 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.
     
Loading...