franzl
23.01.2008, 14:23
Hallo zusammen,
ich bin gerade dabei einen Positionsgeber der Firma austriamicrosystems auszuwerten und bin dabei auf ein Problem gestoßen.
http://www.austriamicrosystems.com/03products/products_detail/AS5045/download/AS5045_datasheet.pdf
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "uart.h"
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
/* 9600 baud */
#define UART_BAUD_RATE 9600
#define MODE PB0
#define SS PB2
#define MOSI PB3
#define MISO PB4
#define SCK PB5
long int position;
unsigned char Geber[3];
char a,b;
unsigned int pos;
char Buffer[4];
int main(void)
{
DDRB |= (1<<MODE)|(1<<SS)|(1<<MOSI)|(1<<SCK);
/* PB2(SS),PB3(MOSI),PB5(SCK)=Ausgang*/
PORTB |= (1<<MODE)|(1<<SS);
/* PB1(MODE),PB2(SS),PB4(MISO),PB5(SCK)=high*/
/*SPI_init*/
SPCR |= (1<<SPR0)|(1<<SPR1)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPE);
/* SPR0/SPR1 = F_CPU/128; SPI Master; Ruhezustand SCK=High;
Übernahme bei zweiter Taktflanke SPE= SPI Enable */
/*
* Initialize UART library, pass baudrate and AVR cpu clock
* with the macro
* UART_BAUD_SELECT() (normal speed mode )
* or
* UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
*/
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
_delay_ms(100);
for(;;)
{
PORTB |= (1<<SS);
//Positionsauswertung um die Position in einem Integer zu speichern
pos = Geber[0];
pos <<=8;
pos |= Geber[1];
pos >>=4;
pos &= 0x0FFF;
//Senden der Position an den PC
itoa( pos, Buffer, 10);
uart_puts(Buffer);
//neue Zeile
uart_puts("\n\r");
if(SPSR & (1<<WCOL))
{uart_puts("Uebertragungsfehler\n\r");}
for(b=0;b<10;b++) //Wartezeit 1s
{_delay_ms(100);}
PORTB &=~ (1<<SS); // Geber auswählen
_delay_us(1);
/*Auslesen des Gebers. Dazu wird 3x ein Dummybyte gesendet
und anschließend die empfangenen Bytes in ein Array Geber gespeichert*/
for(a=0;a<=2;a++)
{SPDR=0;
while(!(SPSR & (1<<SPIF)))
{Geber[a]=SPDR;}
}
}
}
und zwar bekomme ich mit diesem Programm die falschen Werte heraus und weiß nicht warum. Hab dann versucht das CPOL und CPH bit zu ändern und wenn beide 0 sind empfange ich 7richtige bits und muss mir diese dann eben zusammenbasteln. Nur leuchtet es mir nicht ein warum dies mit den meinermeinung nach völlig falschen Takteinstellungen zum Ergebnis führt, aber manchmal auch fehlerhaft ist. Währ super wenn ihr mir sagen könntet wo da in meinem Programm der Fehler liegt, da ich sonst ohne Logikanalyzer wohl nicht mehr weiter komme. Ich programmiere übrigens mit einem Atmega8 und 16MHz Quarz.
mfg franz
ich bin gerade dabei einen Positionsgeber der Firma austriamicrosystems auszuwerten und bin dabei auf ein Problem gestoßen.
http://www.austriamicrosystems.com/03products/products_detail/AS5045/download/AS5045_datasheet.pdf
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "uart.h"
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
/* 9600 baud */
#define UART_BAUD_RATE 9600
#define MODE PB0
#define SS PB2
#define MOSI PB3
#define MISO PB4
#define SCK PB5
long int position;
unsigned char Geber[3];
char a,b;
unsigned int pos;
char Buffer[4];
int main(void)
{
DDRB |= (1<<MODE)|(1<<SS)|(1<<MOSI)|(1<<SCK);
/* PB2(SS),PB3(MOSI),PB5(SCK)=Ausgang*/
PORTB |= (1<<MODE)|(1<<SS);
/* PB1(MODE),PB2(SS),PB4(MISO),PB5(SCK)=high*/
/*SPI_init*/
SPCR |= (1<<SPR0)|(1<<SPR1)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPE);
/* SPR0/SPR1 = F_CPU/128; SPI Master; Ruhezustand SCK=High;
Übernahme bei zweiter Taktflanke SPE= SPI Enable */
/*
* Initialize UART library, pass baudrate and AVR cpu clock
* with the macro
* UART_BAUD_SELECT() (normal speed mode )
* or
* UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
*/
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
sei();
_delay_ms(100);
for(;;)
{
PORTB |= (1<<SS);
//Positionsauswertung um die Position in einem Integer zu speichern
pos = Geber[0];
pos <<=8;
pos |= Geber[1];
pos >>=4;
pos &= 0x0FFF;
//Senden der Position an den PC
itoa( pos, Buffer, 10);
uart_puts(Buffer);
//neue Zeile
uart_puts("\n\r");
if(SPSR & (1<<WCOL))
{uart_puts("Uebertragungsfehler\n\r");}
for(b=0;b<10;b++) //Wartezeit 1s
{_delay_ms(100);}
PORTB &=~ (1<<SS); // Geber auswählen
_delay_us(1);
/*Auslesen des Gebers. Dazu wird 3x ein Dummybyte gesendet
und anschließend die empfangenen Bytes in ein Array Geber gespeichert*/
for(a=0;a<=2;a++)
{SPDR=0;
while(!(SPSR & (1<<SPIF)))
{Geber[a]=SPDR;}
}
}
}
und zwar bekomme ich mit diesem Programm die falschen Werte heraus und weiß nicht warum. Hab dann versucht das CPOL und CPH bit zu ändern und wenn beide 0 sind empfange ich 7richtige bits und muss mir diese dann eben zusammenbasteln. Nur leuchtet es mir nicht ein warum dies mit den meinermeinung nach völlig falschen Takteinstellungen zum Ergebnis führt, aber manchmal auch fehlerhaft ist. Währ super wenn ihr mir sagen könntet wo da in meinem Programm der Fehler liegt, da ich sonst ohne Logikanalyzer wohl nicht mehr weiter komme. Ich programmiere übrigens mit einem Atmega8 und 16MHz Quarz.
mfg franz