Witam,
piszę program do układu wykorzystującego żyroskopowy czujnik przyspieszenia (Adis 16355). Mam problem z niestartowaniem programu- mikrokontroler rozpoczyna pracę, jednak po wykonaniu
sei();
resetuje się i rozpoczyna pracę od początku.
Dzieje się tak jednak tylko wtedy, gdy przed sei(); wykonuję zerowanie();. Jeśli zablokuję zerowanie(). wszystko jest ok- przerwania działają z częstotliwością jaką sobie policzyłem (1ms).
Proszę kogoś bardziej bystrego o analizę kodu i pomoc.
Z góry dziękuje, Przemek.
Aha- jeszcze jeden plik źródłowy z pozostałymi procedurami:
piszę program do układu wykorzystującego żyroskopowy czujnik przyspieszenia (Adis 16355). Mam problem z niestartowaniem programu- mikrokontroler rozpoczyna pracę, jednak po wykonaniu
sei();
resetuje się i rozpoczyna pracę od początku.
Dzieje się tak jednak tylko wtedy, gdy przed sei(); wykonuję zerowanie();. Jeśli zablokuję zerowanie(). wszystko jest ok- przerwania działają z częstotliwością jaką sobie policzyłem (1ms).
Proszę kogoś bardziej bystrego o analizę kodu i pomoc.
Z góry dziękuje, Przemek.
[b]//plik config[/b]
#include "config.h"
void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1 << DD_SS) | (1<< DD_RESET) | (1<<DDB0);
/* Enable SPI, Master, set clock rate fck/16= 1Mb/s */
SPCR = (1<<SPE)|(1<<MSTR) |(1<<SPR0) | (1<<CPHA) | (1<<CPOL) | (1<<SPIE);
//SPSR =(1<<SPI2X); //preskaler pomnożony przez 2
}
void SPI_Transmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
}
unsigned char SPI_Receive(void)
{
/* Wait for reception complete */
while(!(SPSR & (1<<SPIF)));
/* Return data register */
return SPDR;
}
unsigned char SPI_WriteRead(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
/* Return data register */
return SPDR;
}
[b]//plik main[/b]
#include "config.h"
#define BUT PINE & _BV(5)
#define LED_ON PORTE&= ~(1<<PB4) // zapal diode
#define LED_OFF PORTE|= (1<<PB4) // zgas diode
#define XAcclAdr 0x0b
#define YAcclAdr 0x0d
#define ZAcclAdr 0x0f
#define XGyroAdr 0x05
#define YGyroAdr 0x07
#define ZGyroAdr 0x09
volatile signed int liczT0=0,
predkosc=0,
data=0;
volatile unsigned int u2data=0, droga=0, i=0, I=0;
signed int u2_to_dec( unsigned int u2, unsigned char len )
{
unsigned char i=len;
unsigned int potega=1;
if( u2 & _BV(len-1))
{
while(i>0)
{
potega=potega*2;
i--;
}
return u2-potega;//u2-2^(len);
}else
{
return u2;
}
}
signed int dec_to_u2(signed int dec, unsigned char len )
{
unsigned char i=len;
unsigned int potega=1;
if( dec<0)
{
while(i>0)
{
potega=potega*2;
i--;
}
return dec+potega;//u2-2^(len);
}
else
{
return dec;
}
}
signed int offset(unsigned char adr)
{
unsigned char i=0;
signed int suma=0;
for(i=10 ; i!= 0 ; i--)
{
data= read_register(adr) & 0x3FFF;
data= u2_to_dec(data,14);
suma= suma + data;
waitms(1);
}
return suma/10;
}
void zerowanie(unsigned char adr, unsigned char lsb_off_adr)
{
write_command(lsb_off_adr, 0);
write_command(lsb_off_adr + 1, 0);
data=-offset(adr);
u2data= dec_to_u2(data,12);
write_command(lsb_off_adr + 1, u2data>>8);
write_command(lsb_off_adr,u2data & 0b11111111);
return;
}
void Timer0_init()
{
OCR0A=250; //przy presk. 64 wyzwala przerw. co 1ms
TIMSK0 = TIMSK0 | 1<<OCIE0A; //zezwolenie lokalne na przerwania od porównania Timera0
TCCR0A |= 1<<CS00 | 1<<CS01 | 1<<COM0A1; //preskaler na 64 (daje f= 250kHz)
}
SIGNAL(TIMER0_COMP_vect)
{
//kod obsługi przerwania
return;
}
int main()
{
signed int temp=0;
unsigned int test=0;
unsigned char data1,data2;
CS_UP;
RESET_UP;
// waitms(5);
RESET_DOWN;
// waitms(5);
SPI_MasterInit();
USART0_Init(103);
Timer0_init();
[b]zerowanie(0x0a, 0x20);
sei();[/b]
while(1)
{
}
}[/b]Aha- jeszcze jeden plik źródłowy z pozostałymi procedurami:
#include "config.h"
void write_command( unsigned char adr_cmd, unsigned char cmd )
{
CS_DOWN; // chip select na stan niski
waitms(1); //_delay_us(1);
SPI_Transmit(128 + adr_cmd); // transmisja starszego bajtu to adis163
SPI_Transmit(cmd); // transmisja mlodszego bajtu do adis1635x
CS_UP; // chip select na stan wysoki
waitms(1); //_delay_us(1);
}
unsigned int read_register(unsigned char adr)
{
unsigned int temp=0;
unsigned char msb_byte=0, lsb_byte=0;
adr = adr & 0b00111111;
CS_DOWN;
waitms(1); //_delay_us(0.1);
SPI_Transmit(adr);
SPI_Transmit(adr);
CS_UP;
waitms(1); //_delay_us(40);
CS_DOWN;
msb_byte = SPI_WriteRead(adr);
lsb_byte = SPI_WriteRead(adr);
CS_UP;
temp = (unsigned int)(msb_byte<<8);
temp = temp | lsb_byte;
//send_number_dec(msb_byte & 0b1111111);
//send_number_dec(lsb_byte);
return temp;
}
void read_registers()
{
unsigned int temp=0;
unsigned char msb_byte=0, lsb_byte=0, i=0;
CS_DOWN;
waitms(1); //_delay_us(0.1);
SPI_Transmit(0x05);
SPI_Transmit(0x05);
CS_UP;
while (i<11)
{
waitms(1); //_delay_us(40);
CS_DOWN;
msb_byte = SPI_WriteRead(0x07 + i);
lsb_byte = SPI_WriteRead(0x07 + i);
CS_UP;
switch(i)
{
case 0:
XGyroData = (unsigned int)(msb_byte<<8);
XGyroData = ZAcclData | lsb_byte;
break;
case 2:
YGyroData = (unsigned int)(msb_byte<<8);
YGyroData = YGyroData | lsb_byte;
break;
case 4:
ZGyroData = (unsigned int)(msb_byte<<8);
ZGyroData = ZGyroData | lsb_byte;
break;
case 6:
XAcclData = (unsigned int)(msb_byte<<8);
XAcclData = XAcclData | lsb_byte;
break;
case 8:
YAcclData = (unsigned int)(msb_byte<<8);
YAcclData = YAcclData | lsb_byte;
break;
case 10:
ZAcclData = (unsigned int)(msb_byte<<8);
ZAcclData = ZAcclData | lsb_byte;
break;
}
i=i+2;
}
}
unsigned int XAccl()
{
return read_register(0x0B) & 0x3FFF;
}
unsigned int YAccl()
{
return read_register(0x0D) & 0x3FFF;
}
unsigned int ZAccl()
{
return read_register(0x0F) & 0x3FFF;
}
unsigned int XGyro()
{
return read_register(0x05) & 0x3FFF;
}
unsigned int YGyro()
{
return read_register(0x07) & 0x3FFF;
}
unsigned int ZGyro()
{
return read_register(0x09) & 0x3FFF;
}
void adis1635x_conf()
{
}