Tarkoituksena liittää SCA3100 kiihtyvyysanturi EM430F6137RF900 kehitysalustaan SPI-väylää hyväksi käyttäen ja tehdä myös ohjelma anturin lukemista varten.
h4. SCA3100-D04 kiihtyvyysanturi:
- mittausakseleita 3 (x,y ja z)
- mittausalue \+-2g
- mittaustarkuus \+-30mg
- lämpötilan mittausalue \-40...+125 C
- SPI väylä
- [Liitännät|koneautomaatio:SCA3100 liitännät]
- [Datasheet|^sca8x0_21x0_3100_product_family_specification_82_694_00c_0.pdf]
!SCA3100-D04 PCB.JPG|border=1,width=176,height=176!
h4. Ohjelma:
CCS4:lla tehdyllä ohjelmalla voidaan lukea SCA3100 anturin kaikki 3 akselia. Laiteiston puuttellisuuden vuoksi akselien arvojen tarkkailu ei tällä hetkellä onnistu realiaikaisesti, esim. tulostaminen suoraan sarjaväylälle. Akselien arvoja voidaan myös tarkkailla CCS4:n sisällä, mutta tällöinkin vain pysäyttämällä ohjelma ([ohjeet|koneautomaatio:CCS4 arvojen lukeminen] ).
h4. Koodi:
{code}
/***************************************************************************
* EM430F6137 Demo USCI_A0 SPI Interface to SCA3100 Accelerometer
*
* Uses TI EM430F6137 Development Tool
*
* Reads all 3 (x,y,z) axes
*/
#define XTAL 16000000L
#define TICKSPERMS (XTAL / 1000 / 5 - 1)
#define TICKSPERUS (TICKSPERMS / 1000)
#define SPICLOCK 500 // SPI clock = 500kHz
#define SPIFRAMEDELAY ((1000 / SPICLOCK) * 6) // SPI interframe delay [us] = 6 * Tsck
#define SPICSBDELAY ((1000 / SPICLOCK) / 2) // SCK -> CSB delay [us] = 0.5 * Tsck
// LIBRARIES
#include "cc430x613x.h"
#include "math.h"
// PORT DEFINITIONS
#define PORT_CSB_OUT P2OUT
#define PORT_CSB_DIR P2DIR
#define TX_BUFFER UCA0TXBUF
#define RX_BUFFER UCA0RXBUF
// PIN DEFINITIONS
#define PIN_CSB BIT7
//AXIS REG
#define X_LSB 0x04
#define X_MSB 0x05
#define Y_LSB 0x06
#define Y_MSB 0x07
#define Z_LSB 0x08
#define Z_MSB 0x09
// FUNCTION PROTOTYPES
unsigned char ReadRegister(unsigned char Address);
unsigned short realValues(unsigned short values);
void wait_ms(unsigned short ms);
void wait_us(unsigned short us);
unsigned short x_msb;
unsigned short x_lsb;
short x_value;
unsigned short y_msb;
unsigned short y_lsb;
short y_value;
unsigned short z_msb;
unsigned short z_lsb;
short z_value;
void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P1MAP6 = PM_UCA0SIMO; // Map UCA0SIMO output to P1.6
P1MAP5 = PM_UCA0SOMI; // Map UCA0SOMI output to P1.5
P1MAP7 = PM_UCA0CLK; // Map UCA0CLK output to P1.7
PMAPPWD = 0; // Lock port mapping registers
PORT_CSB_DIR |= PIN_CSB;
PORT_CSB_OUT |= PIN_CSB; // Unselect gyro sensor
P1DIR |= BIT5 + BIT6 + BIT7; // ACLK, MCLK, SMCLK set out to pins
P1SEL |= BIT5 + BIT6 + BIT7; // P1.5,6,7 for debugging purposes.
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL0 |= UCMST+UCSYNC+UCCKPH+UCMSB; // 3-pin, 8-bit SPI master
// Clock polarity high, MSB
UCA0CTL1 |= UCSSEL0; // SMCLK
UCA0BR0 = 0x02; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
while(1)
{
x_lsb = ReadRegister(X_LSB);
x_msb = ReadRegister(X_MSB);
x_value = (x_msb<<8) | x_lsb;
x_value = realValues(x_value);
y_lsb = ReadRegister(Y_LSB);
y_msb = ReadRegister(Y_MSB);
y_value = (y_msb<<8) | y_lsb;
y_value=realValues(y_value);
z_lsb = ReadRegister(Z_LSB);
z_msb = ReadRegister(Z_MSB);
z_value = (z_msb<<8) | z_lsb;
z_value=realValues(z_value);
wait_ms(10);
}
}
// Read a byte from the gyro sensor
unsigned char ReadRegister(unsigned char Address)
{
unsigned char Result;
Address <<= 2; // Address to be shifted left by 2 and RW bit to be reset
PORT_CSB_OUT &= ~PIN_CSB; // Select gyro sensor
Result = RX_BUFFER; // Read RX buffer just to clear interrupt flag
TX_BUFFER = Address; // Write address to TX buffer
while (!(UCA0IFG&UCRXIFG)); // Wait until new data was written into RX buffer
Result = RX_BUFFER; // Read RX buffer just to clear interrupt flag
TX_BUFFER = 0; // Write dummy data to TX buffer
while (!(UCA0IFG&UCRXIFG)); // Wait until new data was written into RX buffer
Result = RX_BUFFER; // Read RX buffer
wait_us(SPICSBDELAY); // Delay to satisfy 1/2 clk period delay from
// falling edge of clk to CSB
PORT_CSB_OUT |= PIN_CSB; // Deselect gyro sensor
wait_us(SPIFRAMEDELAY); // Delay to satisfy 6x clk period for CS high state
return Result; // Return new data from RX buffer
}
void wait_ms(unsigned short ms)
{
unsigned short a, b;
for (a = ms; a > 0; a--) // outer loop takes 5 ck per round
for (b = TICKSPERMS; b > 0; b--) // inner loop takes 5 ck per round
asm(" nop");
}
// wait us
void wait_us(unsigned short us)
{
unsigned short a;
us *= TICKSPERUS;
for (a = us; a > 0; a--) // loop takes 5 ck per round
asm(" nop");
}
unsigned int shift(unsigned short thisData, int thisBit)
{
unsigned short data;
data=thisData>>(thisBit-1);
data=data&0x01;
return data;
}
unsigned short realValues(unsigned short values)
{
short table[14];
int i;
int bitti=3;
unsigned short rdy;
for(i=0;i<14;i++)
{
table[i]= shift(values,bitti);
bitti++;
}
rdy=(10/9)*(-table[13]*pow(2,13)+table[12]*pow(2,12)+table[11]*pow(2,11)+table[10]*pow(2,10)+table[9]*pow(2,9)+table[8]*pow(2,8)+table[7]*pow(2,7)+table[6]*pow(2,6)+table[5]*pow(2,5)+table[4]*pow(2,4)+table[3]*pow(2,3)+table[2]*pow(2,2)+table[1]*2+table[0]);
return rdy;
}
{code} |