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

Reading two channels of Adc

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bignick270



Joined: 11 Sep 2008
Posts: 44

View user's profile Send private message

Reading two channels of Adc
PostPosted: Wed Oct 08, 2008 1:24 pm     Reply with quote

I have read through the multiple post on problems with multiple adc readings.

I am having trouble reading my first channel of adc but my second channel is being read. I will include my code below. The comm works and that is not part of the question.

Basically the hardware for this has two 10 position rotary switches used for selecting addresses of the ones and tens digits. The output from the switches goes to a comparator and then it is passed onto the PIC16F877A. The ones digit switch goes into pin A2 and the tens digit goes to pin A3. The hardware is done right because there is complete source code written for this board in assembly. For testing I am transmitting the raw adc values to the computer and will eventually make a algorithm to turn it in the 0-9 address that is selectable from the switch. I get raw adc data for the 10s digit and for the hundreds digit but nothing for the 1s.

Code:

#include <16F877A.h>
#device adc=8

#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT                   
#use delay(clock=18432000)

    //This UART needs the errors statement or there are problems!
#use rs232(baud=38400, parity=E, xmit=PIN_C6, rcv=PIN_C7, bits=8, errors, stream=IN)
#use rs232(baud=38400, parity=E, xmit=PIN_C5, bits=8, FORCE_SW, stream=OUT)
   //added the FORCE_SW---^ this is software UART

#BYTE TXSTA=0x98          //tx status and control register -- hex add of location
#bit TXEN=TXSTA.5

#define UART_TX_OFF TXEN=FALSE      //disable C6 hardware UART pin
#define UART_TX_ON  TXEN=TRUE       //can turn C6 tx pin back to hardware UART

#define bitwiseop 0x7F     //0b01111111 -> used to strip the 1 from first byte of address
                                          // in order to get correct address

//=============================end SERIAL CONTROL OPERATIONS==============//

int8 i;            //index value used in RDA - declared here
int8 j;           //index value used in tx
int8 msg[3];         //global msg array for rx - only 3 bytes
int8 reply[4];    //sample canned reply array
int8 rxflag;     //when message is all received then will set flag var
int8 addr10s;
int8 addr1s;
int8 addr100s;
int8 myadd;
int8 temp;

#int_RDA
void  RDA_isr(void)
{
   if(kbhit(IN))
   {
      msg[i] = fgetc(IN); 
      i++;
   }
   rxflag++;     
}


////////////////////////delay function for transmit/////////////////////
//matches up to xxx's 5.35MS between rx and tx/
//used for testing, need to eliminate later as more code is added
void delay_full()
{
   delay_ms(5);
   delay_us(350);
}

void txsoft()
{
  // disable_interrupts(INT_RDA);   //may need later depending on timing, who knows
   OUTPUT_HIGH(PIN_B2);          //enable tx thru the RS485 chip
   delay_full();                   //delay the 5.35MS for initial testing
   for(j=0; j<4; j++)
   {
      fputc(reply[j], OUT);
      delay_us(490);
   }
   OUTPUT_LOW(PIN_B2);           //disable tx and re-enable rx
   //OUTPUT_LOW(PIN_B5);
   //enable_interrupts(INT_RDA);
}

void addressing()
{
   //addresses come from three sources
   //1)ones: come from comparator connected to a rotary switch - comes into A2
   //2)tens: come from comparator con to a rotary switch switch - comes into A3
   //3)hundreds: come from a dip switch to C1 -> 0 = 0, 1 = 100
   
   /*thoughts on reading dial positons
      10 selectable postions (0-9) thru adc.running 8 bit = 256 possible (0-255)
      256/10 = 25.6 incriments
      same but using 10bit adc   1024/10 = 102.4 incriments
   */
   set_adc_channel(3); //should get adc value from pin A2, 1s address
  // delay_us(20);
   addr1s = read_adc();
   delay_us(20);
   set_adc_channel(4); //should get adc value from pin A3, 10s address
   //delay_us(20);
   addr10s = read_adc();
   addr100s = input_state(PIN_C1);
   if(addr100s == 1)
   {
      addr100s = 100;
   }
   else
   {
      addr100s = 0;
   }
   //myadd = (addr100s + (addr10s*10) + addr1s);
}

void main()
{

   setup_adc_ports(ALL_ANALOG);       
   //according to device header comments. A4 is not included in the ALL_ANALOG
   //Includes: A0,A1,A2,A3,A5,E0,E1,E2, corresponds to asm file xsxxx.asm
   setup_adc(ADC_CLOCK_DIV_2);   //gives .4us per read, doubles as div doubles, internal gives 2-6 us
   setup_psp(PSP_DISABLED);         //disable while not needed
   setup_spi(SPI_SS_DISABLED);      //disable while not needed
   setup_ccp1(CCP_OFF);             //turn off while not needed
   setup_ccp2(CCP_OFF);             //same
   setup_comparator(NC_NC_NC_NC);   //off
   setup_vref(FALSE);               //off, need? dont know never used!
   enable_interrupts(INT_RDA);      //needed for receive
   enable_interrupts(GLOBAL);       //turn the bad boys on
   OUTPUT_LOW(PIN_C3);              //select signal for digital switch
   OUTPUT_LOW(PIN_B2);              //controls tx or rx function on rs485 chip
                                    //keep low initally for rx
   rxflag = 0;
   i = 0;
   ///fill with random data to send
   reply[0] = 0x00;
   reply[1] = 0x40;
   reply[2] = 0x5B;
   reply[3] = 0x25;
   
   while(1)
   {
      if(rxflag == 3)   //if we have rxed 3 bytes then proceed if not keep running
      {   
         rxflag = 0;   //reset rxflag
         i = 0;
         txsoft();     //run tx thru software UART using UART stream OUT
      }
      else
      {
         addressing();
         reply[1] = addr100s;
         reply[2] = addr10s;
         reply[3] = addr1s;
         //this will set the arrays with the raw uart data to be transmitted
      }
   }
}
bignick270



Joined: 11 Sep 2008
Posts: 44

View user's profile Send private message

PostPosted: Wed Oct 08, 2008 1:34 pm     Reply with quote

Forgive me for posting this but I think I just figured out what was wrong. I got up left for a few minutes and came back and as soon as i sat down I happened to look at the datasheet and laying next to me and saw the listing for the channels, I was one off.

So moderators you can go ahead and delete this post if you need to. This has been an issue for almost 2 days so you can understand why i was hasty to post the message.

Sorry guys.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 08, 2008 1:36 pm     Reply with quote

Quote:
#include <16F877A.h>
#device adc=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=18432000)

setup_adc(ADC_CLOCK_DIV_2);

The ADC divisor is incorrect.

Download the 16F877A data sheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf
Look at page 131 (page 133 in the Acrobat reader). Look at this table:
Quote:
TABLE 11-1: TAD vs. MAXIMUM DEVICE OPERATING FREQUENCIES

It shows that your selected divisor of "2" will only work properly with
a PIC oscillator frequency of 1.25 MHz maximum. So it's wrong for
your application. Look farther down the table. You can see that you
have to use a divisor of 32 for proper ADC operation.

Also, look in this part of the ADC section of the data sheet:
Quote:
11.1 A/D Acquisition Requirements

It says that when you change the ADC channel, you must allow enough
time for the internal Holding Capacitor to charge up. You have
commented out all the delays of 20 usec throughout your program.
Put those lines back in.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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