发新帖我要提问
12
返回列表
打印
[应用相关]

[stm32] NRF24L01+USART搞定有线和无线通信

[复制链接]
楼主: features
手机看帖
扫描二维码
随时随地手机跟帖
21
features|  楼主 | 2020-1-1 17:45 | 只看该作者 回帖奖励 |倒序浏览
还要回过头说说我们的USART和NRF24L01,他们的初始化要看main函数中的BSP_Init();函数,该函数负相关硬件的初始化设置(中文意思是板级支持包初始化函数,因为uc-OS可以并不只限于stm32单片机,所以这里要根据不同平台进行相应的设置)。该函数位于bsp.c函数中,其作用相当于将以前我们在main函数中进行的相关硬件初始化单独拿出来封装成一个函数而已~但是,串口和无线对应的中断接收程序却有点不一样,因为这里是操作系统,所以在每个中断子程序前要调用OS_ENTER_CRITICAL();保存当前的全局中断标志,然后OSIntNesting++;中断嵌套深度加1,最后调用OS_EXIT_CRITICAL();恢复全局中断标志进入正常的中断处理,此外在中断响应函数最后要调用OSIntExit(); 检测如果有更高优先级的任务就绪了,则执行一次任务切换。

使用特权

评论回复
22
features|  楼主 | 2020-1-1 17:45 | 只看该作者
串口和无线中断子程序
/*******************************************************************************
* Function Name  : USART1_IRQHandler
* Description    : This function handles USART1 global interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
    unsigned int i;
    OS_CPU_SR  cpu_sr;
    OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断 Tell uC/OS-II that we are starting an ISR
    OSIntNesting++;
    OS_EXIT_CRITICAL();      //恢复全局中断曛?        

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)       //判断读寄存器是否非空
    {   
        RxBufferUSART[RxCounter1++] = USART_ReceiveData(USART1);   //将读寄存器的数据缓存到接收缓冲区里
        if(RxBufferUSART[RxCounter1-2]==0x0d&&RxBufferUSART[RxCounter1-1]==0x0a)     //判断结束标志是否是0x0d 0x0a
        {
            for(i=0; i< RxCounter1; i++) TxBufferRF[i] = RxBufferUSART[i];          //将接收缓冲器的数据转到发送缓冲区,准备转发
            usart_rec_flag=1;                                                             //接收成功标志
            TxBufferRF[RxCounter1]=0;                                             //发送缓冲区结束符   
            TxCounter1=RxCounter1;
            RxCounter1=0;
        }
    }
    if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                   //这段是为了避免STM32 USART 第一个字节发不出去的BUG
    {
        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                         //禁止发缓冲器空中断,
    }   
    OSIntExit();           //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换   
}
/////////////////////////////
void EXTI0_IRQHandler(void)
{
  unsigned char status,i;
  OS_CPU_SR  cpu_sr;
  OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断 Tell uC/OS-II that we are starting an ISR
  OSIntNesting++;
  OS_EXIT_CRITICAL();      //恢复全局中断标志            
  
  if(EXTI_GetITStatus(EXTI_Line0) != RESET)            //判断是否产生了EXTI0中断
  {
      if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0){ //判断是否是PA0线变低            
        status=SPI_Read(READ_REG1+STATUS);            // 读取状态寄存其来判断数据接收状况   
        if(status & 0x40)                            // 判断是否接收到数据                  
        {                                                         
             SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);  //从接收缓冲区里读出数据
            for(i=0; i<32; i++){                              //向USB 端点1的缓冲区里放置数据
                TxBufferUSART[i] = rx_buf[i];     
            }
            rf_rec_flag=1;         
            if((status&0x0e)<=0x0a){                           
               nrf_Pipe_r=(status&0x0e)>>1;                      //读出是在哪个通道接收的
            }
            else nrf_Pipe_r=0;                     
            Rx_Succ=1;            //读取数据完成标志
            /* 根据读出的接收通道号,将相应信息写入状态文本缓冲区 */
            if(nrf_Pipe_r==0) memcpy(status_buf, "Pipe 0 Recive OK!   ", 20);           
            else if(nrf_Pipe_r==1) memcpy(status_buf, "Pipe 1 Recive OK!   ", 20);
            else if(nrf_Pipe_r==2) memcpy(status_buf, "Pipe 2 Recive OK!   ", 20);
            else if(nrf_Pipe_r==3) memcpy(status_buf, "Pipe 3 Recive OK!   ", 20);
            else if(nrf_Pipe_r==4) memcpy(status_buf, "Pipe 4 Recive OK!   ", 20);
            else if(nrf_Pipe_r==5) memcpy(status_buf, "Pipe 5 Recive OK!   ", 20);
        }
        else if((status &0x10)>0){                     //发射达到最大复发次数               
            SPI_RW_Reg(0xe1,0);                          //清除发送缓冲区                  
            RX_Mode();                                 //进入接收模式                                 
            Rx_Succ=1;                                                                                    
            /* 根据发送通道,将相应信息写入状态文本缓冲区 */
            if(nrf_Pipe==0) memcpy(status_buf, "Pipe 0 NO ACK!      ", 20);
            else if(nrf_Pipe==1) memcpy(status_buf, "Pipe 1 NO ACK!      ", 20);
            else if(nrf_Pipe==2) memcpy(status_buf, "Pipe 2 NO ACK!      ", 20);
            else if(nrf_Pipe==3) memcpy(status_buf, "Pipe 3 NO ACK!      ", 20);  
            else if(nrf_Pipe==4) memcpy(status_buf, "Pipe 4 NO ACK!      ", 20);
            else if(nrf_Pipe==5) memcpy(status_buf, "Pipe 5 NO ACK!      ", 20);            
        }
        else if((status &0x20)>0){                     //发射后收到应答            
            SPI_RW_Reg(0xe1,0);                         //清除发送缓冲区              
            RX_Mode();                                 //进入接收模式
            Rx_Succ=1;
            /* 根据发送通道,将相应信息写入状态文本缓冲区 */
            if(nrf_Pipe==0) memcpy(status_buf, "Pipe 0 Send OK!     ", 20);
            else if(nrf_Pipe==1) memcpy(status_buf, "Pipe 1 Send OK!     ", 20);
            else if(nrf_Pipe==2) memcpy(status_buf, "Pipe 2 Send OK!     ", 20);
            else if(nrf_Pipe==3) memcpy(status_buf, "Pipe 3 Send OK!     ", 20);
            else if(nrf_Pipe==4) memcpy(status_buf, "Pipe 4 Send OK!     ", 20);
            else if(nrf_Pipe==5) memcpy(status_buf, "Pipe 5 Send OK!     ", 20);               
        }
        
        SPI_RW_Reg(WRITE_REG1+STATUS, status);         //清除07寄存器标志              
      }        
      EXTI_ClearITPendingBit(EXTI_Line0);             //清除EXTI0上的中断标志              
  }   
  OSIntExit();           //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换     
}

使用特权

评论回复
23
features|  楼主 | 2020-1-1 17:46 | 只看该作者
最后说明

对于纯玩软件的小伙伴,这里涉及的东西有点多,不必细究,看看了解即可。但是对于初学stm32,尤其是还在为stm32控制NRF24L01不通的同学,这个还是挺有用滴~下面有工程的链接,里面有些注释不规范,一切以我博客里说的为准哦~

使用特权

评论回复
24
features|  楼主 | 2020-1-1 17:47 | 只看该作者
链接

上述工程keil代码:http://pan.baidu.com/s/1mgqowQ0

本文链接:http://www.cnblogs.com/zjutlitao/p/4242734.html

上述工程GitHub链接:https://github.com/beautifulzzzz/stm32/tree/master/stm32_USART%2BNRF24L01

可能有用1:[stm32][ucos] 1、基于ucos操作系统的LED闪烁、串口通信简单例程  https://bbs.21ic.com/icview-2893452-1-1.html

可能有用2:[stm32][ucos][ucgui] 2、LED闪烁、串口、滑块、文本编辑框简单例程  https://bbs.21ic.com/icview-2893454-1-1.html

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则