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 with SPI and Interrupt

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







ADC problem with SPI and Interrupt
PostPosted: Thu Nov 27, 2008 1:57 am     Reply with quote

HI~

I am a new C language user and work with CCS compiler.
I have an project that use Timer1 of PIC18F4620 and can't use ADC.

Here is my question:
I try to put the SPI code(from KamPutty) of Accelerometer(LIS3LV02DQ) and the ADC code of Gyro(ADXRS300) together in the same
interruption. but somehow my code can't be edited by CCS.When I only put the ADC code, the program can work very well
in the interruption. As long as I put the SPI code into it and some function, suddenly can't work anymore!
Please help me to solve my program's problem.

Code:
#include <18F4620.H> // <18F452.H>  <16F877.H> // device header file from CCS-C
//#include "KamPutty.c"
#include <stdlib.h>         // for function atoi(), atol(), atof(), etc.

#device ADC=10                   // choose 10 bit AD instead of 8

#define CLOCK_FREQUENCY 10000000

#use     delay (clock= CLOCK_FREQUENCY)    // 10 MHz crystal oscillator

#use     rs232 (baud = 28500, xmit= PIN_C6, rcv= PIN_C7, errors)

#define  ccp2_period  2000          // CCP2_compare_match_interrupt_period
                                    // Sampleing Time according to ccp2_period
int16    dt= 1/10 * 2 * ccp2_period;// dt = 1/10 * 2 * ccp2_period
int16    time_tick  = 0;            // system clock
int16    time_sec   = 0;            // time_tick = 10^6 / (1/10 * 2 * ccp2_period)

int16    ad_data;

#ifdef   __PCM__                    // PIC16Fxxx
#bit     A4       = 0x05.4          // Port_A, pin #5, for CCS-C only
#bit     TRISA4   = 0x85.4
#define  PORTD    *(int8 *)(0x08)
#define  TRISD    *(int8 *)(0x88)
#else                               // PIC18Fxxx
#bit     A4       = 0xF80.4
#bit     TRISA4   = 0xF92.4
#define  PORTD    *(int8 *)(0xF83)
#define  TRISD    *(int8 *)(0xF95)
#endif

// api
#define WHO_AM_I    0x0f
#define OFFSET_X    0x16
#define OFFSET_Y    0x17
#define OFFSET_Z    0x18
#define GAIN_X      0x19
#define GAIN_Y      0x1a
#define GAIN_Z      0x1b
#define CTRL_REG1   0x20
#define CTRL_REG2   0x21
#define CTRL_REG3   0x22
#define HP_FILTER_RESET 0x23
#define STATUS_REG  0x27
#define OUTX_L      0x28
#define OUTX_H      0x29
#define OUTY_L      0x2a
#define OUTY_H      0x2b
#define OUTZ_L      0x2c
#define OUTZ_H      0x2d
#define FF_WU_CFG   0x30
#define FF_WU_SRC   0x31
#define FF_WU_ACK   0x32
#define FF_WU_THS_L 0x34
#define FF_WU_THS_H 0x35
#define FF_WU_DURATION  0x36
#define DD_CFG  0x38
#define DD_SRC  0x39
#define DD_ACK  0x3a
#define DD_THSI_L   0x3c
#define DD_THSI_H   0x3d
#define DD_THSE_L   0x3e
#define DD_THSE_H   0x3f

// pin defines
#define SDO         PIN_B0      // data out
#define SDI         PIN_B1      // data in
#define SPC         PIN_B2      // clock, high when CS=HIGH
#define CS          PIN_B3      // low=enabled

/*-------------Function Zone---------------------------------------*/


int8 const bitMask8[]={
    0b10000000,
    0b01000000,
    0b00100000,
    0b00010000,
    0b00001000,
    0b00000100,
    0b00000010,
    0b00000001
};


void write_8bit_serial_data(unsigned int8 data)
void write_16bit_serial_data(unsigned int8 reg, unsigned int8 data)
unsigned int8 read_8bit_serial_data(unsigned int8 data)
void  my_delay_us ( int16 n );   // roughly delay n usec using delay loop
int16 analog(int8 ch, int8 S_H_delay)  // read analog input channel 'ch'

/*-----------------------Veriable Setting Zone---------------------*/
float yout=0,xin,x1=0,x2=0,x3=0,x4=0,x5=0;  //濾波器用的變數
float a0=0.4 ,a1=0.25 ,a2=0.15 ,a3=0.1,aa4=0.07 ,a5=0.03 ;  //濾波器參數設定

int16 yaw_rate_gyro, yaw_degree_gyro ;
int16 yaw_rate_acc , yaw_degree_acc  ;

int16 X,Y,Z ;
int16 x_acc, y_acc, z_acc ;


/*-------------------------------------------------------------------*/


#INT_CCP2                           // Capture/Compare ISR
void system_clock_CCP2_ISR()
{

   A4 = 1;                          // get a scope to see this signal

   CCP_2 += ccp2_period;            // setup critirion for next CCP2_ISR
                                    // CCP_2 is defined in 16F877.H


   if ( ++time_tick > 1000000/dt ) { time_tick = 0; ++time_sec; };   //  Counting for interrupt

/*-------------------Gyro Data Acquire and  Digital Filtering------------*/
   
    ad_data  = read_adc ( ADC_READ_ONLY );
   

    xin=ad_data;                                        //數位濾波器
    yout = a0*xin+a1*x1+a2*x2+a3*x3+aa4*x4+a5*x5;

    x5=x4;   //參數代換
    x4=x3;
    x3=x2;
    x2=x1;
    x1=xin;
                                                       //5mV  °/s
    yaw_rate_gyro=yout-524;   //  ( x-524 )/1024 * 5V / 0.005 (V /°/s )   出來是角速度 °/s
    //yaw_rate_gyro=(yout-524)/1024*5/0.005;
    yaw_degree_gyro = yaw_rate_gyro*dt; // unit  (度)
                 //---radius_of_turning_center
/*-----------------------End--------------------------------------------*/

              /*------------Accelerometer Data Acquire -------*/

        X=read_8bit_serial_data(0x29);
        X<<=8;
        X+=read_8bit_serial_data(0x28);
        X=~X;

        Y=read_8bit_serial_data(0x2b);
        Y<<=8;
        Y+=read_8bit_serial_data(0x2a);
        Y=~Y;

        Z=read_8bit_serial_data(0x2d);
        Z<<=8;
        Z+=read_8bit_serial_data(0x2c);
        Z=~Z;
                                                //需要delay 一下嗎

        x_acc=X/1671.8;
        y_acc=Y/1671.8;     //+-2G設定    可改成+-6G
        z_acc=Z/1671.8;     //16位元 65536~   X/16384 * 1g *9.8 m /s^2=X/1671.8

 
   //PORTD    = ad_data >> 2;         // 會有一個取樣週期的延遲

   read_adc ( ADC_START_ONLY );

   e_previous = e;

   A4 = 0;

}

void main()
{
   printf("\n\n\r\n PIC 中斷時鐘 與 ADC 測試,取樣頻率 =  Hz ");

   printf("\r\n\n 請將信號產生器接到 RA0 ");

   printf("\r\n\n 請按鍵盤起動時鐘開始測試 ... 再按任意鍵就暫停列印 ... ");

   printf("\r\n\n 暫停列印時,PIC 時鐘、AD 轉換及 ...");

   getc();

   // ----- Initialization --------------------------------------------------

   // powerup device Acc
    write_16bit_serial_data(0x20, 0b11000111); //原始設定是+-2G
    write_16bit_serial_data(0x21, 0b00000001);


   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_2 );

   setup_ccp2 ( CCP_COMPARE_INT );  // configure CCP2 in COMPARE mode and ...
                                    // CCP2 Interrupt on compare match

   enable_interrupts ( INT_CCP2 );
   enable_interrupts ( GLOBAL   );

   set_timer1(0);CCP_2=ccp2_period; // start the CCP2_ISR at 1 msec later

   //setup_adc_ports ( ANALOG_AN0 );  // RA0 as analog input
   setup_adc_ports(AN0_TO_AN1|VSS_VDD);
   
   setup_adc ( ADC_CLOCK_DIV_32 );  // 32 * T_osc = 1.6 us per bit at 20 MHz

   set_adc_channel ( 0 );           // select RA0 as analog input channel


   TRISA4 = 0;                      // port A, RA4 for digital output

   TRISD  = 0;                      // 請將 8-bit DAC 接到 PORTD

   output_high ( PIN_C2 );

   // ----- Initialization --- finished -------------------------------------

   while ( 1 )
   {
      while ( !kbhit() )            // press any key to get out
      {
         delay_ms ( 200 );          // wait 200 msec

        printf("\r\n T= %lu.%04lu sec, AN0= %lu, yout=%d ", time_sec, time_tick, ad_data, yout );
         //printf("\r\n T= %lu.%04lu sec, AN0= %lu ", time_sec, time_tick, ad_data);

      }; getc();                    // remove keyboard input

      printf("\n\n\r PIC_Time = %lu.%04lu sec", time_sec, time_tick);

      printf(" ... press any key ... "); getc();   // wait until key pressed
   }
}
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Nov 27, 2008 3:31 am     Reply with quote

Your performing a lot of time consuming operations in your ISR, float arithmetic is the worst of all. Try to move all calculations to the main level or use integer multiply instead of float.
Monk9514524
Guest







PostPosted: Thu Nov 27, 2008 5:07 am     Reply with quote

Sorry~ I forget to mention that CCS can't edit~ i can;t even put my code into PIC~
Monk9514524
Guest







PostPosted: Thu Nov 27, 2008 5:13 am     Reply with quote

and always stop at #device ADC=10~
Ttelmah
Guest







PostPosted: Thu Nov 27, 2008 5:49 am     Reply with quote

In which case, simplify your code, to see what is wrong.
In the first few lines:
No fuses. You need to specify the oscillator type (HS, and some 'basic' things - NOLVP, NOXINST), before the chip can run.
The configuration (fuses, and clock settings), _must_ be in front of every include, except for the processor definition.
Learn to use the code buttons.
Code:

     #include <18F4620.H> // device header file from CCS-C
     #fuses HS,NOWDT,NOLVP,NOXINST
     #device ADC=10 // choose 10 bit AD instead of 8
     #define CLOCK_FREQUENCY 10000000
     #use delay (clock= CLOCK_FREQUENCY) // 10 MHz crystal oscillator

     #use rs232 (baud = 28500, xmit= PIN_C6, rcv= PIN_C7, errors)
     //End of definitions, _now_ include other stuff
     //#include "KamPutty.c"
     #include <stdlib.h> // for function atoi(), atol(), atof(), etc.
etc..

Start simpler. Just a single function, toggling a pin, to prove you are programming and running the chip, _first_.

You are setting the CCP, to interrupt every 4000 machine instructions. Even a single float multiplication, takes typically over 500 instructions. Once you get the chip working, FvM, is 'spot on'.

Note that you don't want to set the counter forward in the ISR. Using the CCP, when the special even trigger fires, it automatically resets the CCP.
You don't want to enable the CCP interrupt, but the INT_AD interrupt.
When the special even fires, it resets the CCP counter, and _starts_ the ADC automatically. You need to interrupt, when the ADC finishes.

Best Wishes
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