|
发表于 2008-5-24 09:46:00
|
显示全部楼层
麻烦帮我看看程序哪出问题了?是在楼主提供的程序基础上修改的。调试过程:发射端附一个确定字符串“a”,接受端用LCM1602液晶屏显示接受到的数据。可是通信一直没有实现。补充:我用的是MEGA128+PTR905.已在nRF905.h中改了端口
源程序如下:
发射端程序
#include <iom128v.h>
#include "nRF905_Config.h"
#include "nRF905.h"
#include <macros.h>
unsigned char ReceiveBuffer[BUF_SIZE]; // RF接收缓冲区
unsigned char SendBuffer[BUF_SIZE]; // RF发送缓冲区
unsigned char ReceiveCount; // RF接收缓冲区接收个数
unsigned char SendCount; // RF发送缓冲区发送个数
#define xtal 7.3728
//晶振调整 MHz
void _delay_ms(unsigned int ms) //毫秒级延时,当改晶振为几M则xtal设为几
{
unsigned int i;
while(ms--)
{
for(i=1;i<(unsigned int)(xtal*143-2);i++);
}
}
void SPI_Init(void)
{
PORT_SPI |= (1<<MOSI)|(1<<MISO)|(1<<SCK)|(1<<SS); // 设置MOSI和SCK、SS为输出,其他为输入
DDR_SPI |= (1<<MOSI)|(1<<SCK)|(1<<SS);
SPCR = (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<SPR0); // 主机模式,fck/16, SPI方式0
}
unsigned char SPI_ReadWrite(unsigned char cData)
{
SPDR = cData;
while(!(SPSR & (1<<SPIF) )); // 等待SPI发送完毕
return SPDR;
}
void nRF905_Init(unsigned long nRF_rxaddr)
{
unsigned char i;
DDR_NRF905 |= ((1<<TX_EN)|(1<<TRX_CE)|(1<<PWR_UP)|(0<<DR)|(0<<AM)|(0<<CD));
PORT_NRF905 |= ((0<<TX_EN)|(0<<TRX_CE)|(1<<PWR_UP)|(1<<DR)|(1<<AM)|(1<<CD));
nRF905_SetConfig(nRF_rxaddr); // 初始化nRF905,并设置接收地址
nRF905_SetReceiveMode(); // 设置为接收模式
/* 发送缓冲区清零 */
for(i = 0; i < BUF_SIZE; ++i)
{SendBuffer = 0;}
}
unsigned char nRF905_ReadStatus(void)
{
unsigned char val;
CLR_SS(); // 打开SPI
val = SPI_ReadWrite(RC); // 读状态
SET_SS(); // 关闭SPI
return val;
}
void nRF905_SetSendMode(void)
{
_delay_ms(1);
SET_TX_EN(); // 设置为发送模式
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
_delay_ms(1);
CLR_TRX_CE(); // 待机PORTD &= ~(1<<TRX_CE);
_delay_ms(1);
}
void nRF905_SetReceiveMode(void)
{
asm("nop");
asm("nop");
asm("nop");
CLR_TX_EN(); // 设置为接收模式
asm("nop");
_delay_ms(1);
SET_TRX_CE(); // 使能接收
asm("nop");
asm("nop");
asm("nop");
_delay_ms(1);
}
void nRF905_SendStart(void)
{
SET_TRX_CE(); // 开始发送
_delay_ms(10);
while(DR!=1);
CLR_TRX_CE(); // 待机模式
}
void nRF905_SetConfig(unsigned long nRFAddr) //配置nRF905
{
CLR_TRX_CE(); //设置nRF905为待机方式
asm("nop");
CLR_SS(); //打开SPI
// 配置字总共10个字节
SPI_ReadWrite(WC); // Write config command
SPI_ReadWrite(CH_NO_BYTE); // 中心频率低8位
SPI_ReadWrite(PA_PWR_10dBm | HFREQ_PLL_433MHz); // 发射+10dBm,发射频率433MHz,中心频率第9位=0
SPI_ReadWrite(TX_AFW_4BYTE | RX_AFW_4BYTE); // 接收地址宽度4字节,发送地址宽度4字节 0100 0100
SPI_ReadWrite(RX_PW_32BYTE); // 接收数据宽度32字节
SPI_ReadWrite(TX_PW_32BYTE); // 发送数据宽度32字节
SPI_ReadWrite((nRFAddr >> 24)); // 接收有效地址第1字节
SPI_ReadWrite((nRFAddr >> 16) & 0xff); // 接收有效地址第2字节
SPI_ReadWrite((nRFAddr >> 8) & 0xff); // 接收有效地址第3字节
SPI_ReadWrite(nRFAddr & 0xff); // 接收有效地址第4字节
SPI_ReadWrite(CRC16_EN | XOF_16MHz); // CRC16模式使能,晶体振荡器频率16MHz
SET_SS(); // 关闭SPI
if ( PORT_NRF905 & (1 << TX_EN) ) //再回到原来的无线收发模式
{
CLR_TRX_CE(); //设置nRF905为待机方式
}
else
{
SET_TRX_CE(); //设置nRF905为工作方式
}
}
/* 参数为接收端的地址,即:发送给谁? */
void nRF905_SendPacket(unsigned long nRF_rxaddr)
{
unsigned char i;
if( (PIN_NRF905 & ((1<<CD)|(1<<AM)|(1<<DR))) == 0 ) // 周边无射频信号
{
nRF905_SetSendMode();
//LED_ON();
asm("nop");
asm("nop");
asm("nop");
_delay_ms(1);
CLR_SS();
SPI_ReadWrite(WTA); // 写发送地址
SPI_ReadWrite((nRF_rxaddr >> 24)); // 接收有效地址第1字节
SPI_ReadWrite((nRF_rxaddr >> 16) & 0xff); // 接收有效地址第2字节
SPI_ReadWrite((nRF_rxaddr >> 8) & 0xff); // 接收有效地址第3字节
SPI_ReadWrite(nRF_rxaddr & 0xff); // 接收有效地址第4字节
SET_SS();
asm("nop");
asm("nop");
asm("nop");
CLR_SS();
SPI_ReadWrite(WTP);
for( i = 0; i < 32; ++i )
{
SPI_ReadWrite(SendBuffer);
}
SET_SS();
SendCount = 32;
nRF905_SendStart(); // 开始发送
nRF905_SetReceiveMode(); // 发送完毕回到接收模式
//LED_OFF();
}
}
/* 发送端代码 */
//----------------------------------------------------------------------------------
void main()
{
char SendBuffer[32]="a";
SPI_Init();
nRF905_Init(RX_ADDRESS);
/* ****************************
* 发送数据包格式如下
* 0xaa length B0 B1 B2 ... Bn 0x55
*******************************/
/*SendBuffer[0] = 0xaa;
SendBuffer[1] = 2; // 数据包大小 2
SendBuffer[2] = 0x12;
SendBuffer[3] = 0xab;
SendBuffer[4] = 0x55; */
while(1)
{
//液晶显示程序
CLI();
DDRD = 0X00;
PORTD = 0XFF;
EIMSK = 0b00000001;
EIFR = 0Xff;
EICRA = 0X00;
EICRB = 0X00;
SEI();
PORTA = 0X00;
DDRA = 0X02;
DDRD |= LCD_DATA;
DDRC |= LCD_RS | LCD_EN;
LCD_EN_PORT &= ~LCD_EN; //EN=0
LCD_init();
LCD_write_char(0,0x01); //显示清屏
delay_nms(2);
LCD_write_string(1,0,"Transmitting...");
LCD_write_string(7,1,SendBuffer);
/*if( flag == 1 )
{
nRF905_SendPacket(RX_ADDRESS);
flag = 0;
}
if( PIN_NRF905 & (1<<DR) )
{
nRF905_ReceivePacket();
if( ReceiveBuffer[0] == 0x55 )
{
flag = 1;
ReceiveBuffer[0] = 0;
}
} */
nRF905_SendPacket(TX_ADDRESS);
_delay_ms(1000);
}
}
接受端程序如下:
#include <iom128v.h>
#include "nRF905_Config.h"
#include "nRF905.h"
#include <macros.h>
#include <math.h> //液
#include <stdio.h> //晶
#include "1602LCD.h"//屏
#include <stdlib.h> //应
#include <string.h> //用
unsigned char ReceiveBuffer[BUF_SIZE]; // RF接收缓冲区
unsigned char ReceiveCount; // RF接收缓冲区接收个数
unsigned char SendCount; // RF发送缓冲区发送个数
#define xtal 7.3728
//晶振调整 MHz
void _delay_ms(unsigned int ms) //毫秒级延时,当改晶振为几M则xtal设为几
{
unsigned int i;
while(ms--)
{
for(i=1;i<(unsigned int)(xtal*143-2);i++);
}
}
void SPI_Init(void)
{
PORT_SPI |= (1<<MOSI)|(1<<MISO)|(1<<SCK)|(1<<SS); // 设置MOSI和SCK、SS为输出,其他为输入
DDR_SPI |= (1<<MOSI)|(1<<SCK)|(1<<SS);
SPCR = (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(0<<SPR0); // 主机模式,fck/16, SPI方式0
}
unsigned char SPI_ReadWrite(unsigned char cData)
{
SPDR = cData;
while(!(SPSR & (1<<SPIF) )) ; // 等待SPI发送完毕
return SPDR;
}
void nRF905_Init(unsigned long nRF_rxaddr)
{
unsigned char i;
DDR_NRF905 |= ((1<<TX_EN)|(1<<TRX_CE)|(1<<PWR_UP)|(0<<DR)|(0<<AM)|(0<<CD));
PORT_NRF905 |= ((0<<TX_EN)|(0<<TRX_CE)|(1<<PWR_UP)|(1<<DR)|(1<<AM)|(1<<CD));
nRF905_SetConfig(nRF_rxaddr); // 初始化nRF905,并设置接收地址
/* 接收缓冲区清零 */
for(i = 0; i < BUF_SIZE; ++i)
{
ReceiveBuffer = 0;
}
}
unsigned char nRF905_ReadStatus(void)
{
unsigned char val;
CLR_SS(); // 打开SPI
val = SPI_ReadWrite(RC); // 读状态
SET_SS(); // 关闭SPI
return val;
}
void nRF905_SetSendMode(void)
{
_delay_ms(1);
SET_TX_EN(); // 设置为发送模式
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
_delay_ms(1);
CLR_TRX_CE(); // 待机PORTD &= ~(1<<TRX_CE);
_delay_ms(1);
}
void nRF905_SetReceiveMode(void)
{ asm("nop");
asm("nop");
asm("nop");
CLR_TX_EN(); // 设置为接收模式
asm("nop");
_delay_ms(1);
SET_TRX_CE(); // 使能接收
asm("nop");
asm("nop");
asm("nop");
_delay_ms(1);
}
void nRF905_SendStart(void)
{
SET_TRX_CE(); // 开始发送
_delay_ms(10); // while(DR!=1);
CLR_TRX_CE(); // 待机模式
}
void nRF905_SetConfig(unsigned long nRFAddr) //配置nRF905
{
CLR_TRX_CE(); //设置nRF905为待机方式
asm("nop");
CLR_SS(); //打开SPI
// 配置字总共10个字节
SPI_ReadWrite(WC); // Write config command
SPI_ReadWrite(CH_NO_BYTE); // 中心频率低8位
SPI_ReadWrite(PA_PWR_10dBm | HFREQ_PLL_433MHz); // 发射+10dBm,发射频率433MHz,中心频率第9位=0
SPI_ReadWrite(TX_AFW_4BYTE | RX_AFW_4BYTE); // 接收地址宽度4字节,发送地址宽度4字节 0100 0100
SPI_ReadWrite(RX_PW_32BYTE); // 接收数据宽度32字节
SPI_ReadWrite(TX_PW_32BYTE); // 发送数据宽度32字节
SPI_ReadWrite((nRFAddr >> 24)); // 接收有效地址第1字节
SPI_ReadWrite((nRFAddr >> 16) & 0xff); // 接收有效地址第2字节
SPI_ReadWrite((nRFAddr >> 8) & 0xff); // 接收有效地址第3字节
SPI_ReadWrite(nRFAddr & 0xff); // 接收有效地址第4字节
SPI_ReadWrite(CRC16_EN | XOF_16MHz); // CRC16模式使能,晶体振荡器频率16MHz
SET_SS(); // 关闭SPI
if ( PORT_NRF905 & (1 << TX_EN) ) //再回到原来的无线收发模式
{
CLR_TRX_CE(); //设置nRF905为待机方式
}
else
{
SET_TRX_CE(); //设置nRF905为工作方式
}
}
void nRF905_ReceivePacket(void)
{
unsigned char i;
nRF905_SetReceiveMode(); // 设置接收模式
// CD=1且AM=0,DR=0
if( ( PIN_NRF905 & (1<<CD) ) && ((PIND & ((1<<AM)|(1<<DR)) ) == 0) )
{
CLR_TRX_CE(); // 待机模式
asm("nop");
CLR_SS();
SPI_ReadWrite(RRP);
for(i = 0; i < 32; ++i)
{
ReceiveBuffer = SPI_ReadWrite(0xff);
}
SET_SS();
while(PIN_NRF905 & ((1<<AM)|(1<<DR)) ); // 等待
ReceiveCount = 32;
SET_TRX_CE();
// LED_ON();
}
}
/* 接收端代码 */
void main(void)
{ SPI_Init();
nRF905_Init(RX_ADDRESS);
//液晶显示程序
CLI();
DDRD = 0X00;
PORTD = 0XFF;
EIMSK = 0b00000001;
EIFR = 0Xff;
EICRA = 0X00;
EICRB = 0X00;
SEI();
PORTA = 0X00;
DDRA = 0X02;
DDRD |= LCD_DATA;
DDRC |= LCD_RS | LCD_EN;
LCD_EN_PORT &= ~LCD_EN; //EN=0
LCD_init();
LCD_write_char(0,0x01); //显示清屏
delay_nms(2);
LCD_write_string(2,0,"Receiving...");
while(1){
if( PIN_NRF905 & (1<<DR) )
{
nRF905_ReceivePacket();
LCD_write_string(6,1,"a");
}
}
} |
|