OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3204|回复: 2

关于UCOSIII应用RNF24L01与超声波模块的问题

[复制链接]

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2017-8-17
在线时间
50 小时
发表于 2018-10-3 13:05:21 | 显示全部楼层 |阅读模式
实现功能:2.4G无线发送数据给小车做出相应动作,超声波测距小于50厘米小车不会发生动作。
问题:不在实时系统上使用,程序运行起来没有一点问题。当将程序移植进UCOSIII系统运行,只要2.4G一发送数据,程序标红那部分就会执行。实在令我百思不得其解。
主程序部分:
int main(void)
{
        OS_ERR err;
        CPU_SR_ALLOC();
       
        delay_init(168);          //时钟初始化168MHz
        NRFInit();//2.4G初始化
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组配置
        uart_init(115200);  //串口初始化
        //LED_Init();       //内部LED初始化
        LED10_Init();                //外部LED初始化
        BEEP_Init();                //蜂鸣器初始化
        KEY_Init();                 //按键初始化
        trig_init();                //trig管脚初始化
        motor_init();                //电机初始化
        TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);//以1Mhz的频率计数
        RX_Mode(1, 0, 0, 0, 0, 0);//设置为接收模式,NRF24L01只开0通道
        time7_init(8399,49995);//5s 中断一次
        //time6_init();//定时器6初始化
        stop();//默认电机停止
       
        OSInit(&err);                //初始化UCOSIII
        OS_CRITICAL_ENTER();//进入临界区
        //创建开始任务
        OSTaskCreate((OS_TCB         * )&StartTaskTCB,                //任务控制块
                                 (CPU_CHAR        * )"start task",                 //任务名字
                 (OS_TASK_PTR )start_task,                         //任务函数
                 (void                * )0,                                        //传递给任务函数的参数
                 (OS_PRIO          )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0],        //任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10,        //任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE,                //任务堆栈大小
                 (OS_MSG_QTY  )0,                                        //任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK          )0,                                        //当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void           * )0,                                        //用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR         * )&err);                                //存放该函数错误时的返回值
        OS_CRITICAL_EXIT();        //退出临界区         
        OSStart(&err);  //开启UCOSIII
        while(1);
}


//开始任务函数
void start_task(void *p_arg)
{
        OS_ERR err;
        CPU_SR_ALLOC();
        p_arg = p_arg;


        CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0u
   OSStatTaskCPUUsageInit(&err);          //统计任务               
#endif
       
#ifdef CPU_CFG_INT_DIS_MEAS_EN                //如果使能了测量中断关闭时间
    CPU_IntDisMeasMaxCurReset();       
#endif


#if        OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候
         //使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5ms
        OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif               
       
        OS_CRITICAL_ENTER();        //进入临界区
        //创建NRF24L01接收任务
        OSTaskCreate((OS_TCB         * )&ReceiveTaskTCB,               
                                 (CPU_CHAR        * )"receive task",                
                 (OS_TASK_PTR )receive_task,                        
                 (void                * )0,                                       
                 (OS_PRIO          )RECEIVE_TASK_PRIO,     
                 (CPU_STK   * )&RECEIVE_TASK_STK[0],       
                 (CPU_STK_SIZE)RECEIVE_STK_SIZE/10,       
                 (CPU_STK_SIZE)RECEIVE_STK_SIZE,               
                 (OS_MSG_QTY  )0,                                       
                 (OS_TICK          )0,                                       
                 (void           * )0,                                       
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR         * )&err);                               
                                 
        //创建电机运行任务
        OSTaskCreate((OS_TCB         * )&MotorTaskTCB,               
                                 (CPU_CHAR        * )"motor task",                
                 (OS_TASK_PTR )motor_task,                        
                 (void                * )0,                                       
                 (OS_PRIO          )MOTOR_TASK_PRIO,            
                 (CPU_STK   * )&MOTOR_TASK_STK[0],       
                 (CPU_STK_SIZE)MOTOR_STK_SIZE/10,       
                 (CPU_STK_SIZE)MOTOR_STK_SIZE,               
                 (OS_MSG_QTY  )0,                                       
                 (OS_TICK          )0,                                       
                 (void           * )0,                               
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
                 (OS_ERR         * )&err);
        OS_TaskSuspend((OS_TCB*)&StartTaskTCB,&err);                //挂起开始任务                         
        OS_CRITICAL_EXIT();        //退出临界区
}


//NRF24L01接收任务函数
void receive_task(void *p_arg)
{
        p_arg = p_arg;
        while(1)
        {
               
                if(TIM7->SR &0x01)//定时时间到将接收到的数据置为停车
                {
                        TIM7->SR &=~(0X01);//清除中断标志位
                        Rx[0]='t';
                }
                /*检测是否接收到数据,同时检测哪一个通道接收到数据*/
                RxNum = NRF24L01_Check_RxCh();
                switch(RxNum)
                {
                        case RX_P_N0: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道0接收的数据为:%s\r\n",Rx);
                                                  break;
                        case RX_P_N1: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道1接收的数据为:%s\r\n",Rx);
                                                  break;
                        case RX_P_N2: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道2接收的数据为:%s\r\n",Rx);
                                                  break;
                        case RX_P_N3: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道3接收的数据为:%s\r\n",Rx);
                                                  break;
                        case RX_P_N4: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道4接收的数据为:%s\r\n",Rx);
                                                  break;
                        case RX_P_N5: NRF24L01_RxPacket(Rx, RxNum);
                                                  printf("通道5接收的数据为:%s\r\n",Rx);
                                                  break;
                        default:break;
                }
                delay_ms(200);                        //发起任务调度
        }
}


//电机任务函数
void motor_task(void *p_arg)
{
        p_arg = p_arg;
        while(1)
        {
                if(count_distance()>50)
                {
                        alldrown();//关灯
                        BEEP=1;//关闭蜂鸣器
                        switch(Rx[0])
                        {
                                case 'w':
                                        go_ahead();//前进
                                        break;
                                case 'a':
                                        turn_left();//左转
                                        break;
                                case 'd':
                                        turn_right();//右转
                                        break;
                                case 't':
                                        stop();//停车
                                        break;
                                default:break;
                        }
                }
                else
                {
                        stop();//停车
                        BEEP=~BEEP;//500毫秒蜂鸣器响一次
                        flash();//500毫秒闪一次
                        delay_ms(200);//200毫秒
                }
                switch(Rx[0])//该函数使后退不受超声波影响
                {
                        case 's':
                                back();//后退
                                break;
                        default:break;
                }
                delay_ms(200);                                                        //发起任务调度
        }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2017-8-17
在线时间
50 小时
 楼主| 发表于 2018-10-3 13:18:44 | 显示全部楼层
经过检查发现,只要2.4G模块发出数据,超声波模块探测障碍物距离的数据会小于50厘米(哪怕并没有障碍物)。假如不用UCOS系统程序是不会出现这种错误的。怀疑过是否管教重复,但是检查结果是没有
回复 支持 反对

使用道具 举报

11

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2017-8-17
在线时间
50 小时
 楼主| 发表于 2018-10-5 12:11:20 | 显示全部楼层
经检查发现,2.4G无线模块只要发送一个字节数据,超声波就会出现问题,从而返回0厘米的错误数值,才导致程序一直运行那一段。这个现象不用UCOS系统是不会出现的。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 04:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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