|
本帖最后由 维C1° 于 2013-11-30 20:05 编辑
nrf24l01是用普通引脚来模拟SPI时序的,在裸机上调试成功了,可以发射可以接收,但是把它丢到驱动里,就出问题了.发送数据不成功。以下是驱动内容,麻烦各位帮个忙看看,我调了好久了。
这里由于字数要求省去头文件的定义了
#define DEVICE_NAME "NRF24L01" //设备名称
//引脚相关的宏定义
#define CSN S3C2410_GPG0
#define CSN_OUTP S3C2410_GPG0_OUTP
#define CE S3C2410_GPG3
#define CE_OUTP S3C2410_GPG3_OUTP
#define MOSI S3C2410_GPG5
#define MOSI_OUTP S3C2410_GPG5_OUTP
#define SCK S3C2410_GPG6
#define SCK_OUTP S3C2410_GPG6_OUTP
#define MISO S3C2410_GPG7
#define MISO_INP S3C2410_GPG7_INP
#define IRQ S3C2410_GPG11
#define IRQ_INP S3C2410_GPG11_INP
//NRF24L01端口定义
#define CE_OUT s3c2410_gpio_cfgpin(CE, CE_OUTP)
#define CE_UP s3c2410_gpio_pullup(CE, 1)
#define CE_L s3c2410_gpio_setpin(CE, 0)
#define CE_H s3c2410_gpio_setpin(CE, 1)
#define SCK_OUT s3c2410_gpio_cfgpin(SCK, SCK_OUTP)
#define SCK_UP s3c2410_gpio_pullup(SCK, 1)
#define SCK_L s3c2410_gpio_setpin(SCK, 0)
#define SCK_H s3c2410_gpio_setpin(SCK, 1)
#define MISO_IN s3c2410_gpio_cfgpin(MISO, MISO_INP)
#define MISO_STU s3c2410_gpio_getpin(MISO)
#define IRQ_IN s3c2410_gpio_cfgpin(IRQ, IRQ_INP)
#define IRQ_STU s3c2410_gpio_getpin(IRQ)
#define MOSI_OUT s3c2410_gpio_cfgpin(MOSI, MOSI_OUTP)
#define MOSI_UP s3c2410_gpio_pullup(MOSI, 1)
#define MOSI_L s3c2410_gpio_setpin(MOSI, 0)
#define MOSI_H s3c2410_gpio_setpin(MOSI, 1)
#define CSN_OUT s3c2410_gpio_cfgpin(CSN, CSN_OUTP)
#define CSN_UP s3c2410_gpio_pullup(CSN, 1)
#define CSN_L s3c2410_gpio_setpin(CSN, 0)
#define CSN_H s3c2410_gpio_setpin(CSN, 1)
//NRF24L01
#define TX_ADDR_WITDH 5 // 5 uint8s TX address width
#define RX_ADDR_WITDH 5 // 5 uint8s RX address width
#define TX_DATA_WITDH 4 // 20 uint8s TX payload
#define RX_DATA_WITDH 4 // 20 uint8s TX payload
(因为字数的限制,这里略去一些NRF24L01寄存器指令 和寄存器地址的宏定义声明了)
...............................................
//全局变量
U8 TxBuf[4]={ 0x00,0x00,0x00,0x00};
U8 test_TxBuf[4]={ 0x01,0x01,0x00,0x00};
U8 opencount = 0;
U8 TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址
U8 RevTempDate[5];//最后一位用来存放结束标志
void NRFDelay(U16 t)
{
unsigned int x,y;
for(x=t;x>0;x--)
for(y=20;y>0;y--);
}
//NRF24L01初始化
U8 NRF24L01Int(void)
{
NRFDelay(2);//让系统什么都不干
CE_UP;
CSN_UP;
SCK_UP;
MOSI_UP;
CE_OUT;
CSN_OUT;
SCK_OUT;
MOSI_OUT;
MISO_IN;
IRQ_IN;
udelay(500);
CE_L;
ndelay(60);
CSN_H;
ndelay(60);
SCK_L;
ndelay(60); 这里我有一个疑问,这个延时函数好像延时不对, ndelay(1) ,ndelay(10)的延时时间一样,这是怎么回事?
return 1;
}
//功能:NRF24L01的SPI写时序
U8 NRFSPI(U8 date)
{
U8 i;
for(i=0 ;i<8 ;i++)
{
if(date & 0x80)
MOSI_H;
else
MOSI_L;
date=date<<1;
SCK_H;
ndelay(10); 在裸机上这些延时不需要写,在驱动上,有网友说要参照24l01的手册来加延时,但是
加上必要的延时也没有什么作用啊
date |= MISO_STU;
SCK_L;
ndelay(10);
}
return(date);
}
//NRF24L01的SPI时序
U8 NRFReadReg(U8 RegAddr)
{
U8 BackDate;
CSN_L;
ndelay(10);
NRFSPI(RegAddr);
BackDate=NRFSPI(0x00);
CSN_H;
ndelay(70);
return(BackDate);
}
//NRF24L01读写寄存器函数
U8 NRFWriteReg(U8 RegAddr,U8 date)
{
U8 BackDate;
CSN_L;
BackDate=NRFSPI(RegAddr);//写入地址
NRFSPI(date);//写入值
CSN_H;
return(BackDate);
}
//SPI读取RXFIFO寄存器的值
U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen)
{ U8 BackDate,i;
CSN_L; //启动时序
BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址
for(i=0;i<DateLen;i++) //读取数据
{
RxDate=NRFSPI(0);
ndelay(1);
}
CSN_H;
return(BackDate);
}
//SPI写入TXFIFO寄存器的值
U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen)
{ U8 BackDate,i;
CSN_L;
BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址
for(i=0;i<DateLen;i++)//写入数据
{
NRFSPI(*TxDate++);
ndelay(1);
}
CSN_H;
return(BackDate);
}
//NRF设置为发送模式并发送数据
void NRFSetTxMode(U8 *TxDate)
{ //发送模式
CE_L;
NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+P0地址使能指令+发送地址+地址宽度
NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同
NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据
/******下面有关寄存器配置**************/
NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答
NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0
NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次
NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40
NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
NRFWriteReg(W_REGISTER+CONFI_G,0x0e); // CRC使能,16位CRC校验,上电
CE_H;
mdelay(1);
}
//NRF设置为接收模式并接收数据
//接收模式
void NRFSetRXMode(void)
{
CE_L;
NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址
NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答
NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0
NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40
NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度
NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
NRFWriteReg(W_REGISTER+CONFI_G,0x0f); // CRC使能,16位CRC校验,上电,接收模式
CE_H;
NRFDelay(30);
}
U8 CheckACK(void)
{
U8 sta;
sta=NRFReadReg(R_REGISTER+STATUS);
if((sta&0x20)||(sta&0x10))
{
NRFWriteReg(W_REGISTER+STATUS,0XFF);
CSN_L;
NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!
CSN_H;
return 0;
}
else
return 1;
}
//文件的写函数
static int nrf24l01_write(struct file *filp, const char *buffer,size_t count)
{
if(copy_from_user(TxBuf,buffer,count)) //从内核空间复制到用户空间
{
printk("Can't Send Data! " ) ;
return -EFAULT;
}
NRFSetTxMode(TxBuf);
if(!CheckACK())
{
printk ( "Write Success!\n" ) ;
}
else
printk ( "Write Faild!\n" ) ;
return 1;
}
//的读函数
static int nrf24l01_read(struct file *filp, char *buffer,size_t count)
{
U8 sta;
NRFSetRXMode();
sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器
if(sta & 0x40) // 判断是否接收到数据
{
CE_L; //待机
NRFReadRxDate(R_RX_PAYLOAD,RevTempDate,RX_DATA_WITDH);// 从RXFIFO读取数据 接收4位即可,后一位位结束位
NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标
//return(1); //读取数据完成标志
}
NRFWriteReg(W_REGISTER+STATUS,0xff);
printk("read \n" ) ;
}
static int nrf24l01_open(struct inode *node, struct file *file)
{
U8 flag = 0,a=1;
if(opencount == 1) return -EBUSY;
flag = NRF24L01Int();
/*
while(1)
{
CE_H;
ndelay(10); 我是在这里测延时函数的延时时间的,用示波器看引脚电平的变化,测出来 ndelay()延时不准确
CE_L;
ndelay(1);
}
*/
if(flag == 0)
{
printk("uable to open device!\n" ) ;
return -1;
}
else
{
opencount++;
printk("device opened !\n" ) ;
return 0;
}
}
static int nrf24l01_release(struct inode *node, struct file *file)
{
opencount--;
printk(DEVICE_NAME " released !\n");
return 0;
}
static struct file_operations nrf24l01_fops = {
.owner = THIS_MODULE,
.write = nrf24l01_write,
.read = nrf24l01_read,
.release = nrf24l01_release,
.open=nrf24l01_open,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &nrf24l01_fops,
};
static int __init nrf24l01_init(void)
{
int ret;
printk("Initial driver for NRF24L01......................\n" ) ;
ret = misc_register(&misc);
mdelay(10);
if (ret < 0)
{
printk(DEVICE_NAME " can't register major number\n");
return ret;
}
else
{
printk(DEVICE_NAME " register success\n");
return 0;
}
}
static void __exit nrf24l01_exit(void)
{
misc_deregister(&misc);
printk("NRF24L01 unregister success \n" ) ;
}
module_init(nrf24l01_init);
module_exit(nrf24l01_exit);
|
|