|
最近接触nRF24L01无线发射模块,我在调试的过程中碰到了一个问题,让我很郁闷。
我用的芯片是AVR16,从51上移植到16上的。开始直接用AVR SPI的功能,数据从另一片24L01能正常发射出去,另外一片24L01也能正常的接收数据,接收来的数据从串口发出。后来觉得每次都连着计算机来显示接收到的数据,所以加了数码管显示功能。因为用的是学习板,PORTB口接共阳的数码管,所以就不再用AVR的SPI功能了,改用PORTD口来模拟SPI,问题就来了。数据能经24L01发射,但是另外一片接收到的数据是错的(总是接收FF)。也不知道出错再哪里,希望这里的朋友帮我分析一下。
发射部分:
#include"avr/io.h"
#include"Allhead.h"
#include<util/delay.h>
extern uchar dis_buff[4]; //显示缓冲器
/*********************主函数***************************/
int main(void)
{
LAMP_DDR |= _BV(LAMP2); //指示灯
uchar i=3;
uint tt=1234,temp=0;
uchar tx_buff[TX_DATA_WIDTH]; //发射缓存器
timer0_init(); //定时器0初始化
spi_master_init(); //spi初始化
nrf_io_init(); //nRF24L01初始化
nrf_tx_mode(); //nRF24L01设置为发射模式
LAMP2_CLR(); //初始化成功指示
_delay_ms(1500);
LAMP2_SET();
while(1)
{
for(i=3,temp=tt;i!=0xff;i--)
{
dis_buff[i]=temp%10;
temp/=10;
} //把需要发射的16bit数各位分解出来,放到显示缓冲器里
/************以字符发射*************/
tx_buff[0]='0'+dis_buff[0];
tx_buff[1]='0'+dis_buff[1];
tx_buff[2]='0'+dis_buff[2];
tx_buff[3]='0'+dis_buff[3];
nrf_write_dats(WR_TX_PAYLOAD,tx_buff,TX_DATA_WIDTH);//把需要发射的数据写入nRF24L01
while(IRQ_STA()); //等待发射完成
nrf_ack(); //清空nRF24L01发射缓存,请中断,清…………
/************发射完成指示***********/
LAMP2_SET();
_delay_ms(500);
LAMP2_CLR();
_delay_ms(500);
/***********待发送的变量自加************/
if(tt>9999) tt=0;
tt++;
}
return 0;
}
接收部分:
#include<avr/io.h>
#include<util/delay.h>
#include<Allhead.h>
#include<avr/interrupt.h>
extern uchar dis_buff[4];
/************************主函数********************/
int main(void)
{
uchar rec_buff[RX_DATA_WIDTH];
timer0_init();
spi_master_init();
uart_init();
nrf_io_init();
nrf_rx_mode();
put_str("初始化成功,通讯正常……");
put_char('\r');put_char('\n');
put_str("准备接收以下数据");
_delay_ms(3000);
while(1)
{
put_char('\r');put_char('\n');
//接收到数据
if(!IRQ_STA())
{
nrf_ack();
nrf_read_dats(RD_RX_PAYLOAD,rec_buff,RX_DATA_WIDTH);
put_str("NRF24L01接收的数据:");
for(uchar i=0;i<RX_DATA_WIDTH;i++)
{
put_char(rec_buff[i]);
dis_buff[i]=rec_buff[i]-'0';
}
}
//接收不到数据,数码管显示 - - - -
else
{
put_str("NRF24L01接收的数据:nothing");
for(uchar i=0;i<4;i++)
dis_buff[i]=11;
}
_delay_ms(1500);
}
}
SPI操作时序相关:
#include"avr/io.h"
#include"util/delay.h"
#include"Allhead.h"
void spi_master_init(void)
{
//设置SKC\CE\MOSI\CSN为输出,IRQ\MISO为输入
SPI_DDR |= _BV(SCK)|_BV(CE)|_BV(MOSI)|_BV(CSN);
SPI_DDR &=~_BV(IRQ)&~_BV(MISO);
//SPI使能,主机模式,16分频
//SPCR |= _BV(SPE)|_BV(MSTR)|_BV(SPR0);
}
/*
uchar spi_transmit(uchar dat)
{
SPDR = dat;
while(!(SPSR & _BV(SPIF)));
SPSR |= _BV(SPIF);
return SPDR;
}
*/
uchar spi_transmit(uchar date)
{
uchar i;
for(i=0;i<8;i++) // 循环8次
{
//byte最高位输出到MOSI
if(date&0x80)
MOSI_SET();
else
MOSI_CLR();
date<<=1;
// 低一位移位到最高位
SCK_SET();
if(MISO_GET()) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
date|=0x01; // 读MISO到byte最低位
SCK_CLR();
}
_delay_us(40);
return date; // 返回读出的一字节
}
为了方便调试,我在这个.c的文件里做了两个spi_transmit的函数,一个是AVR自身功能的,一个是模拟的。
还有端口、引脚、引脚操作的宏定义
#ifndef _PIN_H_
#define _PIN_H_
/****************spi端口**************************/
#define SPI_DDR DDRD
#define SPI_PORT PORTD
#define SPI_PIN PIND
/*****************指示灯端口********************/
#define LAMP_PORT PORTD
#define LAMP_DDR DDRD
#define LAMP_PIN PIND
/*****************串口********************/
#define UART_PORT PORTD
#define UART_DDR DDRD
#define UART_PIN PIND
/****************spi引脚定义*********************/
#define CE 2
#define IRQ 3
#define CSN 4
#define MOSI 5
#define MISO 6
#define SCK 7
/****************灯引脚定义*********************/
#define LAMP2 1
/****************串口引脚定义*********************/
#define RXD 0
#define TXD 1
/****************spi引脚操作定义******************/
#define CE_SET() SPI_PORT |= _BV(CE)
#define CE_CLR() SPI_PORT &=~_BV(CE)
#define IRQ_STA() (SPI_PIN & _BV(IRQ))
#define SPI_EN() SPI_PORT &=~_BV(CSN)
#define SPI_DI() SPI_PORT |= _BV(CSN)
#define IRQ_CLR() SPI_PORT |= _BV(IRQ)
#define MOSI_CLR() SPI_PORT &=~_BV(MOSI)
#define MOSI_SET() SPI_PORT |= _BV(MOSI)
#define SCK_CLR() SPI_PORT &=~_BV(SCK)
#define SCK_SET() SPI_PORT |= _BV(SCK)
#define MISO_GET() (SPI_PIN &= _BV(MISO))
/****************灯引脚操作定义******************/
#define LAMP2_SET() LAMP_PORT |= _BV(LAMP2)
#define LAMP2_CLR() LAMP_PORT &=~_BV(LAMP2)
/******************结束**************************/
#endif
最后上图片
发射板
xx,传不了图片。算了! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|