SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By fgk
#38528
Here are two short pieces of code I wrote to test two Sparkfun sensors - the LIS3LV030Z serial accelerometer and the MicroMag3 Magnetometer. These were compiled in AVR Studio 4 using avr-gcc. I used an ATMega16 chip and a serial LCD to output the values, but this can be changed easily enough.
Code: Select all
/*
	Accelerometer.c - Communicate with LIS3LV030Z serial accelerometer
	Written by Frank Kienast in November, 2007

	Target is ATMega16 with 12MHz xtal clock.
	Sparkfun Serial LCD (9600 baud) connected to TX.

*/

#define F_CPU 12000000 
#define BAUD 9600
#define UBRR (((F_CPU / (BAUD * 16UL))) - 1)
#define DDR_SPI DDRB
#define PORT_SPI PORTB
#define DD_MOSI DDB5
#define DD_SCK DDB7 
#define DD_SS DDB4

#include <avr/io.h>
#include <string.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>



//Forward declarations
int main();
void init_serial();
void lcd_clear();
void lcd_writec(unsigned char c);
void lcd_writes(char *s);
void lcd_line2();
void init_spi();
uint8_t read_spi(uint8_t adrs);
void write_spi(uint8_t adrs, uint8_t data);
uint8_t spi_comm(uint8_t data);


int main()
{
	char s[20];
	uint8_t resp;
	int delay;

	int16_t x = 0, y = 0, z = 0;
	int16_t lastx = 0, lasty = 0, lastz = 0;


	init_serial();
	init_spi();

	resp = read_spi(0x0f);

	lcd_clear();
	sprintf(s,"Response %x",resp);
	lcd_writes(s);

	for(delay = 0; delay < 1000; delay++)
		_delay_ms(1);

	//Control register 1 normal mode, x,y,z activated
	write_spi(0x20,0b10000111);

	//Control register 2 wait for read before next sample
	write_spi(0x21,0b01000000);

	for(;;)
	{

		x = read_spi(0x28) | (read_spi(0x29) << 8);
		y = read_spi(0x2a) | (read_spi(0x2b) << 8);
		z = read_spi(0x2c) | (read_spi(0x2d) << 8);

		lcd_clear();
		sprintf(s,"%04x %04x",x,y);
		lcd_writes(s);
		lcd_line2();
		sprintf(s,"%04x",z);
		lcd_writes(s);

		//Turn on LED on PB0 if there is motion
		if((abs(x-lastx) > 2) || (abs(y-lasty) > 2) || (abs(z-lastz) > 2))
			PORTB |= (1<<0);
		else
			PORTB &= ~(1<<0);
		lastx = x; lasty = y; lastz = z;

		//Delay between measurements
		for(delay = 0; delay < 100; delay++)
			_delay_ms(1);
	}
}

void init_serial()
{

	// Set baud rate 
	UBRRH = (UBRR>>8);
	UBRRL = UBRR;

	// Set frame format: 8data, 1stop bit 
	UCSRC = (1<<URSEL) |(3<<UCSZ0);
	
	// Enable transmitter 
	UCSRB = (1<<TXEN);

}

void lcd_clear()
{
	lcd_writec(0xfe);
	lcd_writec(0x01);
}

void lcd_line2()
{
	lcd_writec(0xfe);
	lcd_writec(0xc0);
}

void lcd_writec(unsigned char c)
{
	// Wait for empty transmit buffer 
	while ( !( UCSRA & (1<<UDRE)));

	// Put data into buffer, sends the data */
	UDR = c;

	// Wait for empty transmit buffer 
	while ( !( UCSRA & (1<<UDRE)));

}

void lcd_writes(char *s)
{
	int i;

	for(i = 0; i < strlen(s); i++)
		lcd_writec(s[i]);

}

void init_spi()
{

	//SS high
	PORT_SPI |= (1<<DD_SS);

	// Set MOSI and SCK output, all others input 
	DDR_SPI = (1 << DD_SS) | (1<<DD_MOSI)|(1<<DD_SCK) | (1<<0);

	// Enable SPI, Master, set clock rate fck/64 
	SPCR = (1<<SPE)|(1<<MSTR)| (1<<SPR1) | (1<<SPR0);

}

uint8_t read_spi(uint8_t adrs)
{
	uint8_t data;

	//Set read
	adrs |= (1 << 7);
	
	//SS low
	PORT_SPI &= ~(1<<DD_SS);

	//Send address
	spi_comm(adrs);

	//Read byte
	data = spi_comm(0);
	
	//SS high
	PORT_SPI |= (1<<DD_SS);
	
	return data;
}

void write_spi(uint8_t adrs, uint8_t data)
{
	//SS low
	PORT_SPI &= ~(1<<DD_SS);

	//Send address
	spi_comm(adrs);

	//Send byte
	spi_comm(data);

	//SS high
	PORT_SPI |= (1<<DD_SS);
}


uint8_t spi_comm(uint8_t data)
{

	// Start transmission
	SPDR = data;

	// Wait for transmission complete 
	while(!(SPSR & (1<<SPIF)));

	return SPDR;

}

Code: Select all
/*
	Magnetometer.c - Communicate with MicroMag3 Magnetometer
	Written by Frank Kienast in November, 2007

	Target is ATMega16 with 12MHz xtal clock.
	Sparkfun Serial LCD (9600 baud) connected to TX.

*/

#define F_CPU 12000000 
#define BAUD 9600
#define UBRR (((F_CPU / (BAUD * 16UL))) - 1)
#define DDR_SPI DDRB
#define PORT_SPI PORTB
#define PIN_SPI PINB
#define DD_MOSI DDB5
#define DD_SCK DDB7 
#define DD_SS DDB4
#define DD_RST DDB1
#define DD_RDY DDB0

#include <avr/io.h>
#include <string.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>



//Forward declarations
int main();
void init_serial();
void lcd_clear();
void lcd_writec(unsigned char c);
void lcd_writes(char *s);
void lcd_line2();
void init_spi();
uint8_t spi_comm(uint8_t data);


int main()
{
	char s[20];
	int delay;

	int16_t x = 0, y = 0, z = 0, b = 0;

	init_serial();
	init_spi();



	for(;;)
	{
		//x axis
		//lcd_writes("1");
		PORT_SPI &= ~(1<<DD_SS);
		//Pulse RST
		PORT_SPI |= (1<<DD_RST);
		_delay_ms(1);
		PORT_SPI &= ~(1<<DD_RST);
		spi_comm(0b01110001);
		while(!(PIN_SPI & (1<<DD_RDY)));
		x = (spi_comm(0) << 8) | spi_comm(0);
		PORT_SPI |= (1<<DD_SS);

	
		//y axis
		//lcd_writes("2");
		PORT_SPI &= ~(1<<DD_SS);
		//Pulse RST
		PORT_SPI |= (1<<DD_RST);
		_delay_ms(1);
		PORT_SPI &= ~(1<<DD_RST);
		spi_comm(0b01110010);
		while(!(PIN_SPI & (1<<DD_RDY)));
		y = (spi_comm(0) << 8) | spi_comm(0);
		PORT_SPI |= (1<<DD_SS);

	
		//z axis
		PORT_SPI &= ~(1<<DD_SS);
		//Pulse RST
		PORT_SPI |= (1<<DD_RST);
		_delay_ms(1);
		PORT_SPI &= ~(1<<DD_RST);
		spi_comm(0b01110011);
		while(!(PIN_SPI & (1<<DD_RDY)));
		z = (spi_comm(0) << 8) | spi_comm(0);
		PORT_SPI |= (1<<DD_SS);

		//Net
		b = sqrt((double)x*(double)x + (double)y*(double)y + (double)z*(double)z);
		


		lcd_clear();
		sprintf(s,"%5d %5d",x,y);
		lcd_writes(s);
		
		lcd_line2();
		sprintf(s,"%5d %5d",z,b);
		lcd_writes(s);
		

		//Delay between measurements
		for(delay = 0; delay < 500; delay++)
			_delay_ms(1);
	}
}

void init_serial()
{

	// Set baud rate 
	UBRRH = (UBRR>>8);
	UBRRL = UBRR;

	// Set frame format: 8data, 1stop bit 
	UCSRC = (1<<URSEL) |(3<<UCSZ0);
	
	// Enable transmitter 
	UCSRB = (1<<TXEN);

}

void lcd_clear()
{
	lcd_writec(0xfe);
	lcd_writec(0x01);
}

void lcd_line2()
{
	lcd_writec(0xfe);
	lcd_writec(0xc0);
}

void lcd_writec(unsigned char c)
{
	// Wait for empty transmit buffer 
	while ( !( UCSRA & (1<<UDRE)));

	// Put data into buffer, sends the data */
	UDR = c;

	// Wait for empty transmit buffer 
	while ( !( UCSRA & (1<<UDRE)));

}

void lcd_writes(char *s)
{
	int i;

	for(i = 0; i < strlen(s); i++)
		lcd_writec(s[i]);

}

void init_spi()
{

	//SS high
	PORT_SPI |= (1<<DD_SS);

	//RST low
	PORT_SPI &= ~(1<<DD_RST);

	// Set SS, MOSI, SCK, RST output, rest input
	DDR_SPI = (1 << DD_SS) | (1<<DD_MOSI) | (1<<DD_SCK) | (1<<DD_RST);

	// Enable SPI, Master, set clock rate fck/64 
	SPCR = (1<<SPE)|(1<<MSTR)| (1<<SPR1) | (1<<SPR0);

}



uint8_t spi_comm(uint8_t data)
{

	// Start transmission
	SPDR = data;

	// Wait for transmission complete 
	while(!(SPSR & (1<<SPIF)));

	return SPDR;

}

Frank
By lionking75
#45825
Thanks, Do you have a assm. code for ADXL32x , IF you have it please e-mail to me ,or post it here.
Thanks,