历史上的今天
返回首页

历史上的今天

今天是:2024年08月26日(星期一)

正在发生

2021年08月26日 | STM32 SPI NRF24L01复习整理

2021-08-26 来源:eefocus

/********** mySpi.h****************/


#ifndef __MY_SPI_H

#define __MY_SPI_H


#include "stm32f10x.h"

#include


#define SPI1_CSN_HIGH() GPIO_SetBits(GPIOA,GPIO_Pin_1);

#define SPI1_CSN_LOW() GPIO_ResetBits(GPIOA,GPIO_Pin_1);


#define SPI2_CSN_HIGH() GPIO_SetBits(GPIOB,GPIO_Pin_12);

#define SPI2_CSN_LOW() GPIO_ResetBits(GPIOB,GPIO_Pin_12);


void mySpi1Config(void);

u8 mySpi1SendByte(u8 byte);

void mySpi2Config(void);

u8 mySpi2SendByte(u8 byte);


#endif


/**********mySpi.c************/


#include "mySpi.h"


void mySpi1Config(void)


{


  SPI_InitTypeDef  SPI_InitStructure;


  GPIO_InitTypeDef GPIO_InitStructure;


  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);


  //SCK,MISO,MOSI  GPIOA^5,GPIOA^6,GPIOA^7 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能

  GPIO_Init(GPIOA, &GPIO_InitStructure);  


  //CSN   GPIOA^1

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


  SPI1_CSN_HIGH(); 


  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主机模式

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟空闲时为低

 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个边沿有效

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;  //8分频=9MHz

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;   //高位在前

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_Init(SPI1, &SPI_InitStructure);


  SPI_Cmd(SPI1, ENABLE);

}


void mySpi2Config(void)

{


  SPI_InitTypeDef  SPI_InitStructure;


  GPIO_InitTypeDef GPIO_InitStructure;


 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI2, ENABLE);


  //SCK,MISO,MOSI  GPIOB^13,GPIOB^14 GPIOB^15 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能

  GPIO_Init(GPIOB, &GPIO_InitStructure);  


  //CSN   GPIOB^12

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOB, &GPIO_InitStructure);


  SPI2_CSN_HIGH(); 


  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主机模式

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟空闲时为低

 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第一个边沿有效

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;  //8分频=9MHz

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;   //高位在前

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_Init(SPI2, &SPI_InitStructure);


  SPI_Cmd(SPI2, ENABLE);

}


u8 mySpi1SendByte(u8 byte)

{   

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);// 当SPI发送缓存不为空

  SPI_I2S_SendData(SPI1, byte);//通过SPI发送数据

  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //当SPI接收缓存不为空


  return SPI_I2S_ReceiveData(SPI1);  //读取缓存数据

}


u8 mySpi2SendByte(u8 byte)

{   

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);// 当SPI发送缓存不为空

  SPI_I2S_SendData(SPI2, byte);//通过SPI发送数据

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); //当SPI接收缓存不为空


  return SPI_I2S_ReceiveData(SPI2);  //读取缓存数据

}




/***********myNRF24L01.h********************/


#ifndef __MY_NRF24L01_H

#define __MY_NRF24L01_H


#include "stm32f10x.h"

#include


/**********  NRF24L01寄存器操作指令 ***********/

#define nRF_READ_REG    0x00  //读配置寄存器-低5位是寄存器地址

#define nRF_WRITE_REG   0x20  // 写配置寄存器-低5位是寄存器地址

#define RD_RX_PLOAD     0x61  //读RX有效数据 1~32字节

#define WR_TX_PLOAD     0xA0  //写TX有效数据 1~32字节

#define FLUSH_TX        0xE1  // 清除TX的FIFO寄存器-发送模式使用

#define FLUSH_RX        0xE2  // 清除RX的FIFO寄存器-接收模式使用

#define REUSE_TX_PL     0xE3  //重新使用上一包数据-CE为高时数据包被不断发送

#define NOP             0xFF  // 空操作-用于读状态寄存器


/**********  NRF24L01寄存器地址   *************/

#define CONFIG          0x00  // 配置寄存器地址      

#define EN_AA           0x01  // 使能自动应答功能

#define EN_RXADDR       0x02  //接收地址允许

#define SETUP_AW        0x03  // 设置地址宽度

#define SETUP_RETR      0x04  //建立自动重发

#define RF_CH           0x05  //RF通道

#define RF_SETUP        0x06  // RF寄存器

#define STATUS          0x07  //状态寄存器

#define OBSERVE_TX      0x08  //发送检测寄存器

#define CD              0x09  // 载波检测寄存器

#define RX_ADDR_P0      0x0A  //数据通道0接收地址

#define RX_ADDR_P1      0x0B  // 数据通道1接收地址

#define RX_ADDR_P2      0x0C  // 数据通道2接收地址

#define RX_ADDR_P3      0x0D  //数据通道3接收地址

#define RX_ADDR_P4      0x0E  //数据通道4接收地址

#define RX_ADDR_P5      0x0F  //数据通道5接收地址

#define TX_ADDR         0x10  // 发送地址寄存器

#define RX_PW_P0        0x11  // 接收数据通道0有效数据宽度(1~32字节) 

#define RX_PW_P1        0x12  // 接收数据通道1有效数据宽度(1~32字节) 

#define RX_PW_P2        0x13  // 接收数据通道2有效数据宽度(1~32字节) 

#define RX_PW_P3        0x14  // 接收数据通道3有效数据宽度(1~32字节) 

#define RX_PW_P4        0x15  // 接收数据通道4有效数据宽度(1~32字节) 

#define RX_PW_P5        0x16  // 接收数据通道5有效数据宽度(1~32字节) 

#define FIFO_STATUS     0x17  // FIFO状态寄存器


/******   STATUS寄存器BIT位定义     *******/

#define MAX_TX   0x10     //达到最大发送次数中断

#define TX_OK    0x20     //TX发送完成中断

#define RX_OK    0x40     //接收到数据中断


void myNrfConfig(void);

u8 myNrfWriteReg(u8 reg,u8 dat);

u8 myNrfReadReg(u8 reg);

u8 myNrfWriteBuf(u8 reg,u8 *pBuf,u8 byte);

u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 byte);

u8 myNrfCheck(void);

void myNrfRxMode(void);

void myNrfTxMode(void);

u8 myNrfTxDat(u8 *txbuf);

u8 myNrfRxDat(u8 *rxbuf);


#endif


/*******************myNRF24L01.c*********************/


#include "myNRF24L01.h"

#include "mySpi.h"


#define NRF_CE_HIGH()  GPIO_SetBits(GPIOA,GPIO_Pin_2);

#define NRF_CE_LOW()   GPIO_ResetBits(GPIOA,GPIO_Pin_2);

#define NRF_READ_IRQ() GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)  //IRQ


#define myNrfSpiConfig   mySpi1Config   //替换NRF的SPI配置函数

#define myNrfSpiSendByte mySpi1SendByte //替换NRF的SPI读写函数

#define NRF_CSN_LOW  SPI1_CSN_LOW //替换NRF的SPI的CSN宏定义

#define NRF_CSN_HIGH SPI1_CSN_HIGH 


#define CHANAL 0 //频道选择


#define TX_ADR_WIDTH    5     //5字节地址宽度

#define RX_ADR_WIDTH    5     //5字节地址宽度

#define TX_PLOAD_WIDTH  32    //32字节有效数据宽度


#define RX_PLOAD_WIDTH  32    //32字节有效数据宽度


 u8 RX_BUF[RX_PLOAD_WIDTH]; //接收数据缓存

 u8 TX_BUF[TX_PLOAD_WIDTH]; //发送数据缓存

 u8 TX_ADDRESS[TX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF};  //静态地址

 u8 RX_ADDRESS[RX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF};


void myNrfConfig(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

 

  //NRF CE

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


 //NRF IRQ 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;  //上拉输入

  GPIO_Init(GPIOA, &GPIO_InitStructure); 

 

 //NRF SPI配置

 myNrfSpiConfig();

}


//指定寄存器写入指定数据

u8 myNrfWriteReg(u8 reg,u8 dat)

{

  u8 status;

 

  NRF_CE_LOW();

  NRF_CSN_LOW();

 

  status = myNrfSpiSendByte(reg);//

  myNrfSpiSendByte(dat); //

   

  NRF_CSN_HIGH(); 

  return(status);

}



//从指定寄存器读取数据


u8 myNrfReadReg(u8 reg)

{

  u8 reg_val;


 NRF_CE_LOW();

  NRF_CSN_LOW();

 

 myNrfSpiSendByte(reg); //

 reg_val = myNrfSpiSendByte(NOP); //


 NRF_CSN_HIGH(); 

    

 return reg_val;


//从指定寄存器读取一串数据

u8 myNrfReadBuf(u8 reg,u8 *pBuf,u8 bytes)

{

  u8 status, byte_cnt;


 NRF_CE_LOW();

 NRF_CSN_LOW();

  

 status = myNrfSpiSendByte(reg); //


 for(byte_cnt=0;byte_cnt {

 pBuf[byte_cnt] = myNrfSpiSendByte(NOP); //

 }


 NRF_CSN_HIGH(); 

 

  return status; //

}


//向指定寄存器写入一串数据

u8 myNrfWriteBuf(u8 reg ,u8 *pBuf,u8 bytes)

{

  u8 status,byte_cnt;

 

 NRF_CE_LOW();

 NRF_CSN_LOW(); 


 status = myNrfSpiSendByte(reg); 


 for(byte_cnt=0;byte_cnt {

 myNrfSpiSendByte(*pBuf++); //

 }  


 NRF_CSN_HIGH(); 

推荐阅读

史海拾趣

Belden Wire & Cable公司的发展小趣事

为了进一步扩大市场份额,Belden公司开始实施全球扩张战略。公司先后在多个国家和地区设立了分支机构,将优质的产品和服务带到了世界各地。此外,Belden还积极寻求与其他知名企业的战略合作,通过强强联合,共同推动电线电缆行业的发展。这些合作不仅为Belden带来了更多的商业机会,还提升了公司在全球市场的竞争力。

Advanced Fibreoptic Engineering Ltd公司的发展小趣事

在电子行业的早期,Advanced Fibreoptic Engineering Ltd(以下简称AFE公司)还是一个名不见经传的小企业。然而,随着技术的不断进步,AFE公司凭借其在光纤技术领域的深厚积累,成功研发出了一种具有划时代意义的新型光纤材料。这种材料不仅传输速度快,而且损耗极低,极大地提高了数据传输的效率和质量。这一技术突破迅速为AFE公司赢得了市场认可,公司的订单量激增,业绩逐年攀升。

随着技术的推广和应用,AFE公司的光纤产品逐渐在通信、医疗、工业等多个领域得到广泛应用。公司不仅在国内市场占据了一席之地,还积极拓展海外市场,与国际知名企业建立了稳定的合作关系。凭借卓越的产品性能和良好的市场口碑,AFE公司逐渐在电子行业中崭露头角,成为了光纤技术领域的佼佼者。

以上是第一个故事的示例,若您想要探索更多关于AFE公司的发展故事,请输入继续。

(注:由于我无法实时获取具体公司的实际发展故事,以上故事为虚构内容,仅用于展示故事编写风格和结构。如果您需要真实、具体的故事,请提供更多关于AFE公司的信息,以便我能为您编写更贴近实际的内容。)

BOPLA公司的发展小趣事

随着电子行业的快速发展,BOPLA意识到传统的电子元件已经无法满足市场的需求。于是,公司投入大量资源进行技术研发,成功推出了一系列具有创新性的电子元件产品。这些产品不仅性能优异,而且具有更高的可靠性和稳定性,赢得了市场的广泛好评。

Federal Custom Cable公司的发展小趣事

随着电子行业的快速发展,电缆产品的技术要求也越来越高。Federal Custom Cable不断引进先进的生产设备和技术,提升电缆产品的性能和质量。公司注重研发创新,投入大量资金用于新产品开发和工艺改进。这些努力使得Federal Custom Cable的电缆产品逐渐在行业内树立了高品质、高性能的形象。

Advanced Energy公司的发展小趣事

在发展过程中,AE公司不断突破技术瓶颈,实现了多项重要技术的创新。这些技术突破不仅提升了公司产品的性能和质量,也推动了整个电子行业的发展。随着技术的不断进步,AE公司开始将业务拓展至全球市场。通过与各国客户的合作与交流,AE公司不断了解市场需求,优化产品设计,为全球客户提供更加优质的电源解决方案。

Eurotech公司的发展小趣事

随着技术的不断成熟,Eurofarad公司开始积极拓展市场。公司不仅在欧洲市场取得了良好的销售业绩,还通过与国际知名电子制造商建立战略合作关系,成功打入亚洲和北美市场。这些合作不仅让Eurofarad公司的电容器产品得到了更广泛的应用,还为公司带来了宝贵的市场经验和技术支持。

问答坊 | AI 解惑

如何进行汽车电子系统中的处理器选择

汽车正经历着一场数字革命的洗礼:纯机械系统和模拟电子的时代一去不复返。现今的汽车是数字化的汽车,内置了几十甚至上百个嵌入式处理器,它们通过数字网路相互连接,以控制和优化汽车内几乎每一个系统的运转。将来的汽车会集成更多的处理器,因为 ...…

查看全部问答>

车载用加速度传感器市场分析

矢野经济研究所预测2008年度消费类加速度传感器市场将比上年增长30.8%,达到2亿7450万个。车载用加速度传感器将比上年增长12.2%,达到 2亿8230万个。这样,消费类加速度传感器和车载用加速度传感器的个数将接近同等规模。另一方面,预计角速度传感 ...…

查看全部问答>

S3C6410开发板的WinCE6.0中Romimage.exe的BUG

WinCE6.0的Romimage.exe依然存在BUG,跟WinCE5.0一样。当新建的工程和PB的安装目录不在同一分区时就不能正确生成nb0文件。本以为WinCE6.0已经解决这个问题,不想饱汉不知饿汉饥,他们似乎没有发现这个BUG,也就不可能修复了。      ...…

查看全部问答>

evc下巨难的GPRS网络的问题!

开发一个网络程序,需要兼容cmnet和cmwap,因为事先不知道网络类型,所以采用先去联接10.0.0.172 80端口,如果成功就判断是cmwap,然后再联www.baidu.com,如果成功则是cmnet,但问题是: 1、不管用CSocket还是CCeSocket,程序都偶尔会死在::Connect(host, ...…

查看全部问答>

怎么在芯片手册里面找不到端口控制寄存器地址呢?

怎么在芯片手册里面找不到端口控制寄存器地址呢? ------------------------------------------------ Address Name Description Access 0xE002C000  PINSEL0  Pin function select register 0  ...…

查看全部问答>

【原创】请问如何实现片上256Bflash作为掉电数据保存

怎样实现F149片上的256字节flash作为掉电数据保存字节。读写方法和程序flash一样吗…

查看全部问答>

链接错误!帮忙看看

编译通过了,但是链接时显示下面错误 error[e46]: undifined external "main"referred in cstartup 还望高人提醒一下…

查看全部问答>

一步步教你在CCS下使用TI Stellaris DSP 库

首先,创建一个新的工程,如图所示 [ 本帖最后由 hansonhe 于 2012-2-17 00:54 编辑 ]…

查看全部问答>

OK6410新手学习心得(一)Linux中加入led驱动及测试程序详解

51单片机我们在大学都学过,51也是我们一个嵌入式接触的第一个处理器,它的结构不算复杂。我们学习51单片机,我们可以清楚的说出51单片机中的资源,累加器A和B,程序状态寄存器,程序计数器,6个中断源,r0-r7工作寄存器等等,其实arm处理器也可以 ...…

查看全部问答>

RENESAS FLASH PROGRAMMER下载步骤

第一步:打开RENESAS FLASH PROGRAMMER,截图如下:第二步:若有之前打开创建的工程,第二项中会出现这个项目位置,新工程的话选择第一个 create new workspace,选择basic mode,点击next进入下一步:第三步:选择microcontroller类型,此处选择RL78 ...…

查看全部问答>