USB串口高速通讯环形队列(单入单出、多入多出)

辅助理解:数据结构(C语言版)严蔚敏 清华大学出版社(环形队列)

一、C++实现 

Status InitQueue(SqQueue &Q)
{
      //构造一个空队列Q
      Q.base=(QElemType*)malloc( MAXQSIZE*sizeof(QElemType));
      if(!Q.base) 
        {
            return false;
            printf("***************Queue fail");//存储分配失败
        }
      Q.front=Q.rear=0;
      return true;
}

int QueueLength(SqQueue &Q)
{
      //返回Q的长度
      return ((Q.rear-Q.front+MAXQSIZE)%MAXQSIZE);
}

Status EnQueue(SqQueue &Q,QElemType *e,int num)
{
      //插入元素e为Q的新的队尾元素
      if((Q.rear+num)%MAXQSIZE==Q.front) return ERROR;//队列满
      if(Q.rear+num>MAXQSIZE)//到数据末尾需要注意内存拷贝的问题
	{
            memcpy(&Q.base[Q.rear],&e[0],MAXQSIZE-Q.rear);
            memcpy(&Q.base[0],&e[MAXQSIZE-Q.rear],num+Q.rear-MAXQSIZE);
	}
      else
            memcpy(&Q.base[Q.rear],&e[0],num);
      Q.rear=(Q.rear+num)%MAXQSIZE;
      return OK;
}
//出栈一个
Status DeQueue(SqQueue &Q,QElemType &e)
{
      //若队列不为空,则删除Q的对头文件,用e返回其值,并返回ok
      //否则返回ERROR
      if(Q.front==Q.rear) return ERROR;
      e=Q.base[Q.front];
      Q.front=(Q.front+1)%MAXQSIZE;
      return OK;
}
//出栈多个
int DeQueue(SqQueue &Q,QElemType *e,int num)
{
      //若队列不为空,则删除Q的对头文件,用e返回其值,并返回ok
      //否则返回ERROR
    int length=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
    if(length==0) return 0;
    if(num>0)
    { 
        if(length>num-1){
            if(Q.front+num<MAXQSIZE)               
                  memcpy(&e[0],&Q.base[Q.front],num);
            else
                {
                    memcpy(&e[0],&Q.base[Q.front],MAXQSIZE-Q.front);
                    memcpy(&e[MAXQSIZE-Q.front],&Q.base[0],Q.front+num-MAXQSIZE);
                }
            Q.front=(Q.front+num)%MAXQSIZE;                       
            return num;
        }
        else{
            if(Q.front+length<MAXQSIZE)
            {
                memcpy(&e[0],&Q.base[Q.front],length);
            }
            else
            {
                memcpy(&e[0],&Q.base[Q.front],MAXQSIZE-Q.front);
                memcpy(&e[MAXQSIZE-Q.front],&Q.base[0],Q.front+length-MAXQSIZE);
            }
            Q.front=(Q.front+length)%MAXQSIZE; 
            return length;
        }   
    }
    else
        return 0;   
}

 多数据入栈

void Serial_Receive(SerialPub *Ser_)
{
    QElemType rcv_buf[10240];//10k
    Ser_->mlog->logInfo("Serial Program:USB data reception");
    Ser_->serial_tbefore=(ros::Time::now()).toSec();
    while(ros::ok()){
        double serial_tnow=(ros::Time::now()).toSec();	    
        if(serial_tnow-Ser_->serial_tbefore>4||!Ser_->serial_ttyACM1)
        {
            close(Ser_->device);
            Ser_->Serial_open(Ser_->c_s);
	        Ser_->serial_tbefore=(ros::Time::now()).toSec();
        }
        int rcv_ser=read(Ser_->device,rcv_buf, sizeof(rcv_buf));
	    Ser_->time_remeber=0;
        Ser_->serial_tbefore=(ros::Time::now()).toSec();
        if(rcv_ser>0)
        {
            if(!EnQueue(Q_Save,&rcv_buf[0],rcv_ser))
            {
                printf("(%d,%d)\n",Q_Save.front,Q_Save.rear);
            }
        }
    }
}

 多数据出栈

void SerialPub::del_ser(void)
{
    uint8_t update_buff_[204800];
    ssize_t rtn=0;
    while(ros::ok())
    {
        Rec_Begin:
        while(QueueLength(Q_Save)){
            while(ros::ok()){
                DeQueue(Q_Save,&buf_save[0],1);
                if(buf_save[0]==0xA4)
                {
                    frame_buff_[0]=0xA4;
                    DeQueue(Q_Save,&buf_save[0],1);
                    if(buf_save[00]==0x59){
                        frame_buff_[1]=0x59;
                        DeQueue(Q_Save,&buf_save[0],1);
                        if(buf_save[00]==0x43){
                            frame_buff_[2]=0x43;
                            break;
                        }
                    }
                }               
            }         
            rtn = DeQueue(Q_Save,&buf_save[0],7);
            if(rtn!=7){
                mlog->logError("Serial Program:Rec 7 Error");
                myprintf(&buf_save[0],7);
                goto Rec_Begin;
                }    
            memcpy(&frame_buff_[3],&buf_save[0],7);          
            n_size=frame_buff_[9]+(frame_buff_[8]<<8)+(frame_buff_[7]<<16)+(frame_buff_[6]<<24);
            if(printf_terminal_)
                std::cout<<n_size <<std::endl;
            while(QueueLength(Q_Save)<n_size+1){usleep(100);}
            rtn = DeQueue(Q_Save,&buf_save[0],n_size+2); 
            if(rtn!=n_size+2){
               mlog->logError("Serial Program:Rec Lgt Error");
               myprintf(&buf_save[0],n_size+2);
               goto Rec_Begin;
               }
            memcpy(&frame_buff_[10],&buf_save[0],n_size+2);
            if(frame_buff_[n_size+12-2]!=0x0D||frame_buff_[n_size+12-1]!=0x0A){
                mlog->logError("Serial Program:Rec End Error");
                myprintf(&frame_buff_[0],n_size+12);
                goto Rec_Begin;
            }
            switch(frame_buff_[4])
            {
                case Tx2_upd_sof://升级是0x15,回复是0x14
                {
                    switch (frame_buff_[5])
                    {
                        case 01:
                            {
                                send_data_update[4]=0x14;
                                if(1)
                                {
                                    std::string temp_up;
                                    for (uint8_t i=4;i<n_size-4;i++)
                                    {
                                        temp_up += buf_save[i];
                                    }
                                    std::cout << temp_up << std::endl;
                                    temp_up=update_path_;
                                    //temp_up=update_path_+temp_up;
                                    const char *path_up = temp_up.c_str();
                                    mode_t f_attrib = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
                                    up_file = open(path_up, O_WRONLY | O_CREAT | O_TRUNC, f_attrib);
                                    if(up_file < 0)
                                    {
                                        mlog->logError("Serial Program:Function sub 0x15 open update file");
                                    }
                                    upgrade_length=buf_save[3]+(buf_save[2]<<8)+(buf_save[1]<<16)+(buf_save[0]<<24);
                                    mlog->logInfo("Agree to update APP");
                                    cout<<"upgrade_length="<<upgrade_length<<endl;
                                    send_data_update[5]=0x01;//允许升级
                                }
                                else
                                {
                                    mlog->logInfo("Serial Program:Disagree with APP upgrade");
                                    send_data_update[5]=0x02;//不允许升级
                                }
                                RecState.detail.Update_Px30=true;
                            }                      
                            break;
                        case 02:
                            {
                                mlog->logInfo("Serial Program:Receiving upgrade file");
                                int offset=0;//前几个文件为文件名,需进行偏移,假设偏移为0,最后一位为CRC校验4位
                                memcpy(update_buff_,buf_save+offset,n_size-offset-4);
                                //校验crc
                                uint32_t check_crc=0,check_CRC;                         
                                check_crc=crc32_check(&update_buff_[0], n_size-offset-4);
                                //https://zhuanlan.zhihu.com/p/256487370
                                check_CRC=buf_save[n_size-offset-1]+(buf_save[n_size-offset-2]<<8)+(buf_save[n_size-offset-3]<<16)+(buf_save[n_size-offset-4]<<24);
                                if(check_CRC==check_crc)//if(check_crc==buf_save[n_size-2-1])
                                {
                                    send_data_update[4]=0x14;
                                    send_data_update[5]=0x03;//校验成功
                                    write(up_file,update_buff_,n_size-offset-4);//buf_save后面多了od oa 读取的是n_size是否会主动丢掉od oa?
                                    upgrade_length=upgrade_length-(n_size-4);//-(每次接收的长度-4)
                                }
                                else
                                {
                                    send_data_update[4]=0x14;
                                    send_data_update[5]=0x04;//校验失败
                                    mlog->logError("Serial Program:Upgrade function sub 0x15 CRC check error");
                                }
                                RecState.detail.Update_Px30=true;
                                if(upgrade_length<1)
                                {
                                    mlog->logInfo("Serial Program:Receiving upgrade file over");
                                    cout<<"upgrade_length="<<upgrade_length<<endl;
                                    if(fork()==0)
                                    {
                                        execlp("/home/nvidia/positec/robot_update/update.sh","sh",NULL);
                                    }
                                }
                            }
                            break;
                        case 03:
                            {
                                mlog->logInfo("Serial Program:Start Update");
                                close(up_file);
                            }
                            break;
                        case 04:
                            {
                                mlog->logInfo("Serial Program:Start Update");
                                close(up_file);
                            }
                            break;
                        default:
                            mlog->logError("Serial Program:Function sub 0x15 not understand");
                            break;
                    }
                }
                break;
                case M7_tx2://M7数据->a35
                {
                    if(printf_terminal_)
                    {
                        ROS_INFO_STREAM("serial recive");
                        myprintf(&frame_buff_[0],89);
                    }
                    RTK_IMU_ODOM();                
                }
                break;
                case M7_px3_ai://m7-px30-ai数据
                {
                    if(printf_terminal_)
                    {
                        ROS_INFO_STREAM("serial recive");
                        myprintf(&frame_buff_[0],89);
                    }
                    RTK_IMU_ODOM();                
                }
                break;
                case Tx2_p30_Req://请求
                {
                    switch (frame_buff_[10])
                    {
                        case Alg_Res_Req://算法复位请求
                        {
                            std::cout<<"Slam reset"<<std::endl;
                            slam_buf.data[0]=0x01;
                            RecState.detail.Slam_Reset=true;
                        }
                        break;
                        case Dir_Cal_Req://航向校准请求
                        {
                            std::cout<<"Dir_Calib"<<std::endl;
                            slam_buf.data[1]=0x01;
                            dir_cal=0x00;
                            RecState.detail.Dir_Cal_bit=true;                
                        }
                        break;
                        case DownCar_Req://下车
                        {
                            std::cout<<"DownCar_require"<<std::endl;
                            slam_buf.data[2]=0x02;
                            ai_buf.data[1]=0x02;
                            RecState.detail.DownCar_px30=true;
                        }
                        break;
                        case UpCar_Req://上车
                        {
                            std::cout<<"UpCar_require"<<std::endl;
                            slam_buf.data[2]=0x01;
                            ai_buf.data[1]=0x01;
                            RecState.detail.UpCar_px30=true; 
                        }
                        break;
                        case FinCar_Req://上下车完成
                        {
                            std::cout<<"UpDownCar_finish"<<std::endl;
                            slam_buf.data[2]=0x00;
                            ai_buf.data[1]=0x00;
                            RecState.detail.FinCar_px30=true; 
                        }
                        break;
                        case FrtCar_Req://前进
                        {
                            std::cout<<"Front Car_Req"<<std::endl;
                            ai_buf.data[2]=0x00;
                            RecState.detail.Frt_Px30=true; 
                        }
                        break;
                        case BckCar_Req://后退
                        {
                            std::cout<<"Back Car_Req"<<std::endl;
                            ai_buf.data[2]=0x01;
                            RecState.detail.Bck_Px30=true; 
                        }
                        break;
                        default:
                        {
                            mlog->logError("Serial Program:PX30->TX2 REQUIRE:0x9a not understand");
                            myprintf(&frame_buff_[0],89);
                            break;
                        }
                    }               
                }
                break;
                case Tx2_px3_Hand://握手
                {
                    ROS_INFO_STREAM("Hand Shake back message");
                    send_data_hand[4]=0x07;
                    send_data_hand[5]=0x02;
                    printf("Hand Shake recive message" );
                    myprintf(&frame_buff_[0],13); 
                    RecState.detail.Hand_Px30=true;
                    handshake_bit=true;                              
                }
                break;
                case Bld_map_init://build map init point 接收0x09,回复0x08
                {
                    switch (frame_buff_[10])
                    {
                        case 01:
                        {
                            ROS_INFO_STREAM("Recive mapping init point 0x09 0x01");
                            send_data_map[4]=Bld_map_bck;
                            send_data_map[5]=0x01;
                            send_data_map[10]=0x01;
                            map_service++;
                            if(rtk_x==0)
                            {
                                send_data_map[5]=0x02;
                                ROS_INFO_STREAM("No rtk message from m7");
                            }
                            else
                            {
                                send_data_map[5]=0x01;
                                ROS_INFO_STREAM("Mapping init point");
                            }
                            *(double *)&send_data_map[11] = rtk_x;
                            *(double *)&send_data_map[19] = rtk_y;
                            *(float * )&send_data_map[27] = rtk_z;
                            myprintf(&frame_buff_[0],13); 
                            std::ofstream Out_dirStream;
                            Out_dirStream.open(rtk_path_, std::ios::out);
                            Out_dirStream.setf(std::ios::fixed,std::ios::floatfield);
                            Out_dirStream.precision(9);
                            Out_dirStream << rtk_x << " " 
                            << rtk_y << " "
                            << rtk_z << std::endl;
                            Out_dirStream.close();
                            RecState.detail.Map_Px30=true;
                        }
                        break;
                        case 02:
                        {
                            ROS_INFO_STREAM("Recive mapping init point 0x09 0x02");
                            send_data_map[4]=0x08;
                            send_data_map[5]=0x01;
                            send_data_map[10]=0x02;
                            map_service++;
                            ROS_INFO_STREAM("Mapping init point change");
                            double change_point_x=0.00,change_point_y=0.00;
                            if(n_size>16)
                            {
                                memcpy(&change_point_x,&frame_buff_[11], 8);
                                memcpy(&change_point_y,&frame_buff_[19], 8);                       
                                std::ofstream Out_dirStream;
                                Out_dirStream.open(rtk_path_, std::ios::out);
                                Out_dirStream.setf(std::ios::fixed,std::ios::floatfield);
                                Out_dirStream.precision(9);
                                Out_dirStream << change_point_x << " " 
                                << change_point_y << " "
                                << 1.00 << std::endl;
                                std::cout<<"change_point_x= "<<change_point_x<<"change_point_y= "<<change_point_y<<std::endl;
                                Out_dirStream.close();
                                RecState.detail.Map_Px30=true;
                            }
                            else
                            {
                                std::cout<<"change_point length too short,the length is"<<n_size<<std::endl;
                            }
                        }
                        break;
                        default:
                        {
                            mlog->logError("Serial Program:Mapping init point,0x09 not understand");
                            myprintf(&frame_buff_[0],89);
                            break;
                        }
                    }                             
                }
                break;
                case Tx2_p30_log://传LOG
                {
                    RecState.detail.Log_Px30=true;
                }
                break;
                default:
                {
                    mlog->logError("Serial Program:Function main not understand");
                    myprintf(&frame_buff_[0],89);
                    break;
                }
            
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(1));                 
    }
}

二、STM32实现

头文件数据定义

typedef enum
{
  USART_QUEUE_EMPTY = 0,
  USART_QUEUE_FULL = 1,
  USART_QUEUE_OK = 2,
} usart_queue_status_t;


#define USART_QUEUE_SIZE  256 
typedef struct
{  
  u16 front;
  u16 rear;
  u16 size;
  u8 data[USART_QUEUE_SIZE];
} usart_queue_t;

extern usart_queue_t usart1_send;

void UsartQueueInit(usart_queue_t *q);
uint8_t UsartQueuePop(usart_queue_t *q, uint8_t *data);
uint8_t UsartQueuePush(usart_queue_t *q, uint8_t data);

.c文件

#include "sys.h"
#include "usart.h"	  

usart_queue_t usart1_send;


#if 1
#pragma import(__use_no_semihosting)  
//解决HAL库使用时,某些情况可能报错的bug
int _ttywrch(int ch)    
{
    ch=ch;
	return ch;
}
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
	/* Whatever you require here. If the only file you are using is */ 
	/* standard output using printf() for debugging, no file handling */ 
	/* is required. */ 
}; 
/* FILE is typedef’ d in stdio.h. */ 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->ISR&0X40)==0);//循环发送,直到发送完毕   
	USART1->TDR = (u8) ch;      
	return ch;
}
#endif 
//end



//串口缓冲队列初始化
void UsartQueueInit(usart_queue_t *q)
{
    q->size = 0;
    q->front = 0;
    q->rear = 0;
}

//入队
uint8_t UsartQueuePush(usart_queue_t *q, uint8_t data)
{
    if (((q->rear % USART_QUEUE_SIZE) == q->front) && ((q->size == USART_QUEUE_SIZE)))
    {
        //printf("--------------USART_QUEUE_FULL------------------");
        return USART_QUEUE_FULL;
    }
    q->data[q->rear] = data;
    q->rear = (q->rear + 1) % USART_QUEUE_SIZE;
    q->size++;

    return USART_QUEUE_OK;
}
//出队
uint8_t UsartQueuePop(usart_queue_t *q, uint8_t *data)
{
    if ((q->front == q->rear) && (q->size == 0))
    {
        //printf("--------------USART_QUEUE_EMPTY-------------------");
        return USART_QUEUE_EMPTY;
    }

    *data = q->data[q->front];
    q->front = (q->front + 1) % USART_QUEUE_SIZE;
    q->size--;

    return USART_QUEUE_OK;
}



void USART1_IRQHandler(void)
{
	u8 res;	
	if(USART1->ISR&(1<<5))//接收到数据
	{	 
		  res=USART1->RDR; 
			UsartQueuePush(&usart1_send, res);
	}
	USART1->ICR |=0x0008;
} 										 
//初始化IO 串口1 上位机
//pclk2:PCLK2时钟频率(Mhz)
//bound:波特率 
void USART1_Init(u32 pclk2,u32 bound)
{  	 
	u32	temp;	
	temp=(pclk2*1000000+bound/2)/bound;	//得到USARTDIV@OVER8=0,采用四舍五入计算
	RCC->AHB1ENR|=1<<1;   	//使能PORTB口时钟  
	RCC->APB2ENR|=1<<4;  	//使能串口1时钟 
	GPIO_Set(GPIOB,PIN14|PIN15,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PB14,PB15,复用功能,上拉输出
 	GPIO_AF_Set(GPIOB,14,4);	//PB14,AF4
	GPIO_AF_Set(GPIOB,15,4);//PB15,AF4
	//波特率设置
 	USART1->BRR=temp; 		//波特率设置@OVER8=0 	
	USART1->CR1=0;		 	//清零CR1寄存器
	USART1->CR1|=0<<28;	 	//设置M1=0
	USART1->CR1|=0<<12;	 	//设置M0=0&M1=0,选择8位字长 
	USART1->CR1|=0<<15; 	//设置OVER8=0,16倍过采样 
	USART1->CR1|=1<<3;  	//串口发送使能 

	//使能接收中断 
	USART1->CR1|=1<<2;  	//串口接收使能
	USART1->CR1|=1<<5;    	//接收缓冲区非空中断使能	    	
	MY_NVIC_Init(0,2,USART1_IRQn,2);//组2,最低优先级 

	USART1->CR1|=1<<0;  	//串口使能
}

使用时,解析一个丢一个数据,通讯协议定义最短接收指令个数为9,所以当接收一个完成指令在进行解析,接收数据格式CC 33 length order data1 ...... datan check1 check2

void UsartQueueDataProcess(void)
{
   if(usart1_send.size > 9)
    {
        int i = 0;
        UsartCheckInform check_inform;
        if (UsartQueuePop(&usart1_send, &check_inform.Head1) == USART_QUEUE_OK)
        {
            //printf("-----------------head1--------------------------");
            if (check_inform.Head1 == 0xcc) //   head1;
            {
                check_inform.data[0] = 0xcc;
                //printf("-----------------head1--------------------------");
                if (UsartQueuePop(&usart1_send, &check_inform.Head2) == USART_QUEUE_OK)
                {
                    if (check_inform.Head2 == 0x33) // head2
                    {
                        check_inform.data[1] = 0x33;
                        //printf("-----------------head2--------------------------");
                        if (UsartQueuePop(&usart1_send, &check_inform.Lenghth) == USART_QUEUE_OK)
                        {
                            check_inform.data[2] = check_inform.Lenghth;
                           // printf("-----------------Lenghth--------------------------");
                            for (i = 0; i < check_inform.Lenghth; i++)
                            {
                                UsartQueuePop(&usart1_send, &check_inform.data[i + 3]);
                            }
                            if (Check_Sum(check_inform.data, check_inform.Lenghth + 3) == 1) //校验正确
                            {
                                //
                                switch (check_inform.data[3])
                                {
                                case 0x01://  运动控制指令
																	if(state_yksp!=1)
																	{
                                    if (check_inform.data[8] == 1)
                                    {
																			 speedlinedata = (int16_t)(((uint16_t)check_inform.data[5] << 8) + (uint16_t)check_inform.data[4]);
                                       speedangledata = (int16_t)(((uint16_t)check_inform.data[7] << 8) + (uint16_t)check_inform.data[6]);
																		   state_pcsp=1;
																		   carsport_state=0;
																		  speed11=const_speed*(speedlinedata-wheel_interval/2*speedangledata/1000);
																		  speed22=const_speed*(speedlinedata-wheel_interval/2*speedangledata/1000);
																		  speed33=-const_speed*(speedlinedata+wheel_interval/2*speedangledata/1000);
																		  speed44=-const_speed*(speedlinedata+wheel_interval/2*speedangledata/1000);
                                    }
                                    else
                                    {
																		  speed11=0;
																	    speed22=0;
																	    speed33=0;
																	    speed44=0;
                                    }
																		Motor_Velocity(Motor1_Drive_ID,(uint32_t)(speed11));
																		Motor_Velocity(Motor2_Drive_ID,(uint32_t)(speed22));
																		delay_us(1000);
																		Motor_Velocity(Motor3_Drive_ID,(uint32_t)(speed33));
																		Motor_Velocity(Motor4_Drive_ID,(uint32_t)(speed44));
																	}
                                    break ;
																
                                case 0x11: //  信号处理单元 融入数据查询 即融合信息上传频率设定
                                    DataFrequency = check_inform.data[4]; //信息频率上传确定  0为单次
                                    break;
                                case 0x12://  里程计清零指令
                                    X = 0;
                                    Y = 0;
                                    Yaw_Angle = 0;
                                    break;
                                case 0x81:   // 当前发送机状态为0 且第一次解析发送机指令
                                    if ((check_inform.data[4] == 0x01) && (enginestartstopflag == 0x00))
                                    {
                                       
                                        //printf("-----------------ENGING---START------------------------");
                                        emginestarstopstate = 0X0E;
																			  timedurcnt=0;
                                    }
                                    if ((check_inform.data[4] == 0x02) && (enginestartstopflag == 0x01))
                                    {
                                       
                                        //printf("-----------------ENGING---STOP------------------------");
                                        emginestarstopstate=0X10;
																			  timedurcnt=0;
                                    }
                                    break;  
																
                                case 0x82: //  底盘升降
                                    switch (check_inform.data[4])
                                    {
                                    case 0x01:
                                        //  当前不在01 挡位则进行解析
                                        if (UnderPlantFour != 0x01)
                                        {
                                            UnderPlantUpdownConState = 0xFF;
                                            UpdownTimeflag = 0x01;
                                        }
                                        break;
                                    case 0x02:
                                        if (UnderPlantFour != 0x02)
                                        {
                                            UnderPlantUpdownConState = 0xFF;
                                            UpdownTimeflag = 0x02;
                                        }
                                        break;
                                    case 0x03:
                                        if (UnderPlantFour != 0x03)
                                        {
                                            UnderPlantUpdownConState = 0xFF;
                                            UpdownTimeflag = 0x03;
                                        }
                                        break;
                                    case 0x04:
                                        if (UnderPlantFour != 0x04)
                                        {
                                            UnderPlantUpdownConState = 0xFF;
                                            UpdownTimeflag = 0x04;
                                        }
                                        break;
                                    }
                                    break;
                                case 0x90: //  目前只有设置油量选项 根据协议其余信息自动上传
                                    switch (check_inform.data[4])
                                    {
                                    // 设置油量
                                    case 0x03:
                                        oil = check_inform.data[5];
                                        break;
                                    }
                                    break;
                                case 0x92:
                                    //  电机复位请求标志
																		Motor_ErrorReset_Request(Motor1_Drive_ID);
																		Motor_ErrorReset_Request(Motor2_Drive_ID);
																		Motor_ErrorReset_Request(Motor3_Drive_ID);
																		Motor_ErrorReset_Request(Motor4_Drive_ID);
																		MOTOR_init();	
                                    break;
                                default :
                                    break;
                                }
                            }
      
                        }
  
                    }


                }

            }

        }

    }

}

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值