Tiny ASURO Library: Thread und sf.net Seite
Danke für die Antworten
Ich habe mir jetzt die 5 Volt Module geholt und habe noch mal eine Frage und zwar zum SPI:
Fast alle Quellen sagen, dass man das RFM12 wie folgt verbinden soll:
nSEL an SS
SCK an SCK
SDI an MOSI
SDO an MISO
Doch wenn ich gar keine Hardware SPI benutzen will, kann ich ja auch andere IOs benutzen.
Wenn Ich aber die Hardware SPI pins benutze, kann ich dann das RFM12 trotzdem per Software SPI steuern oder lassen sich die Pins (MOSI,MISO,SS,SCK) dann nicht mehr als normale IOs ansteuern?
Es gibt ja eine Option in den Fuses die SPI zu disablen, aber da ich per ISP programmiere funktioniert das nicht.
Nichts existiert durch sich allein!
Bild hier
Finger weg davon! Das ist für die Programmierung über ISP und hat nichts mit SPI im normalen Betrieb zu tun!
Ich wüsste nicht, warum du das tun wolltest (HW-SPI nimmt dir viel Arbeit ab), aber möglich ist das, ja. In dem Falle hast du eine freie Wahl der Anschlüsse am AVR.
Wie bereits erwähnt, wenn du SW-SPI machst, bist du nicht an die HW-SPI-Pins gebunden. Es wäre aber Unsinnig, das RFM12 an die HW-SPI-Pins anzuschließen und dann damit SW-SPI zu machen. Aber: Solange du das HW-SPI nicht einschaltest, sind die entsprechenden Pins ganz normale I/O-Pins und können daher nach belieben verwendet werden.
mfG
Markus
Tiny ASURO Library: Thread und sf.net Seite
Danke für die schnelle Antwort.
Ich weiß jetzt also, dass ich die HW SPI Pins wie ganz normale IOs benutzen kann. Aber wie aktiviere oder deaktiviere ich denn die HW SPI?
Bzw. welches Register ist dafür zuständig?
Nichts existiert durch sich allein!
Bild hier
Hi,
wie du die HW SPI aktivierst, bzw deakivierst steht im Datenblatt. Ab Seite 132 geht es allgemein mit der SPI los, ab Seite 136 beginnt die "Register Description".
Zum aktivieren benutzt man das SPCR Register (S. 136) hier sind erklärt was die einzelnen Bits machen. Wir wollen die SPI im "Master Mode" (MSTR) betreiben und sie aktivieren (SPE). Eventuell musst du noch die SPI Clock Rate anpassen und die entsprechenden Pins müssen auf Ausgan bzw Eingang gestzt werden.
Als nächstes muss eine Routine zum Senden und Empfangen geschrieben werden. Dazu muss als erstes CHip Select aktiviert werden, danach werden die Daten in das Datenregister SPDR (S. 138 ) geschrieben. Die SPI beginnt sofort mit dem Übertragen, man muss lediglich darauf warten, dass die Schnittstelle fertig wird. Das kann man in dem SPSR (S. 138 ) Register feststellen mit dem SPIF Bit.Code:DDRB |= (1<<PB7) | (1<<PB5) | (1<<PB4); PORTB |= (1<<PB4); SPCR = (1<<SPE) | (1<<MSTR);
Hoffe das war verstädnlich viele GrüßeCode:PORTB &=~ (1<<PB4) //Chip select auf low SPDR = data; while(!(SPSR & (1<<SPIF)); PORTB |= (1<<PB4); return SPDR;
KR-500
So Ich hab es jetzt nach einer Pause endlich geschafft die Funkmodule zum funken zu bringen.
Dabei benutze ich eine abgeänderte Software von Benedikt K. http://www.mikrocontroller.net/topic/67273
Leider hat das ganze keine hohe Effektivität. (um die 10%)Code:#include <avr/io.h>#include <avr/interrupt.h> #include "rfm12.h" #define F_CPU 1000000UL #include <util/delay.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif #define IRQ_Port PORTD #define IRQ_Pin PIND #define IRQ_DDR DDRD #define IRQ 2 #define IRQ_Output() IRQ_DDR |= (1<<IRQ) #define IRQ_Input() IRQ_DDR&=~ (1<<IRQ) #define IRQ_High() IRQ_Port|= (1<<IRQ) #define IRQ_Low() IRQ_Port&=~(1<<IRQ) #define IRQ_Wait_Low() while(IRQ_Pin&(1<<IRQ)) #define RF_PORT PORTB #define RF_DDR DDRB #define RF_PIN PINB #define SDI 5 #define SCK 7 #define CS 4 #define SDO 6 void _delay_s(int s) { for (unsigned char i=0; i<s*100; i++) _delay_ms(10); } unsigned short rf12_trans(unsigned short wert) { unsigned short werti=0; unsigned char i; cbi(RF_PORT, CS); for (i=0; i<16; i++) { if (wert&32768) sbi(RF_PORT, SDI); else cbi(RF_PORT, SDI); werti<<=1; if (RF_PIN&(1<<SDO)) werti|=1; sbi(RF_PORT, SCK); wert<<=1; _delay_us(0.3); cbi(RF_PORT, SCK); } sbi(RF_PORT, CS); return werti; } void rf12_init(void) { RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS); RF_PORT=(1<<CS); IRQ_Input(); for (unsigned char i=0; i<10; i++) _delay_ms(10); // wait until POR done rf12_trans(0xC0E0); // AVR CLK: 10MHz rf12_trans(0x80D7); // Enable FIFO rf12_trans(0xC2AB); // Data Filter: internal rf12_trans(0xCA81); // Set FIFO mode rf12_trans(0xE000); // disable wakeuptimer rf12_trans(0xC800); // disable low duty cycle rf12_trans(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz } void rf12_ready(void) { cbi(RF_PORT, CS); while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready } void rf12_txdata(unsigned char data) { rf12_trans(0x8238); // TX on rf12_ready(); rf12_trans(0xB8AA); rf12_ready(); rf12_trans(0xB8AA); rf12_ready(); rf12_trans(0xB8AA); rf12_ready(); rf12_trans(0xB82D); rf12_ready(); rf12_trans(0xB8D4); rf12_ready(); rf12_trans(0xB800|(data)); rf12_ready(); rf12_trans(0x8208); // TX off } char rf12_rxdata(void) { unsigned char data; rf12_trans(0x82C8); // RX on rf12_trans(0xCA81); // set FIFO mode rf12_trans(0xCA83); // enable FIFO rf12_ready(); data=rf12_trans(0xB000); rf12_trans(0x8208); // RX off return data; }
Deswegen wollte ich fragen, was ich machen kann um die Genauigkeit zu verbessern?
Dafür spielt ja wahrscheinlich die Funktion rf12_ready() eine Rolle und auch diese
"Dummy Bytes".
Wie genau funktioniert das eigentlich?
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB82D);
rf12_ready();
rf12_trans(0xB8D4);
Nichts existiert durch sich allein!
Bild hier
Vermutlich muss am Empfänger etwas an der Frequenz (Stichwort: AFC) optimiert werden. Und das sind keine Dummy-Bytes sondern Kommandos. Wie wäre es, wenn du dich Mal mit dem Datenblatt des RF12 auseinander setzt?
mfG
Markus
Tiny ASURO Library: Thread und sf.net Seite
Lesezeichen