您的位置:首页 > 游戏 > 手游 > 莱州教体局网站_网店运营培训哪里好_semantic scholar_百度竞价排名黑幕

莱州教体局网站_网店运营培训哪里好_semantic scholar_百度竞价排名黑幕

2025/1/9 9:48:48 来源:https://blog.csdn.net/2301_80596293/article/details/144950531  浏览:    关键词:莱州教体局网站_网店运营培训哪里好_semantic scholar_百度竞价排名黑幕
莱州教体局网站_网店运营培训哪里好_semantic scholar_百度竞价排名黑幕

目录

前言

一、IO口初始化

二、模拟SPI的基础代码

1.一些代码的宏定义

2.起始信号

3.CS,SCK,MOSI操作

4.MISO,IRQ操作

三.中间层代码

1.字节的输入和读取

 2.写操作

3.读操作

四.应用层代码

1.24L01的检测

2.在main函数进行简单验证

3.24L01宏定义的代码

总结


前言

环境:

芯片:STM32F103C8T6

Keil:V5.24.2.0

模块:NRF24L01


一、IO口初始化

根据:NRF24L01模块STM32通信-调试前言-CSDN博客

需要初始6个IO:4个输出,2个输入

我初始对应的IO口如下;

//输出
CSN		->PA3
CE		->PA4
MOSI	->PA7
SCK		->PA5	
//输入	
IRQ		->PB1
MISO	->PA6

 IO口初始化,包含了OLED和其他的初始化代码.

void Gpio_Init(void)
{
/* 输出
CSN		->PA3//
CE		->PA4
MOSI	->PA7
SCK		->PA5	输入	
IRQ		->PB1
MISO	->PA6
*/	
//outputRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);//inputGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);}

二、模拟SPI的基础代码

1.一些代码的宏定义

#define SPI_CS_PROT			GPIOA	//CS接线引脚通道,	CSN
#define SPI_CS_PIN			GPIO_Pin_3#define SPI_DO_PROT			GPIOA	//D0接线引脚通道,	MOSI
#define SPI_DO_PIN			GPIO_Pin_7#define SPI_SLK_PROT		GPIOA	//CL接线引脚通道,	SCK
#define SPI_SLK_PIN			GPIO_Pin_5#define SPI_DI_PROT			GPIOA	//DI接线引脚通道,	MISO
#define SPI_DI_PIN			GPIO_Pin_6#define SPI_IRQ_PROT		GPIOB	//DI接线引脚通道,	MISO
#define SPI_IRQ_PIN			GPIO_Pin_1#define MYSPI_W_CS(x) 		GPIO_WriteBit(SPI_CS_PROT,SPI_CS_PIN,(BitAction)(x))//对CS线进行操作
#define MYSPI_W_DI(x) 		GPIO_WriteBit(SPI_DI_PROT,SPI_DI_PIN,(BitAction)(x))//对DI线进行操作
#define MYSPI_W_DO(x) 		GPIO_WriteBit(SPI_DO_PROT,SPI_DO_PIN,(BitAction)(x))//对DO线进行操作
#define MYSPI_W_SLK(x) 		GPIO_WriteBit(SPI_SLK_PROT,SPI_SLK_PIN,(BitAction)(x))//对SLK线进行操作
#define NRF24L01_CE(x) 		GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)(x))//对CE线进行操作

2.起始信号

void MySPI_Start(void)
{MYSPI_W_CS(0);		//拉低为开始信号
}void MySPI_Stop(void)
{MYSPI_W_CS(1);		//拉高为结束信号
}

3.CS,SCK,MOSI操作

void MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, SPI_CS_PIN, (BitAction)BitValue);  
}void MySPI_W_SCK(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, SPI_SLK_PIN, (BitAction)BitValue);
}void MySPI_W_MOSI(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, SPI_DO_PIN, (BitAction)BitValue);
}

4.MISO,IRQ操作

uint8_t MySPI_Read_MISO(void)
{return GPIO_ReadInputDataBit(SPI_DI_PROT, SPI_DI_PIN);
}uint8_t MySPI_Read_IRQ(void)
{return GPIO_ReadInputDataBit(SPI_IRQ_PROT, SPI_IRQ_PIN);
}

三.中间层代码

1.字节的输入和读取

uint8_t MySPI_SwapByte(uint8_t ByteSend)	//字节读取和交换
{uint8_t i,ByteReceive = 0x00;for(i = 0;i < 8;i ++){MySPI_W_MOSI(ByteSend & (0x80 >> i));MySPI_W_SCK(1);if (MySPI_Read_MISO() == 1){ByteReceive |= (0x80 >> i);}MySPI_W_SCK(0);}return ByteReceive;
}

 关于这段代码更详细的解说可以观看江科大的视频SPI部分.

 2.写操作

uint8_t NRF24l01_write_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
{uint8_t status, i;MySPI_Start();					  /* 使能SPI传输 */status = MySPI_SwapByte(reg); /* 发送寄存器值(位置),并读取状态值 */for (i = 0; i < len; i++){MySPI_SwapByte(*pbuf++);  /* 写入数据 */}MySPI_Stop();					 /* 关闭SPI传输 */                return status;                      /* 返回读到的状态值 */}

3.读操作

uint8_t NRF24l01_read_buf(uint8_t reg, uint8_t *pbuf, uint8_t len)
{uint8_t status, i;    MySPI_Start();  /* 使能SPI传输 */status = MySPI_SwapByte(reg);         /* 发送寄存器值(位置),并读取状态值 */for (i = 0; i < len; i++){pbuf[i] = MySPI_SwapByte(0X55);   /* 读出数据 */		} return status;                              /* 返回读到的状态值 */
}

四.应用层代码

1.24L01的检测

/*** @brief       检测24L01是否存在* @param       无* @retval      0, 成功; 1, 失败;*/
uint8_t NRF24l01_check(void)
{uint8_t buf[5] = {0XA5, 0XA5, 0XA5, 0XA5, 0XA5};uint8_t i;NRF24l01_write_buf(NRF_WRITE_REG + TX_ADDR, buf, 5);    /* 写入5个字节的地址. */NRF24l01_read_buf(TX_ADDR, buf, 5);                     /* 读出写入的地址 */for (i = 0; i < 5; i++){if (buf[i] != 0XA5) break;}if (i != 5) return 1;   /* 检测24L01错误 */return 0;               /* 检测到24L01 */
}

 关于其中的一些宏定义,代码放在本文末.

2.在main函数进行简单验证

void MY24L01_Init(void)//对模块和通信线的前期操作
{NRF24L01_CE(0);
MYSPI_W_CS(1);
MYSPI_W_SLK(0);}while(1)
{while (NRF24l01_check())    /* 检查NRF24L01是否在线 */{OLED_ShowString(16, 18, "NRF24l01 NGNGNG", OLED_6X8);OLED_Update();}OLED_ShowString(32, 18, "GOOD", OLED_6X8);OLED_Update();
}

 可以使用OLED进行显示,当然因为结果只有0或1,所以也可以采用其他方式进行验证,如LED的亮灭

如果代码正确则可以进行后面的代码书写.

3.24L01宏定义的代码

/******************************************************************************************/
/* 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    /* 空操作,可以用来读状态寄存器 *//* SPI(NRF24L01)寄存器地址 */
#define CONFIG          0x00    /* 配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能; *//* bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能 */
#define EN_AA           0x01    /* 使能自动应答功能  bit0~5,对应通道0~5 */
#define EN_RXADDR       0x02    /* 接收地址允许,bit0~5,对应通道0~5 */
#define SETUP_AW        0x03    /* 设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节; */
#define SETUP_RETR      0x04    /* 建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us */
#define RF_CH           0x05    /* RF通道,bit6:0,工作通道频率; */
#define RF_SETUP        0x06    /* RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益 */
#define STATUS          0x07    /* 状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发 *//* bit5:数据发送完成中断;bit6:接收数据中断; */
#define MAX_TX          0x10    /* 达到最大发送次数中断 */
#define TX_OK           0x20    /* TX发送完成中断 */
#define RX_OK           0x40    /* 接收到数据中断 */#define OBSERVE_TX      0x08    /* 发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器 */
#define CD              0x09    /* 载波检测寄存器,bit0,载波检测; */
#define RX_ADDR_P0      0x0A    /* 数据通道0接收地址,最大长度5个字节,低字节在前 */
#define RX_ADDR_P1      0x0B    /* 数据通道1接收地址,最大长度5个字节,低字节在前 */
#define RX_ADDR_P2      0x0C    /* 数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; */
#define RX_ADDR_P3      0x0D    /* 数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; */
#define RX_ADDR_P4      0x0E    /* 数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; */
#define RX_ADDR_P5      0x0F    /* 数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; */
#define TX_ADDR         0x10    /* 发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等 */
#define RX_PW_P0        0x11    /* 接收数据通道0有效数据宽度(1~32字节),设置为0则非法 */
#define RX_PW_P1        0x12    /* 接收数据通道1有效数据宽度(1~32字节),设置为0则非法 */
#define RX_PW_P2        0x13    /* 接收数据通道2有效数据宽度(1~32字节),设置为0则非法 */
#define RX_PW_P3        0x14    /* 接收数据通道3有效数据宽度(1~32字节),设置为0则非法 */
#define RX_PW_P4        0x15    /* 接收数据通道4有效数据宽度(1~32字节),设置为0则非法 */
#define RX_PW_P5        0x16    /* 接收数据通道5有效数据宽度(1~32字节),设置为0则非法 */
#define NRF_FIFO_STATUS 0x17    /* FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留 *//* bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环; *//******************************************************************************************/

总结

本文代码并未涉及很多的交互动作,只是验证基础代码和IO口的连接正确.操作相对简单,方便及时对代码进行验证,查缺补漏,方便后面代码的调试

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com