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 CCS Technical Support

getting angular position with pic18f2550 and AS5045

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



Joined: 18 Jun 2010
Posts: 5

View user's profile Send private message

getting angular position with pic18f2550 and AS5045
PostPosted: Mon Jun 21, 2010 3:08 am     Reply with quote

Hello everyone,
I tried to get the value of this encoder
http://www.austriamicrosystems.com/eng/Products/Magnetic-Encoders/Rotary-Encoders/AS5045
So I tried to use the SPI(they call ssi in their dataSheet)interface to get the value but unfortunately I think that my program is wrong....
I use this program during the interuption of the timer but my device does not detect any SPI data in the buffer.
I need to be precise in the angle position in order to control my motor...
Thank you :D
my interruption program is that one :
Code:

#INT_TIMER2 
void timer2_isr() // interruption lorsque le Timer2 reboucle
{
   timer++;
   
   set_adc_channel(0);
   // pour éviter d'avoir affaire à des interruption lors de la rotation des moteurs
/*   switch(startADC){
      case 0:
         read_adc(ADC_START_ONLY);
         startADC = 1;
         break;
      case 1:
         angleRec = (int32)read_adc(ADC_READ_ONLY);
         angleRec = (int32)((angleRec*360)/1024);
         printf("angleRec : %Lu\n",angleRec);
         startADC = 0;         
         break;
   }// switch case*/
   
   switch(CSnH){
      case 0:
         output_high(PIN_A2);
         if (spi_data_is_in()){
            angleRec = (int32)spi_read();
            printf("j 'ai détecté des données");
         }
         printf("%Lu \n",angleRec);
         CSnH = 1;
         break;
      case 1:
         output_low(PIN_A2);
         //delay_us(1);
         CSnH =0;
         break;      
   }
}

void main(void){
//   setup_adc_ports(AN0_TO_AN3|VSS_VDD);  //Utilisation des entrées analogique AN0 - tension de 0 à Vdd 
//   setup_adc(ADC_CLOCK_INTERNAL);       //Utilisation de l'horloge interne pour le conversion en analogique
   
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_T2);

   setup_wdt(WDT_OFF);

   setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
   setup_timer_2(T2_DIV_BY_16, 124, 1); // 124 = 2Khz
   setup_timer_3(T3_INTERNAL|T3_DIV_BY_4);

   setup_ccp1(CCP_COMPARE_INT_AND_TOGGLE);
   setup_ccp2(CCP_COMPARE_INT_AND_TOGGLE|CCP_USE_TIMER3);

   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_CCP1);
   enable_interrupts(INT_CCP2);
   if (MotorID !=0){
      enable_interrupts(INT_RDA);
   }
   enable_interrupts(GLOBAL);
   

   //setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);

   //configuration des ports en entrées/sorties - par défaut, les configurer en entrées
   //set_tris_a(0b00001111);//port A en entrées ('1' = IN, '0' = OUT)
   //set_tris_b(0b00000000);//Pin B4 et B5 en sorties, les autres en entrées
   //set_tris_c(0b00000000);//Pin B4 et B5 en sorties, les autres en entrées
   
   set_tris_a(0b000001);//port A en entrées ('1' = IN, '0' = OUT)
   if (MotorID !=0)
      set_tris_b(0b00000001);//Pin B4 et B5 en sorties, les autres en entrées
      
   //set_tris_b(0b11111111); ::ca c'est moi
   set_tris_c(0b00000000);//Pin B4 et B5 en sorties, les autres en entrées
while(1){

}
}


I used the output PWM of the AS5045 but it is horrible because we do not have a good precision.....
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 4:34 am     Reply with quote

'spi data', is never going to be 'in' with your code.
In SPI, one device is the 'master', and _has to generate the clock for every transaction_.
You are the master.
To read bytes from the device, _you_ need to generate clocks to get the data. Your SPI code, is based upon that for a 'slave' device, where the other device is generating the clocks, so 'spi data' can arrive at the chip hardware. With a slave device attached, this will never happen.

I hope you have the 5040, not the 5045.
You need to get rid of the test for date being in, and tell the hardware to generate the clocks (spi_read(0)). You need to clock _two_ bytes in, not the one you show. The unit returns 16 bit data, and six bits of this will need to be masked off, to read the angle. The 5045, will be much harder to handle, requiring 18 clocks, which the PIC hardware will not directly support. Most chips will accept 'extra' clocks, and restart the transaction when CS is operated, to deal with this, but this is not specified in the data for this chip. The chip needs the clock to idle high, and the data to be read on the falling edge of the clock. This corresponds to CKE=1, CKP=1. SPI_H_TO_L, not L_TO_H.

What is operating the chip select on the encoder?.
You don't tell us your clock rate, so we can't tell if the SPI speed setting is acceptable.
What PIC?.

Best Wishes
dronix



Joined: 18 Jun 2010
Posts: 5

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 5:25 am     Reply with quote

Thank you for your reply,
I'm using the pic18f2550 chip, and the clock rate is of 20MHz.
I have connected the PIN_B1 of the chip which correspond to the clock, and I thought that it is generated when i use the setup_spi()(but I'm wrong).
I have a problem the SDO is not connected to my chip :s.
I think it would be a problem because you wrote that
Quote:
generate the clocks (spi_read(0))

Unfortunately, I have to use the clock of the my microcontroller....
I do not really ynderstand what you mean about CKE =1 and CKP =1, Is it a what I must write on the chip? or what I have to write on my pic?
(Sorry but English is not my mother tongue).
Thank you
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 5:41 am     Reply with quote

Quote:
Unfortunately, I have to use the clock of the my microcontroller....
I do not really ynderstand what you mean about CKE =1 and CKP =1, Is it a what I must write on the chip? or what I have to write on my pic?

You need to set up the PIC as a master. The master provides the clock for the SPI transaction. CKE and CKP are to configure the edge and polarity of the clock that the master generates. This configuration must match what the slave expects.
_________________
The search for better is endless. Instead simply find very good and get the job done.
dronix



Joined: 18 Jun 2010
Posts: 5

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 6:01 am     Reply with quote

When You said that I have to set the pic as a master ... I have to set it like that
Code:
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_4|SPI_SS_DISABLED);

Or is there another method ?
I tired to set the CKE and the CKP directly in this function ... But it does not work :s
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 7:03 am     Reply with quote

You SPI setup is better. You have now have setup the PIC to create clocks, but they will only actually be _generated_ when you clock a byte out.

You don't have to worry about DO. The point about SPI, is it generates a simultaneous transfer in both directions at the same time, and it is the act of the master 'sending' a byte, that receives the byte from the slave. You can just leave the PIC DO line disconnected, if the slave does not want this date.

You must connect to the angular sensor CS line, since it is this that actually performs an angular reading.
The sequence needed is:

Raise the CS line.
wait 500nSec
Lower the CS line - this has now triggered a reading
wait another 500nSec
Now read a byte _with clocks_ - spi_read(0)
read next byte - again with clocks

For the 5040, this is 'it'. You now need to assemble the two bytes into a 16bit word, and rotate it right five times to get rid of the status information at the end.
For the 5045, you would have to try clocking in a third byte, and see what the chip does about this. Hopefully you will just get 6 bits of garbage that can be ignored.

You need to lower the SPI clock frequency. The encoder chips support a maximum SPI clock of 1Mhz. You are currently sending 5Mhz (20/4...).
Unfortunately the standard dividers available to you, with a 20MHz master clock, give 5MHz, 1.25MHz, and 312.5KHz. The later is the only 'legal' value, but is rather slow. Since you are already using Timer2, this is the only value you can use.

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