CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

error Reading Multiple ADC Inputs
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

error Reading Multiple ADC Inputs
PostPosted: Mon Jul 31, 2017 6:35 am     Reply with quote

Hello. I am using pic16f914 to read the analog output of a accelerometer ADXL335. I can read 1 channel correctly but when i am trying to read all 3 channels and display the values on LCD it does not work. I am using CCS PCWH 5.074 compiler.

The output of a ADXL is as follows (Readings with ADXL positioned Flat on table) :

1) X - channel (AN0 on PIC ) - 1.59 V
2) Y - channel (AN1 on PIC) - 1.61 V
3) Z- channel (AN5 on PIC ) - 1.977 V

I am using VREF+ = 3.3V (actual 3.25volts) and Vss=0;

Following are readings when channels measured individually:

AN0 - 504 for (1.596 volts)
AN1 - 510 for (1.610 volts)
AN5 - 625 for (1.979 Volts)

Now i am measuring all 3 channels. I am getting 337 on display.

Following is my code:
Code:

#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
//#define VSS_VREF
//#define VREF_VREF

//============================================================================================//
//===========================================================================================//
//                                 LCD Configuration                                        //
//==========================================================================================//
// Digit segments  A           B         C          D           E         F         G          DP
//                 b7          b6        b5         b4          b3        b2        b1         b0
#define DIGIT5  COM0+17,   COM1+17,   COM2+17,   COM3+17,   COM2+18,   COM0+18,   COM1+18,   COM3+18
#define DIGIT4  COM0+3,    COM1+3,    COM2+3,    COM3+3,    COM2+2,    COM0+2,    COM1+2,    COM3+2
#define DIGIT3  COM0+1,    COM1+1,    COM2+1,    COM3+1,    COM2+0,    COM0+0,    COM1+0,    COM3+0
#define DIGIT2  COM0+19,   COM1+19,   COM2+19,   COM3+19,   COM2+20,   COM0+20,   COM1+20,   COM3+20
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//=======================================================================================//
//           character          0    1    2    3    4    5    6    7    8    9  Null
byte const Digit_Map[11]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0x01}; //Decimal

byte const Digit_Map_1[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00}; //no Decimal

//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
////=====================================================================================//

#define Segments 0x1E000F    // Initilize LCD SegmentX

//============================================================================//

#define INTS_PER_SECOND     76      // (20000000/(4*256*256))

int int_count=INTS_PER_SECOND;


int count5 = 0;// after decimal
int count_5 = 0;
int count4=0;   // 1st digit
int count_4=0;   // 1st digit
int count3=0;   // 2nd digit
int count_3=0; 
int count2=0;   // 3rd digit
int count_2=0;
long seconds=0;
long reading;
long reading1;
long reading2;
long reading3;

#int_rtcc               //This function is called

//============================================================================//
void clock_isr()
{                       //every time the RTCC (timer0)
                        //overflows (255->0)
                        //For this program this is apx
                        //31 times per second.

   if(--int_count==0)
   {
      seconds++;
      int_count=INTS_PER_SECOND;
   }
}
//============================================================================//
void Disp_num()
{
   if(reading < 10)
   {
      count_5=reading;
      count_2=11;
      count_3=11;
      count_4=11;
   }
   
   if(10<= reading < 100)
   {
     count_5=reading%10;
     count_4=reading/10;
     count_3=11;
     count_2=11;
   }
   
   if(100 <= reading <999)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=11;
   }
   if(1000 <= reading < 1024)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=reading%10000/1000;
   }
   if(reading >= 1024)
   {
       count_5=11;
       count_4=11;
       count_3=11;
       count_2=11;
   }
}
//=============================================================================//
void sec_disp()
{
   count4=count_4;
   count5=count_5;
   count2=count_2;
   count3=count_3;
   
}
//============================================================================//
void Display()
{
   lcd_symbol (Digit_Map_1[count5], DIGIT5);
   lcd_symbol (Digit_Map[count4], DIGIT4);
   lcd_symbol (Digit_Map_1[count3], DIGIT3);
   lcd_symbol (Digit_Map_1[count2], DIGIT2);
     
}
//============================================================================//
void Digit()
{
      if(seconds>=1)
      {
         set_adc_channel (0);
       //   VCFG0 = 1;  // Enable Vref+. Fix for compiler bug in set_adc_channel().
          delay_us(20);
         reading1 = read_adc();
         delay_us(20);
         
         reading=reading1;
        // delay_ms(1000);
      }
      if(seconds>=2)
      {
         set_adc_channel (1);
         delay_us(20);
         reading2 = read_adc();
         delay_us(20);
         reading=reading2;
        // delay_ms(1000);
      }
      if(seconds>=3)
      {
        set_adc_channel (5);
        delay_us(20);
        reading3 = read_adc();
        delay_us(20);
        reading=reading3;
      //  delay_ms (1000);
        //seconds=0;
      }       
         seconds=0;
     
}

//void ADC_reading()
//{
  // if
//===========================================================================//
//============================================================================//
//get VCFG0 bit (to clear ccs bug which clears VCFG0 bit & due to that Vref
//is always defaulted to Vpp.
#bit VCFG0 = getenv("BIT:VCFG0")   
//===========================================================================//
void main()
{
   set_tris_a (0xdf);
   set_tris_b (0xc0);
   set_tris_c (0x07);
   
   setup_adc_ports(sAN0);
   setup_adc_ports(sAN1);
   setup_adc_ports(sAN5);
   
 
   setup_adc (ADC_CLOCK_INTERNAL);

//   enable_interrupts(GLOBAL);
   
  // setup_timer_1 (T1_DISABLED);     // disable timer 1

 //  setup_timer_2 (T2_DISABLED,0,1);     // disable timer 2

 //  setup_vref (FALSE);              // disable Voltage reference

  // setup_adc (ADC_OFF);             // disable ADC

  // setup_wdt (WDT_OFF);             // disable Watch Dog Timer

 //  setup_ccp1 (CCP_OFF);            // disable compare/capture

  // setup_comparator (NC_NC_NC_NC);  // disable comparators
 
   //#byte VRCON = 0x009D   // VR control register
   //      VRCON = 0x00;    // VR is disabled
         
   //#byte CMCON0 = 0x009C  // Comparator configuration register
  //       CMCON0 = 0x0007; // Comparator is disabled
         
  // #byte ANSEL = 0x0091   // Analog select register
 //        ANSEL = 0x00;    // Digital I/O
         
 //  #byte ADCON0 = 0x00a3  // A/D control register
 //        ADCON0 = 0x00;   // A/D is shut off
 
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   enable_interrupts (INT_RTCC);
   
   enable_interrupts(GLOBAL);
   
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
 
   count5 = 8;
   count4 = 8;
   count3 = 8;
   count2 = 8;
 
   Display ();
   
   delay_ms (1000);
 
     
   while (TRUE)  /* Modify on 9/19/2012 */
   {
       
      digit();     
      Disp_num();
      sec_disp();
      display();
     
    }

   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 7:49 am     Reply with quote

Remember that the set_adc_channel() function is defective.
It clears the VCFG0 bit. So we gave you a fix. The fix
consists of manually setting the VCFG0 bit to 1, after each
call to set_channel(). But in your posted code, you are not
doing this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 7:51 am     Reply with quote

setup_adc_ports does not work like that. The syntax is:

setup_adc_ports(sAN0 | sAN1 | sAN5);

Currently you will only be connecting AN5 to the multiplexer....

You are also running with Vss to Vdd, not the 3.3v reference, and have not got the bugfix posted by PCM_programmer....
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 8:26 am     Reply with quote

Hi,

You are also going backward on things previously pointed out to you, in this case by PCM programmer.

Example:

Code:

#int_rtcc               //This function is called

//============================================================================//
void clock_isr()
{                       //every time the RTCC


Successful programming demands care, and attention to detail. Randomness is not a good programming attribute.....
_________________
John

If it's worth doing, it's worth doing in real hardware!
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 8:28 am     Reply with quote

i HAVE TRIED TO PASTE VCFG0 = 1; AFTER SELECTION OF ADC channel but it shows me error it says unidentified identifier. And also i am unaware of where to paste this code for channel 1 and 5. Please suggest. Sorry i have made modifications bringing #INT rtcc but while copy pasting i don't realize how i ended up having pasted old version.

Code is as shown:
Code:

#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
//#define VSS_VREF
//#define VREF_VREF


//============================================================================================//
//===========================================================================================//
//                                 LCD Configuration                                        //
//==========================================================================================//
// Digit segments  A           B         C          D           E         F         G          DP
//                 b7          b6        b5         b4          b3        b2        b1         b0
#define DIGIT5  COM0+17,   COM1+17,   COM2+17,   COM3+17,   COM2+18,   COM0+18,   COM1+18,   COM3+18
#define DIGIT4  COM0+3,    COM1+3,    COM2+3,    COM3+3,    COM2+2,    COM0+2,    COM1+2,    COM3+2
#define DIGIT3  COM0+1,    COM1+1,    COM2+1,    COM3+1,    COM2+0,    COM0+0,    COM1+0,    COM3+0
#define DIGIT2  COM0+19,   COM1+19,   COM2+19,   COM3+19,   COM2+20,   COM0+20,   COM1+20,   COM3+20
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//=======================================================================================//
//           character          0    1    2    3    4    5    6    7    8    9  Null
byte const Digit_Map[11]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0x01}; //Decimal

byte const Digit_Map_1[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00}; //no Decimal

//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
////=====================================================================================//

#define Segments 0x1E000F    // Initilize LCD SegmentX

//============================================================================//

#define INTS_PER_SECOND     76      // (20000000/(4*256*256))

int int_count=INTS_PER_SECOND;


int count5 = 0;// after decimal
int count_5 = 0;
int count4=0;   // 1st digit
int count_4=0;   // 1st digit
int count3=0;   // 2nd digit
int count_3=0; 
int count2=0;   // 3rd digit
int count_2=0;
long seconds=0;
long reading;
long reading1;
long reading2;
long reading3;



//============================================================================//
#int_rtcc               //This function is called
void clock_isr()
{                       //every time the RTCC (timer0)
                        //overflows (255->0)
                        //For this program this is apx
                        //31 times per second.

   if(--int_count==0)
   {
      seconds++;
      int_count=INTS_PER_SECOND;
   }
}
//============================================================================//
void Disp_num()
{
   if(reading < 10)
   {
      count_5=reading;
      count_2=11;
      count_3=11;
      count_4=11;
   }
   
   if(10<= reading < 100)
   {
     count_5=reading%10;
     count_4=reading/10;
     count_3=11;
     count_2=11;
   }
   
   if(100 <= reading <999)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=11;
   }
   if(1000 <= reading < 1024)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=reading%10000/1000;
   }
   if(reading >= 1024)
   {
       count_5=11;
       count_4=11;
       count_3=11;
       count_2=11;
   }
}
//=============================================================================//
void sec_disp()
{
   count4=count_4;
   count5=count_5;
   count2=count_2;
   count3=count_3;
   
}
//============================================================================//
void Display()
{
   lcd_symbol (Digit_Map_1[count5], DIGIT5);
   lcd_symbol (Digit_Map[count4], DIGIT4);
   lcd_symbol (Digit_Map_1[count3], DIGIT3);
   lcd_symbol (Digit_Map_1[count2], DIGIT2);
     
}
//============================================================================//
void Digit()
{
      if(seconds>=1)
      {
         set_adc_channel (0);
          VCFGO = 1;  // Enable Vref+. Fix for compiler bug in set_adc_channel().
          delay_us(20);
         reading1 = read_adc();
         delay_us(20);
         
         reading=reading1;
        // delay_ms(1000);
      }
      if(seconds>=2)
      {
         set_adc_channel (1);
         VCFGO = 1;
         delay_us(20);
         reading2 = read_adc();
         delay_us(20);
         reading=reading2;
        // delay_ms(1000);
      }
      if(seconds>=3)
      {
        set_adc_channel (5);
        VCFGO = 1;
        delay_us(20);
        reading3 = read_adc();
        delay_us(20);
        reading=reading3;
      //  delay_ms (1000);
        //seconds=0;
      }       
         seconds=0;
     
}

#bit VCFG0 = getenv("BIT:VCFG0")   
//===========================================================================//
void main()
{
   set_tris_a (0xdf);
   set_tris_b (0xc0);
   set_tris_c (0x07);
   
   setup_adc_ports(sAN0|sAN1|sAN5);
   
   setup_adc (ADC_CLOCK_INTERNAL);

//   enable_interrupts(GLOBAL);
   
  // setup_timer_1 (T1_DISABLED);     // disable timer 1

 //  setup_timer_2 (T2_DISABLED,0,1);     // disable timer 2

 //  setup_vref (FALSE);              // disable Voltage reference

  // setup_adc (ADC_OFF);             // disable ADC

  // setup_wdt (WDT_OFF);             // disable Watch Dog Timer

 //  setup_ccp1 (CCP_OFF);            // disable compare/capture

  // setup_comparator (NC_NC_NC_NC);  // disable comparators
 
   //#byte VRCON = 0x009D   // VR control register
   //      VRCON = 0x00;    // VR is disabled
         
   //#byte CMCON0 = 0x009C  // Comparator configuration register
  //       CMCON0 = 0x0007; // Comparator is disabled
         
  // #byte ANSEL = 0x0091   // Analog select register
 //        ANSEL = 0x00;    // Digital I/O
         
 //  #byte ADCON0 = 0x00a3  // A/D control register
 //        ADCON0 = 0x00;   // A/D is shut off
 
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   enable_interrupts (INT_RTCC);
   
   enable_interrupts(GLOBAL);
   
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
 
   count5 = 8;
   count4 = 8;
   count3 = 8;
   count2 = 8;
 
   Display ();
   
   delay_ms (1000);
 
     
   while (TRUE)  /* Modify on 9/19/2012 */
   {
       
      digit();     
      Disp_num();
      sec_disp();
      display();
     
    }

   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 9:07 am     Reply with quote

In the previous thread, I said to do this:
Quote:
To fix it, add this line above main():
Code:
#bit VCFG0 = getenv("BIT:VCFG0")

But you didn't put that line in your current program.

I also said:
Quote:
Then set VCFG0 in code, just after setting the channel:
Code:
set_adc_channel(0);
VCFG0 = 1; // Enable Vref+. Fix for compiler bug in set_adc_channel().

After every call to set_adc_channel(), you need to add the VCFG0 = 1;
line.

I should have made a better fix, such as a macro to replace the built-in
set_adc_channel() function, but I wanted to post a fix quickly so I posted
the simple one.
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 9:27 am     Reply with quote

IT IS THERE JUST ABOVE MAIN . ALSO I M ADDING VCFG0 = 1 ; LINE AFTER EVERY set_adc_channel LINE. BUT I M GETTING ERROR UNIDENTIFIED IDENTIFIER .



Code:

void Digit()
{
      if(seconds>=1)
      {
         set_adc_channel (0);
          VCFG0 = 1; // Enable Vref+. Fix for compiler bug in set_adc_channel().
          delay_us(20);
         reading1 = read_adc();
         reading=reading1;
      }
      if(seconds>=2)
      {
         set_adc_channel (1);
         VCFGO = 1;
         delay_us(20);
         reading2 = read_adc();
         reading=reading2;
      }
      if(seconds>=3)
      {
        set_adc_channel (5);
        VCFGO = 1;
        delay_us(20);
        reading3 = read_adc();
        reading=reading3;
      }
      seconds=0;
     
}

//===========================================================================//
//============================================================================//
//get VCFG0 bit (to clear ccs bug which clears VCFG0 bit & due to that Vref
//is always defaulted to Vpp.
#bit VCFG0 = getenv("BIT:VCFG0")   
//===========================================================================//
void main()
{
   set_tris_a (0xdf);
   set_tris_b (0xc0);
   set_tris_c (0x07);
   
   setup_adc_ports(sAN0|sAN1);
   
   setup_adc (ADC_CLOCK_INTERNAL);

//   enable_interrupts(GLOBAL);
   
  // setup_timer_1 (T1_DISABLED);     // disable timer 1

 //  setup_timer_2 (T2_DISABLED,0,1);     // disable timer 2

 //  setup_vref (FALSE);              // disable Voltage reference

  // setup_adc (ADC_OFF);             // disable ADC

  // setup_wdt (WDT_OFF);             // disable Watch Dog Timer

 //  setup_ccp1 (CCP_OFF);            // disable compare/capture

  // setup_comparator (NC_NC_NC_NC);  // disable comparators
 
   //#byte VRCON = 0x009D   // VR control register
   //      VRCON = 0x00;    // VR is disabled
         
   //#byte CMCON0 = 0x009C  // Comparator configuration register
  //       CMCON0 = 0x0007; // Comparator is disabled
         
  // #byte ANSEL = 0x0091   // Analog select register
 //        ANSEL = 0x00;    // Digital I/O
         
 //  #byte ADCON0 = 0x00a3  // A/D control register
 //        ADCON0 = 0x00;   // A/D is shut off
 
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   enable_interrupts (INT_RTCC);
   
   enable_interrupts(GLOBAL);
   
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
 
   count5 = 8;
   count4 = 8;
   count3 = 8;
   count2 = 8;
 
   Display ();
   
   delay_ms (1000);
 
     
   while (TRUE)  /* Modify on 9/19/2012 */
   {
       
      digit();     
      Disp_num();
      sec_disp();
      display();
     
    }

   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 9:29 am     Reply with quote

OK, here's a revision. Put it above any other code. Example:
Code:
 
#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)

#bit VCFG0 = getenv("BIT:VCFG0") // Put it here
 




Also, get rid of these two lines. They don't do anything and are not needed:
//#define VSS_VREF
//#define VREF_VREF
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 10:04 am     Reply with quote

He is also still not selecting the Vref, and ADC_CLOCK_INTERNAL is not recommended 1MHz.
He had the wrong idea that this controlled Tacq. Not Tad.
Both of these were pointed out in the earlier thread, he is ignoring/not reading what is being posted... :(

Can I suggest:
Code:

#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)

#bit VCFG0 = getenv("BIT:VCFG0") // Put it here

#define SET_AN_CHANNEL(x)   set_adc_channel (x); VCFG0 = 1

//Then select a channel with
    SET_AN_CHANNEL(0); //etc.
    delay_us(5); //This is the Tacq

//Configure the ADC in the main with:

setup_adc_ports(sAN0 | sAN1 | sAN5, Vss_Vdd);
setup_adc (ADC_CLOCK_DIV_32);


I know the VCFG write overrides the adc_ports setup, but it ensures the other bit is off, and means it will be compatible if he switches to another chip.


Last edited by Ttelmah on Mon Jul 31, 2017 10:17 am; edited 1 time in total
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 10:15 am     Reply with quote

I will do that. I am sorry guys i am not ignoring previous instructions as you suggested but because somehow i end up with the old version i am going to start all over again.
I really appereciate your help. I will keep you guys updated.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 10:18 am     Reply with quote

I edited my post to make a tidier suggestion while you were typing. This is what I'd do. Smile
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 11:49 am     Reply with quote

i have wrote a program to read just 2 channels (ch 0-x reading of adxl & ch 4-z reading of adxl), it seems like it only reads channel-0 and does not read channel 4. I noticed one thing when I'm taking input from channel 4 and putting it on channel 1, it reads 608. I have preset all I/O ports using tris command. But still it is not displaying both readings one after another but it just displays first reading which it measures at channel-0.

Code:

//============================================================================//
//                         Inclinometer                                       //
//                         Date: 7-24-2017                                    //
//                                                                            //
//============================================================================//
#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
#bit VCFG0 = getenv("BIT:VCFG0")
#define SET_AN_CHANNEL(x)   set_adc_channel (x); VCFG0 = 1


//============================================================================================//
//===========================================================================================//
//                                 LCD Configuration                                        //
//==========================================================================================//
// Digit segments  A           B         C          D           E         F         G          DP
//                 b7          b6        b5         b4          b3        b2        b1         b0
#define DIGIT5  COM0+17,   COM1+17,   COM2+17,   COM3+17,   COM2+18,   COM0+18,   COM1+18,   COM3+18
#define DIGIT4  COM0+3,    COM1+3,    COM2+3,    COM3+3,    COM2+2,    COM0+2,    COM1+2,    COM3+2
#define DIGIT3  COM0+1,    COM1+1,    COM2+1,    COM3+1,    COM2+0,    COM0+0,    COM1+0,    COM3+0
#define DIGIT2  COM0+19,   COM1+19,   COM2+19,   COM3+19,   COM2+20,   COM0+20,   COM1+20,   COM3+20
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//=======================================================================================//
//           character          0    1    2    3    4    5    6    7    8    9  Null
byte const Digit_Map[11]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0x01}; //Decimal

byte const Digit_Map_1[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00}; //no Decimal

//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
////=====================================================================================//

#define Segments 0x1E000F    // Initilize LCD SegmentX

//============================================================================//

#define INTS_PER_SECOND     76      // (20000000/(4*256*256))

int int_count=INTS_PER_SECOND;


int count5 = 0;// after decimal
int count_5 = 0;
int count4=0;   // 1st digit
int count_4=0;   // 1st digit
int count3=0;   // 2nd digit
int count_3=0; 
int count2=0;   // 3rd digit
int count_2=0;
long seconds=0;
long reading;
long reading1;
long reading2;


//============================================================================//

#int_rtcc               //This function is called
void clock_isr()
{                       //every time the RTCC (timer0)
                        //overflows (255->0)
                        //For this program this is apx
                        //31 times per second.

   if(--int_count==0)
   {
      seconds++;
      int_count=INTS_PER_SECOND;
   }
}
//============================================================================//
void Disp_num()
{
   if(reading < 10)
   {
      count_5=reading;
      count_2=11;
      count_3=11;
      count_4=11;
   }
   
   if(10<= reading < 100)
   {
     count_5=reading%10;
     count_4=reading/10;
     count_3=11;
     count_2=11;
   }
   
   if(100 <= reading <999)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=11;
   }
   if(1000 <= reading < 1024)
   {
     count_5=reading%10;
     count_4=reading%100/10;
     Count_3=reading%1000/100;
     count_2=reading%10000/1000;
   }
}
//=============================================================================//
void sec_disp()
{
   count4=count_4;
   count5=count_5;
   count2=count_2;
   count3=count_3;
   
}
//============================================================================//
void Display()
{
   lcd_symbol (Digit_Map_1[count5], DIGIT5);
   lcd_symbol (Digit_Map[count4], DIGIT4);
   lcd_symbol (Digit_Map_1[count3], DIGIT3);
   lcd_symbol (Digit_Map_1[count2], DIGIT2);
     
}
//============================================================================//
void Digit()
{
      if(seconds>=1)
      {
         SET_AN_CHANNEL (0); // selecting Channel A0;
         delay_us(5); // TACQ > 4.67 us as per data sheet
         reading1 = read_adc();       
         reading = reading1;
      }
      if(seconds>=2)
      {
        SET_AN_CHANNEL (4);
        delay_us(5);
        reading2 = read_adc();
        reading = reading1;
      }
      seconds=0;
}

void main()
{
   set_tris_a (0xe9); //set RA-0,3,5,6,7 as inputs
   set_tris_b (0xc0);
   set_tris_c (0x07);
   set_tris_e (0x08);
   setup_adc_ports(sAN0|sAN4,VSS_VREF);
   setup_adc (ADC_CLOCK_DIV_32); 
 
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   enable_interrupts (INT_RTCC);
   
   enable_interrupts(GLOBAL);
   
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
 
   count5 = 8;
   count4 = 8;
   count3 = 8;
   count2 = 8;
 
   Display ();
   
   delay_ms (1000);
 
     
   while (TRUE) 
   {
       
      digit();     
      Disp_num();
      sec_disp();
      display();
     
    }

   
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 12:11 pm     Reply with quote

The channel select code is totally wrong....

Replace it with this:
Code:

#byte ADCON0=getenv("SFR:ADCON0")
#define SET_AN_CHANNEL(x)   ADCON0=((ADCON0 & 0xC3)+(x<<3))


This fixes the selection and the Vref configuration.

Amazing it hasn't been spotted in ten years!...

I'm not in the lab at the moment, but will pull the old paper data sheet I have and see if this shows the selection as the code is doing, when I get in tomorrow.
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 12:33 pm     Reply with quote

Ttelmah,

this brings back the same problem of Vref+ referece selection & still reads the first channel only.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 31, 2017 12:48 pm     Reply with quote

Quote:
The channel select code is totally wrong....

Replace it with this:
Code:

#byte ADCON0=getenv("SFR:ADCON0")
#define SET_AN_CHANNEL(x) ADCON0=((ADCON0 & 0xC3)+(x<<3))

I don't see how you get that the channel (0 to 7) should be shifted left 3.
Look at page 180 (pg 182 in the Adobe reader) of the 16F914 datasheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41250F.pdf
It shows the ADCON0 register bit layout.
Quote:
REGISTER 12-1: ADCON0: A/D CONTROL REGISTER 0

To move the channel parameter into the CHSx bitfield, is should be
shifted left by 2 bit positions. Here is the layout:
Code:
  7    6     5    4    3    2      1     0
ADFM VCFG1 VCFG0 CHS2 CHS1 CHS0 GO/DONE ADON

Also, you see from the bit layout that 0xC3 is wrong as the mask.
It should be 0xE3. This mask will clear the CHSx bits only.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group