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

ADC problem

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



Joined: 22 Apr 2012
Posts: 6

View user's profile Send private message

ADC problem
PostPosted: Fri Dec 07, 2012 2:37 am     Reply with quote

I wrote a code to get ADC every 4ms. I use 18f887 with 20MHz crystal. Everything works fine till i try to get some more samples while waiting for RF module. The buffer takes 2 or 3 more, problem is when ADC input's constant (every samples when TX Fifo hasn't locked is 185-186), 1 out of 3 samples is wrong (its value's 191, often the first one). I tried not use buffer but read and send to pc, it's still 190-191, read and discard first samples, there's still 1 "191" in one of three samples. I wonder what i did wrong? Embarassed
Here's the code, suspected code marks with slash:
Code:

#include "16f887.h"
#device ADC=8
#include "thu_vien_tx.h"
#FUSES  HS,NOWDT
#use FAST_IO(A)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

unsigned int16 TX_pointer = address_TX_normal_FIFO+HEADER_LENGHT+2;
unsigned int8 ADCvalue = 0;
int1 Fifo_lock = 0;
//buffer, dai 96 byte, su dung kieu circlebuffer
//khong tao ham doc, ghi buffer roi vi gioi han 9 ngan xep cua 887
unsigned int8 buffer_read_pointer = 0;
unsigned int8 buffer_write_pointer = 0;
unsigned int8 buffer_size=0;
unsigned int8 freeze_count = 0;
unsigned int8 transmitted = 0;

#int_TIMER1
void TIMER1_isr(void)
{
   set_timer1(63035);
   if (TX_pointer >address_TX_normal_FIFO_end)
      Fifo_lock = 1;
   if(Fifo_lock==0)
   {
      ADCvalue = read_adc();
      ghi_diachi_dai(TX_pointer, ADCvalue);
      TX_pointer++;
      printf("%u\n",ADCvalue);
   }
////////////////////////////////////////////////////////////////////
/////////////////////////////////////
   else if (buffer_size<96)
   {
      circle_buffer[buffer_write_pointer] = read_adc();
      printf("%u\n",circle_buffer[buffer_write_pointer]);
      buffer_size++;
      if (buffer_write_pointer==95)
         buffer_write_pointer = 0;
      else
         buffer_write_pointer++;
   }
///////////////////////////////////
////////////////////////////////////////////////////////////////////
   else
      freeze_count++;
}

void main()
{
  unsigned int8 temp1 = 0;

  CS_Direction = 0;
  RST_Direction  = 0;
  INT_Direction  = 1;
  WAKE_Direction = 0;
  Delay_ms(5);
  // SPI
  setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4); 
  //Zigbee

  mrf_start();
  pin_wake(); 
  cho_phep_LNA();
  cau_hinh_adc();

  setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
  enable_interrupts(INT_TIMER1); 

  unsigned int8 sequential_num=0;

  TX_pointer = ghi_header(sequential_num);
  TX_pointer += address_TX_normal_FIFO;
  set_timer1(63035);
  transmitted = 0;

  int i =0;

  for (i = 0;i<96;i++)
  circle_buffer[i]=0;
 
  enable_interrupts(GLOBAL);

  while(1)
  {
      if (Doc_int() == 0)
      {
         temp1 = doc_diachi_ngan(INTSTAT);
         Nhan_RX();
         disable_interrupts(INT_TIMER1);
         if (data_RX_FIFO[6]==1&&data_RX_FIFO[10]==0)
            if (data_RX_FIFO[12] == 1)
            if (TX_pointer >address_TX_normal_FIFO_middle)
            {
               Fifo_lock = 1;
               while (TX_pointer <address_TX_normal_FIFO_end)
                  ghi_diachi_dai(TX_pointer++, 0);
               truyen();     
               transmitted = 1;                       
            }
          set_timer1(63035);
          enable_interrupts(INT_TIMER1);
///////////////////////////////////////////////////////////////////
          delay_ms(10);         ///////////////buffer work around here.                                           
          if (transmitted ==1)
          {
             transmitted = 0;
             TX_pointer = ghi_header(++sequential_num);
             TX_pointer += address_TX_normal_FIFO;

             while ( buffer_size>0)
             {
                ghi_diachi_dai(TX_pointer,circle_buffer[buffer_read_pointer]);
                TX_pointer++;
                buffer_size--;
                if (buffer_read_pointer==95)
                   buffer_read_pointer = 0;
                else
                   buffer_read_pointer++;               
             }
             Fifo_lock = 0;
          }
            flush_RX();
      }
      if (freeze_count==250)
      { 
           disable_interrupts(INT_TIMER1);
           freeze_count = 0;
           TX_pointer = ghi_header(++sequential_num);
           TX_pointer += address_TX_normal_FIFO;
           transmitted = 0;       
           Fifo_lock = 0;
           buffer_size = 0;
           buffer_write_pointer = 0;
           buffer_read_pointer = 0;           
           set_timer1(63035);
           enable_interrupts(INT_TIMER1);
           read_adc();
           printf("dung\n");
      }
  }
}

void mrf_start()
{
           software_reset();
           Delay_us(300); 
           RF_reset();
           set_WAKE_from_pin();
           set_long_address(ADDRESS_long_kit_1);
           set_short_address(ADDRESS_short_kit_1);
           set_PAN_ID(PAN_ID);
           flush_RX();
           khoitao_nonbeacon();
           Delay_us(300);
           nonbeacon_PAN_coordinator_device();
           chon_muc_nangluong(20);
           set_frame_format_filter(1);
           set_reception_mode(1);
           //cho_phep_turbo_mode();
           //pin_wake(); 
           cho_phep_LNA();
}
Embarassed

Last edited by Tak on Fri Dec 07, 2012 3:48 am; edited 1 time in total
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Dec 07, 2012 2:51 am     Reply with quote

Reduce your code to the minimum which shows the problem.

It will then be a lot easier for either you, or us, to see what's going on.

Mike
Tak



Joined: 22 Apr 2012
Posts: 6

View user's profile Send private message

PostPosted: Fri Dec 07, 2012 3:13 am     Reply with quote

problem's inside timer isr. When Fifo_lock = 1, the read_adc() got a little higher value (191 and normal it's 185). before that i disable and re-enable timer interrupt.
Code:

////////////////////////////////////////////////////////////////////
/////////////////////////////////////
   else if (buffer_size<96)
   {
      circle_buffer[buffer_write_pointer] = read_adc();
      printf("%u\n",circle_buffer[buffer_write_pointer]);
      buffer_size++;
      if (buffer_write_pointer==95)
         buffer_write_pointer = 0;
      else
         buffer_write_pointer++;
   }
///////////////////////////////////
////////////////////////////////////////////////////////////////////
temtronic



Joined: 01 Jul 2010
Posts: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Dec 07, 2012 8:40 am     Reply with quote

couple of comments
1) always add 'errors' to the USE RS232(...) options when using the hardware UART for serial communications.It'll keep the UART from 'locking up' due to errors like overrun...

2) Putting printf() functions inside any ISR is NOT a good idea! ISRs must be short and fast.

Take a look at the ex_sisr.c example that CCS supplies.Several 'hints' in it tto help you along.

3) re:ADC. Be sure your power supply is rock stable! ANY minor 'ripple','glitch',etc. in VDD will result in an ADC 'misreading' as Vref is the Vdd.Having a separate Vref will eliminate the problem,but at a small cost in parts and layout.Also be sure to use bypass caps! Again, a 'glitch'(a current rush,say when displaying data on the LCD) can cause what appears as a bad ADC reading

hth
jay
Tak



Joined: 22 Apr 2012
Posts: 6

View user's profile Send private message

PostPosted: Fri Dec 07, 2012 6:40 pm     Reply with quote

That's right. I used 5V source from FT232RL. Normally it's good but when mrf24j40MB module transmits, a large current sinks. ADC got after 10 or maybe 15ms will be unstable 'cause RF will restransmit if ack was not received. When I changed power supply to 500mA source with regulator, it worked. Razz
printf's only for reliable test Confused....
Thank you very much, Temtronic
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