  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			Monk9514524 Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| ADC problem with SPI and Interrupt | 
			 
			
				 Posted: Thu Nov 27, 2008 1:57 am     | 
				     | 
			 
			
				
  | 
			 
			
				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 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Nov 27, 2008 3:31 am     | 
				     | 
			 
			
				
  | 
			 
			
				| 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
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Nov 27, 2008 5:07 am     | 
				     | 
			 
			
				
  | 
			 
			
				| Sorry~  I forget to  mention that CCS can't edit~ i can;t even put my code into PIC~ | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Monk9514524 Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Nov 27, 2008 5:13 am     | 
				     | 
			 
			
				
  | 
			 
			
				| and always stop at #device ADC=10~ | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Ttelmah Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu Nov 27, 2008 5:49 am     | 
				     | 
			 
			
				
  | 
			 
			
				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 | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  
		 |