| Author |
Message |
|
|
Posted: Apr 26, 2012 - 03:06 PM |
|

Joined: Nov 02, 2009
Posts: 6
|
|
Hello,
I am trying to interface the BMA180 to the atmega8 using 4-wire SPI. Initially, I successfully tested it with the atmega16 but when I try to to do it with the Atmega8 it doesn't work.
Here is the code I've used
Thus I expect the led on PORTC to be on but the led on PORTD is on indicating that it was not successful. When I check the same code on Atmega16 after altering the DDRB pins, it worked fine .
Is there anything else I need to do apart from change the DDRB pins to make this program work on the atmega8? |
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 03:07 PM |
|

Joined: Nov 02, 2009
Posts: 6
|
|
|
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bma180.h"
#define F_CPU 8000000
#define sbi(var, mask) ((var) |=(uint8_t)(1<<mask)) //Set bit
#define cbi(var, mask) ((var) &=(uint8_t)~(1<<mask)) //clear
void SPI_Init(void)
{
sbi(SPCR,MSTR);
cbi(SPCR,SPR1);
sbi(SPCR,SPR0);
cbi(SPSR,SPI2X);
sbi(SPCR,SPE);
sbi(SPCR,CPOL);
sbi(SPCR,CPHA);
}
void txdata(char data)
{
//while((SPSR&0x80) == 0x80);
SPDR = data;
while((SPSR&0x80) == 0x00);
}
char rxdata(void)
{
//while((SPSR&0x80) == 0x80);
SPDR = 0x55;
while((SPSR&0x80) == 0x00);
return SPDR;
}
|
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 03:09 PM |
|

Joined: Nov 02, 2009
Posts: 6
|
|
| okay for some reason I'm not able to post the full code.. please download the C-file for the code... |
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 04:10 PM |
|


Joined: Jul 18, 2005
Posts: 62228
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
You mean this? (if you study closely you may spot a small edit that allowed me to post it )
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bma180.h"
#define F_CPU 8000000
#define sbi(var, mask) ((var) |=(uint8_t)(1<<mask)) //Set bit
#define cbi(var, mask) ((var) &=(uint8_t)~(1<<mask)) //clear
void SPI_Init(void)
{
sbi(SPCR,MSTR);
cbi(SPCR,SPR1);
sbi(SPCR,SPR0);
cbi(SPSR,SPI2X);
sbi(SPCR,SPE);
sbi(SPCR,CPOL);
sbi(SPCR,CPHA);
}
void txdata(char data)
{
//while((SPSR&0x80) == 0x80);
SPDR = data;
while((SPSR&0x80) == 0x00);
}
char rxdata(void)
{
//while((SPSR&0x80) == 0x80);
SPDR = 0x55;
while((SPSR&0x80) == 0x00);
return SPDR;
}
char read(uint8_t address)
{
//returns the contents of any 1 byte register from any address
//sets the MSB for every address byte (READ mode)
char byte;
address |= 0x80;
cbi(PORTB,4);
txdata(address);
byte = rxdata();
sbi(PORTB,4);
return byte;
}
void write(uint8_t address, char data)
{
//write any data byte to any single address
//adds a 0 to the MSB of the address byte (WRITE mode)
address &= 0x7F;
//printf("\nWriting 0x% x to 0x% x\n", data, address);
cbi(PORTB,4);
_delay_ms(1);
txdata(address);
_delay_ms(1);
txdata(data);
_delay_ms(1);
sbi(PORTB,4);
}
int init_BMA180(uint8_t range, uint8_t bw)
{
char temp, temp1;
// if connected correctly, ID register should be 3
if(read(ID) != 3)
return -1;
//-------------------------------------------------------------------------------------
// Set ee_w bit
temp = read(CTRLREG0);
temp |= 0x10;
write(CTRLREG0, temp); // Have to set ee_w to write any other registers
//-------------------------------------------------------------------------------------
// Set BW
temp = read(BWTCS);
temp1 = bw;
temp1 = temp1<<4;
temp &= (~BWMASK);
temp |= temp1;
write(BWTCS, temp); // Keep tcs<3:0> in BWTCS, but write new BW
//-------------------------------------------------------------------------------------
// Set Range
temp = read(OLSB1);
temp1 = range;
temp1 = (temp1<<RANGESHIFT);
temp &= (~RANGEMASK);
temp |= temp1;
write(OLSB1, temp); //Write new range data, keep other bits the same
//-------------------------------------------------------------------------------------
return 0;
}
int main()
{
SPI_Init();
DDRB = 0;
DDRB = (1<<2)|(1<<3)|(1<<5);
DDRD = 0xFF;
DDRC = 0xFF;
init_BMA180(0x00, 0x00);
while(1)
{
if(read(ID) != 3)
{
PORTD = 0xFF;
PORTC= 0x00;
}
else
{
PORTD = 0x00;
PORTC = 0xFF;
}
}
}
|
_________________
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 04:19 PM |
|

Joined: Nov 02, 2009
Posts: 6
|
|
well thanks...
any theories on why its not working? |
|
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 04:38 PM |
|


Joined: Jul 18, 2005
Posts: 62228
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Nothing immediately obvious but then I don't know this BMA180 device. One thing you should do if you can is put a scope or a logic analyser on the SCK, MISO and MOSI lines and verify that all appear to be operating OK. When you send 0xA5 do you see that bit pattern on MOSI against the pulses on SCK and when you expect the device to respond do you see a square wave pattern on MISO or is it perhaps stuck high or low?
BTW I assume PORTB.4 is the chip select for the device - certainly looks like you are operating that correctly too but again check it with a scope.
EDIT: oh wait a minute I don't see you setting PB4 as output in this line:
Code:
DDRB = (1<<2)|(1<<3)|(1<<5);
Note also that SPI on the AVR has a nasty habit when MSTR is selected that if the _SS pin is left as an input and floats or ir pulled low then the SPI switches out of MSTR mode and becomes a slave (so will not pulse SCK when SPDR is loaded) |
_________________
|
| |
|
|
|
|
|
Posted: Apr 26, 2012 - 05:26 PM |
|

Joined: Nov 02, 2009
Posts: 6
|
|
| Oh thank you man..!! helped me realize what the problem was.. PB4 was Chip select in atmega16 but in atmega8 its PB2.... Thus apart from changing the DDRB values, I also had to change which bit to desert and assert to start and stop the SPI conversation.... Once I changed it, it worked like a charm.... |
|
|
| |
|
|
|
|
|