新闻  |   论坛  |   博客  |   在线研讨会
nRF905驱动程序(Atmega16主控)
0750long | 2009-06-17 12:19:52    阅读:2374   发布文章

nRF905驱动程序(Atmega16主控)

 

头文件:nrf905.h

/*
 * nrf905.h
 *
 *  Created on: 2009-5-8
 *      Author: Administrator
 */

#ifndef NRF905_H_
#define NRF905_H_

// regs
#define WC  0x00    // Write configuration register command
#define RC  0x10  // Read  configuration register command
#define WTP  0x20  // Write TX Payload  command
#define RTP  0x21 // Read  TX Payload  command
#define WTA  0x22 // Write TX Address  command
#define RTA  0x23 // Read  TX Address  command
#define RRP  0x24 // Read  RX Payload  command

// Control IOs
#define NRF905_TX_EN   RF_IO4 // PB3
#define NRF905_TRX_CE  RF_IO5 // PB2
#define NRF905_PWR_UP  RF_IO6 // PB1
#define NRF905_CD      RF_IO3
#define NRF905_AM      RF_IO1
#define NRF905_DR      RF_IO2
#define NRF905_CSN     RF_IO0

// 定义数据包
#define NRF905_PKT_LEN   32
typedef struct {
 u8_t buf[NRF905_PKT_LEN];
 u8_t len;
} packet_905_t;
extern packet_905_t tx_pkt_905;
extern packet_905_t rx_pkt_905;
extern u8_t rx_flag_905;

void nrf_setup(void);
void nrf_powerup_reset(void);
void nrf_write_settings(void);

void nrf_send_packet(u8_t *tx_buf, u8_t size);
u8_t nrf_receive_packet(u8_t *rx_buf, u8_t *length);

void nrf_test(void);

#endif /* NRF905_H_ */

 

实现文件:nrf905.c

/*
 * nrf905.c
 *
 *  Created on: 2009-5-8
 *      Author: zhb
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include "common.h"
#include "nrf905.h"
#include "key.h"

// The content of this struct is nRF905's initialize data.
// CH_NO=1;433MHZ;Normal Opration,No Retrans;RX,TX Address is 4 Bytes
// RX TX Payload Width is 32 Bytes;Disable Extern Clock;Fosc=16MHZ
// 8 Bits CRC And enable
u8_t RxTxConf[10] = {
 0x01, 0x0c, 0x44, 0x20, 0x20, 0xcc, 0xcc, 0xcc, 0xcc, 0x58
 //0x01, 0x0c, 0x44, 0x20, 0x20, 0xcc, 0xcc, 0xcc, 0xcc, 0x5c
};

packet_905_t tx_pkt_905;
packet_905_t rx_pkt_905;
u8_t rx_flag_905;

static void nrf_wait(u16_t cycles)
{
    while (cycles > 6)
        cycles -= 6;
}

// config NRF905 IOs
void nrf_setup(void)
{
 // CSN
 DDRB |= NRF905_CSN;
 PORTB |= NRF905_CSN;

 // other config
 DDRB |= NRF905_PWR_UP | NRF905_TRX_CE | NRF905_TX_EN;

 // 配置SPI总线
 //SPSR |= (1<<SPI2X); // 设置SPI时钟倍速
 SPCR |= (1<<SPE)|(1<<MSTR);  // 使能SPI接口,主机模式

 cli(); // 清所有中断
 MCUCR |= 0x0c; // INT1下降沿触发
 GICR |= 0x80; // 使能INT1

 rx_flag_905 = 0;
}

// Reset after power on
void nrf_powerup_reset(void)
{
 // switch to standby mode
 PORTB |= NRF905_PWR_UP;
 PORTB &= ~NRF905_TRX_CE;
 PORTB &= ~NRF905_TX_EN;
}

// Config parameters of NRF905
void nrf_write_settings(void)
{
 u8_t i;

 // enter standby mode
 PORTB |= NRF905_PWR_UP;
 PORTB &= ~NRF905_TRX_CE;
 PORTB &= ~NRF905_TX_EN;

 nrf_wait(20);

 PORTB &= ~NRF905_CSN;
 // Clear flag set during addr TX
 SPSR = 0x00;
 // Write config command
 SPDR = WC;
 // Wait for TX to finish
 while (!(SPSR & (1<<SPIF))) ;
 nrf_wait(20);
 // Write configration words
 for (i=0; i<10; i++) {
  // Clear flag
  SPSR = 0x00;
  // Write config word
  SPDR = RxTxConf[i];
  // Wait for TX to finish
  while (!(SPSR & (1<<SPIF))) ;
  nrf_wait(20);
 }
 // Clear flag
 SPSR = 0x00;
 PORTB |= NRF905_CSN;

 nrf_wait(20);

 // set RX mode
 PORTB &= ~NRF905_TX_EN;
 PORTB |= NRF905_TRX_CE;
 // 延时>=650us
 nrf_wait(30);
}

// Send a packet
void nrf_send_packet(u8_t *tx_buf, u8_t size)
{
 u8_t i;

 // check if collapse
 while (PIND&NRF905_CD) ;

 // switch to standby mode
 PORTB &= ~NRF905_TRX_CE;
 PORTB |= NRF905_TX_EN;
 nrf_wait(10);

 // write datas to transfer
 PORTB &= ~NRF905_CSN;
 // Clear flag set during addr TX
 SPSR = 0x00;
 SPDR = WTP;
 // Wait for TX to finish
 while (!(SPSR & (1<<SPIF))) ;
 nrf_wait(10);
 for (i=0; i<size; i++) {
  // Clear flag
  SPSR = 0x00;
  SPDR = tx_buf[i];
  // Wait for TX to finish
  while (!(SPSR & (1<<SPIF))) ;
  nrf_wait(10);
 }
 // Clear flag
 SPSR = 0x00;
 PORTB |= NRF905_CSN;
 nrf_wait(10);

 // write TX address
 PORTB &= ~NRF905_CSN;
 // Clear flag set during addr TX
 SPSR = 0x00;
 SPDR = WTA;
 // Wait for TX to finish
 while (!(SPSR & (1<<SPIF))) ;
 nrf_wait(10);
 for (i=0; i<4; i++) {
  // Clear flag
  SPSR = 0x00;
  SPDR = 0xcc;
  // Wait for TX to finish
  while (!(SPSR & (1<<SPIF))) ;
  nrf_wait(10);
 }
 // Clear flag
 SPSR = 0x00;
 PORTB |= NRF905_CSN;

 // start to TX
 PORTB |= NRF905_TRX_CE;
 // wait for tx complete...
 while ((PIND&NRF905_DR) == 0) ; // wait for DR hi
 nrf_wait(10);
 // switch to RX mode
 PORTB &= ~NRF905_TX_EN;
 nrf_wait(20);
}

// receive a packet
u8_t nrf_receive_packet(u8_t *rx_buf, u8_t *length)
{
 u8_t i;

 // Set nRF905 in standby mode
 PORTB &= ~NRF905_TRX_CE;

 PORTB &= ~NRF905_CSN;
 // Clear flag set during addr TX
 SPSR = 0x00;
 SPDR = RRP; // Read payload command
 // Wait for TX to finish
 while (!(SPSR & (1<<SPIF))) ;
 nrf_wait(10);
 for (i=0; i<*length; i++) {
  // clear flag
  SPSR = 0x00;
  SPDR = 0x55; // Read payload command
  // Wait for TX to finish
  while (!(SPSR & (1<<SPIF))) ;
  nrf_wait(10);
  rx_buf[i] = SPDR; // Read data and save to buffer
 }
 // clear flag
 SPSR = 0x00;
 PORTB |= NRF905_CSN;

 // switch to RX mode
 PORTB |= NRF905_TRX_CE;
 nrf_wait(20);

 return 0;
}

// 接收中断函数
SIGNAL(SIG_INTERRUPT1)
{
 rx_pkt_905.len = 32;
 nrf_receive_packet(rx_pkt_905.buf, &(rx_pkt_905.len));
 rx_flag_905 = 1;
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客