栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32通过nrf24l01无线通信模块与电脑通信

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32通过nrf24l01无线通信模块与电脑通信

       因为最近在弄比赛,做了个六足蜘蛛用到了nrf24l01无线通信模块,故作此笔记以便记录,一来分享自己的经验,二来也方便自己未来的学习回顾。本文章不过多讲述原理,主要讲解怎么使用!

     首先 我用的nrf24l01模块是配套使用的,如下图。此模块利用串口通信进行发收消息,注意单片机端的接口与nrf24l01接口的接法,单片机的Tx应接nrf24l01模块的Rx,单片机的Rx接nrf24l01模块的Tx。

 

因为蜘蛛USART1是用来控制总线串行舵机,所以我利用USART3来实现这个模块的通信。stm32上串口3的接口为PB11,PB10,如下图

 接下来便是代码:

uart3.h

#ifndef __USART3_H
#define __USART3_H
#include "stdio.h"	
#include "sys.h" 

#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART3_RX 			1		//使能(1)/禁止(0)串口3接收
//extern u8 Res;	  	
extern u8  USART3_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART3_RX_STA;         		//接收状态标记	
//如果想串口中断接收,请不要注释以下宏定义
void uart3_init(u32 bound);

//void MY_USART3_Init(void);

#endif

uart3.c 

注意,如果程序中还有串口1 uart.c的配置,那么uart3.c将会与之冲突,在此我们只要将uart.c中的

/int fputc(int ch, FILE *f)

//{

//        if(ch =='n')  

//        {  

//            USART_SendData(USART1, 0x0D);  

//            while (!(USART1->SR & USART_FLAG_TXE));

//            USART_SendData(USART1, 0x0A);  

//            while (!(USART1->SR & USART_FLAG_TXE));  

//        }  

//        else  

//        {  

//            USART_SendData(USART1, (unsigned char)ch);  

//            while (!(USART1->SR & USART_FLAG_TXE));   

//        }  

// return ch;

//}

注释掉,不然会与UART3.c中的冲突,重复定义

此程序为uart3.c的配置

#include "sys.h"
#include "uart3.h"	  
// 	 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS         //0
#include "includes.h"					//ucos 使用	  
#endif


//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART3->SR&0x40)==0);//循环发送,直到发送完毕   
    USART3->DR = (u8) ch;

	return ch;
}
#endif 


 
 
#if EN_USART3_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART3_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART3_RX_STA=0;       //接收状态标记	  
//u8 Res;

void uart3_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//GPIOB时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3,
	
	//USART3_TX   GPIOB.10
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10

	//USART1_RX	  GPIOB.11初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11 

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

  USART_Init(USART3, &USART_InitStructure); //初始化串口3
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断(USART_IT_RXNE
  USART_Cmd(USART3, ENABLE);                    //使能串口3 

}

void USART3_IRQHandler(void)                	//串口3中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART3);	//读取接收到的数据
		
		if((USART3_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART3_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
				else USART3_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0x0D
				{	
				if(Res==0x0d)USART3_RX_STA|=0x4000;
				else
					{
					USART3_RX_BUF[USART3_RX_STA&0x3FFF]=Res ;
					USART3_RX_STA++;
					if(USART3_RX_STA>(USART_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "beep.h"
#include "uart.h"
#include "LobotSerialServo.h"
#include "bool.h"
#include "uart3.h"

#define ID1 1
#define ID2 2


 int main(void)
 {
	u16 t;     //警告,变量被声明但未被引用
	u16 len;	
	u16 times=0;
 	vu8 key=0;
	 
	 
	 uart3_init(115200);	 //串口初始化为115200
   	 
	 SystemInit();   //系统时钟等初始化
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先
	 uartInit(115200);//串口初始化为115200
	 
	delay_init();	    	 //延时函数初始化	  
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	BEEP_Init();         	//初始化蜂鸣器端口
	while(1)
	{
		
			if(USART3_RX_STA&0x8000)
		{					   
			len=USART3_RX_STA&0x3fff;//得到此次接收到的数据长度
			for(t=0;t 

   在主函数中USART3_RX_BUF[t]用于储存电脑发送的字符(识别的是ASCLL码),我们可以通过判断USART3_RX_BUF[t]是否等于自己发送的字符对应的ascll码就可以执行自己想要执行的程序了,比如我上面是if(USART3_RX_BUF[t]==0x39)(9对应的ASCLL码的十六进制),如果电脑发送的是字符9,那么LED1翻转,串口舵机1转动到200位置。

其他常用字符对应的ASCLL码

 

 

还有更多字符对应的ASCLL码大家可以自行搜索。 电脑发送的上位机一般淘宝卖家都会有,正点原子XCOM软件用于串口通信的。软件方面发送的配置要跟自己UART3.c中配置的一样才能正常发送(比如停止位,波特率)

 

   这个蜘蛛还涉及IIC控制16路pwm/servo发生器控制板 ,串口总线舵机,以及六足蜘蛛步态解析,之后会一一记录。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937885.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号