![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
greenfalsk
Joined: 12 May 2011 Posts: 2
|
ХЕN 1210 + PIC18F4550 |
Posted: Mon Oct 10, 2011 12:21 am |
|
|
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? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19366
|
|
Posted: Mon Oct 10, 2011 1:25 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 10, 2011 3:03 pm |
|
|
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:
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);
|
|
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|