当串口printf函数在ucosii操作系统出现的奇葩现象???「建议收藏」

当串口printf函数在ucosii操作系统出现的奇葩现象???「建议收藏」被操作系统坑爹的那些事

大家好,又见面了,我是你们的朋友全栈君。

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "gpio.h"
#include "includes.h"//包含操作系统头文
#include "com.h"
#include "fsmc.h"
#include "timer.h"
//ucosii 操作系统 组网
frame_typedef AccessNet_frame={0,1,1,0,1};//UID为1的终端随机接入
frame_typedef REG_REQ={0,1,1,0,2};//REG_REQ
frame_typedef REG_RSP={0,1,1,0,3};//REG_RSP
frame_typedef RNG_REQ={0,1,1,0,4};//RNG_REQ
frame_typedef RNG_RSP={1,1,1,0,5};//RNG_RSP
/UCOSII任务设置///
//START 任务
//设置任务优先级
#define START_TASK_PRIO      			10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE  				64
//任务堆栈	
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);	
 			   
//拆帧任务
//设置任务优先级
#define OPEN_FRAME_TASK_PRIO       			5 
//设置任务堆栈大小
#define OPEN_FRAME_STK_SIZE  		    		64
//任务堆栈	
OS_STK OPEN_FRAME_TASK_STK[OPEN_FRAME_STK_SIZE];
//任务函数
void open_frame_task(void *pdata);
//控制任务
//设置任务优先级
#define NetIn_TASK_PRIO       			4
//设置任务堆栈大小
#define NetIn_STK_SIZE  					64
//任务堆栈
OS_STK NetIn_TASK_STK[NetIn_STK_SIZE];
//任务函数
void NetIn_task(void *pdata);

//LED任务
//设置任务优先级
#define LED_TASK_PRIO       			6 
//设置任务堆栈大小
#define LED_STK_SIZE  		    		64
//任务堆栈	
OS_STK LED_TASK_STK[LED_STK_SIZE];
//任务函数
void led_task(void *pdata);

OS_EVENT * msg_rec_frame;			  //收到帧邮箱事件块指针,msg_key为结构体指针
OS_EVENT * sem_syn;		          //拆帧和控制之间作同步的信号量
int main(void)
{ 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2//
	delay_init(168);		   //初始化延时函数
	LED_Init();		       //初始化LED端口 
	fcmc_Init();           //初始化FSMC接口
	TIM3_Int_Init(1-1,21-1);//PRE=4Mhz,0.25us
	uart_init(9600);		//初始化串口波特率为115200
//	printf("initial success\r\n");
	OSInit();   
 	OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
	OSStart();	
}

 //开始任务

void start_task(void *pdata)
{
  OS_CPU_SR cpu_sr=0;
	pdata = pdata; 
	msg_rec_frame=OSMboxCreate((void*)0);	  //创建消息邮箱
	sem_syn=OSSemCreate(0);		              //创建信号量		 	
    OS_ENTER_CRITICAL();			//进入临界区(无法被中断打断)    
 	OSTaskCreate(open_frame_task,(void *)0,(OS_STK*)&OPEN_FRAME_TASK_STK[OPEN_FRAME_STK_SIZE-1],OPEN_FRAME_TASK_PRIO);						   
    OSTaskCreate(NetIn_task,(void *)0,(OS_STK*)&NetIn_TASK_STK[NetIn_STK_SIZE-1],NetIn_TASK_PRIO);		
  	OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);		
	OSTaskSuspend(START_TASK_PRIO);	//挂起起始任务
	OS_EXIT_CRITICAL();				//退出临界区(可以被中断打断)
} 

//拆帧任务

void open_frame_task(void *pdata)
{	
	u16 recv_data_for_fpga;
	u8 err;
	
	u8 i;
	u8 t,len;	
    u16 b[16]={0};
  frame_typedef rec_data;
	while(1)
	{
		OSSemPend(sem_syn,0,&err);                 //第二个参数为等待时间,为0表示一直等
		if(USART_RX_STA&0x8000)
		{
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			  for(t=0;t<16;t++)
		{
			b[t]=0;//赋初值0}
		}
			for(t=0;t<len;t++)
			{
			b[t]=USART_RX_BUF[t];//将发送的数存到数组中
			}
			USART_RX_STA=0;	
		 recv_data_for_fpga=atonum(b);  //将数组转成数值
		 printf("收到的data为:%d\r\n",recv_data_for_fpga);	
		rec_data=frame_process(recv_data_for_fpga);//拆帧
		OSMboxPost(msg_rec_frame,&rec_data);      //发送消息

		}

		delay_ms(10);
	}
}

//注:open_frame_task实现的功能:串口向单片机发送数据,单片机对发送的数据进行处理,拆帧。
// 入网任务,终端侧
void NetIn_task(void *pdata)
{	
  
frame_typedef r_data={0,0,0,0,0};
   frame_typedef *data=&r_data;
   
	u16 distance;
	u8 NetIn_Status=REG_REQ_Status;
	u8 err;

	while(1)
	{	 
		switch (NetIn_Status)     
		{
			
		    case 2:
			{
				OSSemPost(sem_syn);
			//发送信号量,表示开始读数据
		   data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
			~~printf("接收的data->UID_4bit为:%d\r\n",data->UID_4bit);~~ 
			当printf放在此处,串口打印的值出现错误,不能进入下面if循环。
				if(data->UID_4bit==1&&data->sub_form_4bit==1)   
				{
				~~printf("接收的data->UID_4bit为:%d\r\n",data->UID_4bit);~~ 
				放在此处可打印出,且进入循环?????
					 TIM_Cmd(TIM3,ENABLE);
	                 printf("开始计数");		//开始计数
				   NetIn_Status+=2; 
				}

			}break;
//			case RNG_REQ_Status:
				case 4:
			{ 
				OSSemPost(sem_syn);                     //发送信号量,表示开始读数据
		    data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
			 printf("进入第二回合");
				printf("接收的data->sub_form_4bit为:%d\r\n",data->sub_form_4bit);

				if(data->sub_form_4bit==3)
				{    
					 printf("关闭计数");
					 TIM_Cmd(TIM3,DISABLE);                //关闭计数
						
					 distance=distance_cnt*0.25;           //单位为us
					 printf("distance%d\r\n",distance);
//					 FRAMING(&REG_REQ);                    //发测距回复
	         NetIn_Status+=2; 
				}
//				else NetIn_Status=REG_REQ_Status;
			}break;
			case Success_Status:
			{
				OSSemPost(sem_syn);                     //发送信号量,表示开始读数据
		    data=OSMboxPend(msg_rec_frame,10,&err); //接收拆帧的数据
				if(data->sub_form_4bit==5&&data->success_flag==1)
				{  
					//成功入网,开始发数据
					NetIn_Status=REG_REQ_Status;
				}
				else NetIn_Status=Success_Status;
			}break;
			
			
			default:
		printf("失败,继续循环");
			break;
		}	
		   delay_ms(10);
	};
}

//LED任务
void led_task(void *pdata)
{
	u8 t;
	while(1)
	{
//		t++;
//		delay_ms(10);
//		if(t==8)LED0=1;	//LED0灭
//		if(t==100)		//LED0亮
//		{
//			t=0;
//			LED0=0;
//		}
	LED0=!LED0;
	delay_ms(100);	
	}									 
}

????????为什么printf和消息邮箱放在一起会出现错误,消息邮箱收到的结构体的值会改变????

注:

    #ifndef __COM_H
    #define __COM_H		
    #include "sys.h"	
    #define Random_Access_Status 1
    #define REG_REQ_Status       2
    #define REG_RSP_Status       3
    #define RNG_REQ_Status       4
    #define RNG_RSP_Status       5
    #define Success_Status       6
    typedef struct 
    {
    	u16 success_flag;
        u16 UID_4bit;
    	u16 prio_4bit;
    	u16 form_2bit;
    	u16 sub_form_4bit;
    }frame_typedef;
    
    u16 * HexToBinStr( u16 n,int x);
    
    frame_typedef  frame_process(u16 data);
    void FRAMING(frame_typedef *arm_to_fpga_data);
    u16 atonum(u16 s[]);
    #endif


#include "com.h" 
#include "fsmc.h"
#include "usart.h"


/**************************************************
函数名称:HexToBinStr
函数功能:进制转换
输入参数:(n,x)n代表需要转换的数   x代表进制
返回值:数组a,从高位到地位排序
**************************************************/	
u16 a[16];
u16 * HexToBinStr( u16 n,int x)
{
	u16 y=0;
	while(n!=0)
	{
	 a[15-y]=n%x;
	 n=n/x;
     y++;
	}
	for(;y<16;y++)
	{a[15-y]=0;}
	
	return a;
}


/**************************************************
函数名称:frame_process
函数功能:拆帧处理
输入参数:
返回值:
**************************************************/	

frame_typedef  frame_process(u16 data)
{
  frame_typedef recv_data;
	u16 *data_2b;
	u16 i;
  data_2b=HexToBinStr(data,2);         //转换为二进制
	
//	printf("转换后的二进制数据为");	
//	for(i=0;i<16;i++)
//	 printf("%d",a[i]);	
//	printf("\n\r");
//	recv_data.sub_form_4bit=0;
//	recv_data.form_2bit=0;
//	recv_data.prio_4bit=0;
//	recv_data.UID_4bit=0;
//	recv_data.success_flag=0;
//	
	recv_data.UID_4bit=data_2b[0]*8+data_2b[1]*4+data_2b[2]*2+data_2b[3]*1;
    recv_data.prio_4bit=data_2b[4]*8+data_2b[5]*4+data_2b[6]*2+data_2b[7];
	recv_data.form_2bit=data_2b[8]*2+data_2b[9];
	recv_data.sub_form_4bit=data_2b[10]*8+data_2b[11]*4+data_2b[12]*2+data_2b[13];
	recv_data.success_flag=data_2b[14];
//	
//	printf("接收的recv_data.UID_4bit为:%d\r\n",recv_data.UID_4bit);
//	printf("接收的recv_data.UID_4bit为:%d\r\n",recv_data.sub_form_4bit);
//	
	
	return recv_data;
}

/**************************************************
函数名称:FRAMING
函数功能:组帧
输入参数:数据结构体指针
返回值:
**************************************************/	
void FRAMING(frame_typedef *arm_to_fpga_data)
{
	 u16 Tx_data_to_fpga;
   Tx_data_to_fpga=arm_to_fpga_data->sub_form_4bit+(arm_to_fpga_data->form_2bit<<4)+(arm_to_fpga_data->prio_4bit<<6)+(arm_to_fpga_data->UID_4bit<<10)+(arm_to_fpga_data->success_flag<<14);
	 //fpga_write(2,Tx_data_to_fpga);
	// printf("发送的data为:%d\r\n",Tx_data_to_fpga);
}
/**************************************************
函数名称:FRAMING
函数功能:组帧
输入参数:数据结构体指针
返回值:
**************************************************/	
void control_frame(frame_typedef *control_frame_data)
{
	 
}



/**************************************************
函数名称:atoi
函数功能:将字符串转换为数值
输入参数:字符串数组
返回值:
**************************************************/	
u16 atonum(u16 s[])
{
	u16 i,n;
	n=0;
	for(i=0;s[i]>='0'&&s[i]<='9';i++)
	{
	n=10*n+(s[i]-'0');         
	}
	 return n;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/137809.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Ubuntu 定时执行脚本

    Ubuntu 定时执行脚本一、关于crontabcron是一个Linux定时执行工具,可以在无需人工干预的情况下运行作业。在Ubuntu中,cron是被默认安装并启动的。二、例子直接上例子,来看看怎么用。需求:定时每天8点,自动执行保存在/root目录下hello.sh脚本1、方法很简单,只需编辑ect下crontab文件就行了,这个文件里存放的就是cron要执行的命令,以及定时执行的时间…

  • 深入浅出JMS(一)——JMS简单介绍

    深入浅出JMS(一)——JMS简单介绍

    2021年11月24日
  • PhpSpreadsheet_php读取文件内容

    PhpSpreadsheet_php读取文件内容·1、实例化Spreadsheet对象<?phpnamespaceapp//给类文件的命名空间起个别名usePhpOffice\PhpSpreadsheet\Spreadsheet;//Xlsx类保存文件功能类usePhpOffice\PhpSpreadsheet\Writer\Xlsx;//实例化Spreadsheet对象$spreadsheet=newSpreadsheet();2、Spreadsh

  • 二进制如何转十进制?_二进制转换为十进制的算法

    二进制如何转十进制?_二进制转换为十进制的算法1、计算机的数制介绍数制:计数的方法,指用一组固定的符号和统一的规则来表示数值的方法数位:指数字符号在一个数中所处的位置基数:指在某种进位计数制中,数位上所能使用的数字符号的个数位权:指在某种

  • 什么是Promise,我们用它来做什么?[通俗易懂]

    什么是Promise,我们用它来做什么?[通俗易懂]一、什么是Promise?我们用Promise来解决什么问题?Promise是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。我…

  • allow_url_fopen 和 allow_url_include[通俗易懂]

    allow_url_fopen 和 allow_url_include[通俗易懂]一、在本地php.ini文件中将allow_url_fopen设置为On,重启Apache后,file_get_contents()就能读远程文件。1.读取本地php文件,当文本来解析,并没有执行读

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号