找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4666|回复: 6
打印 上一主题 下一主题
收起左侧

NRF24L01 spi 1602液晶显示的奇怪的问题

[复制链接]
跳转到指定楼层
楼主
      近段时间搞NRF24L01无线模块,头发掉了好几根。有一些疑问,还请指点。
1.SPI_Read(uchar reg )中的reg_val = SPI_RW(0)如何理解,为什么写0后就可读出寄存器中的值了。
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
       uchar reg_val;
       CSN = 0;                // CSN low, initialize SPI communication...
       SPI_RW(reg);            // Select register to read from..
       reg_val = SPI_RW(0);    // ..then read registervalue
       CSN = 1;                // CSN high, terminate SPI communication
       return(reg_val);        // return register value
}
2.SPI_RW(uint uchar)最终uchar是返回状态寄存器STAUS(地址0x07)里面的值吗?
**********************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
       uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
              MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
              uchar = (uchar << 1);          // shift next bit into MSB..
              SCK = 1;                       // Set SCK high..
              uchar |= MISO;                 // capture current MISO bit
              SCK = 0;                       // ..then set SCK low again
    }
    return(uchar);                     // return read uchar
}
3.    自己从别人的程序里修改一下,做了个最简的小程序来查看NRF24L01寄存器里面的值,结果就出现也问题,怎么想也想不出问题在哪。本意是在NRF24L01上电后,先读出寄存器EN_AA里面的值,让它显示在液晶1602的第一行第一个位值,期望值是063。NRF24L01上电后,EN_AA默认值是 0011 1111,即十进制63。然后向EN_AA写入了0x01,再读出EN_AA里面的值,让它显示在液晶1602的第二行第一个位值,期望值显示的是001。
      结果是液晶1602第一行一开始时是显示063,第二行显示是001,但很快第一行显示变成和第二行一样,即显示001。而且第二行的001不断在闪。不知怎么回事,求指教。程序实际较少,我附在楼下了。还望指点迷津!

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:65751 发表于 2014-9-10 10:23 | 只看该作者
本帖最后由 codenew 于 2014-9-10 20:57 编辑

      本意是在NRF24L01上电后,先读出寄存器EN_AA里面的值,让它显示在液晶1602的第一行第一个位值,期望值是063。NRF24L01上电后,EN_AA默认值是 0011 1111,即十进制63。然后向EN_AA写入了0x01,再读出EN_AA里面的值,让它显示在液晶1602的第二行第一个位值,期望值显示的是001。下面是正常显示的图和程序:

#include<reg51.h>   
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
unsigned char code digit[10]={"0123456789"};        //定义字符数组显示数字
//*********NRF24L01 IO端口定义**********//                                    
sbit  MISO =P1^2;
sbit  MOSI =P1^3;
sbit  SCK  =P1^4;
sbit  CE   =P1^6;
sbit  CSN  =P1^5;
sbit  IRQ  =P1^0;
sbit rs=P3^3;//LCD数据/命令选择端(H/L)
sbit rw=P3^4;//LCD/写选择端(H/L)
sbit en=P3^5;//LCD使能控制
//*************NRF24L01寄存器指令***********//
#define READ_REG        0x00   // 读寄存器指令
#define WRITE_REG       0x20   // 写寄存器指令
//*************SPI(nRF24L01)寄存器地址********//
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
void inerDelay_us(unsigned char n);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
uint SPI_RW_Reg(uchar reg, uchar value);
void delays(uint x);
void write_com(uchar com);
void display_temp1(unsigned char x);
void write_date(uchar date);
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{     
         unsigned int TN;  
         unsigned int TD;  
        uchar i=0;
         //BEEP=0;          //防止蜂鸣器的电流声
       inerDelay_us(100);
       CE=0;    // chip enable
       CSN=1;   // Spi disable
       SCK=0;   // Spi clock line init high
       write_com(0x38);   //设置工作方式
       write_com(0x0c);   //设置光标
       write_com(0x06);   //设置输入方式
       write_com(0x01);   //清屏
      
                       
                                 TN=SPI_Read(EN_AA);
                                   write_com(0x80);
                                   display_temp1(TN);     //期望值是063(十进制),NRF24L01上电后,EN_AA默认值是 0011 1111,即十进制63
                                   
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                                   
                                   SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                              
                                  TD=SPI_Read(EN_AA);
                                   write_com(0x80+0x40);      
                                   display_temp1(TD);     //期望值是001,因为前面向EN_AA写入了0x01
                                delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
}
/*****************************************************
函数功能:显示十进制数
入口参数:x
***************************************************/
void display_temp1(unsigned char x)
{
       unsigned char j,k,l;     //j,k,l分别储存温度的百位、十位和个位
       j=x/100;              //取百位
       k=(x%100)/10;         //取十位
       l=x%10;               //取个位  
       write_date(digit[j]);    //将百位数字的字符常量写入LCD
       write_date(digit[k]);    //将十位数字的字符常量写入LCD
       write_date(digit[l]);    //将个位数字的字符常量写入LCD
       //write_date('.');               //小数点
       delays(50);           //延时1ms给硬件一点反应时间     
}           
      
/***********1602液晶显示部分子程序****************/
void write_com(uchar com)
{
       rs=0;//命令
       rw=0;
       P0=com;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
void write_date(uchar date)
{
       rs=1;//数据
       rw=0;
       P0=date;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
       uint status;
       CSN = 0;                   // CSN low, init SPI transaction
       status = SPI_RW(reg);      // select register
       SPI_RW(value);             // ..and write value to it..
       CSN = 1;                   // CSN high again
       return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01SPI时序
/*详细请参考Page19
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
       uchar reg_val;
       CSN = 0;                // CSN low, initialize SPI communication...
       SPI_RW(reg);            // Select register to read from..
       reg_val = SPI_RW(0);    // ..then read registervalue
       CSN = 1;                // CSN high, terminate SPI communication
       return(reg_val);        // return register value
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01SPI写时序
/*详细请参考Page19
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
       uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
              MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
              uchar = (uchar << 1);          // shift next bit into MSB..
              SCK = 1;                       // Set SCK high..
              uchar |= MISO;                 // capture current MISO bit
              SCK = 0;                       // ..then set SCK low again
    }
    return(uchar);                     // return read uchar
}
//*****************长延时*********************************//
void delays(uint x) //毫秒级延时函数
{
  uint i,j;
  for(i=x;i>0;i--)
     for(j=110;j>0;j--);
}
//********************************************************//
//*延时函数
//********************************************************//
void inerDelay_us(unsigned char n)
{  
for(;n>0;n--)
  _nop_();
}

正常.jpg (61.5 KB, 下载次数: 104)

正常

正常
回复

使用道具 举报

板凳
ID:65751 发表于 2014-9-10 10:36 | 只看该作者
本帖最后由 codenew 于 2014-9-10 20:58 编辑

下面程序第一行先显示063,第二行先显示001,很快第一行变成001,而且第二行的001还在不断闪。

#include<reg51.h>   
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
unsigned char code digit[10]={"0123456789"};        //定义字符数组显示数字
//*********NRF24L01 IO端口定义**********//                                    
sbit  MISO =P1^2;
sbit  MOSI =P1^3;
sbit  SCK  =P1^4;
sbit  CE   =P1^6;
sbit  CSN  =P1^5;
sbit  IRQ  =P1^0;
//***液晶1602定义,数据口接P0**//
sbit rs=P3^3;//LCD数据/命令选择端(H/L)
sbit rw=P3^4;//LCD/写选择端(H/L)
sbit en=P3^5;//LCD使能控制
//*************NRF24L01寄存器指令***********//
#define READ_REG        0x00   // 读寄存器指令
#define WRITE_REG       0x20   // 写寄存器指令
//*************SPI(nRF24L01)寄存器地址********//
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
void inerDelay_us(unsigned char n);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
uint SPI_RW_Reg(uchar reg, uchar value);
void delays(uint x);
void write_com(uchar com);
void display_temp1(unsigned char x);
void write_date(uchar date);
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{     
         unsigned int TN;  
         unsigned int TD;  
       inerDelay_us(100);
       CE=0;    // chip enable
       CSN=1;   // Spi disable
       SCK=0;   // Spi clock line init high
       write_com(0x38);   //设置工作方式
       write_com(0x0c);   //设置光标
       write_com(0x06);   //设置输入方式
       write_com(0x01);   //清屏     
                       
                                 TN=SPI_Read(EN_AA);
                                   write_com(0x80);
                                   display_temp1(TN);// 期望值显示的是063(十进制),NRF24L01上电后,EN_AA默认值是 0011 1111,即十进制63
                                   
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                                   
                                   SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                              
                                  TD=SPI_Read(EN_AA);
                                   write_com(0x80+0x40);      
                                   display_temp1(TD); //期望值显示的是001,因为前面向EN_AA写入了0x01
                                delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
}
/*****************************************************
函数功能:显示十进制数
入口参数:x
***************************************************/
void display_temp1(unsigned char x)
{
       unsigned char j,k,l;     //j,k,l分别储存温度的百位、十位和个位
       j=x/100;              //取百位
       k=(x%100)/10;         //取十位
       l=x%10;               //取个位  
       write_date(digit[j]);    //将百位数字的字符常量写入LCD
       write_date(digit[k]);    //将十位数字的字符常量写入LCD
       write_date(digit[l]);    //将个位数字的字符常量写入LCD
       delays(50);           //延时1ms给硬件一点反应时间     
}           
      
/***********1602液晶显示部分子程序****************/
void write_com(uchar com)
{
       rs=0;//命令
       rw=0;
       P0=com;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
void write_date(uchar date)
{
       rs=1;//数据
       rw=0;
       P0=date;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
       uint status;
       CSN = 0;                   // CSN low, init SPI transaction
       status = SPI_RW(reg);      // select register
       SPI_RW(value);             // ..and write value to it..
       CSN = 1;                   // CSN high again
       return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
       uchar reg_val;
       CSN = 0;                // CSN low, initialize SPI communication...
       SPI_RW(reg);            // Select register to read from..
       reg_val = SPI_RW(0);    // ..then read registervalue
       CSN = 1;                // CSN high, terminate SPI communication
       return(reg_val);        // return register value
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
       uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
              MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
              uchar = (uchar << 1);          // shift next bit into MSB..
              SCK = 1;                       // Set SCK high..
              uchar |= MISO;                 // capture current MISO bit
              SCK = 0;                       // ..then set SCK low again
    }
    return(uchar);                     // return read uchar
}
//*****************长延时*********************************//
void delays(uint x) //毫秒级延时函数
{
  uint i,j;
  for(i=x;i>0;i--)
     for(j=110;j>0;j--);
}
//********************************************************//
//*延时函数
//********************************************************//
void inerDelay_us(unsigned char n)
{  
for(;n>0;n--)
  _nop_();
}

异常.jpg (27.85 KB, 下载次数: 94)

异常

异常
回复

使用道具 举报

地板
ID:65751 发表于 2014-9-10 20:51 | 只看该作者
上面两个程序看着是一样的,运行效果却不一样,编译都没错呀,为什么会这样。仔细看了多次,还是觉得一样的,快发疯了。。。
回复

使用道具 举报

5#
ID:37685 发表于 2014-9-10 22:59 来自手机 | 只看该作者
nrf24l01好像有挪威与台湾之分  ,貌似程序不同
回复

使用道具 举报

6#
ID:65751 发表于 2014-9-14 21:00 | 只看该作者
     大家不要花时间看了,找出问题所在了。在程序最后加上while(1);,就什么都正常了。如果不加程序又会从头开始执行。
    主要是平时看C语言教材,主函数最后没有死循环。51单片机主函数必须要有死循环?望大虾解释一下。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的积分奖励!

查看全部评分

回复

使用道具 举报

7#
ID:69678 发表于 2014-11-30 09:16 | 只看该作者
高手哦正在找NRF24L01的程序
#include<reg51.h>   
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
unsigned char code digit[10]={"0123456789"};        //定义字符数组显示数字
//*********NRF24L01 IO端口定义**********//                                    
sbit  MISO =P1^2;
sbit  MOSI =P1^3;
sbit  SCK  =P1^4;
sbit  CE   =P1^6;
sbit  CSN  =P1^5;
sbit  IRQ  =P1^0;
sbit rs=P3^3;//LCD数据/命令选择端(H/L)
sbit rw=P3^4;//LCD读/写选择端(H/L)
sbit en=P3^5;//LCD使能控制
//*************NRF24L01寄存器指令***********//
#define READ_REG        0x00   // 读寄存器指令
#define WRITE_REG       0x20   // 写寄存器指令
//*************SPI(nRF24L01)寄存器地址********//
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
void inerDelay_us(unsigned char n);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
uint SPI_RW_Reg(uchar reg, uchar value);
void delays(uint x);
void write_com(uchar com);
void display_temp1(unsigned char x);
void write_date(uchar date);
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{     
         unsigned int TN;  
         unsigned int TD;  
        uchar i=0;
         //BEEP=0;          //防止蜂鸣器的电流声
       inerDelay_us(100);
       CE=0;    // chip enable
       CSN=1;   // Spi disable
       SCK=0;   // Spi clock line init high
       write_com(0x38);   //设置工作方式
       write_com(0x0c);   //设置光标
       write_com(0x06);   //设置输入方式
       write_com(0x01);   //清屏
      
                       
                                 TN=SPI_Read(EN_AA);
                                   write_com(0x80);
                                   display_temp1(TN);     //期望值是063(十进制),NRF24L01上电后,EN_AA默认值是 0011 1111,即十进制63。
                                   
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                    delays(200);
                                   
                                   SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                              
                                  TD=SPI_Read(EN_AA);
                                   write_com(0x80+0x40);      
                                   display_temp1(TD);     //期望值是001,因为前面向EN_AA写入了0x01。
                                delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);
                                   delays(200);                                   while(1);/********意思是这里加个while(1);就正常是把很好的模板程序受益匪浅********/

}
/*****************************************************
函数功能:显示十进制数
入口参数:x
***************************************************/
void display_temp1(unsigned char x)
{
       unsigned char j,k,l;     //j,k,l分别储存温度的百位、十位和个位
       j=x/100;              //取百位
       k=(x%100)/10;         //取十位
       l=x%10;               //取个位  
       write_date(digit[j]);    //将百位数字的字符常量写入LCD
       write_date(digit[k]);    //将十位数字的字符常量写入LCD
       write_date(digit[l]);    //将个位数字的字符常量写入LCD
       //write_date('.');               //小数点
       delays(50);           //延时1ms给硬件一点反应时间     
}           
      
/***********1602液晶显示部分子程序****************/
void write_com(uchar com)
{
       rs=0;//命令
       rw=0;
       P0=com;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
void write_date(uchar date)
{
       rs=1;//数据
       rw=0;
       P0=date;
       delays(5);
       en=1;
       delays(5);
       en=0;
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
       uint status;
       CSN = 0;                   // CSN low, init SPI transaction
       status = SPI_RW(reg);      // select register
       SPI_RW(value);             // ..and write value to it..
       CSN = 1;                   // CSN high again
       return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/*详细请参考Page19
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
       uchar reg_val;
       CSN = 0;                // CSN low, initialize SPI communication...
       SPI_RW(reg);            // Select register to read from..
       reg_val = SPI_RW(0);    // ..then read registervalue
       CSN = 1;                // CSN high, terminate SPI communication
       return(reg_val);        // return register value
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/*详细请参考Page19
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
       uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
              MOSI = (uchar & 0x80);         // 用传过来的数据和0x80进行&与运算
              uchar = (uchar << 1);          // shift next bit into MSB..
              SCK = 1;                       // Set SCK high..
              uchar |= MISO;                 // capture current MISO bit
              SCK = 0;                       // ..then set SCK low again
    }
    return(uchar);                     // return read uchar
}
//*****************长延时*********************************//
void delays(uint x) //毫秒级延时函数
{
  uint i,j;
  for(i=x;i>0;i--)
     for(j=110;j>0;j--);
}
//********************************************************//
//*延时函数
//********************************************************//
void inerDelay_us(unsigned char n)
{  
for(;n>0;n--)
  _nop_();
}


评分

参与人数 1威望 +50 黑币 +50 收起 理由
admin + 50 + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表