Na stronie producenta:
http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=83 jest datasheet, zwięzły, opisane to co najważniejsze, jest graficznie przedstawiony algorytm nadawania i odbioru. Transmisja jest bardzo prosta, zależy kto w jakim języku pisze, ja robię w avr-gcc ale robiłem też w bascomie, przykład w avr-gcc - tylko kawałek kodu oczywiście, bo przecież jak ktoś pisze program to musi umieć dostosować go do swoich potrzeb i znać obsługę np. SPI, a jak nie potrafi napisać programu na podstawie kawałka kodu, to znaczy że nie będzie potrafił go zrobić i nawet cały program mu nic nie da bo nie będzie wiedział jak go przerobić i tyle :]
Konfiguracja modułu:
Code:
void set_config_module(void) //Konfiguracja modułu - ustawienie danych możliwych do zmiany (adres) i stałych (częstotliwość kwarcu, częstotliwość pracy numer kanału).
{
eeprom_read_char(g_RX_address, RX_ADDRESS_EEP, ADDRESS_LEN);
print(g_RX_address, 4);
PORTC &= ~(1<<PWR_UP);
PORTC &= ~(1<<TX_EN);
PORTC &= ~(1<<TRX_CE); //Wyłączenie części radiowej, konfiguracja
PORTC |= (1<<PWR_UP);
wait_ms(5);
PORTB &= ~(1<<CSN); //Sygnał CSN - przed każdym wyborem rejestru wymagane jest opadające zbocze
SPI_send_chr(5); //W_Config - rejestr konfiguracyjny do zapisu, bajt 5..8 - adres RX, bajt 9 - tryb CRC, częstotliwość kwarcu
SPI_send(g_RX_address, 0, ADDRESS_LEN);
SPI_send_chr(219); //11011011 - 16 bit CRC, CRC enable, kwarc w module 16MHz, zewnętrzny sygnał zegarowy włączony, częstotliwość 500kHz
PORTB |= (1<<CSN);
wait_us(1);
PORTB &= ~(1<<CSN);
SPI_send_chr(130); //142 - 10001110 - Rejestr szybkiej konfiguracji częstotliwości i kanału, moc 10dBm, 130 - 10000010 = -10dBm
SPI_send_chr(118); //01110110 - 868.4MHz
PORTB |= (1<<CSN);
wait_us(1);
PORTC |= (1<<TRX_CE); //Włączenie części radiowej, tryb odbioru (TX_EN = 0)
wait_ms(1);
}
Wysyłanie danych:
Code:
PORTC &= ~(1<<TRX_CE); //TX_EN = 1, TRX_CE = 0 - tryb nadawania.
PORTC |= (1<<TX_EN);
wait_ms(1);
PORTB &= ~(1<<CSN);
SPI_send_chr(34); //W_TX_ADDRESS - rejestr adresu RX do zapisu
SPI_send(g_TX_address, 0, ADDRESS_LEN); //Ustawiany jest adres odbiorcy, do którego trafią dane
PORTB |= (1<<CSN);
wait_us(1);
PORTB &= ~(1<<CSN);
SPI_send_chr(32); //Bufor nadawczy
SPI_send(g_Buffer, 0, DEST_ADDRESS_POS + ADDRESS_LEN); //Przesyła wszystkie bajty od początku (długość ramki) do adresu docelowego włącznie.
SPI_send(g_RX_address, 0, ADDRESS_LEN);
SPI_send(g_Buffer, DEST_ADDRESS_POS + 2 * ADDRESS_LEN, BUFFER_SIZE - 1 - 2 * ADDRESS_LEN); //Przesyła resztę danych w ramce.
PORTB |= (1<<CSN);
wait_us(1);
PORTC |= (1<<TRX_CE); //Włączenie nadawania
wait_us(20);
wait_ms_break(2000); //W tym czasie dane zostaną wysłane a przerwanie aktywowane sygnałem DR zakończy oczekiwanie.
Odczyt (to jest po prostu zapis dowolnych danych do SPI celem odebrania danych znajdujących się w buforze):
Code: void SPI_read(void)
{
unsigned char i;
PORTB &= ~(1<<CSN);
SPI_send_chr(36); //R_RX_PAYLOAD - bufor odbiorczy do odczytu
SPI_send_chr('A'); //Wysłanie danych (dowolnych) celem odebrania znaku
g_Buffer[0] = SPDR; //Pobranie liczby, określającej ile znaków ma zostać odczytanych
for(i=1; i<32; i++)
{
SPI_send_chr('A');
g_Buffer[i] = SPDR;
}
PORTB |= (1<<CSN);
wait_us(2);
}
Te kawałki kodu są w wielu miejscach rozbudowane po prostu do moich potrzeb, transmisję realizuję wg zalożeń jakie sobie narzuciłem (ramka danych, zawiera różne informacje o swoim składzie itp., nie jest to potrzebne do przeprowadzenia najprostszych transmisji, tak więc fragmenty te można znacznie odchudzić), czasami znajdą się jakieś instrukcje print które są oczywiście nadmiarowe, po prostu chcę widzieć na terminalu jakie dane trafiają do i z modułu.
Kod w Bascomie mogę umieścić w całości, bo ten w avr-gcc to znajdzie się w mojej pracy inżynierskiej, więc żeby później nie mówili że jest na necie to więcej nie zamieszczam :]
Code: Csn Alias Portb.0
Am Alias Pinb.1
Cd Alias Pinc.0
Pwr_up Alias Portc.1
Trx_ce Alias Portc.2
Tx_en Alias Portc.3
Dr Alias Pind.2
Cd_led Alias Portd.5
Am_led Alias Portd.6
Dr_led Alias Portd.7
Ddrb = &B00101101
Ddrc = &B0001110
Ddrd = &B11111011
Cd_led = 1
Am_led = 1
Dr_led = 1
Csn = 1
'Portd.0 = 1
Config 1wire = Portd.0
Dim Pol_stopnia As Bit
Dim Dane(2) As Byte , Temperatura As Integer
Dim A As Byte , B As Byte , I As Byte , J As Byte , Z As Byte , Tekst As String * 32
'Wait 1
'Print "Wprowadz tekst (maks. 32 znaki, zakoncz ENTER): "
'Input Tekst
Tekst = "temperatura" + Chr(13) + Chr(10)
'Print "Dziekuje. Odliczanie rozpoczete (5 sekund)."
For I = 1 To 5
Cd_led = 0
Waitms 500
Cd_led = 1
Waitms 500
Next I
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128
Trx_ce = 0
Pwr_up = 1
Waitms 5
Tx_en = 1
Waitms 1
Spiinit
Csn = 0
B = 9
A = Spimove(b)
A = 219
Spiout A , 1
Csn = 1
Waitus 1
Csn = 0
A = 142
Spiout A , 1
A = 118
Spiout A , 1
Trx_ce = 1
Waitus 100
Trx_ce = 0
Csn = 1
Waitus 1
Csn = 0
B = 32
A = Spimove(b)
Spiout Tekst , 32
Trx_ce = 1
Waitus 100
Trx_ce = 0
Csn = 1
Do
Tekst = Space(32)
1wreset
1wwrite &HCC
1wwrite &H44
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE
Temperatura = 1wread(2)
If Temperatura.0 = 0 Then
Pol_stopnia = 0
Else
Pol_stopnia = 1
End If
If Temperatura.8 = 0 Then
Tekst = "+"
Else
Tekst = "-"
Temperatura = 65536 - Temperatura
End If
Temperatura = Temperatura / 2
Tekst = Tekst + Str(temperatura)
If Pol_stopnia = 0 Then
Tekst = Tekst + ".0"
Else
Tekst = Tekst + ".5"
End If
Tekst = Tekst + Chr(13) + Chr(10)
Csn = 1
Waitus 1
Csn = 0
B = 32
A = Spimove(b)
Tekst = Trim(tekst)
Spiout Tekst , 32
Trx_ce = 1
Waitus 100
Trx_ce = 0
Loop
Do
Loop
oraz
Code: Csn Alias Portb.0
Am Alias Pinb.1
Cd Alias Pinc.0
Pwr_up Alias Portc.1
Trx_ce Alias Portc.2
Tx_en Alias Portc.3
Dr Alias Pind.2
Cd_led Alias Portd.5
Am_led Alias Portd.6
Dr_led Alias Portd.7
Ddrb = &B00101101
Ddrc = &B0001110
Ddrd = &B11111011
Cd_led = 1
Am_led = 1
Dr_led = 1
Csn = 1
Dim L1 As Bit , L2 As Bit , L3 As Bit
Dim A As Byte , B As Byte , I As Byte , J As Byte , Z As Byte , Tekst As String * 1
L1 = 0
L2 = 0
L3 = 0
Print "Podlaczono; oczekiwanie: "
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 128
Trx_ce = 0
Pwr_up = 1
Waitms 5
Tx_en = 0
Waitms 1
Spiinit
Csn = 0
B = 9
A = Spimove(b)
A = 219
Spiout A , 1
Csn = 1
Waitus 1
Csn = 0
A = 142
Spiout A , 1
A = 118
Spiout A , 1
Csn = 1
Waitus 1
Csn = 0
Trx_ce = 1
Waitms 1
Do
If Cd = 1 Then
L1 = 1
Cd_led = 0
End If
If Cd = 0 And L1 = 1 Then
L1 = 0
'Wait 2
Cd_led = 1
End If
If Am = 1 Then
L2 = 1
Am_led = 0
End If
If Am = 0 And L2 = 1 Then
L2 = 0
'Wait 2
Am_led = 1
End If
If Dr = 1 Then
Csn = 0
L3 = 1
Dr_led = 0
Wait 20
A = 36
Spiout A , 1
For I = 1 To 32
Spiin Tekst , 1
Tekst = Trim(tekst)
Print Tekst;
Next I
Csn = 1
End If
If Dr = 0 And L3 = 1 Then
L3 = 0
Dr_led = 1
End If
Loop
w Bascomie to pisałem na szybkiego, bez zabawy w optymalizację, tak żeby tylko uruchomić te moduły (termometr na 1-wire, drugi moduł podpięty do kompa wyświetla w terminalu temperaturę), zresztą porzuciłem ten język i przeniosłem się na avr-gcc.