stm32+neo6m GPS模块定位系统

来源:互联网 发布:spss22 mac版教程 编辑:程序博客网 时间:2024/05/22 13:42

开发平台:主处理器是意法半导体的stm32f103系列,这款芯片应用广泛,并且资料很多。

主要定位模块:ublox的一款芯片

开发环境:MDK5.0

主要代码还是参考原子的历程,在它的基础上实现了只提取经纬度,海拔等操作

硬件连接:3.3V电源给GPS模块供电,stm32串口2接GPS。

软件实现主要流程:stm32串口初始化,模块初始化,设置更新速率,保存配置,串口2接收消息,对接收到的消息进行字符串处理,提取有用的信息加以利用。

以下给出主要程序:

串口部分:

串口2初始化代码:

    void USART2_Init_JAVE( u32 bound )    {                GPIO_InitTypeDef  GPIO_InitStructure;        USART_InitTypeDef USART_InitStructure;        NVIC_InitTypeDef  NVIC_InitStructure;                USART_DeInit(USART2);                //使能串口3的时钟 和对应GPIO时钟        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                        //配置TX引脚GPIO        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;        GPIO_Init(GPIOA,&GPIO_InitStructure);                //配置RX引脚GPIO        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;        GPIO_Init(GPIOA,&GPIO_InitStructure);                //配置串口2        USART_InitStructure.USART_BaudRate = bound;        USART_InitStructure.USART_WordLength = USART_WordLength_8b;        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(USART2, &USART_InitStructure);                //使能串口2        USART_Cmd(USART2,ENABLE);                USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);        //配置串口2接收中断        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        NVIC_Init(&NVIC_InitStructure);                USART_ClearFlag(USART2, USART_FLAG_RXNE);                USART_GetFlagStatus(USART2,USART_FLAG_TC);     /* 先读SR,再写DR */            }


串口2中断函数:

    void RX2_Handler( void )    {        char temp = 0;#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.OSIntEnter();    #endif                if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)        {            temp = USART_ReceiveData( USART2 );     /* 读取USART2数据,自动清零标志位 RXNE */                    if( RX2_Point <= 1999)            {                                RX2_Temp[RX2_Point] = temp;                                RX2_Point++;                            }elseRX2_Point=0;                    }#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.OSIntExit();   #endif              }


串口2接收扫描:

unsigned short USART2_Scan(u16 *len){unsigned short int ftemp = 0;ftemp = RX2_Point;*len=0;if( ftemp != 0 ){delay_ms(100);while ( ftemp != RX2_Point ){ ftemp = RX2_Point; delay_ms(100);}RX2_Point = 0;      /* 重置指针 */*len= ftemp;return 1;   /* 扫描到数据,返回1 */}return 0;}


GPS驱动部分:

设置更新速率代码:

//配置UBLOX NEO-6的更新速率    //measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz)//reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)//返回值:0,发送成功;其他,发送失败.unsigned char Ublox_Cfg_Rate(unsigned short measrate,unsigned char reftime){_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF; if(measrate<200)return 1;//小于200ms,直接退出 cfg_rate->header=0X62B5;//cfg headercfg_rate->id=0X0806; //cfg rate idcfg_rate->dlength=6; //数据区长度为6个字节.cfg_rate->measrate=measrate;//脉冲间隔,mscfg_rate->navrate=1;//导航速率(周期),固定为1cfg_rate->timeref=reftime; //参考时间为GPS时间Ublox_CheckSum((unsigned char*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);//while(DMA1_Channel7->CNDTR!=0);//等待通道7传输完成   //UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate));//通过dma发送出去Ublox_Send_Date((unsigned char*)cfg_rate,sizeof(_ublox_cfg_rate));//发送数据给NEO-6M return Ublox_Cfg_Ack_Check();}



GPS初始化:

unsigned char GPS_Init(void){unsigned char key = 0xFF,cnt=0;//保存配置成功的标志,成功时返回的值是0;MyPrintf("GPS 初始化\r\n");Ublox_Cfg_Prt(38400);//重新设置模块的波特率为38400 while((Ublox_Cfg_Rate(2000,1)!=0)&&key)//持续判断,直到可以检查到NEO-6M,且数据保存成功{MyPrintf("2");USART2_Init_JAVE( 38400 );//初始化串口2波特率为9600(EEPROM没有保存数据的时候,波特率为9600.)Ublox_Cfg_Prt(38400);//重新设置模块的波特率为38400 if(++cnt>=5) return 1;//错误key=Ublox_Cfg_Cfg_Save();//保存配置,配置成功,返回0  delay_ms(50);}   return 0;}


算法处理部分:(字符串处理)

对于接收到的消息进行提取处理:

//分析GPGGA信息//gpsx:nmea信息结构体//buf:接收到的GPS数据缓冲区首地址void NMEA_GPGGA_Analysis(GPS_PacketTypeDef *GPS_Packet,u8 *buf){unsigned char *p1,dx,posx;unsigned int temp;float rs;p1=(unsigned char *)strstr((const char *)buf,"$GPGGA");  //此处可改为"$GPGGA"posx=NMEA_Comma_Pos(p1,9);//得到海拔高度if(posx!=0XFF){GPS_Packet->altitude=NMEA_Str2num(p1+posx,&dx);  MyPrintf("altitude=%d\r\n",GPS_Packet->altitude);}posx=NMEA_Comma_Pos(p1,2);//得到纬度if(posx!=0XFF){temp=NMEA_Str2num(p1+posx,&dx);  GPS_Packet->latitude=temp/NMEA_Pow(10,dx+2);//得到°rs=temp%NMEA_Pow(10,dx+2);//得到' GPS_Packet->latitude=GPS_Packet->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° MyPrintf("latitude=%d\r\n",GPS_Packet->latitude);}  posx=NMEA_Comma_Pos(p1,4);//得到经度if(posx!=0XFF){  temp=NMEA_Str2num(p1+posx,&dx);  GPS_Packet->longitude=temp/NMEA_Pow(10,dx+2);//得到°rs=temp%NMEA_Pow(10,dx+2);//得到' GPS_Packet->longitude=GPS_Packet->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° MyPrintf("longitude=%d\r\n",GPS_Packet->longitude);}posx=NMEA_Comma_Pos(p1,6);//定位状态if(posx!=0XFF){GPS_Packet->status=*(p1+posx)-'0';MyPrintf("status=%d\r\n",GPS_Packet->status);}}


GPS测试主程序:

 unsigned char GPS_Run(void) { unsigned char flag=0;//定位信息成功标志 unsigned short rxlen,i;//rxlen:数据长度 unsigned char cnt=0;  while(1) {  if(cnt>2) {sign_run=1;return 0;} cnt++; rxlen=0; USART2_Scan(&rxlen); if(rxlen !=0) {for(i=0;i<rxlen;i++){GPS_Temp[i]=RX2_Temp[i];  //MyPrintf("%c",RX2_Temp[i]);}GPS_Temp[i]=0;//自动添加结束符for(i=0;i<rxlen;i++){MyPrintf("%c",GPS_Temp[i]);}MyPrintf("\r\n");if(GPS_Check(GPS_Temp)!=0) {MyPrintf("无效定位数据\r\n");continue ;}MyPrintf("开始解析定位数据\r\n");NMEA_GPGGA_Analysis(&GPS_Packet,(unsigned char*)GPS_Temp);//分析GPS模块发送回来的数据,提取经纬度信息并换算成度flag = GPS_Packet.status;//定位成功的标志if(flag == 1 || flag == 2)          //定位成功->读取数据存入MSG数据包并退出{MyPrintf("GPS success\r\n");GPS_Show( );Task_LED( );return 1;} } delay_ms(50); } }



由于位置信息还会受到卫星信号强弱的影响,因此从GPS模块里面接收到的信息不一定就是有效的位置信息。如果定位失败,模块会返回类似这样的信息

$GPRMC,,V,,,,,,,,,,N*53$GPVTG,,,,,,,,,N*30$GPGGA,,,,,,0,00,99.99,,,,,,*48$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30$GPGSV,1,1,01,19,,,35*76$GPGLL,,,,,,V,N*64
可以简单地认为,只要¥GPGLL这一行数据里含有“V”字符,那么这一次数据就是无效的,应当舍弃,等待下一次正确的信号输出。

如果卫星信号足够强,定位数据有效,那么模块会返回类似这样的信息

$GPRMC,031851.00,A,2309.86780,N,11325.74067,E,0.683,,060916,,,A*74$GPVTG,,T,,M,0.683,N,1.265,K,A*2E$GPGGA,031851.00,2309.86780,N,11325.74067,E,1,04,5.43,19.1,M,-5.1,M,,*7B$GPGSA,A,3,28,17,19,01,,,,,,,,,6.77,5.43,4.04*03$GPGSV,3,1,09,01,24,037,20,02,01,233,,03,44,084,29,06,35,242,*72$GPGSV,3,2,09,08,01,087,,11,14,051,,17,40,326,30,19,26,302,29*76$GPGSV,3,3,09,28,75,000,31*4A$GPGLL,2309.86798,N,11325.74064,E,031852.00,A,A*61


下面给出模块驱动部分的全部源码:

C文件:

//GPS校验和计算//buf:数据缓存区首地址//len:数据长度//cka,ckb:两个校验结果.void Ublox_CheckSum(unsigned char *buf,unsigned short len,unsigned char* cka,unsigned char*ckb){unsigned short i;*cka=0;*ckb=0;for(i=0;i<len;i++){*cka=*cka+buf[i];*ckb=*ckb+*cka;}}//检查CFG配置执行情况//返回值:0,ACK成功//       1,接收超时错误//       2,没有找到同步字符//       3,接收到NACK应答unsigned char Ublox_Cfg_Ack_Check(void){ unsigned short len=0,i,rxlen;unsigned char rval=0;while(USART2_Scan(&rxlen)==0 && len<100)//等待接收到应答   { len++; delay_ms(5);}if(len<100)   //超时错误.{for(i=0;i<rxlen;i++)if(RX2_Temp[i]==0XB5)break;//查找同步字符 0XB5if(i==rxlen)rval=2;//没有找到同步字符else if(RX2_Temp[i+3]==0X00)rval=3;//接收到NACK应答else rval=0;   //接收到ACK应答}else rval=1;//接收超时错误MyPrintf("rval = %d\r\n",rval);return rval;  }//配置NMEA输出信息格式//baudrate:波特率,4800/9600/19200/38400/57600/115200/230400  //返回值:0,执行成功;其他,执行失败unsigned char Ublox_Cfg_Prt(unsigned int baudrate){_ublox_cfg_prt *cfg_prt=(_ublox_cfg_prt *)USART2_TX_BUF;cfg_prt->header=0X62B5;//cfg headercfg_prt->id=0X0006;//cfg prt idcfg_prt->dlength=20;//数据区长度为20个字节.cfg_prt->portid=1;//操作串口1cfg_prt->reserved=0; //保留字节,设置为0cfg_prt->txready=0; //TX Ready设置为0cfg_prt->mode=0X08D0; //8位,1个停止位,无校验位cfg_prt->baudrate=baudrate; //波特率设置cfg_prt->inprotomask=0X0007;//0+1+2cfg_prt->outprotomask=0X0007;//0+1+2 cfg_prt->reserved4=0; //保留字节,设置为0 cfg_prt->reserved5=0; //保留字节,设置为0 Ublox_CheckSum((unsigned char*)(&cfg_prt->id),sizeof(_ublox_cfg_prt)-4,&cfg_prt->cka,&cfg_prt->ckb);//while(DMA1_Channel7->CNDTR!=0);//等待通道7传输完成   //UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_prt));//通过dma发送出去Ublox_Send_Date((unsigned char*)cfg_prt,sizeof(_ublox_cfg_prt));//发送数据给NEO-6M   delay_ms(200);//等待发送完成 USART2_Init_JAVE(baudrate);//重新初始化串口2   return Ublox_Cfg_Ack_Check();//这里不会反回0,因为UBLOX发回来的应答在串口重新初始化的时候已经被丢弃了.} //配置保存//将当前配置保存在外部EEPROM里面//返回值:0,执行成功;1,执行失败.unsigned char Ublox_Cfg_Cfg_Save(void){unsigned char i;_ublox_cfg_cfg *cfg_cfg=(_ublox_cfg_cfg *)USART2_TX_BUF;cfg_cfg->header=0X62B5;//cfg headercfg_cfg->id=0X0906;//cfg cfg idcfg_cfg->dlength=13;//数据区长度为13个字节. cfg_cfg->clearmask=0;//清除掩码为0cfg_cfg->savemask=0XFFFF; //保存掩码为0XFFFFcfg_cfg->loadmask=0; //加载掩码为0 cfg_cfg->devicemask=4; //保存在EEPROM里面 Ublox_CheckSum((unsigned char*)(&cfg_cfg->id),sizeof(_ublox_cfg_cfg)-4,&cfg_cfg->cka,&cfg_cfg->ckb);//while(DMA1_Channel7->CNDTR!=0);//等待通道7传输完成   //UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_cfg));//通过dma发送出去Ublox_Send_Date((unsigned char*)cfg_cfg,sizeof(_ublox_cfg_cfg));//发送数据给NEO-6M for(i=0;i<6;i++)if(Ublox_Cfg_Ack_Check()==0)break;//EEPROM写入需要比较久时间,所以连续判断多次return i==6?1:0;}//配置UBLOX NEO-6的更新速率    //measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz)//reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)//返回值:0,发送成功;其他,发送失败.unsigned char Ublox_Cfg_Rate(unsigned short measrate,unsigned char reftime){_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF; if(measrate<200)return 1;//小于200ms,直接退出 cfg_rate->header=0X62B5;//cfg headercfg_rate->id=0X0806; //cfg rate idcfg_rate->dlength=6; //数据区长度为6个字节.cfg_rate->measrate=measrate;//脉冲间隔,mscfg_rate->navrate=1;//导航速率(周期),固定为1cfg_rate->timeref=reftime; //参考时间为GPS时间Ublox_CheckSum((unsigned char*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);//while(DMA1_Channel7->CNDTR!=0);//等待通道7传输完成   //UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate));//通过dma发送出去Ublox_Send_Date((unsigned char*)cfg_rate,sizeof(_ublox_cfg_rate));//发送数据给NEO-6M return Ublox_Cfg_Ack_Check();}//从buf里面得到第cx个逗号所在的位置//返回值:0~0XFE,代表逗号所在位置的偏移.//       0XFF,代表不存在第cx个逗号unsigned char NMEA_Comma_Pos(unsigned char *buf,unsigned char cx){     unsigned char *p=buf;while(cx){ if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//遇到'*'或者非法字符,则不存在第cx个逗号if(*buf==',')cx--;buf++;}return buf-p; }//m^n函数//返回值:m^n次方.unsigned int NMEA_Pow(unsigned char m,unsigned char n){unsigned int result=1; while(n--)result*=m;    return result;}//str转换为数字,以','或者'*'结束//buf:数字存储区//dx:小数点位数,返回给调用函数//返回值:转换后的数值int NMEA_Str2num(unsigned char *buf,unsigned char*dx){unsigned char *p=buf;unsigned int ires=0,fres=0;unsigned char ilen=0,flen=0,i;unsigned char mask=0;int res;while(1) //得到整数和小数的长度{if(*p=='-'){mask|=0X02;p++;}//是负数if(*p==','||(*p=='*'))break;//遇到结束了if(*p=='.'){mask|=0X01;p++;}//遇到小数点了else if(*p>'9'||(*p<'0'))//有非法字符{ilen=0;flen=0;break;}if(mask&0X01)flen++;else ilen++;p++;}if(mask&0X02)buf++;//去掉负号for(i=0;i<ilen;i++)//得到整数部分数据{  ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');}if(flen>5)flen=5;//最多取5位小数*dx=flen; //小数点位数for(i=0;i<flen;i++)//得到小数部分数据{  fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');} res=ires*NMEA_Pow(10,flen)+fres;if(mask&0X02)res=-res;   return res;}  //分析GPGGA信息//gpsx:nmea信息结构体//buf:接收到的GPS数据缓冲区首地址void NMEA_GPGGA_Analysis(GPS_PacketTypeDef *GPS_Packet,u8 *buf){unsigned char *p1,dx,posx;unsigned int temp;float rs;p1=(unsigned char *)strstr((const char *)buf,"$GPGGA");  //此处可改为"$GPGGA"posx=NMEA_Comma_Pos(p1,9);//得到海拔高度if(posx!=0XFF){GPS_Packet->altitude=NMEA_Str2num(p1+posx,&dx);  MyPrintf("altitude=%d\r\n",GPS_Packet->altitude);}posx=NMEA_Comma_Pos(p1,2);//得到纬度if(posx!=0XFF){temp=NMEA_Str2num(p1+posx,&dx);  GPS_Packet->latitude=temp/NMEA_Pow(10,dx+2);//得到°rs=temp%NMEA_Pow(10,dx+2);//得到' GPS_Packet->latitude=GPS_Packet->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° MyPrintf("latitude=%d\r\n",GPS_Packet->latitude);}  posx=NMEA_Comma_Pos(p1,4);//得到经度if(posx!=0XFF){  temp=NMEA_Str2num(p1+posx,&dx);  GPS_Packet->longitude=temp/NMEA_Pow(10,dx+2);//得到°rs=temp%NMEA_Pow(10,dx+2);//得到' GPS_Packet->longitude=GPS_Packet->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//转换为° MyPrintf("longitude=%d\r\n",GPS_Packet->longitude);}posx=NMEA_Comma_Pos(p1,6);//定位状态if(posx!=0XFF){GPS_Packet->status=*(p1+posx)-'0';MyPrintf("status=%d\r\n",GPS_Packet->status);}}void Ublox_Send_Date(unsigned char* dbuf,unsigned short len){unsigned short j;for(j=0;j<len;j++)//循环发送数据{while((USART2->SR&0X40)==0);//循环发送,直到发送完毕   USART2->DR=dbuf[j];  }}u8 GPS_Check(u8 *buff){u8 *p_start,*p_process;//,*p_end;//u8 temp[500];u8 res=0;//u16 cnt=0,i=0;//MyPrintf("检查GPS数据\r\n");p_start =(u8*)strstr((const char*)buff,"$GPRMC");if(p_start!=NULL)//找不到地理位置信息,返回无效{if(strstr((const char*)p_start,"$GPVTG")!=NULL && strstr((const char*)p_start,"$GPGGA")!=NULL)if(strstr((const char*)p_start,"$GPGSA")!=NULL && strstr((const char*)p_start,"$GPGSV")!=NULL)if((p_process=(u8*)strstr((const char*)p_start,"$GPGLL"))!=NULL){//MyPrintf("检查无效字符\r\n");if((strstr((const char*)p_process,"V"))!=NULL)res=0xFF;}}elseres=1;//MyPrintf("GPS Check Result=%d\r\n",res);return res;//返回无效定位数据}


H文件:

#ifndef _NEO_6M_#define _NEO_6M_#include "global.h"//UBLOX NEO-6M 配置(清除,保存,加载等)结构体__packed typedef struct  {    unsigned short header;//cfg header,固定为0X62B5(小端模式)unsigned short id;//CFG CFG ID:0X0906 (小端模式)unsigned short dlength;//数据长度 12/13unsigned int clearmask;//子区域清除掩码(1有效)unsigned int savemask;//子区域保存掩码unsigned int loadmask;//子区域加载掩码unsigned char devicemask;   //目标器件选择掩码b0:BK RAM;b1:FLASH;b2,EEPROM;b4,SPI FLASHunsigned char  cka; //校验CK_A   unsigned char  ckb; //校验CK_B  }_ublox_cfg_cfg; //UBLOX NEO-6M UART端口设置结构体__packed typedef struct  {    unsigned short header;//cfg header,固定为0X62B5(小端模式)unsigned short id;//CFG PRT ID:0X0006 (小端模式)unsigned short dlength;//数据长度 20unsigned char  portid;//端口号,0=IIC;1=UART1;2=UART2;3=USB;4=SPI;unsigned char  reserved;//保留,设置为0unsigned short txready;//TX Ready引脚设置,默认为0unsigned int mode;//串口工作模式设置,奇偶校验,停止位,字节长度等的设置.unsigned int baudrate;//波特率设置unsigned short inprotomask; //输入协议激活屏蔽位  默认设置为0X07 0X00即可.unsigned short outprotomask; //输出协议激活屏蔽位  默认设置为0X07 0X00即可.unsigned short reserved4; //保留,设置为0unsigned short reserved5; //保留,设置为0 unsigned char  cka; //校验CK_A   unsigned char  ckb;    //校验CK_B  }_ublox_cfg_prt; //UBLOX NEO-6M 刷新速率配置结构体__packed typedef struct  {    unsigned short header;//cfg header,固定为0X62B5(小端模式)unsigned short id;//CFG RATE ID:0X0806 (小端模式)unsigned short dlength;//数据长度unsigned short measrate;//测量时间间隔,单位为ms,最少不能小于200ms(5Hz)unsigned short navrate;//导航速率(周期),固定为1unsigned short timeref;//参考时间:0=UTC Time;1=GPS Time;unsigned char  cka;//校验CK_A   unsigned char  ckb;//校验CK_B  }_ublox_cfg_rate; unsigned char Ublox_Cfg_Prt(unsigned int baudrate);unsigned char Ublox_Cfg_Cfg_Save(void);void Ublox_Send_Date(unsigned char* dbuf,unsigned short len);void NMEA_GPGGA_Analysis(GPS_PacketTypeDef *GPS_Packet,unsigned char *buf);unsigned char Ublox_Cfg_Rate(unsigned short measrate,unsigned char reftime);u8 GPS_Check(u8 *buff);#endif



0 0
原创粉丝点击