Skocz do zawartości

Atmega8+rfm12b- budowa układu według forbotowskiego poradnika


nariox

Pomocna odpowiedź

Czy jakaś bratnia dusza zechciałaby mi pomóc w ustawieniu i odpaleniu modułów rfm12b z atmega8?

Posługuję się poradnikiem zamieszczonym na blogu, uart ruszył, test połączenia z rfm12b zdany,ale niestety nic nie moge odebrać. Nie wiem gdzie szukać przyczyny.

Układ uruchamiam na kwarcu zewnętrznym wprowadziłem niewielkie zmiany w stosunku do oryginalnych bibliotek, żeby uruchomić UART i to w zasadzie tyle- Czy wielkość anteny ma duże znaczenie? Układy składam na płytkach stykowych, Antene uciąłem drut około 165mm.

Moduły na 868 w wersji smd(dolutowalem goldpiny) .Poniżej zamieszam dokładne kody w C dla nadajnika i Odbiornika.

Odbiornik:

/*
* slave_rfm12b_v2.c
*
* Created: 2016-02-02 18:09:29
*  Author: nari0x
*/ 


/*
* main.c
*
*  Created on: 19-02-2014
*      Author: Piotr Rzeszut
*  
* Description: Przykład komunikacji z modułem RFM12B
*/
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
#include <avr/interrupt.h>

#include "RFM12B.h"
#include "uart.h"

char bufor[65];


int main(void){
_delay_ms(500);

Rfm_spi_init();//inicjalizacja magistrali SPI

Rfm_init();//wstępna konfiguracja układu RFM12B

DDRC |= (1<<PC5);        //dodałem te dwie linijki żeby wiedzieć kiedy program wykona się do końca- na końcu gasi diodę
PORTC |= (1<<PC5);



DDRB &= ~((1<<PB0)|(1<<PB1));//konfiguruję piny PB0-1 jako wejście
PORTB |= (1<<PB0)|(1<<PB1);//i włączam podciąganie

uint8_t data;

while(1){

	//sprawdzam przyciski i ustawiam odpowiednie bity w bajcie do nadania
	data = 0;
	if(!(PINB&(1<<PB0))){        // zmieniłem piny na których są przyciski, bo kolidowalo z obslugą spi
		data |= 1;

	}	
	if(!(PINB&(1<<PB1))){
		data |= 2;
	}
	if(data==0)continue;//jeśli nic nie wciśnięto to rozpoczynamy pętlę od początku

	//włączamy nadajnik
	Rfm_xmit(POWER|EN_TRANSMISSION|EN_SYNTH|EN_OSC|DIS_CLKO);
	//nadajemy 3 bajty synchronizacji (0xAA)
	//dwa pierwsze są już domyślnie umieszczone w buforze nadawczym po komendzie włączającej nadajnik
	Rfm_ready_wait();
	Rfm_xmit(TX_WRITE|0xAA);
	//następnie kolejny bajt synchrnoizacji (0x2D)
	Rfm_ready_wait();
	Rfm_xmit(TX_WRITE|0x2D);
	Rfm_ready_wait();
	//oraz definiowalny bajt synchronizacji (czyli nasz adres)
	Rfm_xmit(TX_WRITE|0xD4);
	Rfm_ready_wait();
	Rfm_xmit(TX_WRITE|data);
	Rfm_ready_wait();
	//oraz pusty bajt - konieczny by poprawnie zakończyć trnasmisję
	Rfm_xmit(TX_WRITE|0xAA);
	Rfm_ready_wait();
	//następnie czekamy na zakończenie transmisji
	uint16_t status;
	do 
	{
		status=Rfm_xmit(STATUS_READ);
	} while (!(status&M_TX_READY));
	//i wyłączamy nadajnik
	Rfm_xmit(POWER|DIS_CLKO);
	_delay_ms(100);
	PORTC &= ~(1<<PC5);

}

return 0;
}

zmodyfikowany RFM12b.c:

/*
* RFM12B.c
*
*  Created on: 19-02-2014
*      Author: Piotr Rzeszut
*  
* Description: Funkcje do obsługi układu RFM12B z poziomu procesora AVR
*/
#include "RFM12B.h"

void Rfm_spi_init(void){
SPI_DDR |= (1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_SS);//konfiguracja kierunku i podcigania linii SPI
SPI_PORT |= (1<<SPI_MISO);
//do poprawnej pracy modułu SPI w procesorze linia SS musi być ustawiona jako wyjście

SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0);//SPI w trybie master z podziałem zegara przez 64 


CS_PORT |= (1<<CS_RFM);//dezaktywacja układu RFM12B
CS_DDR |= (1<<CS_RFM);//konfiguracja kierunku linii CS
}

uint16_t Rfm_xmit(uint16_t data){
//na początek rodzielamy dane na 2 bajty
uint8_t msb, lsb;
lsb = data;
msb = data>>8;
CS_PORT &= ~(1<<CS_RFM);//aktywujemy linię CS układu
//teraz wysyłamy 2 bajty jednocześnie odbierając 2 bajty z układu
SPDR = msb;
while(!(SPSR&(1<<7)));
msb = SPDR;
SPDR = lsb;
while(!(SPSR&(1<<7)));
lsb = SPDR;
//_delay_ms(1);
CS_PORT |= (1<<CS_RFM);//dezaktywujemy linię CS układu
//i zwracamy odebrane dane
return( (((uint16_t)msb)<<8)+((uint16_t)lsb) );
}

void Rfm_init(void){
Rfm_xmit(SW_RESET);//resetuję programowo układ RFM12B
_delay_ms(250);

//inicjalizacja RFM12B
//ustawienie pasma 868MHz, konfiguracja FIFO
Rfm_xmit(CONFIGURATION|EN_DATA_REG|EN_FIFO|BAND_868|CAP_12_0);
//włączenie oscylatora
Rfm_xmit(POWER|EN_OSC|DIS_CLKO);
//ustawienie pasma (musi być takie samo w nadajniku i odbiorniku)
//Dla naszego układu częstotliwość musi zawierać się w przedziale 860480000-879515000Hz i musi być podawana ze skokami 5000Hz
Rfm_xmit(FREQUENCY|RF12_FREQUENCY_CALC_868(868000000UL));
//ustawienie prędkości transmisji danych (musi być takia sama w nadajniku i odbiorniku)
Rfm_xmit(BAUD|BAUD_4800);
//ustawienie pasma 134kHz i parametrów odbiornika
Rfm_xmit(RECEIVER|P20_VDI|BW134|LNA_0|RSSI_103);
//ustawienie cyfroiwego filtra danych i opcji odzyskiwania zegara
Rfm_xmit(DATA_FILTER|AUTO_CR|DIGITAL_F|DQD_4);
//reset bufora FIFO, konfiguracja synchronizacji za pomocą 2 bajtów, ustawienie generowania przerwania FFIT po odebraniu 8 bitów
Rfm_xmit(FIFO_RST|FIFO_IT_8|FIFO_SYNC|HS_RST_DIS);


//konfiguracja kontrolera częstotliwości
Rfm_xmit(AFC|KEEP_RX|REST_OFF|EN_FOFFSET|EN_AFC);
//konfiguracja nadajnika i jego mocy (na ustawienie maksymalne)
Rfm_xmit(TRANSMITER|FSK_PHASE_0|FSK_DF_90K|OUT_P_0);
//konfiguracja pętli PLL
Rfm_xmit(PLL|PLL_DH_DIS|SEL_CLK_2_5|MAX_BAUD_256);

//wyłączenie timera wakeup
Rfm_xmit(WAKEUP_TIM|WUT_X_2_0|0);
//wyłączenie oszczędzania energii
Rfm_xmit(LOW_DC|LOW_DC_DIS);
//ustawienie monitora napięcia na 2,2V
Rfm_xmit(BOD_CLK|CLK_5_00|BOD_2_2);
}

uint8_t Rfm_ready_wait(void){
uint8_t i=0;

CS_PORT &= ~(1<<CS_RFM);//załączam pin CS układu
_delay_us(10);//czekam nieco aby układ mógł zareagować

while(!((1<<SPI_MISO)&SPI_PIN)){//następnie co 1ms sprawdzam, czy układ jest wolny, tzn, czy wystawił na linii MISO 1.
	_delay_ms(5);
	if((++i)==200){
		return 1;//po ok. 200ms przerywam oczekiwanie i zwracam 1 - czyli sygnalizuję błąd
	}
}
return 0;//jeśli pętal zostanie przerwana z powodu wystąpienia stanu wysokiego na linii MISO to zwracam 0 - nie ma błędu
}

zmieniłem tylko wartosci w pętli ostatniej,gdzie doczytalem ze czasem sa problemy z tego powodu

RFM12b.h- zmienione zostały tylko definicje pinów pod które podpięty jest rfm12b

/*
/*
* RFM12B.h
*
*  Created on: 10-06-2013
*      Author: Piotr Rzeszut
*  
* Description: Funkcje do obsługi układu RFM12B z poziomu procesora AVR
*/
#ifndef RFM12B_H
#define RFM12B_H

#include <avr/io.h>
#include <util/delay.h>
#include "RFM12B_reg.h"

//definicje pinów IO, na których podłączona jest magistrala SPI
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define SPI_PIN PINB

#define SPI_SS PB2
#define SPI_MOSI PB3
#define SPI_MISO PB4
#define SPI_SCK PB5

//pin CS możemy wybrać dowolnie
#define CS_DDR DDRB
#define CS_PORT PORTB
#define CS_RFM PB2

void Rfm_spi_init(void);

uint16_t Rfm_xmit(uint16_t data);

void Rfm_init(void);

uint8_t Rfm_ready_wait(void);

#endif //RFM12B_H

W rf12b_reg.h nic nie zmienialem

Kod dla obiornika:


/*
* main.c
*
*  Created on: 19-02-2014
*      Author: Piotr Rzeszut
*  
* Description: Przykład komunikacji z modułem RFM12B
*/
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
#include <avr/interrupt.h>

#include "RFM12B.h"
#include "uart.h"

char bufor[65];



//--------------------------------------------------------------------------------------------------------
//Kod dla układu MASTER
//--------------------------------------------------------------------------------------------------------
int main(void){

Rfm_spi_init();//inicjalizacja magistrali SPI
uart_init(9600);//inicjalizacja USART
sei();//włączamy przerwania do obsługi uart

uart_puts("\r\n\r\nRFM12B - RECEIVER\r\n");//wyświetlamy powitanie

Rfm_init();//inicjalizujemy układ RFM12B

Rfm_xmit(SYNC_PATTERN|0xD4);
//ustawiamy programowalny bajt synchronizacji na wartość 0xD4
//wykorzystamy tę funkcjonalność do adresowania wielu układów

//włączamy odbiornik
Rfm_xmit(POWER|EN_RX|EN_BASEBAND|EN_OSC|DIS_CLKO);
_delay_ms(5);

while(1){
	//para komend powodująca w efekcie działania reset synchronizacji odbiornika
	Rfm_xmit(FIFO_RST|FIFO_IT_8|HS_RST_DIS);
	Rfm_xmit(FIFO_RST|FIFO_IT_8|EN_AFT_SYNC|HS_RST_DIS);

	uint8_t timeout=Rfm_ready_wait();//oczekujemy na odebranie przez układ danych
	if(timeout){//i w zależności od tego czy układ odpowiedział
		//albo wyświetlamy informacje o braku odebranych danych
		uart_puts("NO INCOMING DATA\r\n");
	}else{
		//albo odbieramy dane z bufora
		uint8_t data=Rfm_xmit(FIFO_READ);
		//i wyświetlamy je
		sprintf(bufor,"INCOMING DATA:%d\r\n",data);
		uart_puts(bufor);
	}
}

return 0;
}

Inicjalizacja UART:

(uart.c)

/*
* uart.c
*
*  Created on: 23-05-2013
*      Author: Piotr Rzeszut
*  
* Description: Przykład obsługi UART z zastosowaniem przerwań i bufora kołowego
*/
#include "uart.h"

volatile char UART_RX_BUF[UART_BUFFER_SIZE];
volatile uint8_t uart_rx_h=0;
volatile uint8_t uart_rx_t=0;

volatile char UART_TX_BUF[UART_BUFFER_SIZE];
volatile uint8_t uart_tx_h=0;
volatile uint8_t uart_tx_t=0;

volatile uint8_t rx_overrun=0;

void uart_init(uint16_t baud){
//wyliczamy wartość rejestru UBRR
uint16_t ubrr_cal=F_CPU/16/baud-1;
//konfiguracja baud
UBRRH = (uint8_t)(ubrr_cal>>8);
UBRRL = (uint8_t)ubrr_cal;
//włączenie UART

UCSRC =(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);
UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}

void uart_putc(char data){
uint8_t new_h=(uart_tx_h+1)&UART_BUFFER_MASK;
while(new_h==uart_tx_t);
UART_TX_BUF[new_h]=data;
uart_tx_h=new_h;
UCSRB |= (1<<UDRIE);
}

void uart_puts(char *string){
char c;
while((c=*string++))uart_putc(c);
}

void uart_putint(int number, uint8_t base){
char buffer[20];
itoa(number,buffer,base);
uart_puts(buffer);
}

char uart_getc(void){
if(uart_rx_t==uart_rx_h)return 0;
uart_rx_t=(uart_rx_t+1)&UART_BUFFER_MASK;
return UART_RX_BUF[uart_rx_t];
}

uint16_t uart_getint(void){
 char odebrany=0;
 uint16_t liczba=0;
 do{
 	odebrany=uart_getc();
   if(odebrany!=0){
     if(odebrany!='\r'){//filtrujemy znak zakończenia liczby
  	uart_putc(odebrany);
       liczba*=10;
       liczba+=odebrany-'0';
     }
   }
 }while(odebrany!='\r');//jeśli odebraliśmy znak zakończenia liczby to wychodzimy z pętli  
 return liczba;//zwracamy odebraną liczbę
}

ISR(USART_RXC_vect){
uint8_t new_h=(uart_rx_h+1)&UART_BUFFER_MASK;

if(new_h!=uart_rx_t){
	uart_rx_h=new_h;
	UART_RX_BUF[uart_rx_h]=UDR;
}else{
	rx_overrun=1;
	new_h=UDR;//odczytujemy bufor, żeby nie zawiesić systemu
}
}

ISR(USART_UDRE_vect){
if(uart_tx_t!=uart_tx_h){
	uart_tx_t=(uart_tx_t+1)&UART_BUFFER_MASK;
	UDR=UART_TX_BUF[uart_tx_t];
}else{
	UCSRB &= ~(1<<UDRIE);
}
}

RFM12b.c tak samo jak w przypadku nadajnika

w pozostałych nic nie mieszałem

Czy ktoś kto bawił się tymi kodami zechciałby mi pomóc? Hardware jest chyba dobrze zrobione,PIN NIRQ zostawiam niepodłączony,reszta jak na schemacie w poradniku.

https://forbot.pl/blog/artykuly/programowanie/rfm12b-2-koniec-ciszy-eterze-id1861

Posprawdzam jeszcze raz dziś wszystko wieczorem.

Osobie która mi pomoże odwdzięczę się poza forum;)) . Dość długo już przy tym dumam i nic;(

PS: posiadm też GB P.Mirosława ,jeżeli ktoś umiałby mi pomóc zrobić z tego identyczny program jak ten w poradniku , to nie wiem jak mu się odwdzięcze

Chciałbym zrobić po prostu gotowy program i potem sobie go spokojnie przeanalizować i zmodyfikować.

rfm12b_mega8.rar

Link do komentarza
Share on other sites

Z pomocą przyszedł Green Book,po krótkich modyfikacjach programów z książki udało się odpalić i skomunikować ze sobą dwa moduły.

Trudno mi na razie powiedzieć gdzie tkwi błąd.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.