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

ХЕN 1210 + PIC18F4550

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



Joined: 12 May 2011
Posts: 2

View user's profile Send private message

ХЕN 1210 + PIC18F4550
PostPosted: Mon Oct 10, 2011 12:21 am     Reply with quote

I have a magnetometer ХЕN 1210 linked in SPI to a pic18F4550(master). Datasheet is here: http://www.xensor.nl/pdffiles/sheets/xen1210.pdf
Source Code:
Code:
#include <18F4550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use spi(MODE=1)

#define USB_HID_DEVICE  TRUE
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE    64 
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT
#define USB_EP1_RX_SIZE    64

#include <pic18_usb.h> 
#include <desc.h>     
#include <usb.c>         

void Init_XEN (void)
{
    // POWER-OFF COMMAND
    output_bit(PIN_B5,1); // CS
    delay_us(50);
    spi_write(0x40);
    spi_write(0x00);
    spi_write(0x00);
    delay_us(50);
    output_bit(PIN_B5,0); // CS

    // RESET COMMAND
    output_bit(PIN_B5,1); // CS
    delay_us(50);
    spi_write(0x10);
    spi_write(0x00);
    spi_write(0x00);
    delay_us(50);
    output_bit(PIN_B5,0); // CS

    // TIME COMMAND
    output_bit(PIN_B5,1); // CS
    delay_us(50);
    spi_write(0x01);
    spi_write(0x41);
    spi_write(0x13);
    delay_us(50);
    output_bit(PIN_B5,0); // CS

    // TEST COMMAND
    output_bit(PIN_B5,1); // CS
    delay_us(50);
    spi_write(0x02);
    spi_write(0x3A);
    spi_write(0x00);
    delay_us(50);
    output_bit(PIN_B5,0); // CS
}


void main() {
   int8 in_data[64];
   int8 out_data[64];
   int16 mm1,mm2;

   SETUP_ADC_PORTS(AN0);
   SETUP_ADC(ADC_CLOCK_DIV_64);
   SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_1);
   SETUP_TIMER_1(T1_DISABLED);
   SETUP_TIMER_2(T2_DIV_BY_1, 10, 1); 
   SETUP_TIMER_3(T3_INTERNAL | T3_DIV_BY_8);
   SETUP_CCP1(CCP_PWM);
   set_pwm1_duty(5);
   SETUP_CCP2(CCP_OFF);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   SETUP_SPI(SPI_MASTER | SPI_CLK_DIV_4|SPI_XMIT_L_TO_H);

   
   usb_init();

   Init_XEN();
   
   while (TRUE) {
      usb_task();

      if (usb_enumerated()) {

         if (usb_kbhit(1)) {
             usb_get_packet(1, in_data, 64);

             // Подаем команду Single Shot
            output_bit(PIN_B5,1); // CS
            delay_us(50);
            spi_write(0x60);
            spi_write(0x00);
            spi_write(0x00);
            delay_us(50);
            output_bit(PIN_B5,0); // CS

            delay_ms(100);

            output_bit(PIN_B5,1); // CS
            delay_us(50);
            out_data[0] = spi_read();
            out_data[1] = spi_read();
            out_data[2] = spi_read();
            delay_us(50);
            output_bit(PIN_B5,0); // CS

             usb_put_packet(1, out_data, 64, USB_DTS_TOGGLE);

         }
      }
   }
}


On the oscilloscope can be seen that the initialization fails, and ACC_Data[0]..[2] values always 255.
Does anyone know how to solve this problem?
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 1:25 am     Reply with quote

Er. Obvious thing #1, look at what levels you have on CS. This is a _low_ chip select. Set it high at the start of your code, and low to select the chip.

Then second thing, have a small delay between deselecting the chip, and reselecting it. Note 'Tbuf' in figure 4 of the data sheet. About 5uSec required.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 10, 2011 3:03 pm     Reply with quote

And this is a bug:
Quote:

output_bit(PIN_B5,1); // CS
delay_us(50);
out_data[0] = spi_read();
out_data[1] = spi_read();
out_data[2] = spi_read();
delay_us(50);
output_bit(PIN_B5,0); // CS


In CCS, the spi_read() function will only generate SCLK if it's given
a parameter. For most applications this is 0. So change all the bold
items above to this:
Code:

spi_read(0);

Now you will actually be able to read something back from the SPI slave.


One final comment. This type of line is not the best:
Quote:

output_bit(PIN_B5,0); // CS

A cleaner way to do it is to put a #define statement above main()
which tells the compiler what pin is used for Chip Select:
Code:

#define XEN1210_CS  PIN_B5

void main()
{



}

Then in your code to access the SPI slave chip, simply set the CS line
low and then high. With this method, you can change the CS pin easily
with one little edit above main(), if you desire to do so. With your method
it requires laborious edits within the program. Also the code shown below
is basically self-documenting. You don't even need a comment.
Code:

output_low(XEN1210_CS);
data[0] = spi_read(0);
.
.

output_high(XEN1210_CS);
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