|
|
View previous topic :: View next topic |
Author |
Message |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
SPI Setup and Problems |
Posted: Sun Jan 16, 2005 12:55 pm |
|
|
Hello All,
First attempt with SPI and not having much good luck. Any help would be greatly appreciated. I have read as many of the relevent posts as I could find.
Compiler: 3.18
Part: 18F452
Standard Run Mode
Target Voltage: 5v
Osc Speed: 4MHz
PIC is master, slave is a magnetometer module.
http://www.pnicorp.com/supportProduct?nodeId=c4b10&tab=datasheets
Basic operation is described on page 9 and is included here:
MicroMag Host Processor Interface
Basic operation will follow these steps.
1 SSNOT is brought low.
2 Pulse RESET high (return to low state). You must RESET the MicroMag before every measurement.
3 Data is clocked in on the MOSI line. Once eight bits are read in, the MicroMag will execute the command.
4 The MicroMag will make the measurement. A measurement consists of forward biasing the sensor and making a period count; then reverse biasing the sensor and counting again; and finally, taking the difference between the two bias directions.
5 At the end of the measurement, the DRDY line is set to high indicating that the data is ready. In response to the next 16 SCLK pulses, data is shifted out on the MISO line. If you need to make another measurement, go to Step 2. You can send another command after the reset. In this case, keep SSNOT low. If you will not be using the MicroMag, set SSNOT to high
to disable the SPI port.
Here is my relevent code:
Code: | /*******************************
Part Specific Settings
*******************************/
#include <18F452.H>
#device ADC=8 // place A/D in 8 bit mode
#fuses HS,NOPROTECT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BRGH1oK,errors)
#byte portb = 0x0f81
#byte portd = 0x0f83
/*******************************
I/O Definitions
*******************************/
// port A not_used
// port B not_used
#define mm_reset PIN_C0
#define mm_drdy PIN_C1
#define mm_ssnot PIN_C2
// SCL PIN_C3
// SDA PIN_C4
// SDO PIN_C5
// RS232 TX PIN_C6
// RS232 RX PIN_C7
// port D not_used
#define debug_1_LED PIN_E0
#define debug_2_LED PIN_E1
// not_used PIN_E2
/*************************
MicroMag Support
*************************/
int1 mm_read_stat = 1;
signed int16 reading_hi = 0;
signed int16 reading_lo = 0;
signed int16 reading = 0;
/*************************
Prototypes
*************************/
/*************************
Includes
*************************/
#include <INPUT.C>
#include <STDLIB.H>
#include <STRING.H>
/*********************************************
MAIN
*********************************************/
void main() {
setup_wdt(wdt_off);
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 );
output_high(mm_ssnot);
output_low(mm_ssnot);
output_low(mm_reset);
output_float(mm_drdy);
/*********************************************
MAIN DO LOOP
*********************************************/
do {
//Regular events here
if (mm_read_stat) {
output_high(mm_reset);
delay_us(5);
output_low(mm_reset);
printf("\n\rReset MM\n\r");
spi_write(0b00000001);
mm_read_stat = 0;
}
if (input(mm_drdy)) {
reading_hi = spi_read(0x00);
reading_lo = spi_read(0x00);
printf("\n\r High Byte");
printf("\n\r %u", reading_hi);
printf("\n\r Low Byte");
printf("\n\r %u", reading_lo);
reading = ((reading_hi << 8) & reading_lo);
printf("\n\r Reading");
printf("\n\r %u", reading);
mm_read_stat = 1;
}
)
/*************** END MAIN LOOP **************/
while(TRUE);
}
|
MicroMag Peculiarities:
1MHz max clock
1Byte command (obviously, with SPI)
2Byte data return
Some of the specific questions I have are:
There isn't a "USE#" for SPI, am I missing some required code to get the SPI configured?
I believe I've got the clock polarity set correctly but can't be sure.
Am I handling the 2Bytes of returned data correctly? (Just SPI_READ() twice and put the bytes together?)
Thanks again for any help,
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 16, 2005 3:58 pm |
|
|
1. In your setup_spi() statement, you are specifying the rising edge.
But this function parameter is defined as the edge at which data
changes, not the edge that it's sampled on. If you look at the
MicroMag data sheet, you'll see that data changes on the falling edge.
So you need to change the parameter to be: SPI_H_TO_L
2. Your printf statement is only setup to display an 8-bit value.
You need to use "lu" or "lx" to display a value greater than
8-bits with CCS.
Change this it to this:
Code: | printf("\n\r %lu", reading); |
3. I'm not sure what you're doing with "mm_rdstat". After sending
the command, I would have put in a while() statement to wait for
DRDY to go high, before proceeding any farther. Something like this:
Code: | while(!input(mm_drdy)); |
In in a real program, I would also put in a timeout loop. After a
suitable period had passed, I would give up waiting for DRDY to
go high, and exit the routine with a "return" value of "FAILED",
or "FAILURE_TIMED_OUT".
4. Also, if I was writing a driver for this chip, I would make it with
functions. I'd make a driver file called "micromag.c" with all the
functions in it. I'd also have "micromag.h" file with the function
prototypes and #define statements for constants, etc.
Then you can #include these files in any future project.
I didn't examine everything in your program, so there may be other
problems that I didn't see. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Mon Jan 17, 2005 10:04 am |
|
|
PCM,
Thanks for the help. It's up and running.
Quote: | 3. I'm not sure what you're doing with "mm_rdstat". |
That was a status marker so that the main loop could continue while the MicroMag was taking the measurement. No need to hold up progress waiting for the reading?
I also canned the reassembly of the two bytes into a long. I'm only really interested in the delta of the last digit.
Thanks for the tips on modularization. Right now just slapping stuff together on a test board. My coding probably shows how new I am. Hopefully, I'll work up to elegant optimized code.
Thanks Again,
John |
|
|
|
|
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
|